diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..1b536ff --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,36 @@ + +## arguments + +* argparse : the standard way +* getopt : for C users +* baker : decorator overs functions +* [docopt](http://docopt.org/) : CLI description language ; python 3.6 ! ; nim port available + +## TUI + +* must display tables +* must display progress bar + +## semver + + +* pip install semver https://pypi.org/project/semver/, https://github.com/python-semver/python-semver/releases +* pip install python-semanticversion +* most pakging tool : packaging https://packaging.pypa.io/en/latest/version.html, setuptool, distutils + +## arch + +use `os.uname()` + +## downloader + +* requests + +## install + +* unpack in ~/.local/programs/ +* link exe in ~/.local/bin + + + + diff --git a/README.md b/README.md index 59bd73f..3bcd868 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ Inspired by envinstall (private), [webinstall](gh:webinstall/webi-installers), [ - [ ] identify installed version - [ ] can install itself - [ ] have nice defaults (gh release, targz, x86_64, linux, etc.) + - [ ] favor convention over configuration + - [ ] tries to guess as much as possible - [ ] small codebase, preferably one file @@ -48,6 +50,20 @@ Inspired by envinstall (private), [webinstall](gh:webinstall/webi-installers), [ - overlap with package managers (apt, yum, etc.) or environment managers (nix, asdf, etc.) +# conventions and defaults + +* default status of an entry is "tested" which means the process has been tested under linux-amd64 +* entry name in the catalog is the name of the exe ; a prefered name can be added as a property +* tools in unpacked in `~/.local/programs` then symlinked in `~/.local/bin` which must be in PATH +* semver = semantic versioning : tools are versionned as `major[.minor[.patch[-prerelease[+build]]]]` so versions can be compared +* installed version is obtained by ruinning ` --version` +* OS and arch are obtained with `os.uname()` python function +* default release system is GitHub releases and use `repo` property +* default packaging is `.tar.gz` +* default structure is to have the exe in the `bin` folder + +most defaults can be overriden + # FAQ @@ -70,6 +86,10 @@ Tools developers / maintainers are not supposed to know CliGet exists. It adapts Only the first time. After being installed, CliGet is managed by CliGet. +#### why this name ? + +It is like wget but fo CLI. Plus, I like the sound of it :) + #### I already use [asdf](https://asdf-vm.com/), why would I need cliget ? asdf is a wonderful tool when it comes to do software development in various programming language while mixing versions from one project to an other. diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..94b16e8 --- /dev/null +++ b/TODO.md @@ -0,0 +1,22 @@ + + +- [ ] choose forge + * github + * gitlab + * framagit + * codeberg + * source hut + * my gitea + +- [ ] reserve name + - [ ] GH + - [ ] Pypy + +- [ ] release + - [ ] GH release + - [ ] pypy package + +- [ ] open issue in managed tool forge for them to add cliget install method + +- [ ] communicate on geeks'platform : HN, lobsters, reddit, linuxfr + diff --git a/catalog.yaml b/catalog.yaml index 3d2e454..33f8b56 100644 --- a/catalog.yaml +++ b/catalog.yaml @@ -161,6 +161,11 @@ rg: desc: improved grep repo: BurntSushi/ripgrep +sake: + desc: a command runner for local and remote hosts + repo: alajmo/sake + website: https://sakecli.com/ + slugify: desc: generate sluged version of input repo: un33k/python-slugify @@ -183,7 +188,6 @@ tab: website: http://tab-lang.xyz/ repo: https://bitbucket.org/tkatchev/tab - task: repo: go-task/task desc: A task runner / simpler Make alternative written in Go @@ -222,6 +226,10 @@ vd: desc: interactive multitool for tabular data pip: visidata,lxml,odfpy,openpyxl,pyarrow,urllib3,requests,pyinstaller +vhs: + desc: Write terminal GIFs as code for integration testing and demoing your CLI tools. + repo: charmbracelet/vhs + vuls: desc: Agent-less vulnerability scanner for Linux, FreeBSD, Container, WordPress, Programming language libraries, Network devices repo: future-architect/vuls diff --git a/cliget.py b/cliget.py new file mode 100644 index 0000000..7f779f6 --- /dev/null +++ b/cliget.py @@ -0,0 +1,63 @@ +"""Cliget - install cli tools in you user profile + +Usage: + cliget [-c URL] list + cliget [-c URL] search PAT + cliget [-c URL] update [--all] [TOOL ...] + +list list all installed tools +search search for tools in the catalog with the given pattenr +update list all updatable tools +update TOOL update tools +update --all update all updatable tools + + +Options: + -h, --help + -c, --catalog URL +""" + +from yaml import load, SafeLoader +import semver +from docopt import docopt +from subprocess import run, CalledProcessError, TimeoutExpired + +class DotDict(dict): + def __getattr__(self, name): + return self[name] if name in self else None + +def loadcatalog(options)->dict: + catalog=options.get('--catalog', 'catalog.yaml') + return load(open(catalog),SafeLoader) + +ver = semver.VersionInfo.parse('1.2.3-pre.2+build.4') +#print(ver.major, ver.minor, ver.patch) + +_version = lambda cmd: run([cmd, '--version'], input='', text=True, capture_output=True, check=True, timeout=0.1).stdout.split('\n')[0] + +def debug(mess): + #print(mess) + pass + +def dolist(options): + ctl = loadcatalog(options) + for cli,_ in ctl.items(): + # search in path + try: + debug(cli, _version(cli)) + except CalledProcessError: + debug(cli, "call error") + except TimeoutExpired: + debug(cli, "timeout") + except FileNotFoundError: + debug(cli, "not found") + + +if __name__ == '__main__': + options = docopt(__doc__, version='Cliget 0.1.0') + print(options) + options = DotDict(options) + if options.list: + dolist(options) + elif options.search: + dosearch(options) diff --git a/requirements.txt b/requirements.txt index c3726e8..276d4f5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,3 @@ pyyaml +docopt +semver