-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy path_cli_version.py
More file actions
95 lines (72 loc) · 3.43 KB
/
Copy path_cli_version.py
File metadata and controls
95 lines (72 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""Copilot CLI version and platform asset information.
At publish time, CLI_VERSION is overwritten by scripts/inject-cli-version.mjs
with the concrete version string (e.g. "1.0.64-1"). In development (editable
installs, running from source) the sentinel value None disables automatic
download — callers must set an explicit path or COPILOT_CLI_PATH.
"""
from __future__ import annotations
import platform
import sys
# Sentinel: None means "no pinned version" (dev/editable install).
# Overwritten at publish time by scripts/inject-cli-version.mjs.
# DO NOT reformat this line — the inject script matches it exactly.
CLI_VERSION: str | None = None
# Maps (sys.platform, platform.machine()) → (archive filename, binary name inside archive).
PLATFORM_ASSETS: dict[tuple[str, str], tuple[str, str]] = {
("linux", "x86_64"): ("copilot-linux-x64.tar.gz", "copilot"),
("linux", "aarch64"): ("copilot-linux-arm64.tar.gz", "copilot"),
("linux", "arm64"): ("copilot-linux-arm64.tar.gz", "copilot"),
("darwin", "x86_64"): ("copilot-darwin-x64.tar.gz", "copilot"),
("darwin", "arm64"): ("copilot-darwin-arm64.tar.gz", "copilot"),
("win32", "AMD64"): ("copilot-win32-x64.zip", "copilot.exe"),
("win32", "ARM64"): ("copilot-win32-arm64.zip", "copilot.exe"),
}
# Musl (Alpine) variants — detected at runtime via _is_musl().
_MUSL_ASSETS: dict[str, tuple[str, str]] = {
"x86_64": ("copilot-linuxmusl-x64.tar.gz", "copilot"),
"aarch64": ("copilot-linuxmusl-arm64.tar.gz", "copilot"),
"arm64": ("copilot-linuxmusl-arm64.tar.gz", "copilot"),
}
_DOWNLOAD_BASE_URL = "https://github.com/github/copilot-cli/releases/download"
def _is_musl() -> bool:
"""Detect whether the current Linux system uses musl libc (e.g. Alpine)."""
if sys.platform != "linux":
return False
try:
import subprocess
result = subprocess.run(["ldd", "--version"], capture_output=True, text=True, timeout=5)
# musl's ldd prints "musl libc" in its output
output = result.stdout + result.stderr
return "musl" in output.lower()
except (FileNotFoundError, subprocess.TimeoutExpired, OSError):
return False
def get_platform_key() -> tuple[str, str]:
"""Return the (sys.platform, machine) key for the current platform."""
return (sys.platform, platform.machine())
def get_asset_info() -> tuple[str, str]:
"""Return (archive_filename, binary_name) for the current platform.
Raises RuntimeError if the platform is not supported.
"""
key = get_platform_key()
# On Linux, check for musl/Alpine first
if key[0] == "linux" and _is_musl():
musl_info = _MUSL_ASSETS.get(key[1])
if musl_info:
return musl_info
info = PLATFORM_ASSETS.get(key)
if info is None:
raise RuntimeError(
f"Unsupported platform: {key[0]}/{key[1]}. "
f"Supported platforms: {', '.join(f'{p}/{m}' for p, m in PLATFORM_ASSETS)}"
)
return info
def get_download_url(version: str, archive_name: str) -> str:
"""Return the download URL for a given version and archive."""
import os
base = os.environ.get("COPILOT_CLI_DOWNLOAD_BASE_URL", _DOWNLOAD_BASE_URL)
return f"{base}/v{version}/{archive_name}"
def get_checksums_url(version: str) -> str:
"""Return the URL for the SHA256SUMS.txt file."""
import os
base = os.environ.get("COPILOT_CLI_DOWNLOAD_BASE_URL", _DOWNLOAD_BASE_URL)
return f"{base}/v{version}/SHA256SUMS.txt"