ggcode 1.0.9__tar.gz → 1.1.0__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.
- ggcode-1.1.0/PKG-INFO +69 -0
- ggcode-1.1.0/README.md +57 -0
- ggcode-1.1.0/ggcode.egg-info/PKG-INFO +69 -0
- {ggcode-1.0.9 → ggcode-1.1.0}/ggcode.egg-info/SOURCES.txt +2 -1
- ggcode-1.1.0/ggcode_release_installer/__init__.py +1 -0
- {ggcode-1.0.9 → ggcode-1.1.0}/ggcode_release_installer/cli.py +23 -10
- {ggcode-1.0.9 → ggcode-1.1.0}/pyproject.toml +1 -1
- ggcode-1.1.0/tests/test_cli.py +41 -0
- ggcode-1.0.9/PKG-INFO +0 -16
- ggcode-1.0.9/README.md +0 -4
- ggcode-1.0.9/ggcode.egg-info/PKG-INFO +0 -16
- ggcode-1.0.9/ggcode_release_installer/__init__.py +0 -1
- {ggcode-1.0.9 → ggcode-1.1.0}/ggcode.egg-info/dependency_links.txt +0 -0
- {ggcode-1.0.9 → ggcode-1.1.0}/ggcode.egg-info/entry_points.txt +0 -0
- {ggcode-1.0.9 → ggcode-1.1.0}/ggcode.egg-info/top_level.txt +0 -0
- {ggcode-1.0.9 → ggcode-1.1.0}/setup.cfg +0 -0
ggcode-1.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ggcode
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Thin Python wrapper that installs the ggcode GitHub Release binary
|
|
5
|
+
Author: topcheer
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/topcheer/ggcode
|
|
8
|
+
Project-URL: Repository, https://github.com/topcheer/ggcode.git
|
|
9
|
+
Project-URL: Issues, https://github.com/topcheer/ggcode/issues
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# ggcode Python wrapper
|
|
14
|
+
|
|
15
|
+
`ggcode` on PyPI is a thin Python wrapper for the `ggcode` terminal agent.
|
|
16
|
+
|
|
17
|
+
It does not ship the platform binary inside the wheel. Instead, the wrapper downloads the latest
|
|
18
|
+
matching `ggcode` GitHub Release on first run, caches it locally, and then launches it.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install ggcode
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Then run:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
ggcode
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## What it does
|
|
33
|
+
|
|
34
|
+
- Detects your operating system and CPU architecture
|
|
35
|
+
- Downloads the latest matching `ggcode` archive from GitHub Releases
|
|
36
|
+
- Verifies the archive against `checksums.txt`
|
|
37
|
+
- Extracts and caches the binary for future runs
|
|
38
|
+
|
|
39
|
+
## Pin a specific ggcode release
|
|
40
|
+
|
|
41
|
+
By default, the wrapper always resolves the latest `ggcode` release.
|
|
42
|
+
|
|
43
|
+
To force a specific release, set `GGCODE_INSTALL_VERSION`:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
GGCODE_INSTALL_VERSION=vX.Y.Z ggcode
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
or:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
GGCODE_INSTALL_VERSION=X.Y.Z ggcode
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Supported platforms
|
|
56
|
+
|
|
57
|
+
- macOS
|
|
58
|
+
- Linux
|
|
59
|
+
- Windows
|
|
60
|
+
|
|
61
|
+
Supported architectures:
|
|
62
|
+
|
|
63
|
+
- x86_64 / amd64
|
|
64
|
+
- arm64
|
|
65
|
+
|
|
66
|
+
## Project links
|
|
67
|
+
|
|
68
|
+
- Repository: https://github.com/topcheer/ggcode
|
|
69
|
+
- Issues: https://github.com/topcheer/ggcode/issues
|
ggcode-1.1.0/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# ggcode Python wrapper
|
|
2
|
+
|
|
3
|
+
`ggcode` on PyPI is a thin Python wrapper for the `ggcode` terminal agent.
|
|
4
|
+
|
|
5
|
+
It does not ship the platform binary inside the wheel. Instead, the wrapper downloads the latest
|
|
6
|
+
matching `ggcode` GitHub Release on first run, caches it locally, and then launches it.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install ggcode
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then run:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
ggcode
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## What it does
|
|
21
|
+
|
|
22
|
+
- Detects your operating system and CPU architecture
|
|
23
|
+
- Downloads the latest matching `ggcode` archive from GitHub Releases
|
|
24
|
+
- Verifies the archive against `checksums.txt`
|
|
25
|
+
- Extracts and caches the binary for future runs
|
|
26
|
+
|
|
27
|
+
## Pin a specific ggcode release
|
|
28
|
+
|
|
29
|
+
By default, the wrapper always resolves the latest `ggcode` release.
|
|
30
|
+
|
|
31
|
+
To force a specific release, set `GGCODE_INSTALL_VERSION`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
GGCODE_INSTALL_VERSION=vX.Y.Z ggcode
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
or:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
GGCODE_INSTALL_VERSION=X.Y.Z ggcode
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Supported platforms
|
|
44
|
+
|
|
45
|
+
- macOS
|
|
46
|
+
- Linux
|
|
47
|
+
- Windows
|
|
48
|
+
|
|
49
|
+
Supported architectures:
|
|
50
|
+
|
|
51
|
+
- x86_64 / amd64
|
|
52
|
+
- arm64
|
|
53
|
+
|
|
54
|
+
## Project links
|
|
55
|
+
|
|
56
|
+
- Repository: https://github.com/topcheer/ggcode
|
|
57
|
+
- Issues: https://github.com/topcheer/ggcode/issues
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ggcode
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Thin Python wrapper that installs the ggcode GitHub Release binary
|
|
5
|
+
Author: topcheer
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/topcheer/ggcode
|
|
8
|
+
Project-URL: Repository, https://github.com/topcheer/ggcode.git
|
|
9
|
+
Project-URL: Issues, https://github.com/topcheer/ggcode/issues
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# ggcode Python wrapper
|
|
14
|
+
|
|
15
|
+
`ggcode` on PyPI is a thin Python wrapper for the `ggcode` terminal agent.
|
|
16
|
+
|
|
17
|
+
It does not ship the platform binary inside the wheel. Instead, the wrapper downloads the latest
|
|
18
|
+
matching `ggcode` GitHub Release on first run, caches it locally, and then launches it.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install ggcode
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Then run:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
ggcode
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## What it does
|
|
33
|
+
|
|
34
|
+
- Detects your operating system and CPU architecture
|
|
35
|
+
- Downloads the latest matching `ggcode` archive from GitHub Releases
|
|
36
|
+
- Verifies the archive against `checksums.txt`
|
|
37
|
+
- Extracts and caches the binary for future runs
|
|
38
|
+
|
|
39
|
+
## Pin a specific ggcode release
|
|
40
|
+
|
|
41
|
+
By default, the wrapper always resolves the latest `ggcode` release.
|
|
42
|
+
|
|
43
|
+
To force a specific release, set `GGCODE_INSTALL_VERSION`:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
GGCODE_INSTALL_VERSION=vX.Y.Z ggcode
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
or:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
GGCODE_INSTALL_VERSION=X.Y.Z ggcode
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Supported platforms
|
|
56
|
+
|
|
57
|
+
- macOS
|
|
58
|
+
- Linux
|
|
59
|
+
- Windows
|
|
60
|
+
|
|
61
|
+
Supported architectures:
|
|
62
|
+
|
|
63
|
+
- x86_64 / amd64
|
|
64
|
+
- arm64
|
|
65
|
+
|
|
66
|
+
## Project links
|
|
67
|
+
|
|
68
|
+
- Repository: https://github.com/topcheer/ggcode
|
|
69
|
+
- Issues: https://github.com/topcheer/ggcode/issues
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.1.0"
|
|
@@ -9,19 +9,18 @@ import subprocess
|
|
|
9
9
|
import sys
|
|
10
10
|
import tarfile
|
|
11
11
|
import tempfile
|
|
12
|
+
import urllib.parse
|
|
12
13
|
import urllib.request
|
|
13
14
|
import zipfile
|
|
14
15
|
from pathlib import Path
|
|
15
16
|
|
|
16
|
-
from . import __version__
|
|
17
|
-
|
|
18
17
|
OWNER = "topcheer"
|
|
19
18
|
REPO = "ggcode"
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
def normalize_version() -> str:
|
|
23
|
-
selected = os.environ.get("GGCODE_INSTALL_VERSION",
|
|
24
|
-
if not selected or selected == "latest"
|
|
22
|
+
selected = os.environ.get("GGCODE_INSTALL_VERSION", "").strip()
|
|
23
|
+
if not selected or selected == "latest":
|
|
25
24
|
return "latest"
|
|
26
25
|
if selected.startswith("v"):
|
|
27
26
|
return selected
|
|
@@ -29,15 +28,15 @@ def normalize_version() -> str:
|
|
|
29
28
|
|
|
30
29
|
|
|
31
30
|
def resolve_target() -> tuple[str, str]:
|
|
32
|
-
|
|
33
|
-
if
|
|
31
|
+
system = sys.platform
|
|
32
|
+
if system.startswith("linux"):
|
|
34
33
|
goos = "linux"
|
|
35
|
-
elif
|
|
34
|
+
elif system == "darwin":
|
|
36
35
|
goos = "darwin"
|
|
37
|
-
elif
|
|
36
|
+
elif system in ("win32", "cygwin"):
|
|
38
37
|
goos = "windows"
|
|
39
38
|
else:
|
|
40
|
-
raise RuntimeError(f"Unsupported platform: {
|
|
39
|
+
raise RuntimeError(f"Unsupported platform: {system}")
|
|
41
40
|
|
|
42
41
|
machine = platform.machine().lower() or os.environ.get("PROCESSOR_ARCHITECTURE", "").lower()
|
|
43
42
|
if machine in ("x86_64", "amd64"):
|
|
@@ -67,6 +66,20 @@ def download(url: str) -> bytes:
|
|
|
67
66
|
return response.read()
|
|
68
67
|
|
|
69
68
|
|
|
69
|
+
def resolve_release_version(version: str) -> str:
|
|
70
|
+
if version != "latest":
|
|
71
|
+
return version
|
|
72
|
+
|
|
73
|
+
with urllib.request.urlopen(f"https://github.com/{OWNER}/{REPO}/releases/latest") as response:
|
|
74
|
+
final_url = response.geturl()
|
|
75
|
+
|
|
76
|
+
parsed = urllib.parse.urlparse(final_url)
|
|
77
|
+
parts = [part for part in parsed.path.split("/") if part]
|
|
78
|
+
if len(parts) < 4 or parts[-2] != "tag":
|
|
79
|
+
raise RuntimeError(f"Could not resolve latest ggcode release from {final_url}")
|
|
80
|
+
return urllib.parse.unquote(parts[-1])
|
|
81
|
+
|
|
82
|
+
|
|
70
83
|
def parse_checksums(body: str) -> dict[str, str]:
|
|
71
84
|
checksums: dict[str, str] = {}
|
|
72
85
|
for raw_line in body.splitlines():
|
|
@@ -77,7 +90,7 @@ def parse_checksums(body: str) -> dict[str, str]:
|
|
|
77
90
|
|
|
78
91
|
|
|
79
92
|
def ensure_installed() -> Path:
|
|
80
|
-
version = normalize_version()
|
|
93
|
+
version = resolve_release_version(normalize_version())
|
|
81
94
|
goos, arch = resolve_target()
|
|
82
95
|
archive_ext = ".zip" if goos == "windows" else ".tar.gz"
|
|
83
96
|
archive_name = f"ggcode_{goos}_{arch}{archive_ext}"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import unittest
|
|
5
|
+
from unittest.mock import patch
|
|
6
|
+
|
|
7
|
+
from ggcode_release_installer import cli
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ResolveTargetTests(unittest.TestCase):
|
|
11
|
+
def test_normalize_version_defaults_to_latest(self) -> None:
|
|
12
|
+
with patch.dict(os.environ, {}, clear=True):
|
|
13
|
+
self.assertEqual(cli.normalize_version(), "latest")
|
|
14
|
+
|
|
15
|
+
def test_normalize_version_uses_explicit_override(self) -> None:
|
|
16
|
+
with patch.dict(os.environ, {"GGCODE_INSTALL_VERSION": "1.2.3"}, clear=True):
|
|
17
|
+
self.assertEqual(cli.normalize_version(), "v1.2.3")
|
|
18
|
+
|
|
19
|
+
def test_resolve_target_uses_platform_module_for_machine(self) -> None:
|
|
20
|
+
with patch.object(cli.sys, "platform", "darwin"):
|
|
21
|
+
with patch.object(cli.platform, "machine", return_value="arm64"):
|
|
22
|
+
self.assertEqual(cli.resolve_target(), ("darwin", "arm64"))
|
|
23
|
+
|
|
24
|
+
def test_resolve_target_falls_back_to_processor_architecture(self) -> None:
|
|
25
|
+
env = dict(os.environ, PROCESSOR_ARCHITECTURE="AMD64")
|
|
26
|
+
with patch.dict(os.environ, env, clear=True):
|
|
27
|
+
with patch.object(cli.sys, "platform", "win32"):
|
|
28
|
+
with patch.object(cli.platform, "machine", return_value=""):
|
|
29
|
+
self.assertEqual(cli.resolve_target(), ("windows", "x86_64"))
|
|
30
|
+
|
|
31
|
+
def test_resolve_release_version_follows_latest_redirect(self) -> None:
|
|
32
|
+
response = unittest.mock.Mock()
|
|
33
|
+
response.geturl.return_value = "https://github.com/topcheer/ggcode/releases/tag/v9.9.9"
|
|
34
|
+
response.__enter__ = unittest.mock.Mock(return_value=response)
|
|
35
|
+
response.__exit__ = unittest.mock.Mock(return_value=False)
|
|
36
|
+
with patch.object(cli.urllib.request, "urlopen", return_value=response):
|
|
37
|
+
self.assertEqual(cli.resolve_release_version("latest"), "v9.9.9")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
unittest.main()
|
ggcode-1.0.9/PKG-INFO
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: ggcode
|
|
3
|
-
Version: 1.0.9
|
|
4
|
-
Summary: Thin Python wrapper that installs the ggcode GitHub Release binary
|
|
5
|
-
Author: topcheer
|
|
6
|
-
License: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/topcheer/ggcode
|
|
8
|
-
Project-URL: Repository, https://github.com/topcheer/ggcode.git
|
|
9
|
-
Project-URL: Issues, https://github.com/topcheer/ggcode/issues
|
|
10
|
-
Requires-Python: >=3.9
|
|
11
|
-
Description-Content-Type: text/markdown
|
|
12
|
-
|
|
13
|
-
# ggcode Python wrapper
|
|
14
|
-
|
|
15
|
-
This package installs a small Python launcher that downloads the matching `ggcode`
|
|
16
|
-
binary from GitHub Releases on first run and then executes it.
|
ggcode-1.0.9/README.md
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: ggcode
|
|
3
|
-
Version: 1.0.9
|
|
4
|
-
Summary: Thin Python wrapper that installs the ggcode GitHub Release binary
|
|
5
|
-
Author: topcheer
|
|
6
|
-
License: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/topcheer/ggcode
|
|
8
|
-
Project-URL: Repository, https://github.com/topcheer/ggcode.git
|
|
9
|
-
Project-URL: Issues, https://github.com/topcheer/ggcode/issues
|
|
10
|
-
Requires-Python: >=3.9
|
|
11
|
-
Description-Content-Type: text/markdown
|
|
12
|
-
|
|
13
|
-
# ggcode Python wrapper
|
|
14
|
-
|
|
15
|
-
This package installs a small Python launcher that downloads the matching `ggcode`
|
|
16
|
-
binary from GitHub Releases on first run and then executes it.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.0.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|