svg_icon 0.2.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +35 -2
- data/README.md +16 -4
- data/Rakefile +9 -1
- data/docs/superpowers/plans/2026-08-18-svg-icon-fetch-cli.md +557 -0
- data/docs/superpowers/specs/2026-08-18-svg-icon-fetch-design.md +100 -0
- data/exe/svg_icon +7 -0
- data/lib/data/lucide.json +6268 -0
- data/lib/svg_icon/cli.rb +68 -0
- data/lib/svg_icon/configuration.rb +4 -1
- data/lib/svg_icon/fetcher.rb +73 -0
- data/lib/svg_icon/helper.rb +23 -12
- data/lib/svg_icon/version.rb +1 -1
- data/lib/svg_icon.rb +83 -27
- data/svg_icon.gemspec +3 -1
- metadata +39 -7
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# svg_icon fetch CLI — 设计文档
|
|
2
|
+
|
|
3
|
+
- 日期:2026-08-18
|
|
4
|
+
- 状态:已批准
|
|
5
|
+
|
|
6
|
+
## 背景
|
|
7
|
+
|
|
8
|
+
gem 内置的 icon set json(bi/bx/lucide/heroicons)来自 [iconify/icon-sets](https://github.com/iconify/icon-sets/tree/master/json)。把所有 icon set 打包进 gem 不现实。需要一个 CLI 命令,让用户从 iconify/icon-sets 抓取任意 icon set 到项目本地,并通过配置使用。
|
|
9
|
+
|
|
10
|
+
## 目标
|
|
11
|
+
|
|
12
|
+
- `svg_icon fetch <name>` 从 iconify/icon-sets 下载 `<name>.json` 到项目 `config/svg_icons/` 目录
|
|
13
|
+
- 下载的 json 作为独立 icon set 使用:`config.icon = "<name>"` 时优先加载它,与内置 lucide 等平级
|
|
14
|
+
- 零新增运行时依赖(标准库 `net/http` + 现有 `multi_json`)
|
|
15
|
+
- 下载后离线可用,建议提交进版本控制
|
|
16
|
+
|
|
17
|
+
## 架构
|
|
18
|
+
|
|
19
|
+
### 1. CLI(`exe/svg_icon`)
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
$ svg_icon fetch bi
|
|
23
|
+
Fetching https://raw.githubusercontent.com/iconify/icon-sets/master/json/bi.json
|
|
24
|
+
Saved to config/svg_icons/bi.json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- 使用 `OptionParser` 做子命令分发
|
|
28
|
+
- `fetch <name>` 行为:
|
|
29
|
+
- 下载 URL:`https://raw.githubusercontent.com/iconify/icon-sets/master/json/<name>.json`
|
|
30
|
+
- 目标:`<icons_path>/<name>.json`,目录不存在时自动创建
|
|
31
|
+
- 先写临时文件,校验成功后 rename 到目标;失败不留下半截文件
|
|
32
|
+
- 目标已存在则覆盖(作为更新手段)
|
|
33
|
+
- 校验规则:JSON 可解析,且是 Hash 且含 `icons`(Hash)键
|
|
34
|
+
- 错误处理(全部 stderr + exit 1):
|
|
35
|
+
- 网络错误 / HTTP 非 200 → `FetchError`
|
|
36
|
+
- JSON 无效或不含 `icons` → `FetchError`
|
|
37
|
+
- 缺少子命令或参数 → usage 提示,exit 1
|
|
38
|
+
|
|
39
|
+
### 2. 配置扩展(`lib/svg_icon/configuration.rb`)
|
|
40
|
+
|
|
41
|
+
- 新增 `attr_accessor :icons_path`,默认 `File.join(Dir.pwd, "config/svg_icons")`
|
|
42
|
+
- 语义:外部 icon set 的查找目录
|
|
43
|
+
|
|
44
|
+
### 3. 数据查找(`lib/svg_icon.rb`)
|
|
45
|
+
|
|
46
|
+
`file_data` 查找顺序:
|
|
47
|
+
|
|
48
|
+
1. 外部 `<icons_path>/<icon>.json`(存在则优先)
|
|
49
|
+
2. 内置 `lib/data/<icon>.json`
|
|
50
|
+
3. 都不存在 → 现有 `SvgIcon::Error`("Icon data file not found")
|
|
51
|
+
|
|
52
|
+
外部优先:用户下载的版本覆盖内置,且内置 bi/bx 等与下载同名时以外部为准(数据更新)。
|
|
53
|
+
|
|
54
|
+
### 4. Fetcher(`lib/svg_icon/fetcher.rb`)
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
module SvgIcon
|
|
58
|
+
class FetchError < Error; end
|
|
59
|
+
|
|
60
|
+
class Fetcher
|
|
61
|
+
def initialize(base_url: DEFAULT_BASE_URL, http: Net::HTTP, ...)
|
|
62
|
+
def fetch(name, destination) # destination 是完整目标文件路径(含文件名),由调用方组装
|
|
63
|
+
# 返回 bool/抛出 FetchError
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- `base_url` 和 http 客户端可注入,便于测试
|
|
69
|
+
- 下载 → 解析校验 → 写临时文件 → rename
|
|
70
|
+
|
|
71
|
+
## 错误处理汇总
|
|
72
|
+
|
|
73
|
+
| 场景 | 行为 |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| 网络错误 / DNS 失败 | `SvgIcon::FetchError`,exit 1 |
|
|
76
|
+
| HTTP 404(icon set 不存在) | `SvgIcon::FetchError`,exit 1 |
|
|
77
|
+
| 返回体不是合法 JSON | `SvgIcon::FetchError`,exit 1 |
|
|
78
|
+
| JSON 不含 `icons` 对象 | `SvgIcon::FetchError`,exit 1 |
|
|
79
|
+
| `icons_path` 目录不可写 | 原样异常,exit 1 |
|
|
80
|
+
|
|
81
|
+
## 测试(minitest)
|
|
82
|
+
|
|
83
|
+
- **fetcher_test.rb**(`test/fetcher_test.rb`)
|
|
84
|
+
- 成功下载并写入正确文件(mock HTTP)
|
|
85
|
+
- 404 → FetchError
|
|
86
|
+
- 无效 JSON → FetchError
|
|
87
|
+
- 缺 `icons` 键 → FetchError
|
|
88
|
+
- 失败时不留下临时/半截文件
|
|
89
|
+
- **查找顺序**(`test/svg_icon_test.rb` 扩展)
|
|
90
|
+
- `icons_path` 存在同名文件 → 加载外部
|
|
91
|
+
- 外部没有 → 回退内置
|
|
92
|
+
- 都没有 → `SvgIcon::Error`
|
|
93
|
+
- **CLI 集成**(`test/cli_test.rb`)
|
|
94
|
+
- 在临时目录跑 `svg_icon fetch <name>`,断言 exit 0、文件写入
|
|
95
|
+
- 无效参数 → exit 1
|
|
96
|
+
|
|
97
|
+
## README 更新
|
|
98
|
+
|
|
99
|
+
- 新增 "Fetching icon sets" 章节:安装、`svg_icon fetch bi` 用法、`config.icon` / `config.icons_path` 示例
|
|
100
|
+
- 建议把 `config/svg_icons/` 提交进版本控制,部署无需重新抓取
|