gitinstall 1.1.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.
- gitinstall/__init__.py +61 -0
- gitinstall/_sdk.py +541 -0
- gitinstall/academic.py +831 -0
- gitinstall/admin.html +327 -0
- gitinstall/auto_update.py +384 -0
- gitinstall/autopilot.py +349 -0
- gitinstall/badge.py +476 -0
- gitinstall/checkpoint.py +330 -0
- gitinstall/cicd.py +499 -0
- gitinstall/clawhub.html +718 -0
- gitinstall/config_schema.py +353 -0
- gitinstall/db.py +984 -0
- gitinstall/db_backend.py +445 -0
- gitinstall/dep_chain.py +337 -0
- gitinstall/dependency_audit.py +1153 -0
- gitinstall/detector.py +542 -0
- gitinstall/doctor.py +493 -0
- gitinstall/education.py +869 -0
- gitinstall/enterprise.py +802 -0
- gitinstall/error_fixer.py +953 -0
- gitinstall/event_bus.py +251 -0
- gitinstall/executor.py +577 -0
- gitinstall/feature_flags.py +138 -0
- gitinstall/fetcher.py +921 -0
- gitinstall/huggingface.py +922 -0
- gitinstall/hw_detect.py +988 -0
- gitinstall/i18n.py +664 -0
- gitinstall/installer_registry.py +362 -0
- gitinstall/knowledge_base.py +379 -0
- gitinstall/license_check.py +605 -0
- gitinstall/llm.py +569 -0
- gitinstall/log.py +236 -0
- gitinstall/main.py +1408 -0
- gitinstall/mcp_agent.py +841 -0
- gitinstall/mcp_server.py +386 -0
- gitinstall/monorepo.py +810 -0
- gitinstall/multi_source.py +425 -0
- gitinstall/onboard.py +276 -0
- gitinstall/planner.py +222 -0
- gitinstall/planner_helpers.py +323 -0
- gitinstall/planner_known_projects.py +1010 -0
- gitinstall/planner_templates.py +996 -0
- gitinstall/remote_gpu.py +633 -0
- gitinstall/resilience.py +608 -0
- gitinstall/run_tests.py +572 -0
- gitinstall/skills.py +476 -0
- gitinstall/tool_schemas.py +324 -0
- gitinstall/trending.py +279 -0
- gitinstall/uninstaller.py +415 -0
- gitinstall/validate_top100.py +607 -0
- gitinstall/watchdog.py +180 -0
- gitinstall/web.py +1277 -0
- gitinstall/web_ui.html +2277 -0
- gitinstall-1.1.0.dist-info/METADATA +275 -0
- gitinstall-1.1.0.dist-info/RECORD +59 -0
- gitinstall-1.1.0.dist-info/WHEEL +5 -0
- gitinstall-1.1.0.dist-info/entry_points.txt +3 -0
- gitinstall-1.1.0.dist-info/licenses/LICENSE +21 -0
- gitinstall-1.1.0.dist-info/top_level.txt +1 -0
gitinstall/badge.py
ADDED
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
"""
|
|
2
|
+
badge.py - Install 按钮 / 徽章系统
|
|
3
|
+
====================================
|
|
4
|
+
|
|
5
|
+
让项目维护者在 README 中嵌入一键安装按钮。
|
|
6
|
+
|
|
7
|
+
功能:
|
|
8
|
+
1. SVG 徽章生成(纯 Python,无需外部服务)
|
|
9
|
+
2. Markdown / HTML / reStructuredText 安装按钮代码
|
|
10
|
+
3. VS Code URI 协议集成 (vscode://gitinstall.gitinstall/install?repo=...)
|
|
11
|
+
4. 安装统计追踪
|
|
12
|
+
5. 自定义样式(颜色、大小、语言)
|
|
13
|
+
|
|
14
|
+
零外部依赖,纯 Python 标准库。
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import html
|
|
20
|
+
import re
|
|
21
|
+
import urllib.parse
|
|
22
|
+
from typing import Optional
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# ─────────────────────────────────────────────
|
|
26
|
+
# SVG 徽章模板
|
|
27
|
+
# ─────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
# 受 shields.io 启发的扁平化 SVG 徽章
|
|
30
|
+
_SVG_FLAT = """\
|
|
31
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="20" role="img" aria-label="{aria}">
|
|
32
|
+
<title>{aria}</title>
|
|
33
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
34
|
+
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
35
|
+
<stop offset="1" stop-opacity=".1"/>
|
|
36
|
+
</linearGradient>
|
|
37
|
+
<clipPath id="r"><rect width="{width}" height="20" rx="3" fill="#fff"/></clipPath>
|
|
38
|
+
<g clip-path="url(#r)">
|
|
39
|
+
<rect width="{label_width}" height="20" fill="#555"/>
|
|
40
|
+
<rect x="{label_width}" width="{msg_width}" height="20" fill="{color}"/>
|
|
41
|
+
<rect width="{width}" height="20" fill="url(#s)"/>
|
|
42
|
+
</g>
|
|
43
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="11">
|
|
44
|
+
<text aria-hidden="true" x="{label_x}" y="15" fill="#010101" fill-opacity=".3">{label}</text>
|
|
45
|
+
<text x="{label_x}" y="14">{label}</text>
|
|
46
|
+
<text aria-hidden="true" x="{msg_x}" y="15" fill="#010101" fill-opacity=".3">{message}</text>
|
|
47
|
+
<text x="{msg_x}" y="14">{message}</text>
|
|
48
|
+
</g>
|
|
49
|
+
</svg>"""
|
|
50
|
+
|
|
51
|
+
# 大按钮样式
|
|
52
|
+
_SVG_BUTTON = """\
|
|
53
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}" role="img" aria-label="{aria}">
|
|
54
|
+
<title>{aria}</title>
|
|
55
|
+
<defs>
|
|
56
|
+
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
|
|
57
|
+
<stop offset="0%" stop-color="{color_light}"/>
|
|
58
|
+
<stop offset="100%" stop-color="{color}"/>
|
|
59
|
+
</linearGradient>
|
|
60
|
+
<filter id="shadow">
|
|
61
|
+
<feDropShadow dx="0" dy="1" stdDeviation="1" flood-opacity="0.2"/>
|
|
62
|
+
</filter>
|
|
63
|
+
</defs>
|
|
64
|
+
<rect width="{width}" height="{height}" rx="6" fill="url(#bg)" filter="url(#shadow)"/>
|
|
65
|
+
<g fill="#fff" text-anchor="middle" font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif">
|
|
66
|
+
<text x="{cx}" y="{text_y}" font-size="{font_size}" font-weight="600">{icon} {message}</text>
|
|
67
|
+
{subtitle_element}
|
|
68
|
+
</g>
|
|
69
|
+
</svg>"""
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# 颜色预设
|
|
73
|
+
BADGE_COLORS = {
|
|
74
|
+
"blue": "#0078d4",
|
|
75
|
+
"green": "#28a745",
|
|
76
|
+
"red": "#cb2431",
|
|
77
|
+
"orange": "#f66a0a",
|
|
78
|
+
"purple": "#6f42c1",
|
|
79
|
+
"black": "#24292e",
|
|
80
|
+
"gray": "#6a737d",
|
|
81
|
+
# 品牌色
|
|
82
|
+
"github": "#24292e",
|
|
83
|
+
"vscode": "#007acc",
|
|
84
|
+
"python": "#3776ab",
|
|
85
|
+
"node": "#339933",
|
|
86
|
+
"rust": "#dea584",
|
|
87
|
+
"go": "#00add8",
|
|
88
|
+
"docker": "#2496ed",
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _estimate_text_width(text: str, font_size: int = 11) -> int:
|
|
93
|
+
"""估算文本宽度(像素)"""
|
|
94
|
+
# 近似计算,参考 shields.io 的方法
|
|
95
|
+
width = 0
|
|
96
|
+
for ch in text:
|
|
97
|
+
if ord(ch) > 127:
|
|
98
|
+
width += font_size * 0.9 # CJK 字符更宽
|
|
99
|
+
elif ch.isupper():
|
|
100
|
+
width += font_size * 0.65
|
|
101
|
+
elif ch in 'mwMW':
|
|
102
|
+
width += font_size * 0.75
|
|
103
|
+
elif ch in 'ijl.!|':
|
|
104
|
+
width += font_size * 0.35
|
|
105
|
+
else:
|
|
106
|
+
width += font_size * 0.55
|
|
107
|
+
return int(width) + 10 # padding
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# ─────────────────────────────────────────────
|
|
111
|
+
# 徽章生成
|
|
112
|
+
# ─────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
def generate_badge_svg(
|
|
115
|
+
label: str = "GitInstall",
|
|
116
|
+
message: str = "Install",
|
|
117
|
+
color: str = "blue",
|
|
118
|
+
style: str = "flat", # "flat" | "button"
|
|
119
|
+
) -> str:
|
|
120
|
+
"""
|
|
121
|
+
生成 SVG 徽章。
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
label: 左侧标签文字
|
|
125
|
+
message: 右侧消息文字
|
|
126
|
+
color: 颜色名或十六进制值
|
|
127
|
+
style: "flat"(小徽标)或 "button"(大按钮)
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
SVG 字符串
|
|
131
|
+
"""
|
|
132
|
+
color_hex = BADGE_COLORS.get(color, color)
|
|
133
|
+
if not color_hex.startswith("#"):
|
|
134
|
+
color_hex = "#0078d4"
|
|
135
|
+
|
|
136
|
+
safe_label = html.escape(label)
|
|
137
|
+
safe_message = html.escape(message)
|
|
138
|
+
aria = f"{safe_label}: {safe_message}"
|
|
139
|
+
|
|
140
|
+
if style == "button":
|
|
141
|
+
return _generate_button_svg(safe_label, safe_message, color_hex, aria)
|
|
142
|
+
|
|
143
|
+
# Flat badge
|
|
144
|
+
label_width = _estimate_text_width(label) + 2
|
|
145
|
+
msg_width = _estimate_text_width(message) + 2
|
|
146
|
+
total_width = label_width + msg_width
|
|
147
|
+
|
|
148
|
+
return _SVG_FLAT.format(
|
|
149
|
+
width=total_width,
|
|
150
|
+
label_width=label_width,
|
|
151
|
+
msg_width=msg_width,
|
|
152
|
+
color=color_hex,
|
|
153
|
+
label=safe_label,
|
|
154
|
+
message=safe_message,
|
|
155
|
+
label_x=label_width / 2,
|
|
156
|
+
msg_x=label_width + msg_width / 2,
|
|
157
|
+
aria=aria,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _generate_button_svg(
|
|
162
|
+
label: str, message: str, color: str, aria: str,
|
|
163
|
+
width: int = 200, height: int = 44,
|
|
164
|
+
) -> str:
|
|
165
|
+
"""生成大按钮 SVG"""
|
|
166
|
+
# 计算亮色版本
|
|
167
|
+
r, g, b = int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16)
|
|
168
|
+
light_r = min(255, r + 30)
|
|
169
|
+
light_g = min(255, g + 30)
|
|
170
|
+
light_b = min(255, b + 30)
|
|
171
|
+
color_light = f"#{light_r:02x}{light_g:02x}{light_b:02x}"
|
|
172
|
+
|
|
173
|
+
cx = width / 2
|
|
174
|
+
font_size = 15
|
|
175
|
+
text_y = height / 2 + 5
|
|
176
|
+
|
|
177
|
+
subtitle_element = ""
|
|
178
|
+
if label != message:
|
|
179
|
+
text_y = height / 2 + 1
|
|
180
|
+
subtitle_element = (
|
|
181
|
+
f'<text x="{cx}" y="{height / 2 + 14}" '
|
|
182
|
+
f'font-size="10" opacity="0.85">{label}</text>'
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
return _SVG_BUTTON.format(
|
|
186
|
+
width=width,
|
|
187
|
+
height=height,
|
|
188
|
+
color=color,
|
|
189
|
+
color_light=color_light,
|
|
190
|
+
cx=cx,
|
|
191
|
+
text_y=text_y,
|
|
192
|
+
font_size=font_size,
|
|
193
|
+
icon="▶",
|
|
194
|
+
message=message,
|
|
195
|
+
subtitle_element=subtitle_element,
|
|
196
|
+
aria=aria,
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# ─────────────────────────────────────────────
|
|
201
|
+
# 嵌入代码生成
|
|
202
|
+
# ─────────────────────────────────────────────
|
|
203
|
+
|
|
204
|
+
def generate_install_url(
|
|
205
|
+
repo: str,
|
|
206
|
+
scheme: str = "vscode", # "vscode" | "web" | "cli"
|
|
207
|
+
base_url: str = "",
|
|
208
|
+
) -> str:
|
|
209
|
+
"""
|
|
210
|
+
生成安装 URL。
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
repo: owner/repo 格式
|
|
214
|
+
scheme: URL 方案
|
|
215
|
+
- "vscode": VS Code URI 协议
|
|
216
|
+
- "web": Web 安装页面
|
|
217
|
+
- "cli": 命令行安装
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
安装 URL
|
|
221
|
+
"""
|
|
222
|
+
safe_repo = urllib.parse.quote(repo, safe="")
|
|
223
|
+
|
|
224
|
+
if scheme == "vscode":
|
|
225
|
+
return f"vscode://gitinstall.gitinstall/install?repo={safe_repo}"
|
|
226
|
+
elif scheme == "web":
|
|
227
|
+
base = base_url or "https://gitinstall.dev"
|
|
228
|
+
return f"{base}/install/{safe_repo}"
|
|
229
|
+
elif scheme == "cli":
|
|
230
|
+
return f"gitinstall install {repo}"
|
|
231
|
+
return ""
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def generate_markdown_badge(
|
|
235
|
+
repo: str,
|
|
236
|
+
label: str = "GitInstall",
|
|
237
|
+
message: str = "Install with GitInstall",
|
|
238
|
+
color: str = "blue",
|
|
239
|
+
scheme: str = "vscode",
|
|
240
|
+
style: str = "flat",
|
|
241
|
+
base_url: str = "",
|
|
242
|
+
) -> str:
|
|
243
|
+
"""
|
|
244
|
+
生成 Markdown 格式的安装按钮代码。
|
|
245
|
+
|
|
246
|
+
用法:维护者将返回的代码复制到 README.md 即可。
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
Markdown 代码字符串
|
|
250
|
+
"""
|
|
251
|
+
install_url = generate_install_url(repo, scheme=scheme, base_url=base_url)
|
|
252
|
+
|
|
253
|
+
if style == "shields":
|
|
254
|
+
# 使用 shields.io 在线服务
|
|
255
|
+
safe_label = urllib.parse.quote(label, safe="")
|
|
256
|
+
safe_msg = urllib.parse.quote(message, safe="")
|
|
257
|
+
color_name = color if color in BADGE_COLORS else "blue"
|
|
258
|
+
badge_url = f"https://img.shields.io/badge/{safe_label}-{safe_msg}-{color_name}"
|
|
259
|
+
return f"[]({install_url})"
|
|
260
|
+
|
|
261
|
+
# 内联 SVG(无需外部服务)
|
|
262
|
+
svg = generate_badge_svg(label=label, message=message, color=color, style=style)
|
|
263
|
+
# 将 SVG 转为 data URI 用于 Markdown img tag
|
|
264
|
+
svg_encoded = urllib.parse.quote(svg)
|
|
265
|
+
return f"[]({install_url})"
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def generate_html_button(
|
|
269
|
+
repo: str,
|
|
270
|
+
text: str = "Install with GitInstall",
|
|
271
|
+
color: str = "blue",
|
|
272
|
+
scheme: str = "vscode",
|
|
273
|
+
size: str = "medium", # "small" | "medium" | "large"
|
|
274
|
+
base_url: str = "",
|
|
275
|
+
) -> str:
|
|
276
|
+
"""
|
|
277
|
+
生成 HTML 格式的安装按钮。
|
|
278
|
+
|
|
279
|
+
可嵌入到任何支持 HTML 的页面(GitHub README、文档站等)。
|
|
280
|
+
"""
|
|
281
|
+
install_url = generate_install_url(repo, scheme=scheme, base_url=base_url)
|
|
282
|
+
color_hex = BADGE_COLORS.get(color, color)
|
|
283
|
+
safe_text = html.escape(text)
|
|
284
|
+
safe_url = html.escape(install_url)
|
|
285
|
+
|
|
286
|
+
sizes = {
|
|
287
|
+
"small": ("padding:4px 12px;font-size:12px;", "14"),
|
|
288
|
+
"medium": ("padding:8px 20px;font-size:14px;", "18"),
|
|
289
|
+
"large": ("padding:12px 28px;font-size:16px;", "22"),
|
|
290
|
+
}
|
|
291
|
+
style_str, _ = sizes.get(size, sizes["medium"])
|
|
292
|
+
|
|
293
|
+
return (
|
|
294
|
+
f'<a href="{safe_url}" '
|
|
295
|
+
f'style="display:inline-block;{style_str}'
|
|
296
|
+
f'background:{color_hex};color:#fff;'
|
|
297
|
+
f'border-radius:6px;text-decoration:none;font-weight:600;'
|
|
298
|
+
f'font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif">'
|
|
299
|
+
f'▶ {safe_text}</a>'
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def generate_rst_badge(
|
|
304
|
+
repo: str,
|
|
305
|
+
message: str = "Install with GitInstall",
|
|
306
|
+
color: str = "blue",
|
|
307
|
+
scheme: str = "vscode",
|
|
308
|
+
base_url: str = "",
|
|
309
|
+
) -> str:
|
|
310
|
+
"""生成 reStructuredText 格式的安装徽章"""
|
|
311
|
+
install_url = generate_install_url(repo, scheme=scheme, base_url=base_url)
|
|
312
|
+
safe_label = urllib.parse.quote("GitInstall", safe="")
|
|
313
|
+
safe_msg = urllib.parse.quote(message, safe="")
|
|
314
|
+
color_name = color if color in BADGE_COLORS else "blue"
|
|
315
|
+
badge_url = f"https://img.shields.io/badge/{safe_label}-{safe_msg}-{color_name}"
|
|
316
|
+
return (
|
|
317
|
+
f".. image:: {badge_url}\n"
|
|
318
|
+
f" :target: {install_url}\n"
|
|
319
|
+
f" :alt: {message}"
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
# ─────────────────────────────────────────────
|
|
324
|
+
# README 自动注入
|
|
325
|
+
# ─────────────────────────────────────────────
|
|
326
|
+
|
|
327
|
+
_BADGE_MARKER_START = "<!-- GITINSTALL-BADGE-START -->"
|
|
328
|
+
_BADGE_MARKER_END = "<!-- GITINSTALL-BADGE-END -->"
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def inject_badge_into_readme(
|
|
332
|
+
readme_path: str,
|
|
333
|
+
repo: str,
|
|
334
|
+
style: str = "flat",
|
|
335
|
+
color: str = "blue",
|
|
336
|
+
scheme: str = "vscode",
|
|
337
|
+
position: str = "top", # "top" | "after_title" | "badges"
|
|
338
|
+
) -> bool:
|
|
339
|
+
"""
|
|
340
|
+
自动在 README 中注入安装按钮。
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
readme_path: README.md 文件路径
|
|
344
|
+
repo: owner/repo
|
|
345
|
+
style: 徽章样式
|
|
346
|
+
color: 颜色
|
|
347
|
+
scheme: URL 方案
|
|
348
|
+
position: 注入位置
|
|
349
|
+
- "top": 文件顶部
|
|
350
|
+
- "after_title": 第一个标题之后
|
|
351
|
+
- "badges": 现有徽章行之后
|
|
352
|
+
|
|
353
|
+
Returns:
|
|
354
|
+
是否成功注入
|
|
355
|
+
"""
|
|
356
|
+
with open(readme_path, "r", encoding="utf-8") as f:
|
|
357
|
+
content = f.read()
|
|
358
|
+
|
|
359
|
+
badge_md = generate_markdown_badge(repo, color=color, scheme=scheme, style="shields")
|
|
360
|
+
badge_block = f"{_BADGE_MARKER_START}\n{badge_md}\n{_BADGE_MARKER_END}"
|
|
361
|
+
|
|
362
|
+
# 如果已存在,替换
|
|
363
|
+
if _BADGE_MARKER_START in content:
|
|
364
|
+
pattern = re.escape(_BADGE_MARKER_START) + r".*?" + re.escape(_BADGE_MARKER_END)
|
|
365
|
+
content = re.sub(pattern, badge_block, content, flags=re.DOTALL)
|
|
366
|
+
else:
|
|
367
|
+
if position == "after_title":
|
|
368
|
+
# 在第一个 # 标题行之后插入
|
|
369
|
+
match = re.search(r'^#\s+.+\n', content, re.MULTILINE)
|
|
370
|
+
if match:
|
|
371
|
+
insert_at = match.end()
|
|
372
|
+
content = content[:insert_at] + "\n" + badge_block + "\n" + content[insert_at:]
|
|
373
|
+
else:
|
|
374
|
+
content = badge_block + "\n\n" + content
|
|
375
|
+
elif position == "badges":
|
|
376
|
+
# 在现有徽章(shields.io / badge 图片)行之后插入
|
|
377
|
+
match = re.search(r'(\[!\[.*?\]\(.*?\)\]\(.*?\)\s*\n)+', content)
|
|
378
|
+
if match:
|
|
379
|
+
insert_at = match.end()
|
|
380
|
+
content = content[:insert_at] + badge_block + "\n" + content[insert_at:]
|
|
381
|
+
else:
|
|
382
|
+
content = badge_block + "\n\n" + content
|
|
383
|
+
else:
|
|
384
|
+
# top
|
|
385
|
+
content = badge_block + "\n\n" + content
|
|
386
|
+
|
|
387
|
+
with open(readme_path, "w", encoding="utf-8") as f:
|
|
388
|
+
f.write(content)
|
|
389
|
+
|
|
390
|
+
return True
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
# ─────────────────────────────────────────────
|
|
394
|
+
# 生成完整的嵌入代码片段
|
|
395
|
+
# ─────────────────────────────────────────────
|
|
396
|
+
|
|
397
|
+
def generate_embed_snippet(
|
|
398
|
+
repo: str,
|
|
399
|
+
formats: Optional[list[str]] = None,
|
|
400
|
+
color: str = "blue",
|
|
401
|
+
scheme: str = "vscode",
|
|
402
|
+
base_url: str = "",
|
|
403
|
+
) -> dict[str, str]:
|
|
404
|
+
"""
|
|
405
|
+
生成所有格式的嵌入代码片段。
|
|
406
|
+
|
|
407
|
+
Args:
|
|
408
|
+
repo: owner/repo
|
|
409
|
+
formats: 要生成的格式列表,None 则生成全部
|
|
410
|
+
color: 颜色
|
|
411
|
+
scheme: URL 方案
|
|
412
|
+
|
|
413
|
+
Returns:
|
|
414
|
+
{format_name: code_snippet} 字典
|
|
415
|
+
"""
|
|
416
|
+
if formats is None:
|
|
417
|
+
formats = ["markdown", "html", "rst", "url"]
|
|
418
|
+
|
|
419
|
+
snippets = {}
|
|
420
|
+
|
|
421
|
+
if "markdown" in formats:
|
|
422
|
+
snippets["markdown"] = generate_markdown_badge(
|
|
423
|
+
repo, color=color, scheme=scheme, style="shields"
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
if "html" in formats:
|
|
427
|
+
snippets["html"] = generate_html_button(
|
|
428
|
+
repo, color=color, scheme=scheme, base_url=base_url
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
if "html_large" in formats:
|
|
432
|
+
snippets["html_large"] = generate_html_button(
|
|
433
|
+
repo, color=color, scheme=scheme, size="large", base_url=base_url
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
if "rst" in formats:
|
|
437
|
+
snippets["rst"] = generate_rst_badge(
|
|
438
|
+
repo, color=color, scheme=scheme, base_url=base_url
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
if "url" in formats:
|
|
442
|
+
snippets["url"] = generate_install_url(repo, scheme=scheme, base_url=base_url)
|
|
443
|
+
|
|
444
|
+
if "cli" in formats:
|
|
445
|
+
snippets["cli"] = generate_install_url(repo, scheme="cli")
|
|
446
|
+
|
|
447
|
+
return snippets
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def format_embed_snippets(snippets: dict[str, str], repo: str) -> str:
|
|
451
|
+
"""格式化嵌入代码片段,方便用户复制"""
|
|
452
|
+
lines = [
|
|
453
|
+
f"🔘 GitInstall 一键安装按钮 — {repo}",
|
|
454
|
+
"",
|
|
455
|
+
"将以下代码添加到你的 README 即可:",
|
|
456
|
+
"",
|
|
457
|
+
]
|
|
458
|
+
|
|
459
|
+
format_labels = {
|
|
460
|
+
"markdown": "📝 Markdown (README.md)",
|
|
461
|
+
"html": "🌐 HTML (Medium)",
|
|
462
|
+
"html_large": "🌐 HTML (Large)",
|
|
463
|
+
"rst": "📄 reStructuredText",
|
|
464
|
+
"url": "🔗 Direct URL",
|
|
465
|
+
"cli": "💻 CLI Command",
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
for fmt, code in snippets.items():
|
|
469
|
+
label = format_labels.get(fmt, fmt)
|
|
470
|
+
lines.append(f"### {label}")
|
|
471
|
+
lines.append("```")
|
|
472
|
+
lines.append(code)
|
|
473
|
+
lines.append("```")
|
|
474
|
+
lines.append("")
|
|
475
|
+
|
|
476
|
+
return "\n".join(lines)
|