almost working impl
This commit is contained in:
parent
ee25e5dd62
commit
e7b2bb4828
8
TODO.md
8
TODO.md
|
@ -9,6 +9,13 @@
|
||||||
- [*] code style => blake, defaults
|
- [*] code style => blake, defaults
|
||||||
|
|
||||||
- [ ] tests
|
- [ ] tests
|
||||||
|
- [ ] catalog completion report:
|
||||||
|
- has github repo
|
||||||
|
- has release
|
||||||
|
- has semver release
|
||||||
|
- output semver on `--version`
|
||||||
|
- has linux + x86_64 + tgz asset
|
||||||
|
- has exe at a known place
|
||||||
- [ ] cli x (not there, there with old version, there with latest version)
|
- [ ] cli x (not there, there with old version, there with latest version)
|
||||||
|
|
||||||
- [ ] choose forge(s), one will be the golden source of the catalog
|
- [ ] choose forge(s), one will be the golden source of the catalog
|
||||||
|
@ -46,3 +53,4 @@
|
||||||
- [ ] async loading of versions ; fill output when available
|
- [ ] async loading of versions ; fill output when available
|
||||||
- [ ] cache GH response for a given time
|
- [ ] cache GH response for a given time
|
||||||
- [ ] explore a way to combine docopt and baker
|
- [ ] explore a way to combine docopt and baker
|
||||||
|
- [ ] look at fig completions
|
||||||
|
|
53
catalog.yaml
53
catalog.yaml
|
@ -1,5 +1,5 @@
|
||||||
ab:
|
ab:
|
||||||
name: Apache Benchmark
|
fullname: Apache Benchmark
|
||||||
desc: a tool for benchmarking your Apache Hypertext Transfer Protocol (HTTP) server
|
desc: a tool for benchmarking your Apache Hypertext Transfer Protocol (HTTP) server
|
||||||
|
|
||||||
arc:
|
arc:
|
||||||
|
@ -36,7 +36,13 @@ claws:
|
||||||
|
|
||||||
cliget:
|
cliget:
|
||||||
desc: install various tools in your user profile
|
desc: install various tools in your user profile
|
||||||
github: setop/cliget
|
#github: setop/cliget
|
||||||
|
|
||||||
|
d2:
|
||||||
|
fullname: Declarative Diagramming
|
||||||
|
desc: a diagram scripting language that turns text to diagrams
|
||||||
|
website: https://d2-lang.com/
|
||||||
|
github: terrastruct/d2
|
||||||
|
|
||||||
dslcad:
|
dslcad:
|
||||||
desc: a programming language & interpreter for building 3D models
|
desc: a programming language & interpreter for building 3D models
|
||||||
|
@ -66,8 +72,9 @@ fzf:
|
||||||
glances:
|
glances:
|
||||||
desc: a better top/htop
|
desc: a better top/htop
|
||||||
|
|
||||||
gloss:
|
glow:
|
||||||
desc: markdown viewer
|
desc: markdown viewer
|
||||||
|
github: charmbracelet/glow
|
||||||
|
|
||||||
gotty:
|
gotty:
|
||||||
desc: Share your terminal as a web application
|
desc: Share your terminal as a web application
|
||||||
|
@ -104,7 +111,7 @@ httpx:
|
||||||
tags: curl
|
tags: curl
|
||||||
|
|
||||||
hx:
|
hx:
|
||||||
name: helix
|
fullname: helix
|
||||||
desc: text editor, inspired by vim
|
desc: text editor, inspired by vim
|
||||||
|
|
||||||
jless:
|
jless:
|
||||||
|
@ -124,6 +131,18 @@ just:
|
||||||
github: casey/just
|
github: casey/just
|
||||||
tags: task runner, rust
|
tags: task runner, rust
|
||||||
|
|
||||||
|
k3d:
|
||||||
|
desc: a lightweight wrapper to run k3s (Rancher Lab’s minimal Kubernetes distribution) in docker.
|
||||||
|
website: https://k3d.io/
|
||||||
|
github: k3d-io/k3d
|
||||||
|
status: not a tar.gz
|
||||||
|
|
||||||
|
k3s:
|
||||||
|
desc: Lightweight Kubernetes
|
||||||
|
website: https://k3s.io/
|
||||||
|
github: k3s-io/k3s
|
||||||
|
status: no linux asset
|
||||||
|
|
||||||
ko:
|
ko:
|
||||||
desc: a simple, fast container image builder for Go applications.
|
desc: a simple, fast container image builder for Go applications.
|
||||||
github: ko-build/ko
|
github: ko-build/ko
|
||||||
|
@ -132,6 +151,11 @@ lazygit:
|
||||||
desc: simple terminal UI for git commands
|
desc: simple terminal UI for git commands
|
||||||
github: jesseduffield/lazygit
|
github: jesseduffield/lazygit
|
||||||
|
|
||||||
|
litestream:
|
||||||
|
desc: Streaming replication for SQLite.
|
||||||
|
github: benbjohnson/litestream
|
||||||
|
website: https://litestream.io/
|
||||||
|
|
||||||
mc:
|
mc:
|
||||||
desc: minio client
|
desc: minio client
|
||||||
versions: # see https://github.com/penpyt/asdf-mc/raw/master/bin/list-all
|
versions: # see https://github.com/penpyt/asdf-mc/raw/master/bin/list-all
|
||||||
|
@ -148,6 +172,11 @@ mosh:
|
||||||
website: https://mosh.org/
|
website: https://mosh.org/
|
||||||
github: mobile-shell/mosho
|
github: mobile-shell/mosho
|
||||||
|
|
||||||
|
ndcu:
|
||||||
|
desc: a disk usage analyzer with an ncurses interface
|
||||||
|
website: https://dev.yorhel.nl/ncdu
|
||||||
|
releases: https://dev.yorhel.nl/download/
|
||||||
|
|
||||||
outrun:
|
outrun:
|
||||||
desc: Delegate execution of a local command to a remote machine.
|
desc: Delegate execution of a local command to a remote machine.
|
||||||
github: Overv/outrun
|
github: Overv/outrun
|
||||||
|
@ -168,7 +197,7 @@ pylufic:
|
||||||
|
|
||||||
qjs:
|
qjs:
|
||||||
desc: a small and embeddable Javascript engine.
|
desc: a small and embeddable Javascript engine.
|
||||||
name: QuiskJS
|
fullname: QuiskJS
|
||||||
releases: http://ffmpeg.org/releases/
|
releases: http://ffmpeg.org/releases/
|
||||||
|
|
||||||
|
|
||||||
|
@ -185,7 +214,7 @@ rlwrap:
|
||||||
github: hanslub42/rlwrap
|
github: hanslub42/rlwrap
|
||||||
|
|
||||||
rg:
|
rg:
|
||||||
name: ripgrep
|
fullname: ripgrep
|
||||||
desc: improved grep
|
desc: improved grep
|
||||||
github: BurntSushi/ripgrep
|
github: BurntSushi/ripgrep
|
||||||
|
|
||||||
|
@ -228,6 +257,10 @@ terminews:
|
||||||
desc: RSS client in the terminal
|
desc: RSS client in the terminal
|
||||||
github: antavelos/terminews
|
github: antavelos/terminews
|
||||||
|
|
||||||
|
termdbms:
|
||||||
|
desc: A TUI for viewing and editing database files, CSV and SQLite.
|
||||||
|
github: mathaou/termdbms
|
||||||
|
|
||||||
#tldr:
|
#tldr:
|
||||||
# desc: Collaborative cheatsheets for console commands ; must choose a client
|
# desc: Collaborative cheatsheets for console commands ; must choose a client
|
||||||
# website: https://tldr.sh/
|
# website: https://tldr.sh/
|
||||||
|
@ -250,7 +283,7 @@ ttyd:
|
||||||
|
|
||||||
up:
|
up:
|
||||||
desc: interactively edit pipe
|
desc: interactively edit pipe
|
||||||
name: Ultimate Plumber
|
fullname: Ultimate Plumber
|
||||||
github: akavel/up
|
github: akavel/up
|
||||||
|
|
||||||
ups:
|
ups:
|
||||||
|
@ -259,7 +292,7 @@ ups:
|
||||||
tag: language:go
|
tag: language:go
|
||||||
|
|
||||||
vd:
|
vd:
|
||||||
name: VisiData
|
fullname: VisiData
|
||||||
desc: interactive multitool for tabular data
|
desc: interactive multitool for tabular data
|
||||||
pip: visidata,lxml,odfpy,openpyxl,pyarrow,urllib3,requests,pyinstaller
|
pip: visidata,lxml,odfpy,openpyxl,pyarrow,urllib3,requests,pyinstaller
|
||||||
|
|
||||||
|
@ -284,7 +317,7 @@ wrk:
|
||||||
github: wg/wrk
|
github: wg/wrk
|
||||||
|
|
||||||
ww:
|
ww:
|
||||||
name: webwormhole
|
fullname: webwormhole
|
||||||
desc: creates ephemeral pipes between computers
|
desc: creates ephemeral pipes between computers
|
||||||
website: https://webwormhole.io/
|
website: https://webwormhole.io/
|
||||||
|
|
||||||
|
@ -301,7 +334,7 @@ zee:
|
||||||
cargo:
|
cargo:
|
||||||
|
|
||||||
z:
|
z:
|
||||||
name: zoxide
|
fullname: zoxide
|
||||||
desc: A smarter cd command. Supports all major shells, inspired by z and autojump.
|
desc: A smarter cd command. Supports all major shells, inspired by z and autojump.
|
||||||
github: ajeetdsouza/zoxide
|
github: ajeetdsouza/zoxide
|
||||||
|
|
||||||
|
|
38
cliget.py
38
cliget.py
|
@ -27,6 +27,7 @@ Options:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from collections import namedtuple
|
||||||
import sys, os, shutil
|
import sys, os, shutil
|
||||||
from docopt import docopt
|
from docopt import docopt
|
||||||
from yaml import load, SafeLoader
|
from yaml import load, SafeLoader
|
||||||
|
@ -37,6 +38,15 @@ from fuzzywuzzy import fuzz
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
class DotDict(dict):
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return self[name] if name in self else None
|
||||||
|
|
||||||
|
|
||||||
|
Tool = namedtuple('Tool','cli,props,lver,rver')
|
||||||
|
Tool.__annotations__ = {'cli':str, 'props':DotDict, 'lver':VersionInfo,'rver':VersionInfo}
|
||||||
|
|
||||||
|
|
||||||
def trace(*mess):
|
def trace(*mess):
|
||||||
if "TRACE" in os.environ:
|
if "TRACE" in os.environ:
|
||||||
print("TRACE", mess)
|
print("TRACE", mess)
|
||||||
|
@ -50,11 +60,6 @@ def warn(*mess):
|
||||||
print("WARNING:", *mess)
|
print("WARNING:", *mess)
|
||||||
|
|
||||||
|
|
||||||
class DotDict(dict):
|
|
||||||
def __getattr__(self, name):
|
|
||||||
return self[name] if name in self else None
|
|
||||||
|
|
||||||
|
|
||||||
def _load_catalog(options) -> dict:
|
def _load_catalog(options) -> dict:
|
||||||
catalog = options.get(
|
catalog = options.get(
|
||||||
"__catalog", "https://codeberg.org/setop/cliget/raw/branch/main/catalog.yaml"
|
"__catalog", "https://codeberg.org/setop/cliget/raw/branch/main/catalog.yaml"
|
||||||
|
@ -70,6 +75,7 @@ def _load_catalog(options) -> dict:
|
||||||
|
|
||||||
|
|
||||||
def _find_semver(s: str) -> VersionInfo:
|
def _find_semver(s: str) -> VersionInfo:
|
||||||
|
trace(s)
|
||||||
ver = VersionInfo(0, 0, 0)
|
ver = VersionInfo(0, 0, 0)
|
||||||
try:
|
try:
|
||||||
ver = VersionInfo.parse(s)
|
ver = VersionInfo.parse(s)
|
||||||
|
@ -164,14 +170,19 @@ def dolistupdate(options):
|
||||||
def _gh_versions(repo: str) -> [VersionInfo | None]:
|
def _gh_versions(repo: str) -> [VersionInfo | None]:
|
||||||
[owner, repo] = repo.split("/")
|
[owner, repo] = repo.split("/")
|
||||||
url = f"https://api.github.com/repos/{owner}/{repo}/releases"
|
url = f"https://api.github.com/repos/{owner}/{repo}/releases"
|
||||||
|
# GH API raise 403 when too many requests are sent
|
||||||
|
# TODO implement retry with threshold
|
||||||
response = requests.get(url)
|
response = requests.get(url)
|
||||||
|
trace(response)
|
||||||
return [_find_semver(o.get("tag_name")) for o in response.json()]
|
return [_find_semver(o.get("tag_name")) for o in response.json()]
|
||||||
|
|
||||||
|
|
||||||
def _gh_version(repo: str) -> [VersionInfo | None]:
|
def _gh_version(repo: str) -> [VersionInfo | None]:
|
||||||
[owner, repo] = repo.split("/")
|
[owner, repo] = repo.split("/")
|
||||||
url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
|
url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
|
||||||
|
trace(url)
|
||||||
response = requests.get(url)
|
response = requests.get(url)
|
||||||
|
trace(response)
|
||||||
return _find_semver(response.json().get("tag_name"))
|
return _find_semver(response.json().get("tag_name"))
|
||||||
|
|
||||||
|
|
||||||
|
@ -226,11 +237,15 @@ def doinstall(options):
|
||||||
def _match_arch_machine(name: str) -> bool:
|
def _match_arch_machine(name: str) -> bool:
|
||||||
sysname = os.uname().sysname.lower() # os
|
sysname = os.uname().sysname.lower() # os
|
||||||
machine = os.uname().machine.lower() # arch
|
machine = os.uname().machine.lower() # arch
|
||||||
return name.lower().find(sysname) > 0 and name.lower().find(machine) > 0
|
# we don't consider libc - glic or musl - as musl is usually statically embed
|
||||||
|
lname = name.lower()
|
||||||
|
return (lname.find(sysname) > 0
|
||||||
|
and (lname.find(machine) > 0
|
||||||
|
or (machine == "x86_64" and lname.find("amd64") > 0)) # x86_64 and "amd64" are synonym
|
||||||
|
)
|
||||||
|
|
||||||
|
def _get_gh_matching_release(repo):
|
||||||
def _perform_gh_install(cli, repo, version=None):
|
# get asset list from last release
|
||||||
# get asset list
|
|
||||||
url = f"https://api.github.com/repos/{repo}/releases/latest"
|
url = f"https://api.github.com/repos/{repo}/releases/latest"
|
||||||
r = requests.get(url)
|
r = requests.get(url)
|
||||||
assets = r.json()["assets"]
|
assets = r.json()["assets"]
|
||||||
|
@ -238,6 +253,10 @@ def _perform_gh_install(cli, repo, version=None):
|
||||||
# select right asset
|
# select right asset
|
||||||
asset = DotDict(next(filter(lambda x: _match_arch_machine(x["name"]), assets)))
|
asset = DotDict(next(filter(lambda x: _match_arch_machine(x["name"]), assets)))
|
||||||
trace(asset.name, asset.url)
|
trace(asset.name, asset.url)
|
||||||
|
return asset
|
||||||
|
|
||||||
|
def _perform_gh_install(cli, repo, version=None):
|
||||||
|
asset = _get_gh_matching_release(repo)
|
||||||
# mkdirs
|
# mkdirs
|
||||||
p = os.path
|
p = os.path
|
||||||
home = os.environ["HOME"]
|
home = os.environ["HOME"]
|
||||||
|
@ -259,6 +278,7 @@ def _perform_gh_install(cli, repo, version=None):
|
||||||
trace("process tgz")
|
trace("process tgz")
|
||||||
os.makedirs(progloc, exist_ok=True)
|
os.makedirs(progloc, exist_ok=True)
|
||||||
run(["tar", "xfz", location, "-C", progloc])
|
run(["tar", "xfz", location, "-C", progloc])
|
||||||
|
# TODO look for exe : ./cli, ./<tar root folder>/cli, exe propertie
|
||||||
# symlink
|
# symlink
|
||||||
# TODO remove existing symlink
|
# TODO remove existing symlink
|
||||||
os.symlink(p.join('../programs', cli, cli), p.join(home, ".local/bin", cli))
|
os.symlink(p.join('../programs', cli, cli), p.join(home, ".local/bin", cli))
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
pyyaml
|
pyyaml
|
||||||
docopt
|
docopt
|
||||||
semver
|
semver
|
||||||
#fuzzywuzzy
|
fuzzywuzzy
|
||||||
thefuzz
|
#thefuzz
|
||||||
#python-Levenshtein
|
#python-Levenshtein
|
||||||
requests
|
requests
|
||||||
#tabulate
|
#tabulate
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
from collections import namedtuple as nt
|
||||||
|
from cliget import _load_catalog as ldc, _local_version as lv, _gh_version
|
||||||
|
from semver import VersionInfo
|
||||||
|
|
||||||
|
Result = nt('res', "cli lver gh rver asset exe")
|
||||||
|
#Result.__repr__ = lambda x: f'{x.gh}'
|
||||||
|
|
||||||
|
# catalog completion report:
|
||||||
|
ctl = ldc({'__catalog':'catalog.yaml'})
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
report = {}
|
||||||
|
for cli, props in ctl.items():
|
||||||
|
lver, gh, rver, asset, exe = (False,)*5 # it is False until it is True
|
||||||
|
# output semver on `--version`
|
||||||
|
lver = lv(cli) > VersionInfo(0)
|
||||||
|
# has github repo
|
||||||
|
gh = props.github is not None
|
||||||
|
if gh:
|
||||||
|
# has semver release
|
||||||
|
rver = _gh_version(props.github) > VersionInfo(0)
|
||||||
|
# has linux + x86_64 + tgz asset
|
||||||
|
# has exe at a known place
|
||||||
|
r = Result(cli, lver, gh, rver, asset, exe)
|
||||||
|
print(r)
|
||||||
|
|
Loading…
Reference in New Issue