multi-lang-build 0.2.0__tar.gz → 0.2.2__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.
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/PKG-INFO +1 -1
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/pyproject.toml +2 -1
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/__init__.py +8 -1
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/cli.py +70 -13
- multi_lang_build-0.2.2/src/multi_lang_build/mirror/cli.py +340 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/register.py +143 -126
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/.gitignore +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/LICENSE +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/README.md +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/compiler/__init__.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/compiler/base.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/compiler/go.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/compiler/pnpm.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/compiler/python.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/mirror/__init__.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/mirror/config.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/py.typed +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/src/multi_lang_build/types.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/tests/__init__.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/tests/conftest.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/tests/test_compiler.py +0 -0
- {multi_lang_build-0.2.0 → multi_lang_build-0.2.2}/tests/test_mirror.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: multi-lang-build
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Multi-language automated build tool with domestic mirror acceleration support
|
|
5
5
|
Project-URL: Homepage, https://github.com/example/multi-lang-build
|
|
6
6
|
Project-URL: Repository, https://github.com/example/multi-lang-build
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "multi-lang-build"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "Multi-language automated build tool with domestic mirror acceleration support"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -43,6 +43,7 @@ pnpm-build = "multi_lang_build.compiler.pnpm:main"
|
|
|
43
43
|
go-build = "multi_lang_build.compiler.go:main"
|
|
44
44
|
python-build = "multi_lang_build.compiler.python:main"
|
|
45
45
|
multi-lang-register = "multi_lang_build:main_register"
|
|
46
|
+
multi-lang-mirror = "multi_lang_build.mirror.cli:mirror_main"
|
|
46
47
|
|
|
47
48
|
[project.urls]
|
|
48
49
|
Homepage = "https://github.com/example/multi-lang-build"
|
|
@@ -7,7 +7,7 @@ from multi_lang_build.compiler.python import PythonCompiler
|
|
|
7
7
|
from multi_lang_build.mirror.config import MirrorConfig, get_mirror_config
|
|
8
8
|
from multi_lang_build.register import register_skill
|
|
9
9
|
|
|
10
|
-
__version__ = "0.2.
|
|
10
|
+
__version__ = "0.2.1"
|
|
11
11
|
__all__ = [
|
|
12
12
|
"BuildConfig",
|
|
13
13
|
"BuildResult",
|
|
@@ -55,3 +55,10 @@ def main_register() -> None:
|
|
|
55
55
|
args = parser.parse_args()
|
|
56
56
|
success = register_skill(args.ide)
|
|
57
57
|
sys.exit(0 if success else 1)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def main_mirror() -> None:
|
|
61
|
+
"""Entry point for the mirror CLI tool."""
|
|
62
|
+
from multi_lang_build.mirror.cli import mirror_main
|
|
63
|
+
|
|
64
|
+
mirror_main()
|
|
@@ -92,12 +92,54 @@ Supported languages:
|
|
|
92
92
|
mirror_parser = subparsers.add_parser(
|
|
93
93
|
"mirror",
|
|
94
94
|
help="Manage mirror configurations",
|
|
95
|
-
description="List or configure mirror settings",
|
|
95
|
+
description="List or configure domestic mirror acceleration settings",
|
|
96
|
+
epilog="""
|
|
97
|
+
Examples:
|
|
98
|
+
%(prog)s mirror list List all available mirrors
|
|
99
|
+
%(prog)s mirror set pip Configure pip mirror (default)
|
|
100
|
+
%(prog)s mirror set go Configure go proxy mirror
|
|
101
|
+
%(prog)s mirror set pnpm Configure pnpm registry mirror
|
|
102
|
+
%(prog)s mirror show Show current configuration
|
|
103
|
+
%(prog)s mirror reset Reset configuration
|
|
104
|
+
""",
|
|
96
105
|
)
|
|
97
106
|
mirror_subparsers = mirror_parser.add_subparsers(dest="mirror_action")
|
|
98
107
|
|
|
99
108
|
list_parser = mirror_subparsers.add_parser("list", help="List available mirrors")
|
|
100
|
-
list_parser.add_argument("--
|
|
109
|
+
list_parser.add_argument("--json", action="store_true", help="Output as JSON")
|
|
110
|
+
|
|
111
|
+
set_parser = mirror_subparsers.add_parser("set", help="Set mirror configuration")
|
|
112
|
+
set_parser.add_argument(
|
|
113
|
+
"type",
|
|
114
|
+
type=str,
|
|
115
|
+
default="pip",
|
|
116
|
+
nargs="?",
|
|
117
|
+
choices=["pip", "go", "npm", "pnpm"],
|
|
118
|
+
help="Package manager type (default: pip)",
|
|
119
|
+
)
|
|
120
|
+
set_parser.add_argument(
|
|
121
|
+
"mirror",
|
|
122
|
+
type=str,
|
|
123
|
+
nargs="?",
|
|
124
|
+
default="pip",
|
|
125
|
+
help="Mirror to use",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
show_parser = mirror_subparsers.add_parser("show", help="Show current configuration")
|
|
129
|
+
show_parser.add_argument(
|
|
130
|
+
"--global",
|
|
131
|
+
dest="global_level",
|
|
132
|
+
action="store_true",
|
|
133
|
+
help="Show global config instead of project-level",
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
reset_parser = mirror_subparsers.add_parser("reset", help="Reset configuration")
|
|
137
|
+
reset_parser.add_argument(
|
|
138
|
+
"--global",
|
|
139
|
+
dest="global_level",
|
|
140
|
+
action="store_true",
|
|
141
|
+
help="Reset global config instead of project-level",
|
|
142
|
+
)
|
|
101
143
|
|
|
102
144
|
# Register subcommand for IDE integration
|
|
103
145
|
register_parser = subparsers.add_parser(
|
|
@@ -210,18 +252,33 @@ Examples:
|
|
|
210
252
|
)
|
|
211
253
|
|
|
212
254
|
elif parsed_args.language == "mirror":
|
|
213
|
-
|
|
214
|
-
from multi_lang_build.mirror.config import get_all_mirror_names, get_mirror_config
|
|
255
|
+
from multi_lang_build.mirror.cli import configure_mirror, print_mirrors, get_current_config
|
|
215
256
|
|
|
216
|
-
|
|
217
|
-
if parsed_args
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
257
|
+
if parsed_args.mirror_action == "list":
|
|
258
|
+
if getattr(parsed_args, "json", False):
|
|
259
|
+
from multi_lang_build.mirror.cli import get_all_mirrors
|
|
260
|
+
import json
|
|
261
|
+
print(json.dumps(get_all_mirrors(), indent=2, ensure_ascii=False))
|
|
262
|
+
else:
|
|
263
|
+
print_mirrors()
|
|
264
|
+
elif parsed_args.mirror_action == "set":
|
|
265
|
+
mirror_type = getattr(parsed_args, "type", "pip")
|
|
266
|
+
mirror_key = getattr(parsed_args, "mirror", "pip")
|
|
267
|
+
success = configure_mirror(mirror_type, mirror_key)
|
|
268
|
+
sys.exit(0 if success else 1)
|
|
269
|
+
elif parsed_args.mirror_action == "show":
|
|
270
|
+
config = get_current_config()
|
|
271
|
+
if config:
|
|
272
|
+
print("\n📦 Current Mirror Configuration:")
|
|
273
|
+
print("-" * 40)
|
|
274
|
+
for key, value in config.items():
|
|
275
|
+
print(f" • {key}: {value}")
|
|
276
|
+
print()
|
|
277
|
+
else:
|
|
278
|
+
print("\n📦 No mirror configured")
|
|
279
|
+
print(" Run 'multi-lang-build mirror set <type> <mirror>' to configure")
|
|
280
|
+
print()
|
|
281
|
+
print_mirrors()
|
|
225
282
|
else:
|
|
226
283
|
mirror_parser.print_help()
|
|
227
284
|
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
"""Mirror configuration CLI for domestic acceleration."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Literal
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_all_mirrors() -> dict:
|
|
14
|
+
"""Get all available mirrors with their configurations."""
|
|
15
|
+
from multi_lang_build.mirror.config import MIRROR_CONFIGS
|
|
16
|
+
|
|
17
|
+
mirrors = {}
|
|
18
|
+
for key, config in MIRROR_CONFIGS.items():
|
|
19
|
+
mirrors[key] = {
|
|
20
|
+
"name": config["name"],
|
|
21
|
+
"url": config["url"],
|
|
22
|
+
}
|
|
23
|
+
return mirrors
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def print_mirrors() -> None:
|
|
27
|
+
"""Print all available mirrors."""
|
|
28
|
+
mirrors = get_all_mirrors()
|
|
29
|
+
|
|
30
|
+
print("\n📦 Available Mirrors:")
|
|
31
|
+
print("-" * 60)
|
|
32
|
+
|
|
33
|
+
# Group by category
|
|
34
|
+
categories = {
|
|
35
|
+
"js": ["npm", "pnpm", "yarn"],
|
|
36
|
+
"go": ["go", "go_qiniu", "go_vip"],
|
|
37
|
+
"python": ["pip", "pip_aliyun", "pip_douban", "pip_huawei", "python", "poetry"],
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
category_names = {
|
|
41
|
+
"js": "🌐 JavaScript (npm/pnpm/yarn)",
|
|
42
|
+
"go": "🔷 Go",
|
|
43
|
+
"python": "🐍 Python (pip/PyPI)",
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for cat_key, cat_mirrors in categories.items():
|
|
47
|
+
print(f"\n{category_names.get(cat_key, cat_key)}")
|
|
48
|
+
for mirror_key in cat_mirrors:
|
|
49
|
+
if mirror_key in mirrors:
|
|
50
|
+
config = mirrors[mirror_key]
|
|
51
|
+
print(f" • {mirror_key:12} - {config['name']}")
|
|
52
|
+
print(f" {config['url']}")
|
|
53
|
+
|
|
54
|
+
print()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def configure_pip(mirror_key: str) -> bool:
|
|
58
|
+
"""Configure pip mirror using pip config command."""
|
|
59
|
+
from multi_lang_build.mirror.config import get_mirror_config
|
|
60
|
+
|
|
61
|
+
config = get_mirror_config(mirror_key)
|
|
62
|
+
if config is None:
|
|
63
|
+
print(f"❌ Unknown pip mirror: {mirror_key}")
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
url = config["url"]
|
|
67
|
+
if not url.endswith("/simple") and not url.endswith("/simple/"):
|
|
68
|
+
url = f"{url}/simple"
|
|
69
|
+
|
|
70
|
+
# Try pip3 first, fallback to pip
|
|
71
|
+
pip_cmd = "pip3" if sys.platform != "win32" else "pip"
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
subprocess.run(
|
|
75
|
+
[pip_cmd, "config", "set", "global.index-url", url],
|
|
76
|
+
check=True,
|
|
77
|
+
)
|
|
78
|
+
print(f"✅ pip mirror set to: {url}")
|
|
79
|
+
return True
|
|
80
|
+
except subprocess.CalledProcessError as e:
|
|
81
|
+
print(f"❌ Failed to set pip mirror: {e}")
|
|
82
|
+
return False
|
|
83
|
+
except FileNotFoundError:
|
|
84
|
+
# Try alternative
|
|
85
|
+
try:
|
|
86
|
+
alternative = "pip" if pip_cmd == "pip3" else "pip3"
|
|
87
|
+
subprocess.run(
|
|
88
|
+
[alternative, "config", "set", "global.index-url", url],
|
|
89
|
+
check=True,
|
|
90
|
+
)
|
|
91
|
+
print(f"✅ pip mirror set to: {url}")
|
|
92
|
+
return True
|
|
93
|
+
except Exception:
|
|
94
|
+
print("❌ pip/pip3 not found")
|
|
95
|
+
return False
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def configure_go(mirror_key: str) -> bool:
|
|
99
|
+
"""Configure Go proxy using go env -w."""
|
|
100
|
+
from multi_lang_build.mirror.config import get_mirror_config
|
|
101
|
+
|
|
102
|
+
config = get_mirror_config(mirror_key)
|
|
103
|
+
if config is None:
|
|
104
|
+
print(f"❌ Unknown Go mirror: {mirror_key}")
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
# Get the GOPROXY value from environment variables
|
|
108
|
+
proxy_value = config["environment_variables"].get("GOPROXY", f"{config['url']},direct")
|
|
109
|
+
|
|
110
|
+
try:
|
|
111
|
+
subprocess.run(
|
|
112
|
+
["go", "env", "-w", f"GOPROXY={proxy_value}"],
|
|
113
|
+
check=True,
|
|
114
|
+
)
|
|
115
|
+
print(f"✅ Go GOPROXY set to: {proxy_value}")
|
|
116
|
+
|
|
117
|
+
# Also set GOSUMDB if present
|
|
118
|
+
gosumdb = config["environment_variables"].get("GOSUMDB")
|
|
119
|
+
if gosumdb:
|
|
120
|
+
subprocess.run(
|
|
121
|
+
["go", "env", "-w", f"GOSUMDB={gosumdb}"],
|
|
122
|
+
check=True,
|
|
123
|
+
)
|
|
124
|
+
print(f"✅ Go GOSUMDB set to: {gosumdb}")
|
|
125
|
+
|
|
126
|
+
return True
|
|
127
|
+
except subprocess.CalledProcessError as e:
|
|
128
|
+
print(f"❌ Failed to set Go mirror: {e}")
|
|
129
|
+
return False
|
|
130
|
+
except FileNotFoundError:
|
|
131
|
+
print("❌ go not found")
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def configure_npm(mirror_key: str) -> bool:
|
|
136
|
+
"""Configure npm/pnpm registry."""
|
|
137
|
+
from multi_lang_build.mirror.config import get_mirror_config
|
|
138
|
+
|
|
139
|
+
config = get_mirror_config(mirror_key)
|
|
140
|
+
if config is None:
|
|
141
|
+
print(f"❌ Unknown npm mirror: {mirror_key}")
|
|
142
|
+
return False
|
|
143
|
+
|
|
144
|
+
url = config["url"]
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
subprocess.run(
|
|
148
|
+
["npm", "config", "set", "registry", url],
|
|
149
|
+
check=True,
|
|
150
|
+
)
|
|
151
|
+
print(f"✅ npm registry set to: {url}")
|
|
152
|
+
|
|
153
|
+
# Also set for pnpm if available
|
|
154
|
+
try:
|
|
155
|
+
subprocess.run(
|
|
156
|
+
["pnpm", "config", "set", "registry", url],
|
|
157
|
+
check=True,
|
|
158
|
+
)
|
|
159
|
+
print(f"✅ pnpm registry set to: {url}")
|
|
160
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
return True
|
|
164
|
+
except subprocess.CalledProcessError as e:
|
|
165
|
+
print(f"❌ Failed to set npm registry: {e}")
|
|
166
|
+
return False
|
|
167
|
+
except FileNotFoundError:
|
|
168
|
+
print("❌ npm not found")
|
|
169
|
+
return False
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def get_current_config() -> dict:
|
|
173
|
+
"""Get current mirror configuration."""
|
|
174
|
+
config = {}
|
|
175
|
+
|
|
176
|
+
# Try pip3 first, fallback to pip
|
|
177
|
+
pip_cmd = "pip3" if sys.platform != "win32" else "pip"
|
|
178
|
+
|
|
179
|
+
try:
|
|
180
|
+
result = subprocess.run(
|
|
181
|
+
[pip_cmd, "config", "get", "global.index-url"],
|
|
182
|
+
capture_output=True,
|
|
183
|
+
text=True,
|
|
184
|
+
)
|
|
185
|
+
if result.returncode == 0 and result.stdout.strip():
|
|
186
|
+
config["pip"] = result.stdout.strip()
|
|
187
|
+
except Exception:
|
|
188
|
+
pass
|
|
189
|
+
|
|
190
|
+
# Check Go
|
|
191
|
+
try:
|
|
192
|
+
result = subprocess.run(
|
|
193
|
+
["go", "env", "GOPROXY"],
|
|
194
|
+
capture_output=True,
|
|
195
|
+
text=True,
|
|
196
|
+
)
|
|
197
|
+
if result.returncode == 0:
|
|
198
|
+
config["go"] = result.stdout.strip()
|
|
199
|
+
except Exception:
|
|
200
|
+
pass
|
|
201
|
+
|
|
202
|
+
# Check npm
|
|
203
|
+
try:
|
|
204
|
+
result = subprocess.run(
|
|
205
|
+
["npm", "config", "get", "registry"],
|
|
206
|
+
capture_output=True,
|
|
207
|
+
text=True,
|
|
208
|
+
)
|
|
209
|
+
if result.returncode == 0:
|
|
210
|
+
config["npm"] = result.stdout.strip()
|
|
211
|
+
except Exception:
|
|
212
|
+
pass
|
|
213
|
+
|
|
214
|
+
return config
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def configure_mirror(mirror_type: str, mirror_key: str) -> bool:
|
|
218
|
+
"""Configure mirror for a specific package manager.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
mirror_type: Package manager type (pip, go, npm)
|
|
222
|
+
mirror_key: Mirror key to use
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
True if successful, False otherwise
|
|
226
|
+
"""
|
|
227
|
+
if mirror_type == "pip":
|
|
228
|
+
return configure_pip(mirror_key)
|
|
229
|
+
elif mirror_type == "go":
|
|
230
|
+
return configure_go(mirror_key)
|
|
231
|
+
elif mirror_type in ["npm", "pnpm"]:
|
|
232
|
+
return configure_npm(mirror_key)
|
|
233
|
+
else:
|
|
234
|
+
print(f"❌ Unknown package manager: {mirror_type}")
|
|
235
|
+
return False
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def mirror_main():
|
|
239
|
+
"""Main entry point for mirror command."""
|
|
240
|
+
import argparse
|
|
241
|
+
|
|
242
|
+
parser = argparse.ArgumentParser(
|
|
243
|
+
description="Configure domestic mirror acceleration",
|
|
244
|
+
epilog="""
|
|
245
|
+
Examples:
|
|
246
|
+
%(prog)s list List all available mirrors
|
|
247
|
+
%(prog)s set pip Configure pip mirror (default)
|
|
248
|
+
%(prog)s set go Configure Go proxy
|
|
249
|
+
%(prog)s set npm Configure npm registry
|
|
250
|
+
%(prog)s show Show current configuration
|
|
251
|
+
""",
|
|
252
|
+
)
|
|
253
|
+
parser.add_argument(
|
|
254
|
+
"--version",
|
|
255
|
+
action="version",
|
|
256
|
+
version="%(prog)s 0.2.2",
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
subparsers = parser.add_subparsers(dest="command", help="Commands")
|
|
260
|
+
|
|
261
|
+
# list command
|
|
262
|
+
list_parser = subparsers.add_parser("list", help="List available mirrors")
|
|
263
|
+
list_parser.add_argument(
|
|
264
|
+
"--json",
|
|
265
|
+
action="store_true",
|
|
266
|
+
help="Output as JSON",
|
|
267
|
+
)
|
|
268
|
+
list_parser.add_argument(
|
|
269
|
+
"--type",
|
|
270
|
+
type=str,
|
|
271
|
+
choices=["pip", "go", "npm"],
|
|
272
|
+
help="Filter by type",
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
# set command
|
|
276
|
+
set_parser = subparsers.add_parser("set", help="Configure mirror")
|
|
277
|
+
set_parser.add_argument(
|
|
278
|
+
"type",
|
|
279
|
+
type=str,
|
|
280
|
+
default="pip",
|
|
281
|
+
nargs="?",
|
|
282
|
+
choices=["pip", "go", "npm", "pnpm"],
|
|
283
|
+
help="Package manager type (default: pip)",
|
|
284
|
+
)
|
|
285
|
+
set_parser.add_argument(
|
|
286
|
+
"mirror",
|
|
287
|
+
type=str,
|
|
288
|
+
nargs="?",
|
|
289
|
+
default="pip",
|
|
290
|
+
help="Mirror to use",
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
# show command
|
|
294
|
+
show_parser = subparsers.add_parser("show", help="Show current mirror configuration")
|
|
295
|
+
|
|
296
|
+
args = parser.parse_args()
|
|
297
|
+
|
|
298
|
+
if args.command == "list":
|
|
299
|
+
mirrors = get_all_mirrors()
|
|
300
|
+
if getattr(args, "json", False):
|
|
301
|
+
print(json.dumps(mirrors, indent=2, ensure_ascii=False))
|
|
302
|
+
else:
|
|
303
|
+
print_mirrors()
|
|
304
|
+
|
|
305
|
+
elif args.command == "set":
|
|
306
|
+
mirror_type = args.type
|
|
307
|
+
mirror_key = args.mirror
|
|
308
|
+
success = configure_mirror(mirror_type, mirror_key)
|
|
309
|
+
sys.exit(0 if success else 1)
|
|
310
|
+
|
|
311
|
+
elif args.command == "show":
|
|
312
|
+
config = get_current_config()
|
|
313
|
+
if config:
|
|
314
|
+
print("\n📦 Current Mirror Configuration:")
|
|
315
|
+
print("-" * 40)
|
|
316
|
+
for key, value in config.items():
|
|
317
|
+
print(f" • {key}: {value}")
|
|
318
|
+
print()
|
|
319
|
+
else:
|
|
320
|
+
print("\n📦 No mirror configured")
|
|
321
|
+
print(" Run 'multi-lang-build mirror set <type> <mirror>' to configure")
|
|
322
|
+
print()
|
|
323
|
+
print_mirrors()
|
|
324
|
+
|
|
325
|
+
else:
|
|
326
|
+
# No subcommand, show help
|
|
327
|
+
parser.print_help()
|
|
328
|
+
print("\n📋 Commands:")
|
|
329
|
+
print(" list List all available mirrors")
|
|
330
|
+
print(" set <type> <name> Configure mirror (type: pip/go/npm)")
|
|
331
|
+
print(" show Show current configuration")
|
|
332
|
+
print("\n📋 Examples:")
|
|
333
|
+
print(" multi-lang-build mirror list")
|
|
334
|
+
print(" multi-lang-build mirror set pip")
|
|
335
|
+
print(" multi-lang-build mirror set go")
|
|
336
|
+
print(" multi-lang-build mirror set npm")
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
if __name__ == "__main__":
|
|
340
|
+
mirror_main()
|
|
@@ -25,36 +25,44 @@ def get_cli_path() -> str:
|
|
|
25
25
|
return f"{sys.executable} -m multi_lang_build"
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def register_claude_code() -> bool:
|
|
28
|
+
def register_claude_code(project_level: bool = True) -> bool:
|
|
29
29
|
"""Register as Claude Code skill.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
project_level: If True (default), register to project-level .claude/CLAUDE.md.
|
|
33
|
+
If False, register to global ~/.claude/CLAUDE.md.
|
|
33
34
|
"""
|
|
34
35
|
try:
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
36
|
+
# Determine registration path
|
|
37
|
+
if project_level:
|
|
38
|
+
# Project-level: .claude/CLAUDE.md in current directory
|
|
39
|
+
config_dir = Path.cwd() / ".claude"
|
|
40
|
+
config_dir.mkdir(exist_ok=True)
|
|
41
|
+
claude_md = config_dir / "CLAUDE.md"
|
|
42
|
+
level_name = "project-level"
|
|
43
|
+
else:
|
|
44
|
+
# Global-level: ~/.claude/CLAUDE.md (only check CLI for global)
|
|
45
|
+
result = subprocess.run(
|
|
46
|
+
["which", "claude"],
|
|
47
|
+
capture_output=True,
|
|
48
|
+
text=True,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if result.returncode != 0:
|
|
52
|
+
print("❌ Claude Code CLI not found. Please install it first:")
|
|
53
|
+
print(" npm install -g @anthropic-ai/claude-code")
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
claude_dir = Path.home() / ".claude"
|
|
57
|
+
claude_dir.mkdir(exist_ok=True)
|
|
58
|
+
claude_md = claude_dir / "CLAUDE.md"
|
|
59
|
+
level_name = "global"
|
|
60
|
+
|
|
61
|
+
# Read existing content
|
|
53
62
|
existing_content = ""
|
|
54
63
|
if claude_md.exists():
|
|
55
64
|
existing_content = claude_md.read_text()
|
|
56
|
-
|
|
57
|
-
# Add multi-lang-build skill section
|
|
65
|
+
|
|
58
66
|
skill_section = """
|
|
59
67
|
|
|
60
68
|
## Multi-Lang Build Tool
|
|
@@ -83,50 +91,51 @@ multi-lang-build pnpm ./src --output ./dist --mirror
|
|
|
83
91
|
|
|
84
92
|
When working with Go projects, check if there are multiple main packages and use the `--target` flag to specify which one to build.
|
|
85
93
|
"""
|
|
86
|
-
|
|
94
|
+
|
|
87
95
|
if "## Multi-Lang Build Tool" not in existing_content:
|
|
88
96
|
with open(claude_md, "a") as f:
|
|
89
97
|
f.write(skill_section)
|
|
90
|
-
print(f"✅ Registered with Claude Code (added to {claude_md})")
|
|
98
|
+
print(f"✅ Registered with Claude Code ({level_name}, added to {claude_md})")
|
|
91
99
|
else:
|
|
92
|
-
print(f"ℹ️ Already registered with Claude Code ({claude_md})")
|
|
93
|
-
|
|
100
|
+
print(f"ℹ️ Already registered with Claude Code ({level_name}, {claude_md})")
|
|
101
|
+
|
|
94
102
|
return True
|
|
95
|
-
|
|
103
|
+
|
|
96
104
|
except Exception as e:
|
|
97
105
|
print(f"❌ Failed to register with Claude Code: {e}")
|
|
98
106
|
return False
|
|
99
107
|
|
|
100
108
|
|
|
101
|
-
def register_opencode() -> bool:
|
|
109
|
+
def register_opencode(project_level: bool = True) -> bool:
|
|
102
110
|
"""Register as OpenCode skill.
|
|
103
|
-
|
|
104
|
-
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
project_level: If True (default), register to project-level .opencode/skills.json.
|
|
114
|
+
If False, register to global ~/.config/opencode/skills.json.
|
|
105
115
|
"""
|
|
106
116
|
try:
|
|
107
|
-
#
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
117
|
+
# Determine registration path
|
|
118
|
+
if project_level:
|
|
119
|
+
# Project-level: .opencode/skills.json in current directory
|
|
120
|
+
base_dir = Path.cwd()
|
|
121
|
+
config_dir = base_dir / ".opencode"
|
|
122
|
+
config_dir.mkdir(exist_ok=True)
|
|
123
|
+
skills_file = config_dir / "skills.json"
|
|
124
|
+
level_name = "project-level"
|
|
125
|
+
else:
|
|
126
|
+
# Global-level: ~/.config/opencode/skills.json
|
|
127
|
+
config_dir = Path.home() / ".config" / "opencode"
|
|
128
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
129
|
+
skills_file = config_dir / "skills.json"
|
|
130
|
+
level_name = "global"
|
|
131
|
+
|
|
122
132
|
# Create or update skills.json
|
|
123
|
-
skills_file = config_dir / "skills.json"
|
|
124
133
|
skills: dict = {}
|
|
125
|
-
|
|
134
|
+
|
|
126
135
|
if skills_file.exists():
|
|
127
136
|
with open(skills_file) as f:
|
|
128
137
|
skills = json.load(f)
|
|
129
|
-
|
|
138
|
+
|
|
130
139
|
# Add multi-lang-build skill
|
|
131
140
|
skills["multi-lang-build"] = {
|
|
132
141
|
"name": "multi-lang-build",
|
|
@@ -143,47 +152,48 @@ def register_opencode() -> bool:
|
|
|
143
152
|
"multi-lang-build pnpm ./src --output ./dist --mirror",
|
|
144
153
|
]
|
|
145
154
|
}
|
|
146
|
-
|
|
155
|
+
|
|
147
156
|
with open(skills_file, "w") as f:
|
|
148
157
|
json.dump(skills, f, indent=2)
|
|
149
|
-
|
|
150
|
-
print(f"✅ Registered with OpenCode (config: {skills_file})")
|
|
158
|
+
|
|
159
|
+
print(f"✅ Registered with OpenCode ({level_name}, config: {skills_file})")
|
|
151
160
|
return True
|
|
152
|
-
|
|
161
|
+
|
|
153
162
|
except Exception as e:
|
|
154
163
|
print(f"❌ Failed to register with OpenCode: {e}")
|
|
155
164
|
return False
|
|
156
165
|
|
|
157
166
|
|
|
158
|
-
def register_trae() -> bool:
|
|
167
|
+
def register_trae(project_level: bool = True) -> bool:
|
|
159
168
|
"""Register as Trae skill.
|
|
160
|
-
|
|
161
|
-
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
project_level: If True (default), register to project-level .trae/skills.json.
|
|
172
|
+
If False, register to global ~/.trae/skills.json.
|
|
162
173
|
"""
|
|
163
174
|
try:
|
|
164
|
-
#
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
175
|
+
# Determine registration path
|
|
176
|
+
if project_level:
|
|
177
|
+
# Project-level: .trae/skills.json in current directory
|
|
178
|
+
base_dir = Path.cwd()
|
|
179
|
+
config_dir = base_dir / ".trae"
|
|
180
|
+
config_dir.mkdir(exist_ok=True)
|
|
181
|
+
skills_file = config_dir / "skills.json"
|
|
182
|
+
level_name = "project-level"
|
|
183
|
+
else:
|
|
184
|
+
# Global-level: ~/.trae/skills.json
|
|
185
|
+
config_dir = Path.home() / ".trae"
|
|
186
|
+
config_dir.mkdir(exist_ok=True)
|
|
187
|
+
skills_file = config_dir / "skills.json"
|
|
188
|
+
level_name = "global"
|
|
189
|
+
|
|
179
190
|
# Create or update skills.json
|
|
180
|
-
skills_file = config_dir / "skills.json"
|
|
181
191
|
skills: dict = {}
|
|
182
|
-
|
|
192
|
+
|
|
183
193
|
if skills_file.exists():
|
|
184
194
|
with open(skills_file) as f:
|
|
185
195
|
skills = json.load(f)
|
|
186
|
-
|
|
196
|
+
|
|
187
197
|
# Add multi-lang-build skill
|
|
188
198
|
skills["multi-lang-build"] = {
|
|
189
199
|
"name": "Multi-Lang Build",
|
|
@@ -210,49 +220,48 @@ def register_trae() -> bool:
|
|
|
210
220
|
}
|
|
211
221
|
]
|
|
212
222
|
}
|
|
213
|
-
|
|
223
|
+
|
|
214
224
|
with open(skills_file, "w") as f:
|
|
215
225
|
json.dump(skills, f, indent=2)
|
|
216
|
-
|
|
217
|
-
print(f"✅ Registered with Trae (config: {skills_file})")
|
|
226
|
+
|
|
227
|
+
print(f"✅ Registered with Trae ({level_name}, config: {skills_file})")
|
|
218
228
|
return True
|
|
219
|
-
|
|
229
|
+
|
|
220
230
|
except Exception as e:
|
|
221
231
|
print(f"❌ Failed to register with Trae: {e}")
|
|
222
232
|
return False
|
|
223
233
|
|
|
224
234
|
|
|
225
|
-
def register_codebuddy() -> bool:
|
|
235
|
+
def register_codebuddy(project_level: bool = True) -> bool:
|
|
226
236
|
"""Register as CodeBuddy skill.
|
|
227
|
-
|
|
228
|
-
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
project_level: If True (default), register to project-level .codebuddy/skills.yaml.
|
|
240
|
+
If False, register to global ~/.codebuddy/skills.yaml.
|
|
229
241
|
"""
|
|
230
242
|
try:
|
|
231
|
-
#
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
# Create or update skills.yaml (CodeBuddy may use YAML)
|
|
247
|
-
skills_file = config_dir / "skills.yaml"
|
|
248
|
-
|
|
243
|
+
# Determine registration path
|
|
244
|
+
if project_level:
|
|
245
|
+
# Project-level: .codebuddy/skills.yaml in current directory
|
|
246
|
+
base_dir = Path.cwd()
|
|
247
|
+
config_dir = base_dir / ".codebuddy"
|
|
248
|
+
config_dir.mkdir(exist_ok=True)
|
|
249
|
+
skills_file = config_dir / "skills.yaml"
|
|
250
|
+
level_name = "project-level"
|
|
251
|
+
else:
|
|
252
|
+
# Global-level: ~/.codebuddy/skills.yaml
|
|
253
|
+
config_dir = Path.home() / ".codebuddy"
|
|
254
|
+
config_dir.mkdir(exist_ok=True)
|
|
255
|
+
skills_file = config_dir / "skills.yaml"
|
|
256
|
+
level_name = "global"
|
|
257
|
+
|
|
249
258
|
skill_config = """# Multi-Lang Build Skill
|
|
250
259
|
skills:
|
|
251
260
|
multi-lang-build:
|
|
252
261
|
name: "Multi-Lang Build"
|
|
253
262
|
description: "Multi-language automated build tool with mirror acceleration"
|
|
254
263
|
version: "0.2.0"
|
|
255
|
-
|
|
264
|
+
|
|
256
265
|
commands:
|
|
257
266
|
build-go:
|
|
258
267
|
description: "Build Go project"
|
|
@@ -270,7 +279,7 @@ skills:
|
|
|
270
279
|
- name: mirror
|
|
271
280
|
description: "Enable mirror acceleration"
|
|
272
281
|
type: flag
|
|
273
|
-
|
|
282
|
+
|
|
274
283
|
build-python:
|
|
275
284
|
description: "Build Python project"
|
|
276
285
|
command: "multi-lang-build python {source} --output {output}"
|
|
@@ -284,7 +293,7 @@ skills:
|
|
|
284
293
|
- name: mirror
|
|
285
294
|
description: "Enable mirror acceleration"
|
|
286
295
|
type: flag
|
|
287
|
-
|
|
296
|
+
|
|
288
297
|
build-pnpm:
|
|
289
298
|
description: "Build pnpm project"
|
|
290
299
|
command: "multi-lang-build pnpm {source} --output {output}"
|
|
@@ -299,65 +308,67 @@ skills:
|
|
|
299
308
|
description: "Enable mirror acceleration"
|
|
300
309
|
type: flag
|
|
301
310
|
"""
|
|
302
|
-
|
|
311
|
+
|
|
303
312
|
# Append or create
|
|
304
313
|
if skills_file.exists():
|
|
305
314
|
content = skills_file.read_text()
|
|
306
315
|
if "multi-lang-build" not in content:
|
|
307
316
|
with open(skills_file, "a") as f:
|
|
308
317
|
f.write("\n" + skill_config)
|
|
309
|
-
print(f"✅ Registered with CodeBuddy (updated {skills_file})")
|
|
318
|
+
print(f"✅ Registered with CodeBuddy ({level_name}, updated {skills_file})")
|
|
310
319
|
else:
|
|
311
|
-
print(f"ℹ️ Already registered with CodeBuddy ({skills_file})")
|
|
320
|
+
print(f"ℹ️ Already registered with CodeBuddy ({level_name}, {skills_file})")
|
|
312
321
|
else:
|
|
313
322
|
skills_file.write_text(skill_config)
|
|
314
|
-
print(f"✅ Registered with CodeBuddy (created {skills_file})")
|
|
315
|
-
|
|
323
|
+
print(f"✅ Registered with CodeBuddy ({level_name}, created {skills_file})")
|
|
324
|
+
|
|
316
325
|
return True
|
|
317
|
-
|
|
326
|
+
|
|
318
327
|
except Exception as e:
|
|
319
328
|
print(f"❌ Failed to register with CodeBuddy: {e}")
|
|
320
329
|
return False
|
|
321
330
|
|
|
322
331
|
|
|
323
332
|
def register_skill(
|
|
324
|
-
ide: Literal["claude", "opencode", "trae", "codebuddy", "all"] = "claude"
|
|
333
|
+
ide: Literal["claude", "opencode", "trae", "codebuddy", "all"] = "claude",
|
|
334
|
+
global_level: bool = False
|
|
325
335
|
) -> bool:
|
|
326
336
|
"""Register multi-lang-build as a skill for the specified IDE.
|
|
327
|
-
|
|
337
|
+
|
|
328
338
|
Args:
|
|
329
339
|
ide: The IDE to register with. Options: "claude", "opencode", "trae", "codebuddy", "all"
|
|
330
340
|
Default is "claude".
|
|
331
|
-
|
|
341
|
+
global_level: If True, register to global config. If False (default), register to project-level.
|
|
342
|
+
|
|
332
343
|
Returns:
|
|
333
344
|
True if registration succeeded, False otherwise.
|
|
334
345
|
"""
|
|
335
346
|
print(f"📝 Registering multi-lang-build for {ide}...\n")
|
|
336
|
-
|
|
347
|
+
|
|
337
348
|
if ide == "all":
|
|
338
349
|
results = [
|
|
339
|
-
("Claude Code", register_claude_code()),
|
|
340
|
-
("OpenCode", register_opencode()),
|
|
341
|
-
("Trae", register_trae()),
|
|
342
|
-
("CodeBuddy", register_codebuddy()),
|
|
350
|
+
("Claude Code", register_claude_code(project_level=not global_level)),
|
|
351
|
+
("OpenCode", register_opencode(project_level=not global_level)),
|
|
352
|
+
("Trae", register_trae(project_level=not global_level)),
|
|
353
|
+
("CodeBuddy", register_codebuddy(project_level=not global_level)),
|
|
343
354
|
]
|
|
344
|
-
|
|
355
|
+
|
|
345
356
|
print("\n" + "=" * 50)
|
|
346
357
|
print("Registration Summary:")
|
|
347
358
|
for name, success in results:
|
|
348
359
|
status = "✅" if success else "❌"
|
|
349
360
|
print(f" {status} {name}")
|
|
350
|
-
|
|
361
|
+
|
|
351
362
|
return all(success for _, success in results)
|
|
352
|
-
|
|
363
|
+
|
|
353
364
|
elif ide == "claude":
|
|
354
|
-
return register_claude_code()
|
|
365
|
+
return register_claude_code(project_level=not global_level)
|
|
355
366
|
elif ide == "opencode":
|
|
356
|
-
return register_opencode()
|
|
367
|
+
return register_opencode(project_level=not global_level)
|
|
357
368
|
elif ide == "trae":
|
|
358
|
-
return register_trae()
|
|
369
|
+
return register_trae(project_level=not global_level)
|
|
359
370
|
elif ide == "codebuddy":
|
|
360
|
-
return register_codebuddy()
|
|
371
|
+
return register_codebuddy(project_level=not global_level)
|
|
361
372
|
else:
|
|
362
373
|
print(f"❌ Unknown IDE: {ide}")
|
|
363
374
|
print("Supported IDEs: claude, opencode, trae, codebuddy, all")
|
|
@@ -377,7 +388,13 @@ if __name__ == "__main__":
|
|
|
377
388
|
choices=["claude", "opencode", "trae", "codebuddy", "all"],
|
|
378
389
|
help="IDE to register with (default: claude)",
|
|
379
390
|
)
|
|
380
|
-
|
|
391
|
+
parser.add_argument(
|
|
392
|
+
"--global",
|
|
393
|
+
dest="global_level",
|
|
394
|
+
action="store_true",
|
|
395
|
+
help="Register to global config instead of project-level",
|
|
396
|
+
)
|
|
397
|
+
|
|
381
398
|
args = parser.parse_args()
|
|
382
|
-
success = register_skill(args.ide)
|
|
399
|
+
success = register_skill(args.ide, global_level=args.global_level)
|
|
383
400
|
sys.exit(0 if success else 1)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|