# 铁铺 (TiePM) 使用指南

> **铁铺**是玄铁语言的官方包管理器。提供搜索、安装、发布铁器(玄铁包)的完整工作流。

---

## 概述

### 1.什么是铁铺?

铁铺(TiePM)之于玄铁,犹如 npm 之于 Node.js、cargo 之于 Rust。它解决了以下问题:

- **发现**:搜索可用的铁器(库/工具)
- **安装**:一键安装铁器到本地,自动验证完整性
- **发布**:将你的项目打包并登记到官方索引,供他人使用

### 2.核心概念

| 术语 | 说明 |
|------|------|
| **铁器** | 可发布的玄铁包(库或可执行程序) |
| **索引** | 远程 JSON 文件,记录所有可用铁器的元信息 |
| **tiepm.toml** | 项目根目录下的包清单文件,描述铁器的元信息 |
| **哈希** | SHA256 校验值,确保下载文件完整且未被篡改 |

### 3.工作目录

铁铺的所有本地数据存储在用户目录下:

```
~/.tiepm/
├── 缓存/              # 下载的 .zip 缓存
├── 已安装/            # 已解压安装的铁器
│   ├── 数组工具/
│   ├── 网络库/
│   └── ...
└── 索引.json          # 本地缓存的远程索引
```

---

## 安装铁铺

铁铺本身也是一个铁器,可以通过自举方式安装。

### 方式一:从源码编译

```bash
# 克隆铁铺仓库
git clone https://gitcode.com/MARKJY/TiePM.git
cd tiepm

# 使用玄铁编译器编译
xtc tie tiepm.xt
```

编译产物为 `tiepm.exe`,将其放入 PATH 目录即可全局使用。

### 方式一:从仓库源码编译(推荐)

```bash
# 在玄铁仓库根目录
xtc tie tiepm/铁铺.xt
```

产物为 `tiepm/tiepm.exe`,放入 PATH 目录即可全局使用。CLI 入口为 `tiepm/铁铺.xt`(调度)+ `tiepm/核心.xt`(逻辑)。


## 命令参考

### 一览

| 命令 | 说明 | 状态 |
|------|------|------|
| `tiepm az <包名> [约束]` | 安装铁器(自动解析传递依赖) | 待 HTTPS |
| `tiepm lc` | 列出已安装的铁器 | 可用 |
| `tiepm ss <关键词>` | 在远程索引中搜索 | 待 HTTPS |
| `tiepm fb` | 发布当前目录的铁器 | 待 HTTPS |
| `tiepm ql` | 清理下载缓存 | 可用 |

### 安装 — `tiepm az <包名>`

从远程索引查找并安装指定铁器。

```bash
tiepm az UI //使用铁铺远程拉取UI库下载过来
```

**执行流程**:

1. 从 `https://tiepm.xt.markjy.com/index.json` 获取远程索引
2. 查找包名,获取最新版本的哈希、仓库地址
3. 构造下载 URL:`{仓库}/archive/v{版本}.zip`
4. 下载 ZIP 到 `~/.tiepm/缓存/`
5. 使用 `certutil -hashfile` 计算 SHA256 并与索引记录比对
6. 解压到 `~/.tiepm/已安装/<包名>/`
7. 清理下载缓存

**别名**:`铁铺 install <包名>`(英文命令等效)

### 搜索 — `tiepm ss <关键词>`

在远程索引中按关键词搜索铁器,匹配包名和描述。

```bash
tiepm ss HTTP
```

输出示例:

```
=== 搜索结果 ===
HTTP v1.0.0 - HTTP 客户端与服务端工具
```

### 发布 — `tiepm fb`

将当前目录的项目打包并输出发布所需信息。

**前置条件**:项目根目录存在 `tiepm.toml` 文件。

```bash
tiepm fb
```

**执行流程**:

1. 读取并解析 `tiepm.toml`
2. 使用 `tar -czf` 打包项目(排除 `.git`、`.tiepm`、打包文件自身)
3. 计算 `.zip` 文件的 SHA256
4. 输出发布信息和 API 调用指令

**输出示例**:

```
[铁铺] === 发布铁器 ===                                            
[铁铺] 包名: HTTP v1.0.0
[铁铺] 作者: 问号盒              
[铁铺] 描述: 玄铁HTTP/1.1服务端库—纯玄铁实现,基于听/连原语;每连接一请求一响应
[铁铺] SHA256: fae6e724a09fde62be8590d48558f613a0e6c4cb5ac98eec6kdjQwcFkXq4

=== 发布信息 ===
包名: HTTP
版本: 1.0.0
哈希: fae6e724a09fde62be8590d48558f613a0e6c4cb5ac98eec6kdjQwcFkXq4
仓库: https://gitcode.com/MARKJY/XuanTieHTTP
产物: C:\Users\Administrator\.tiepm\缓存\XuanTieHTTP_v1.0.0.zip

=== 第 1/2 步(需手动,涉及 GitHub 权限) ===
1. git tag v1.0.0 && git push --tags
2. 在 GitHub 仓库页面创建 Release(标签选 v1.0.0),把 XuanTieHTTP_v1.0.0.zip 作为附件上传(文件名不要改)

=== 第 3 步:注册到铁铺索引(自动) ===
[铁铺] 服务器响应: {"消息":"HTTP v1.0.0 已发布","状态":"成功"}
[铁铺] 索引注册完成 ✓ 可用 tiepm ss HTTP 验证
```

