lark-cli 0.1.1__tar.gz
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.
- lark_cli-0.1.1/PKG-INFO +58 -0
- lark_cli-0.1.1/README.md +50 -0
- lark_cli-0.1.1/pyproject.toml +23 -0
- lark_cli-0.1.1/setup.cfg +4 -0
- lark_cli-0.1.1/setup.py +35 -0
- lark_cli-0.1.1/src/lark_cli/__init__.py +3 -0
- lark_cli-0.1.1/src/lark_cli/cli.py +10 -0
- lark_cli-0.1.1/src/lark_cli/install_hooks.py +5 -0
- lark_cli-0.1.1/src/lark_cli/release.py +146 -0
- lark_cli-0.1.1/src/lark_cli.egg-info/PKG-INFO +58 -0
- lark_cli-0.1.1/src/lark_cli.egg-info/SOURCES.txt +15 -0
- lark_cli-0.1.1/src/lark_cli.egg-info/dependency_links.txt +1 -0
- lark_cli-0.1.1/src/lark_cli.egg-info/entry_points.txt +2 -0
- lark_cli-0.1.1/src/lark_cli.egg-info/top_level.txt +1 -0
- lark_cli-0.1.1/tests/test_cli.py +27 -0
- lark_cli-0.1.1/tests/test_install_hooks.py +13 -0
- lark_cli-0.1.1/tests/test_release.py +38 -0
lark_cli-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lark-cli
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A tiny CLI that says Coming soon
|
|
5
|
+
Author: Your Name
|
|
6
|
+
Requires-Python: >=3.7
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# lark-cli
|
|
10
|
+
|
|
11
|
+
Python wrapper for the official `larksuite/cli` release binary.
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
- Resolves the latest GitHub release from `https://github.com/larksuite/cli`
|
|
16
|
+
- Chooses the current platform asset automatically
|
|
17
|
+
- Runs the extracted `lark-cli` binary
|
|
18
|
+
- Passes all CLI arguments through unchanged
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
lark-cli <any-args>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
lark-cli api list --page 1
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Local binary cache location
|
|
33
|
+
|
|
34
|
+
- macOS/Linux: `~/.cache/lark-cli-python-wrapper/current/lark-cli`
|
|
35
|
+
- Windows: `%LOCALAPPDATA%\lark-cli-python-wrapper\current\lark-cli.exe`
|
|
36
|
+
|
|
37
|
+
Set `LARK_CLI_WRAPPER_HOME` to override this location.
|
|
38
|
+
|
|
39
|
+
## Build & publish to PyPI
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
python3 -m pip install --upgrade build twine
|
|
43
|
+
python3 -m build
|
|
44
|
+
python3 -m twine check dist/*
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Before upload, bump `version` in `pyproject.toml` (for example `0.1.1` -> `0.1.2`).
|
|
48
|
+
|
|
49
|
+
> Do not upload with `dist/*` if old files still exist in `dist/`, otherwise PyPI may reject duplicates.
|
|
50
|
+
|
|
51
|
+
Upload only the current version files explicitly:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
python3 -m twine upload \
|
|
55
|
+
dist/lark_cli-0.1.1-py3-none-any.whl \
|
|
56
|
+
dist/lark-cli-0.1.1.tar.gz \
|
|
57
|
+
--verbose
|
|
58
|
+
```
|
lark_cli-0.1.1/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# lark-cli
|
|
2
|
+
|
|
3
|
+
Python wrapper for the official `larksuite/cli` release binary.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- Resolves the latest GitHub release from `https://github.com/larksuite/cli`
|
|
8
|
+
- Chooses the current platform asset automatically
|
|
9
|
+
- Runs the extracted `lark-cli` binary
|
|
10
|
+
- Passes all CLI arguments through unchanged
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
lark-cli <any-args>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
lark-cli api list --page 1
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Local binary cache location
|
|
25
|
+
|
|
26
|
+
- macOS/Linux: `~/.cache/lark-cli-python-wrapper/current/lark-cli`
|
|
27
|
+
- Windows: `%LOCALAPPDATA%\lark-cli-python-wrapper\current\lark-cli.exe`
|
|
28
|
+
|
|
29
|
+
Set `LARK_CLI_WRAPPER_HOME` to override this location.
|
|
30
|
+
|
|
31
|
+
## Build & publish to PyPI
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python3 -m pip install --upgrade build twine
|
|
35
|
+
python3 -m build
|
|
36
|
+
python3 -m twine check dist/*
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Before upload, bump `version` in `pyproject.toml` (for example `0.1.1` -> `0.1.2`).
|
|
40
|
+
|
|
41
|
+
> Do not upload with `dist/*` if old files still exist in `dist/`, otherwise PyPI may reject duplicates.
|
|
42
|
+
|
|
43
|
+
Upload only the current version files explicitly:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
python3 -m twine upload \
|
|
47
|
+
dist/lark_cli-0.1.1-py3-none-any.whl \
|
|
48
|
+
dist/lark-cli-0.1.1.tar.gz \
|
|
49
|
+
--verbose
|
|
50
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "lark-cli"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "A tiny CLI that says Coming soon"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.7"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Your Name" }
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.scripts]
|
|
16
|
+
lark-cli = "lark_cli.cli:main"
|
|
17
|
+
|
|
18
|
+
[tool.pytest.ini_options]
|
|
19
|
+
pythonpath = ["src"]
|
|
20
|
+
testpaths = ["tests"]
|
|
21
|
+
|
|
22
|
+
[tool.setuptools.packages.find]
|
|
23
|
+
where = ["src"]
|
lark_cli-0.1.1/setup.cfg
ADDED
lark_cli-0.1.1/setup.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from setuptools import setup
|
|
5
|
+
from setuptools.command.develop import develop
|
|
6
|
+
from setuptools.command.install import install
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
PROJECT_ROOT = Path(__file__).resolve().parent
|
|
10
|
+
SRC_DIR = PROJECT_ROOT / "src"
|
|
11
|
+
sys.path.insert(0, str(SRC_DIR))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class InstallWithBinary(install):
|
|
15
|
+
def run(self):
|
|
16
|
+
super().run()
|
|
17
|
+
from lark_cli.install_hooks import download_release_during_install
|
|
18
|
+
|
|
19
|
+
download_release_during_install()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DevelopWithBinary(develop):
|
|
23
|
+
def run(self):
|
|
24
|
+
super().run()
|
|
25
|
+
from lark_cli.install_hooks import download_release_during_install
|
|
26
|
+
|
|
27
|
+
download_release_during_install()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
setup(
|
|
31
|
+
cmdclass={
|
|
32
|
+
"install": InstallWithBinary,
|
|
33
|
+
"develop": DevelopWithBinary,
|
|
34
|
+
}
|
|
35
|
+
)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
import tarfile
|
|
5
|
+
import tempfile
|
|
6
|
+
import time
|
|
7
|
+
import urllib.request
|
|
8
|
+
import zipfile
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from platform import machine, system
|
|
11
|
+
from stat import S_IXGRP, S_IXOTH, S_IXUSR
|
|
12
|
+
from typing import Dict, Iterable, Tuple
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
LATEST_RELEASE_API = "https://api.github.com/repos/larksuite/cli/releases/latest"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def normalize_platform(raw_system: str, raw_machine: str) -> Tuple[str, str, str]:
|
|
19
|
+
os_name = raw_system.lower()
|
|
20
|
+
if os_name not in {"darwin", "linux", "windows"}:
|
|
21
|
+
raise RuntimeError(f"Unsupported OS: {raw_system}")
|
|
22
|
+
|
|
23
|
+
normalized_machine = raw_machine.lower()
|
|
24
|
+
if normalized_machine in {"x86_64", "amd64"}:
|
|
25
|
+
arch = "amd64"
|
|
26
|
+
elif normalized_machine in {"arm64", "aarch64"}:
|
|
27
|
+
arch = "arm64"
|
|
28
|
+
else:
|
|
29
|
+
raise RuntimeError(f"Unsupported architecture: {raw_machine}")
|
|
30
|
+
|
|
31
|
+
extension = ".zip" if os_name == "windows" else ".tar.gz"
|
|
32
|
+
return os_name, arch, extension
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def choose_asset(assets: Iterable[Dict[str, str]], os_name: str, arch: str, extension: str) -> Dict[str, str]:
|
|
36
|
+
target_suffix = f"-{os_name}-{arch}{extension}"
|
|
37
|
+
for asset in assets:
|
|
38
|
+
name = asset.get("name", "")
|
|
39
|
+
if name.startswith("lark-cli-") and name.endswith(target_suffix):
|
|
40
|
+
return asset
|
|
41
|
+
raise RuntimeError(f"No matching release asset for {os_name}/{arch}{extension}")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _fetch_latest_release() -> Dict[str, object]:
|
|
45
|
+
request = urllib.request.Request(
|
|
46
|
+
LATEST_RELEASE_API,
|
|
47
|
+
headers={"Accept": "application/vnd.github+json"},
|
|
48
|
+
)
|
|
49
|
+
with urllib.request.urlopen(request, timeout=20) as response:
|
|
50
|
+
payload = json.loads(response.read().decode("utf-8"))
|
|
51
|
+
return payload
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _default_install_root() -> Path:
|
|
55
|
+
custom_root = os.environ.get("LARK_CLI_WRAPPER_HOME")
|
|
56
|
+
if custom_root:
|
|
57
|
+
return Path(custom_root)
|
|
58
|
+
|
|
59
|
+
home = Path.home()
|
|
60
|
+
if os.name == "nt":
|
|
61
|
+
base = Path(os.environ.get("LOCALAPPDATA", home))
|
|
62
|
+
else:
|
|
63
|
+
base = Path(os.environ.get("XDG_CACHE_HOME", home / ".cache"))
|
|
64
|
+
return base / "lark-cli-python-wrapper"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _find_binary(extracted_dir: Path, binary_name: str) -> Path:
|
|
68
|
+
for root, _, files in os.walk(extracted_dir):
|
|
69
|
+
if binary_name in files:
|
|
70
|
+
return Path(root) / binary_name
|
|
71
|
+
raise RuntimeError(f"Binary '{binary_name}' not found in extracted release archive")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _extract_archive(archive_path: Path, destination: Path) -> None:
|
|
75
|
+
if archive_path.name.endswith(".tar.gz"):
|
|
76
|
+
with tarfile.open(archive_path, mode="r:gz") as tar:
|
|
77
|
+
tar.extractall(destination)
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
if archive_path.name.endswith(".zip"):
|
|
81
|
+
with zipfile.ZipFile(archive_path, mode="r") as archive:
|
|
82
|
+
archive.extractall(destination)
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
raise RuntimeError(f"Unsupported archive format: {archive_path.name}")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _download_file(url: str, destination: Path) -> None:
|
|
89
|
+
request = urllib.request.Request(
|
|
90
|
+
url,
|
|
91
|
+
headers={
|
|
92
|
+
"Accept": "application/octet-stream",
|
|
93
|
+
"User-Agent": "lark-cli-python-wrapper",
|
|
94
|
+
},
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
last_error = None
|
|
98
|
+
for _ in range(3):
|
|
99
|
+
try:
|
|
100
|
+
with urllib.request.urlopen(request, timeout=60) as response, destination.open("wb") as file_obj:
|
|
101
|
+
shutil.copyfileobj(response, file_obj)
|
|
102
|
+
return
|
|
103
|
+
except Exception as error: # noqa: BLE001
|
|
104
|
+
last_error = error
|
|
105
|
+
time.sleep(1)
|
|
106
|
+
|
|
107
|
+
if last_error is not None:
|
|
108
|
+
raise last_error
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def ensure_installed_binary(force: bool = False) -> str:
|
|
112
|
+
os_name, arch, extension = normalize_platform(system(), machine())
|
|
113
|
+
binary_name = "lark-cli.exe" if os_name == "windows" else "lark-cli"
|
|
114
|
+
|
|
115
|
+
install_root = _default_install_root()
|
|
116
|
+
target_dir = install_root / "current"
|
|
117
|
+
binary_path = target_dir / binary_name
|
|
118
|
+
|
|
119
|
+
if binary_path.exists() and not force:
|
|
120
|
+
return str(binary_path)
|
|
121
|
+
|
|
122
|
+
release = _fetch_latest_release()
|
|
123
|
+
assets = release.get("assets", [])
|
|
124
|
+
if not isinstance(assets, list):
|
|
125
|
+
raise RuntimeError("Release payload missing assets list")
|
|
126
|
+
selected_asset = choose_asset(assets, os_name, arch, extension)
|
|
127
|
+
|
|
128
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
129
|
+
|
|
130
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
131
|
+
temp_path = Path(temp_dir)
|
|
132
|
+
archive_path = temp_path / selected_asset["name"]
|
|
133
|
+
_download_file(selected_asset["browser_download_url"], archive_path)
|
|
134
|
+
|
|
135
|
+
extract_dir = temp_path / "extract"
|
|
136
|
+
extract_dir.mkdir(parents=True, exist_ok=True)
|
|
137
|
+
_extract_archive(archive_path, extract_dir)
|
|
138
|
+
extracted_binary = _find_binary(extract_dir, binary_name)
|
|
139
|
+
|
|
140
|
+
shutil.copy2(extracted_binary, binary_path)
|
|
141
|
+
|
|
142
|
+
if os_name != "windows":
|
|
143
|
+
current_mode = binary_path.stat().st_mode
|
|
144
|
+
binary_path.chmod(current_mode | S_IXUSR | S_IXGRP | S_IXOTH)
|
|
145
|
+
|
|
146
|
+
return str(binary_path)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lark-cli
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A tiny CLI that says Coming soon
|
|
5
|
+
Author: Your Name
|
|
6
|
+
Requires-Python: >=3.7
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# lark-cli
|
|
10
|
+
|
|
11
|
+
Python wrapper for the official `larksuite/cli` release binary.
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
- Resolves the latest GitHub release from `https://github.com/larksuite/cli`
|
|
16
|
+
- Chooses the current platform asset automatically
|
|
17
|
+
- Runs the extracted `lark-cli` binary
|
|
18
|
+
- Passes all CLI arguments through unchanged
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
lark-cli <any-args>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
lark-cli api list --page 1
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Local binary cache location
|
|
33
|
+
|
|
34
|
+
- macOS/Linux: `~/.cache/lark-cli-python-wrapper/current/lark-cli`
|
|
35
|
+
- Windows: `%LOCALAPPDATA%\lark-cli-python-wrapper\current\lark-cli.exe`
|
|
36
|
+
|
|
37
|
+
Set `LARK_CLI_WRAPPER_HOME` to override this location.
|
|
38
|
+
|
|
39
|
+
## Build & publish to PyPI
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
python3 -m pip install --upgrade build twine
|
|
43
|
+
python3 -m build
|
|
44
|
+
python3 -m twine check dist/*
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Before upload, bump `version` in `pyproject.toml` (for example `0.1.1` -> `0.1.2`).
|
|
48
|
+
|
|
49
|
+
> Do not upload with `dist/*` if old files still exist in `dist/`, otherwise PyPI may reject duplicates.
|
|
50
|
+
|
|
51
|
+
Upload only the current version files explicitly:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
python3 -m twine upload \
|
|
55
|
+
dist/lark_cli-0.1.1-py3-none-any.whl \
|
|
56
|
+
dist/lark-cli-0.1.1.tar.gz \
|
|
57
|
+
--verbose
|
|
58
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
setup.py
|
|
4
|
+
src/lark_cli/__init__.py
|
|
5
|
+
src/lark_cli/cli.py
|
|
6
|
+
src/lark_cli/install_hooks.py
|
|
7
|
+
src/lark_cli/release.py
|
|
8
|
+
src/lark_cli.egg-info/PKG-INFO
|
|
9
|
+
src/lark_cli.egg-info/SOURCES.txt
|
|
10
|
+
src/lark_cli.egg-info/dependency_links.txt
|
|
11
|
+
src/lark_cli.egg-info/entry_points.txt
|
|
12
|
+
src/lark_cli.egg-info/top_level.txt
|
|
13
|
+
tests/test_cli.py
|
|
14
|
+
tests/test_install_hooks.py
|
|
15
|
+
tests/test_release.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
lark_cli
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from lark_cli import cli
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_main_forwards_all_args_to_downloaded_binary(monkeypatch):
|
|
7
|
+
captured = {}
|
|
8
|
+
|
|
9
|
+
def fake_ensure_installed_binary():
|
|
10
|
+
return "/tmp/lark-cli"
|
|
11
|
+
|
|
12
|
+
class Result:
|
|
13
|
+
returncode = 7
|
|
14
|
+
|
|
15
|
+
def fake_run(cmd):
|
|
16
|
+
captured["cmd"] = cmd
|
|
17
|
+
return Result()
|
|
18
|
+
|
|
19
|
+
monkeypatch.setattr(cli, "ensure_installed_binary", fake_ensure_installed_binary)
|
|
20
|
+
monkeypatch.setattr(cli.subprocess, "run", fake_run)
|
|
21
|
+
monkeypatch.setattr(cli.sys, "argv", ["lark-cli", "im", "send", "--text", "hello"])
|
|
22
|
+
|
|
23
|
+
with pytest.raises(SystemExit) as raised:
|
|
24
|
+
cli.main()
|
|
25
|
+
|
|
26
|
+
assert raised.value.code == 7
|
|
27
|
+
assert captured["cmd"] == ["/tmp/lark-cli", "im", "send", "--text", "hello"]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from lark_cli import install_hooks
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_install_hook_triggers_download(monkeypatch):
|
|
5
|
+
called = {"value": False}
|
|
6
|
+
|
|
7
|
+
def fake_download():
|
|
8
|
+
called["value"] = True
|
|
9
|
+
|
|
10
|
+
monkeypatch.setattr(install_hooks, "ensure_installed_binary", fake_download)
|
|
11
|
+
install_hooks.download_release_during_install()
|
|
12
|
+
|
|
13
|
+
assert called["value"] is True
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from lark_cli.release import choose_asset, normalize_platform
|
|
2
|
+
from lark_cli import release
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def test_normalize_platform_for_macos_arm64():
|
|
6
|
+
os_name, arch, ext = normalize_platform("Darwin", "arm64")
|
|
7
|
+
assert os_name == "darwin"
|
|
8
|
+
assert arch == "arm64"
|
|
9
|
+
assert ext == ".tar.gz"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_choose_asset_for_linux_amd64():
|
|
13
|
+
assets = [
|
|
14
|
+
{"name": "lark-cli-1.0.0-darwin-arm64.tar.gz", "browser_download_url": "a"},
|
|
15
|
+
{"name": "lark-cli-1.0.0-linux-amd64.tar.gz", "browser_download_url": "b"},
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
selected = choose_asset(assets, "linux", "amd64", ".tar.gz")
|
|
19
|
+
assert selected["browser_download_url"] == "b"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_ensure_binary_uses_cached_file_without_network(monkeypatch, tmpdir):
|
|
23
|
+
root = tmpdir.mkdir("wrapper-home")
|
|
24
|
+
current_dir = root.mkdir("current")
|
|
25
|
+
binary_path = current_dir.join("lark-cli")
|
|
26
|
+
binary_path.write("#!/bin/sh\n")
|
|
27
|
+
|
|
28
|
+
monkeypatch.setenv("LARK_CLI_WRAPPER_HOME", str(root))
|
|
29
|
+
monkeypatch.setattr(release, "system", lambda: "Darwin")
|
|
30
|
+
monkeypatch.setattr(release, "machine", lambda: "arm64")
|
|
31
|
+
|
|
32
|
+
def fail_fetch():
|
|
33
|
+
raise AssertionError("network should not be called when cached binary exists")
|
|
34
|
+
|
|
35
|
+
monkeypatch.setattr(release, "_fetch_latest_release", fail_fetch)
|
|
36
|
+
|
|
37
|
+
resolved = release.ensure_installed_binary()
|
|
38
|
+
assert resolved == str(binary_path)
|