From b5b21f6ca924d6836771a580d3e5057f3b87b54f Mon Sep 17 00:00:00 2001 From: setop Date: Wed, 15 Feb 2023 18:24:14 +0100 Subject: [PATCH] more entries in the catalog ; more readme and faq ; onging impl --- README.md | 5 ++-- TODO.md | 20 ++++++++++++++-- catalog.yaml | 24 ++++++++++++++++--- cliget.py | 60 ++++++++++++++++++++++++++++++++++++++---------- cmd.txt | 2 +- requirements.txt | 1 + 6 files changed, 92 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 3bcd868..5b7cef5 100644 --- a/README.md +++ b/README.md @@ -52,13 +52,14 @@ Inspired by envinstall (private), [webinstall](gh:webinstall/webi-installers), [ # conventions and defaults -* default status of an entry is "tested" which means the process has been tested under linux-amd64 +* default status of an entry in the catalog is "ok" 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 +* packages are downloaded in `.cache/cliget` * 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 release system is GitHub releases and use `github` property * default packaging is `.tar.gz` * default structure is to have the exe in the `bin` folder diff --git a/TODO.md b/TODO.md index 94b16e8..3298b28 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,16 @@ +- [ ] implement MVP + - [+] minimal catalog + - [+] search catalog + - [+] local current versions + - [ ] latest version, github strategy + - [ ] intall, github strategy -- [ ] choose forge +- [ ] choose forge(s), one will be the golden source of the catalog * github * gitlab * framagit - * codeberg + * codeberg <= golden source * source hut * my gitea @@ -20,3 +26,13 @@ - [ ] communicate on geeks'platform : HN, lobsters, reddit, linuxfr +- [ ] post MVP improvement + - [ ] check local env: + - [ ] existence of `.local`, `.local/programs`, `.local/bin` + - [ ] that permissions are ok + - [ ] that `.local/bin` are in `PATH` + - [ ] allow to force installation version + - [ ] allow to list versions + - [ ] improve search algorithm, fuzzing + + diff --git a/catalog.yaml b/catalog.yaml index 6cf199f..8268276 100644 --- a/catalog.yaml +++ b/catalog.yaml @@ -41,6 +41,10 @@ cliget: exa: desc: enhanced ls +fail: + desc: this entry will fail, for test purpos + github: fail/fail + fd: desc: A simple, fast and user-friendly alternative to `find` github: sharkdp/fd @@ -100,13 +104,16 @@ hx: desc: text editor, inspired by vim jless: - desc: json document browser + desc: a command-line JSON viewer designed for reading, exploring, and searching through JSON data + github: PaulJuliusMartinez/jless jp: - desc: ploting + desc: dead simple terminal plots from JSON data + github: sgreben/jp jq: desc: json query + github: stedolan/jq just: desc: a handy way to save and run project-specific commands. @@ -132,13 +139,19 @@ mintproxy: desc: interactive, SSL/TLS-capable intercepting proxy with a console interface for HTTP/1, HTTP/2, and WebSockets. pipx: +mosh: + desc: Remote terminal application that allows roaming, supports intermittent connectivity, and provides intelligent local echo and line editing of user keystrokes. + website: https://mosh.org/ + github: mobile-shell/mosho + outrun: desc: Delegate execution of a local command to a remote machine. github: Overv/outrun pip: pet: - desc: manager snippets + desc: Simple command-line snippet manager + github: knqyf263/pet pylufic: inst: direct @@ -221,6 +234,11 @@ up: name: Ultimate Plumber github: akavel/up +ups: + desc: Command line tools for manipulating UPS patch files + githb: rameshvarun/ups + tag: language:go + vd: name: VisiData desc: interactive multitool for tabular data diff --git a/cliget.py b/cliget.py index a899965..166282e 100644 --- a/cliget.py +++ b/cliget.py @@ -3,10 +3,12 @@ Usage: cliget [-v] [-c URL] list cliget [-v] [-c URL] search PAT + cliget [-v] [-c URL] install TOOL ... cliget [-v] [-c URL] update [--all] [TOOL ...] list list all installed tools search search for tools in the catalog with the given pattern +install TOOL install some tools update list all updatable tools update TOOL update tools update --all update all updatable tools @@ -18,6 +20,7 @@ Options: -v, --verbose """ +import logging import sys, os from docopt import docopt from yaml import load, SafeLoader @@ -25,10 +28,14 @@ from semver import VersionInfo import re from subprocess import run, CalledProcessError, TimeoutExpired from fuzzywuzzy import fuzz +import requests -def debug(*mess): - #print("DEBUG", mess) - pass +def trace(*mess): + if "TRACE" in os.environ: + print("TRACE", mess) + +def warn(*mess): + print(f"WARN {mess[0]}") class DotDict(dict): def __getattr__(self, name): @@ -36,7 +43,9 @@ class DotDict(dict): def loadcatalog(options)->dict: catalog=options.get('__catalog', 'catalog.yaml') - return load(open(catalog), SafeLoader) + o = load(open(catalog), SafeLoader) + trace(o) + return { k:DotDict(v) for k,v in o.items()} def find_semver(s:str) -> VersionInfo: ver = VersionInfo(0,0,0) @@ -46,7 +55,7 @@ def find_semver(s:str) -> VersionInfo: try: ver = VersionInfo(*list(i.group(0) for i in re.finditer('\d+', s))[:3]) except Exception as e: - debug("parse error", e) + trace("parse error", e) return ver @@ -59,14 +68,14 @@ def _internal_list(options) -> tuple[str,VersionInfo]: # search in path try: vers = _version(cli) - debug(cli, vers) + trace(cli, vers) yield cli, props, find_semver(vers) except CalledProcessError: - debug(cli, "call error") + trace(cli, "call error") except TimeoutExpired: - debug(cli, "timeout") + trace(cli, "timeout") except FileNotFoundError: - debug(cli, "not found") + trace(cli, "not found") def dolist(options): for (cli, _, ver) in _internal_list(options): @@ -77,7 +86,7 @@ def dosearch(options): ctl = loadcatalog(options) L = [] for cli, props in ctl.items(): - debug(cli, props) + trace(cli, props) rtitle = fuzz.ratio(cli, pat) rdesc = fuzz.partial_ratio(props['desc'], pat) score = 2 * rtitle + rdesc @@ -93,17 +102,44 @@ def dolistupdate(options): if props.github: pass pass + + +def _gh_version(repo:str) -> [VersionInfo|None]: + [owner, repo] = repo.split("/") + url = f'https://api.github.com/repos/{owner}/{repo}/releases/latest' + response = requests.get(url) + return response.json().get("name") + +def doinstall(options): + tools = options.TOOL + ctl = loadcatalog(options) + for tool in tools: + if tool in ctl: + props = ctl[tool] + if props.github: + vers = _gh_version(props.github) + trace(vers) + else: + warn(f'{tool} not in catalog') + if __name__ == '__main__': + if "DEBUG" in os.environ: + logging.basicConfig(level=logging.DEBUG) + logging.debug("debug is on") + else: + logging.info("not in debug") options = docopt(__doc__, version='Cliget 0.1.0') options = DotDict({k.replace('-','_'):v for (k,v) in options.items() if v is not None}) - debug(options) + trace(options) if options.list: dolist(options) elif options.search: dosearch(options) - elif options.update: + elif options.install or options.update: if not options.__all and len(options.TOOL)==0: dolistupdate(options) + elif len(options.TOOL)>0: + doinstall(options) else: print("not implemented") diff --git a/cmd.txt b/cmd.txt index 3cba195..36a9d75 100644 --- a/cmd.txt +++ b/cmd.txt @@ -1,4 +1,4 @@ -. ./venv/bin/activate +. ./.venv/bin/activate diff --git a/requirements.txt b/requirements.txt index 16a50f8..0a45e45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ docopt semver fuzzywuzzy python-Levenshtein +requests