**完整发布工作流**:

```bash
# 确保代码已提交
git add . && git commit -m "v1.0.0 发布准备"

# 执行铁铺发布(打包 + 计算哈希)
tiepm fb

# 打 Git 标签并推送
git tag v1.0.0 //你也可以自己在网页上面创建
git push origin master --tags

# 在 GitHub 上创建 Release,上传输出的 .zip 文件。
# 标签要选对对应的版本,确保zip已上传、Tag标签核对无误,就完成全流程了。可以直接尝试在本地az最新你上传的铁器。
```

### 列表 — `tiepm lc`

列出所有已安装的铁器。

```bash
tiepm lc
```

输出示例:

```
[铁铺] === 已安装的铁器 ===
  数组工具
  网络库
```

### 清理 — `tiepm ql`

清理 `~/.tiepm/缓存/` 目录中的下载缓存。

```bash
tiepm clean
```

**别名**:`铁铺 clean`


## 使用已安装的铁器

安装铁器后,在代码中直接用**裸包名**引用(无需路径!),像 Python 的 `import` 或 npm 的 `require` 一样:

```xuantie
引 "数组工具"

示(数组工具.去重([1, 2, 1, 3]))
```

编译器自动在 `~/.tiepm/已安装/<包名>/` 下查找入口 `.xt` 文件。无需写 `../已安装/数组工具/数组工具.xt`。

**与文件路径引用的对比**:

```xuantie
// 传统方式(相对路径,仅本地项目内使用)
引 "./lib/数组.xt" 予 A

// 铁铺方式(裸包名,自动从已安装位置解析)
引 "数组工具"
```

**解析优先级**:
1. 裸包名(如 `"数组工具"`)→ 编译器在 `~/.tiepm/已安装/` 下查找
2. 带路径前缀(如 `"./lib/xxx"`、`"../xxx"`)→ 相对源文件目录解析
3. 绝对路径(如 `"C:/..."`)→ 直接使用

**未安装时的错误提示**:

```
编译错误: 无法解析铁铺包引用 '数组工具'
  提示: 请先执行 'tiepm az 数组工具' 安装此包
```

---

## 包清单:tiepm.toml

每个铁器项目根目录需要一个 `tiepm.toml` 文件来描述包的元信息。

### 完整模板

```toml
# tiepm.toml - 铁铺包清单

[包]
名称 = "数组工具"                              # 必填:包名
版本 = "1.0.0"                                 # 必填:语义版本号
仓库 = "https://github.com/username/array-utils" # 必填:GitHub 仓库地址

[作者]
姓名 = "开发者名"                              # 选填
邮箱 = "dev@example.com"                       # 选填

[依赖]
# 铁铺 = "2.0.0"                               # 预留:依赖声明(后续支持)

[描述]
简介 = "提供数组去重、过滤、映射等工具函数"     # 选填:功能简述
许可 = "MIT"                                   # 选填:许可证
```

### 字段说明

**[包]** 节(必填):

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| 名称 | 字 | 是 | 铁器名称,用于搜索和安装 |
| 版本 | 字 | 是 | 语义版本号,格式 `主.次.补` |
| 仓库 | 字 | 是 | GitHub 仓库完整 URL |

**[作者]** 节(选填):

| 字段 | 类型 | 说明 |
|------|------|------|
| 姓名 | 字 | 作者/维护者名称 |
| 邮箱 | 字 | 联系邮箱 |

**[依赖]** 节(选填):

声明当前铁器依赖的其他铁器。安装时铁铺会**自动递归解析并安装所有传递依赖**。

```toml
[依赖]
字符串工具 = "^1.0.0"    # 最低版本约束
网络库 = "2.0.0"          # 精确版本
文件工具 = "*"             # 任意版本
```

**版本约束格式**:

| 格式 | 示例 | 含义 |
|------|------|------|
| 精确版本 | `"1.0.0"` | 必须精确匹配此版本 |
| 最低版本 | `"^1.0.0"` | 此版本或更高 |
| 任意版本 | `"*"` | 使用最新可用版本 |

**依赖解析行为**:

1. 读取 `tiepm.toml` 的 `[依赖]` 节
2. 对每个依赖,从远程索引查找满足约束的最高版本
3. 下载、验证哈希、解压安装
4. 读取该依赖自己的 `tiepm.toml`,递归解析其子依赖
5. 最大递归深度 10 层,超出则报错(防循环依赖)
6. 解析完成后自动执行版本冲突检测

