bober-cli 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bobcli/__init__.py +3 -0
- bobcli/__main__.py +108 -0
- bober_cli-0.2.0.dist-info/METADATA +52 -0
- bober_cli-0.2.0.dist-info/RECORD +6 -0
- bober_cli-0.2.0.dist-info/WHEEL +4 -0
- bober_cli-0.2.0.dist-info/entry_points.txt +2 -0
bobcli/__init__.py
ADDED
bobcli/__main__.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Resolve / install the Go bobcli binary and exec it."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
MODULE = "github.com/fuwiak/bober-ai/cli/bobcli@latest"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def data_bin_dir() -> Path:
|
|
15
|
+
base = os.environ.get("XDG_CACHE_HOME") or os.path.join(Path.home(), ".cache")
|
|
16
|
+
d = Path(base) / "bobcli" / "bin"
|
|
17
|
+
d.mkdir(parents=True, exist_ok=True)
|
|
18
|
+
return d
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def cached_binary() -> Path:
|
|
22
|
+
name = "bobcli.exe" if os.name == "nt" else "bobcli"
|
|
23
|
+
return data_bin_dir() / name
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def which_go_bobcli() -> Path | None:
|
|
27
|
+
"""Find a real Go binary, skipping this pip launcher."""
|
|
28
|
+
launcher = Path(sys.argv[0]).resolve()
|
|
29
|
+
gopath = os.environ.get("GOPATH") or str(Path.home() / "go")
|
|
30
|
+
candidates = [
|
|
31
|
+
os.environ.get("BOBCLI_BIN"),
|
|
32
|
+
str(Path.home() / "bin" / "bobcli"),
|
|
33
|
+
str(Path(gopath) / "bin" / "bobcli"),
|
|
34
|
+
shutil.which("bobcli"),
|
|
35
|
+
]
|
|
36
|
+
for candidate in candidates:
|
|
37
|
+
if not candidate:
|
|
38
|
+
continue
|
|
39
|
+
p = Path(candidate).expanduser()
|
|
40
|
+
try:
|
|
41
|
+
p = p.resolve()
|
|
42
|
+
except OSError:
|
|
43
|
+
continue
|
|
44
|
+
if not p.is_file() or not os.access(p, os.X_OK):
|
|
45
|
+
continue
|
|
46
|
+
if p == launcher:
|
|
47
|
+
continue
|
|
48
|
+
if p.parent == data_bin_dir():
|
|
49
|
+
return p
|
|
50
|
+
# Prefer Go/Bubble Tea binaries (~MB), skip tiny shell wrappers
|
|
51
|
+
if p.stat().st_size > 500_000:
|
|
52
|
+
return p
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def ensure_binary() -> Path:
|
|
57
|
+
env = os.environ.get("BOBCLI_BIN", "").strip()
|
|
58
|
+
if env:
|
|
59
|
+
p = Path(env).expanduser()
|
|
60
|
+
if p.is_file() and os.access(p, os.X_OK):
|
|
61
|
+
return p
|
|
62
|
+
raise SystemExit(f"BOBCLI_BIN={env} not found or not executable")
|
|
63
|
+
|
|
64
|
+
found = which_go_bobcli()
|
|
65
|
+
if found:
|
|
66
|
+
return found
|
|
67
|
+
|
|
68
|
+
dest = cached_binary()
|
|
69
|
+
if dest.is_file() and os.access(dest, os.X_OK) and dest.stat().st_size > 500_000:
|
|
70
|
+
return dest
|
|
71
|
+
|
|
72
|
+
go = shutil.which("go")
|
|
73
|
+
if not go:
|
|
74
|
+
raise SystemExit(
|
|
75
|
+
"bobcli: Go binary not found and `go` is not on PATH.\n"
|
|
76
|
+
"Install Go 1.22+ (https://go.dev/dl/) then re-run: bobcli version\n"
|
|
77
|
+
"Or build from repo: cd cli/bobcli && go build -o bobcli . "
|
|
78
|
+
"&& export BOBCLI_BIN=$PWD/bobcli"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
print("bobcli: installing Go CLI via `go install` (first run)…", file=sys.stderr)
|
|
82
|
+
gobin = data_bin_dir()
|
|
83
|
+
run_env = {**os.environ, "GOBIN": str(gobin)}
|
|
84
|
+
try:
|
|
85
|
+
subprocess.check_call([go, "install", MODULE], env=run_env)
|
|
86
|
+
except subprocess.CalledProcessError as exc:
|
|
87
|
+
raise SystemExit(
|
|
88
|
+
"bobcli: `go install` failed. "
|
|
89
|
+
"Check network / module github.com/fuwiak/bober-ai/cli/bobcli"
|
|
90
|
+
) from exc
|
|
91
|
+
|
|
92
|
+
installed = gobin / ("bobcli.exe" if os.name == "nt" else "bobcli")
|
|
93
|
+
if not installed.is_file():
|
|
94
|
+
raise SystemExit("bobcli: go install finished but binary missing")
|
|
95
|
+
if installed != dest:
|
|
96
|
+
shutil.copy2(installed, dest)
|
|
97
|
+
dest.chmod(dest.stat().st_mode | 0o111)
|
|
98
|
+
return dest
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def main(argv: list[str] | None = None) -> None:
|
|
102
|
+
args = list(sys.argv[1:] if argv is None else argv)
|
|
103
|
+
binary = ensure_binary()
|
|
104
|
+
os.execv(str(binary), [str(binary), *args])
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
if __name__ == "__main__":
|
|
108
|
+
main()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: bober-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Bober Systems Yandex ops CLI (Webmaster, Metrika, Direct, Business) — Go TUI, pip launcher
|
|
5
|
+
Project-URL: Homepage, https://www.bober-systems.ru
|
|
6
|
+
Project-URL: Repository, https://github.com/fuwiak/bober-ai
|
|
7
|
+
Project-URL: Documentation, https://github.com/fuwiak/bober-ai/tree/main/cli/bobcli
|
|
8
|
+
Project-URL: Issues, https://github.com/fuwiak/bober-ai/issues
|
|
9
|
+
Author-email: Bober Systems <contact@bober-systems.ru>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
Keywords: bobcli,bober,cli,metrika,webmaster,yandex
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
20
|
+
Classifier: Topic :: System :: Systems Administration
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# bober-cli (pip)
|
|
25
|
+
|
|
26
|
+
Thin Python launcher for the **bobcli** Go CLI (Bubble Tea TUI).
|
|
27
|
+
|
|
28
|
+
> Разработано **Bober Systems**, бизнес-партнёром Yandex Cloud. Проект развивается независимо и не является официальным продуктом Яндекса.
|
|
29
|
+
>
|
|
30
|
+
> *Developed by Bober Systems, a Yandex Cloud business partner. This project is independently developed and is not an official Yandex product.*
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install bober-cli
|
|
36
|
+
# or
|
|
37
|
+
pipx install bober-cli
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Команда после установки: **`bobcli`**.
|
|
41
|
+
|
|
42
|
+
Требование: **Go 1.22+** на PATH (бинарь ставится через `go install` при первом запуске).
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
bobcli version
|
|
46
|
+
bobcli webmaster status
|
|
47
|
+
bobcli credentials # masked by default
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Переопределить бинарь: `export BOBCLI_BIN=/path/to/bobcli`.
|
|
51
|
+
|
|
52
|
+
Исходники CLI: [`cli/bobcli`](https://github.com/fuwiak/bober-ai/tree/main/cli/bobcli) в репозитории [bober-ai](https://github.com/fuwiak/bober-ai).
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
bobcli/__init__.py,sha256=FdjrROmmnHm6x57WL5pTHvtAW9tatqcOKYhKzhJIToc,80
|
|
2
|
+
bobcli/__main__.py,sha256=OLUuLGLfnDpezfWX9VAEnZrDSv3jCTGpDUphYY-M_qg,3300
|
|
3
|
+
bober_cli-0.2.0.dist-info/METADATA,sha256=zZYwO4oAbJdlxthnlnMD5CuMUHePyh7Vq1nF6iTHYOk,2107
|
|
4
|
+
bober_cli-0.2.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
5
|
+
bober_cli-0.2.0.dist-info/entry_points.txt,sha256=WY0wxyndAPfvIzyr43BuQ2jinAfkdv_qW5cnZhtfWGw,48
|
|
6
|
+
bober_cli-0.2.0.dist-info/RECORD,,
|