**[描述]** 节(选填):

| 字段 | 类型 | 说明 |
|------|------|------|
| 简介 | 字 | 包功能一句话描述,用于搜索结果展示 |
| 许可 | 字 | 开源许可证名称 |

---

## 版本规范

铁铺采用语义版本号(Semantic Versioning):

```
主版本.次版本.补丁版本
  MAJOR . MINOR . PATCH
```

| 版本变更 | 含义 |
|----------|------|
| 补丁版本 +1 | 向后兼容的 bug 修复(`1.0.0` → `1.0.1`) |
| 次版本 +1 | 向后兼容的功能新增(`1.0.0` → `1.1.0`) |
| 主版本 +1 | 不兼容的 API 变更(`1.0.0` → `2.0.0`) |

安装时默认获取最新版本(按字符串排序比较版本号)。

---

## 索引工作原理

### 索引格式

远程索引是一个 JSON 对象,位于 `https://tiepm.xt.markjy.com/index.json`:

```json
{
  "数组工具": {
    "1.0.0": {
      "版本": "1.0.0",
      "哈希": "a1b2c3d4e5f6...",
      "仓库": "https://github.com/username/array-utils",
      "作者": "张三",
      "描述": "提供数组去重、过滤、映射等工具函数"
    }
  }
}
```

每个包名下可以包含多个版本。搜索 API 返回每个包的最新版本。

### 下载地址构造

铁铺从 GitHub Releases 下载包文件。下载 URL 由仓库地址和版本号拼接而成:

```
{仓库}/archive/v{版本}.zip
```

例如:
- 仓库:`https://github.com/username/array-utils`
- 版本:`1.0.0`
- 下载 URL:`https://github.com/username/array-utils/archive/v1.0.0.zip`

这个 URL 由 GitHub 自动生成(基于 Git tag `v1.0.0`),无需手动上传 Release 资源。

### 本地缓存

首次安装时,铁铺从远程获取索引并缓存到 `~/.tiepm/索引.json`。后续操作优先使用缓存,减少网络请求。

### 版本冲突检测

当多个依赖要求同一个包的不同版本时,安装完成后铁铺会自动检测并报告冲突。

**示例冲突场景**:

```
包 A 依赖: 字符串工具 >=1.0.0
包 B 依赖: 字符串工具 >=2.0.0
```

如果只有 `字符串工具 v1.5.0` 在索引中,A 的约束满足但 B 的不满足,铁铺报错:

```
==============================
[铁铺] 版本冲突: 1 个包存在版本冲突
==============================
包 "字符串工具":
  包 A -> >=1.0.0
  包 B -> >=2.0.0
  包 B(已安装 1.5.0) -> >=2.0.0
==============================
[铁铺] 请手动解决版本冲突后重试
```

**解决方式**:联系包的维护者发布满足更高版本约束的新版本,或调整依赖声明。

---

## 安全机制

### SHA256 哈希验证

每个包在索引中记录了其 `.zip` 文件的 SHA256 哈希值。安装时铁铺会:

1. 下载 `.zip` 文件到本地缓存
2. 计算实际文件的 SHA256
3. 与索引中记录的哈希比对
4. 不匹配则拒绝安装并报错

这确保了文件在传输过程中未被篡改或损坏。

### 手动验证(可选)

你也可以手动验证下载的文件:

```bash
# Windows (certutil)
certutil -hashfile 数组工具_v1.0.0.zip SHA256

# Linux/macOS
sha256sum 数组工具_v1.0.0.zip
```

---

## 创建你的第一个铁器

本节通过一个完整示例演示从零开始创建并发布一个铁器。

### 第一步:创建项目

```bash
mkdir 我的工具
cd 我的工具
```

### 第二步:编写源码

创建 `工具.xt`:

```xuantie
// 工具.xt - 我的第一个铁器

公 函 问好(名称) {
    返 "你好," & 名称 & "!"
}

公 函 加法(a, b) {
    返 a + b
}
```

### 第三步:创建清单

创建 `tiepm.toml`:

```toml
[包]
名称 = "我的工具"
版本 = "1.0.0"
仓库 = "https://github.com/你的用户名/我的工具"

[描述]
简介 = "一个简单的示例铁器"
```

### 第四步:发布

```bash
# 执行发布命令
tiepm fb

# 按照输出的步骤:
# 初始化 Git 仓库并推送
git init
git add .
git commit -m "v1.0.0"
git tag v1.0.0
git remote add origin https://gitcode.com/你的用户名/我的工具.git
git push -u origin master --tags

# 最后上仓库网页版创建Release并选择对应的tag和上传对应的zip作为附件即可完成。
```

### 第五步:验证

```bash
# 换一个目录,尝试安装刚发布的铁器
cd ..
tiepm sz 我的工具
```

---