# Technical Documentation: RubyMetric/chsrc

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/RubyMetric/chsrc)

### Overview (`README.md`)

<div align="center">
  <img alt="chsrc logo" src="doc/image/chsrc.png"/>
</div>

全平台通用换源工具与框架 `chsrc`，**目标支持 Linux, Windows (native, MSYS2, Cygwin), macOS, BSD, Android 等尽可能多的操作系统环境，龙芯、飞腾、RISC-V 等尽可能多的 CPU**。我们使用 **C11** 来完成上述目标，以保证最大的可用性。本软件为**自由软件**，SDPX 软件许可证为 `GPL-3.0-or-later and MIT`

<br>



<table align="center">
  <tr>
  <td>
    <a href="https://trendshift.io/repositories/10744" target="_blank"><img src="https://trendshift.io/api/badge/repositories/10744" alt="RubyMetric%2Fchsrc | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
  </td>
  <td>
    <a href="https://hellogithub.com/repository/7666ba91e01e4a59be5809b02d9e8ff6" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=7666ba91e01e4a59be5809b02d9e8ff6&claim_uid=H6YVMUy7ulev8R4&theme=dark" alt="Featured｜HelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a>
  </td>
  <td>
    <a href="https://atomgit.com/RubyMetric/chsrc"><img src="https://atomgit.com/RubyMetric/chsrc/star/new_badge.svg" /></a>
  </td>
  </tr>
</table>

<br>



## ❤️ 致所有的朋友们

2025年8月11日，我因通宵重构本项目代码而被送去抢救（[#252](https://github.com/RubyMetric/chsrc/issues/252)，[突发！换源工具 chsrc 作者在重构过程中被送去 120 抢救](https://v2ex.com/t/1151802)）。大家给予的关心和帮助让我非常非常感动！在此，我衷心感谢每一位朋友！**无论是开源还是闭源，无论是否为职业程序员，我们其实都是一群使用软件、热心互助、充满友爱的人，这是一个温暖的大家庭**。

我为 `chsrc` 采用 GPL 协议，怀着殷切的期望：**希望能够营造像 Richard Stallman 在创建 GNU 项目之前，在 MIT 那样的氛围——写自己用得上的软件，与大家一起开发、维护，简单纯粹，无关商业利益。就像小区、校园自发组建的足球篮球队，从一次偶然的加入，逐渐成长为互相支持的伙伴**。

这次经历让我更加深刻地体会到：开源，是一种把大家联系在一起的方式，它让互助和协作成为可能。最后，希望大家能够**时刻关注**自己的身体，**你可以随时 `chsrc` `chown` `chgrp` `chmod` 无限次，但是无法 `chbody`**！

<br>



## 🤝 协作与贡献

> [!TIP]
> **`chsrc` 不仅是一个命令行工具，同时也是一个体现了 Ruby on Rails 思想的 MVC 换源框架，它甚至使你能够在不了解C语言的情况下编写出新的换源方法 (recipe)。** 配合使用 [rawstr4c], 这将比写 shell 脚本更加轻松。 [如何编写 recipe?](./doc/10-如何编写recipe.md)

---

> [!NOTE]
> 这也许是你可以参与的第一个现实世界中有用的C语言项目，[用 VS Code 一分钟内上手编译、运行、测试 chsrc](./doc/01-开发与构建.md)
>
> 欢迎对 GitHub、Gitee 协作不熟悉的人以此为契机学习参与贡献, 欢迎任何编程初学者。[从开发到提交PR，我们覆盖全流程文档](./doc/)
---

> [!IMPORTANT]
> **`chsrc` 可换源 65+ 菜品。每个人仅仅贡献和维护自己熟悉的部分，回报是得到其他所有领域专家的帮助。** [欢迎成为 recipe 维护者](https://github.com/RubyMetric/chsrc/issues/275)

<br>



## 📌 示例

桌面端:

<div align="center">
  <img alt="chsrc set node" src="doc/image/example-set-nodejs.png"/>
</div>

<br>

安卓:

<div align="center">
  <img alt="chsrc set python and chsrc set termux" src="doc/image/chsrc-on-Android-set-python-and-termux.jpg" width="300" height="750"/>
</div>

<br>



## 🚀 安装

<a href="https://repology.org/project/chsrc/versions">
  <img src="https://repology.org/badge/vertical-allrepos/chsrc.svg" alt="Packaging status" align="right">
</a>

> [!IMPORTANT]
> 若通过下述手动方式安装，则会下载到当前目录，可直接通过 `./chsrc` 运行

<details>
<summary>Windows</summary>

- 可通过 `scoop` 安装，感谢 [@rocascent] 与 [@niheaven]

```bash
scoop install chsrc
```

<br>

- 可通过 `WinGet` 安装，感谢 [@YU-7] 与 [@Dragon1573]

```bash
winget install RubyMetric.chsrc
```

<br>

- 可通过 `PowerShell` 脚本一键下载最新版二进制文件，感谢 [@wickdynex]

    若下方链接无法访问，可使用 `https://gitee.com/RubyMetric/chsrc/raw/main/tool/installer.ps1` 替代

```PowerShell
# 使用 -Version 指定版本 (不指定时默认为 pre)
#   1. 安装 pre 版本; 这比从包管理器安装的总是更新一些
#   2. 安装旧版本; 有时新版本可能引入某些 Bug，临时使用旧版本解决燃眉之急
"& { $(iwr -useb https://chsrc.run/windows) } -Version pre" | iex
```

<br>

- 或手动下载二进制文件，这是最新版，往往比 `scoop` 提供的更新，适用于修复 Bug、添加新功能后及时使用，以及未安装 `scoop` 时

```bash
# x64
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-x64-windows.exe -o chsrc.exe

# x86
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-x86-windows.exe -o chsrc.exe

# Arm64 (WoA, Windows on Arm)
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-arm64-windows.exe -o chsrc.exe
```

</details>



<details>
<summary>Linux</summary>

- 可通过 `apt`/`dpkg` 安装，感谢 [@sanchuanhehe]

```bash
# x64
$ curl -LO https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc_latest-1_amd64.deb

# 也可以使用 Wget
wget https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc_latest-1_amd64.deb

$ sudo apt install ./chsrc_latest-1_amd64.deb
# 或
$ sudo sudo dpkg -i chsrc_latest-1_amd64.deb
```

<br>

- 支持 `AUR`，可通过 `yay` 安装，感谢 [@Jerry-Terrasse]

```bash
# AUR
$ yay -S chsrc-bin # Binary from GitHub Release
$ yay -S chsrc-git # Build  from the latest main branch (stable)
$ yay -S chsrc     # Build  from GitHub Release
```

<br>

- 可通过 `shell` 脚本一键安装最新版，感谢 [@Efterklang] 与 [@wickdynex]

    若下方链接无法访问，可使用 `https://gitee.com/RubyMetric/chsrc/raw/main/tool/installer.sh` 替代

```bash
# 非root用户默认安装至 ~/.local/bin
$ curl https://chsrc.run/posix | bash

# 也可以使用 Wget
$ wget -O - https://chsrc.run/posix | bash

# root用户默认安装至 /usr/local/bin
$ curl https://chsrc.run/posix | sudo bash

# 使用 -d 指定目录安装
$ curl https://chsrc.run/posix | bash -s -- -d ./

# 使用 -v 指定版本 (不指定时默认为 pre)
#   1. 安装 pre 版本; 这比从包管理器安装的总是更新一些
#   2. 安装旧版本; 有时新版本可能引入某些 Bug，临时使用旧版本解决燃眉之急
$ curl https://chsrc.run/posix | bash -s -- -v 0.2.1

# 使用 -l en 输出英文
$ curl https://chsrc.run/posix | bash -s -- -l en
```

<br>

- 可手动下载二进制文件安装

```bash
# x64
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-x64-linux -o chsrc; chmod +x ./chsrc

# aarch64
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-aarch64-linux -o chsrc; chmod +x ./chsrc

# riscv64
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-riscv64-linux -o chsrc; chmod +x ./chsrc

# armv7
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-armv7-linux -o chsrc; chmod +x ./chsrc
```

如果你所在的处理器架构没有预编译版本，可以使用 [chsrc-bootstrap]

</details>



<details>
<summary>macOS</summary>

- 可通过 `homebrew` 安装，感谢 [@Aaron-212] 与 [@chenrui333]

```bash
brew install chsrc
```

<br>

- 可通过 `shell` 脚本安装最新版，感谢 [@Efterklang] 与 [@wickdynex]

    若下方链接无法访问，可使用 `https://gitee.com/RubyMetric/chsrc/raw/main/tool/installer.sh` 替代

```bash
# 非root用户默认安装至 ~/.local/bin
$ curl https://chsrc.run/posix | bash

# root用户默认安装至 /usr/local/bin
$ curl https://chsrc.run/posix | sudo bash

# 使用 -d 指定目录安装
$ curl https://chsrc.run/posix | bash -s -- -d ./

# 使用 -v 指定版本 (不指定时默认为 pre)
#   1. 安装 pre 版本; 这比从包管理器安装的总是更新一些
#   2. 安装旧版本; 有时新版本可能引入某些 Bug，临时使用旧版本解决燃眉之急
$ curl https://chsrc.run/posix | bash -s -- -v 0.2.1

# 使用 -l en 输出英文
$ curl https://chsrc.run/posix | bash -s -- -l en
```

<br>

- 或手动下载二进制文件，这是最新版，往往比 `homebrew` 提供的更新，适用于修复 Bug、添加新功能后及时使用

```bash
# arm64/aarch64
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-aarch64-macos -o chsrc; chmod +x ./chsrc

# x64
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-x64-macos -o chsrc; chmod +x ./chsrc
```

</details>



<details>
<summary>BSD</summary>

如果已安装好了编译 `chsrc` 所需要的依赖，可直接运行:

```bash
git clone https://gitee.com/RubyMetric/chsrc.git; cd chsrc
clang -Iinclude -Ilib src/chsrc-main.c -o chsrc
```

**如果还不存在这些依赖，你将会被死锁住: 我还没有换源，我该如何安装这些依赖呢？**

这就是 [chsrc-bootstrap] 起作用的时刻，你可使用BSD系统的原生脚本语言编写 `bootstrapper`，[并向我们提交](https://github.com/RubyMetric/chsrc/issues/230)

注: `chsrc` 实现的 `FreeBSD recipe` 长期存在问题，因此一个新的 `bootstrapper` 是相当必要的，请帮助你自己和大家!

</details>



<details>
<summary>Android/Termux</summary>

Termux 中默认无 `Wget`，我们都用 `cURL` 来下载安装

```bash
# arm64/aarch64
curl -L https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-arm64-android -o chsrc; chmod +x ./chsrc
```

如果你所在的处理器架构没有预编译版本，可以使用 [chsrc-bootstrap]:

```bash
curl -L https://gitee.com/RubyMetric/chsrc/raw/main/bootstrap/Termux.bash | bash
```

</details>



<details>
<summary>其他平台</summary>

若你所在的平台不存在预编译好的 `chsrc`，你需要手动编译。如果已安装好了编译 `chsrc` 所需要的依赖，可直接运行:

```bash
git clone https://gitee.com/RubyMetric/chsrc.git; cd chsrc; make
```

**如果还不存在这些依赖，你将会被死锁住: 我还没有换源，我该如何安装这些依赖呢？**

这就是 [chsrc-bootstrap] 起作用的时刻，你可使用该平台原生脚本语言编写 `bootstrapper`，[并向我们提交](https://github.com/RubyMetric/chsrc/issues/230)

</details>

<br>

## 💡 使用

```bash
名称:
   chsrc - Change Source - (GPLv3+)

使用:
   chsrc <command> [options] [dish] [mirror]

命令:
   help,  h                 打印此帮助，或 -h, --help
   issue, i                 查看相关issue

   list, ls, l              列出可用镜像站和可换源菜品
   list  mirror|dish        列出支持的: 镜像站/换源菜品
   list  os|lang|ware       列出支持的: 操作系统/编程语言/软件
   list   <dish>            查看该菜品可用源与支持功能

   measure, m, cesu <dish>  对该菜品所有源测速

   get, g <dish>            查看该菜品当前源的使用情况

   set, s <dish>            换源，自动测速后挑选最快源
   set    <dish>  first     换源，使用维护团队测速第一的源
   set    <dish> <mirror>   换源，指定使用某镜像站 (通过list <dish>查看)
   set    <dish>  <URL>     换源，用户自定义源URL
   reset  <dish>            重置，使用上游默认使用的源

选项:
   -dry                       Dry Run，模拟换源过程，命令仅打印并不运行
   -scope=project|user|system 仅对本项目换源 / 用户级换源 / 系统级换源 (通过ls <dish>查看)
   -ipv6                      使用IPv6测速
   -en(glish)                 使用英文输出
   -no-color                  无颜色输出
```

<br>

```bash
自动测速，寻找最快者，换源

    $ chsrc set ruby

不想自动测速的时候，可使用维护团队测试的最快镜像站

    $ chsrc set ruby first

先列出可用的镜像站，然后选择其一，如使用 RubyChina 作为镜像站

    $ chsrc ls  ruby
    $ chsrc set ruby rubychina

若有自己的镜像，可以使用自定义URL

    $ chsrc set ruby https://gems.ruby-china.com/

对支持 *项目级* 换源的菜品，可以避免全局（*系统级* 或 *用户级*）换源

    $ chsrc set -scope=project bundler
    $ chsrc set -scope project pdm
```

<br>

## 编程语言开发

```bash
chsrc set ruby|rb|gem|bundler|rubygems

chsrc set python | py | pypi # 同时换 pip, poetry, pdm, uv 这4个包管理器，也可以4个独立换源
  chsrc set pip
  chsrc set poetry
  chsrc set pdm
  chsrc set uv

chsrc set rye

chsrc set node | nodejs # 同时换 npm, yarn 和 pnpm 这3个包管理器，也可以3个独立换源
  chsrc set npm
  chsrc set yarn
  chsrc set pnpm

chsrc set nvm
chsrc set bun

chsrc set perl | cpan
chsrc set php  | composer
chsrc set lua  | luarocks

chsrc set rust | cargo | crate
chsrc set rustup

chsrc set go
chsrc set java    | maven | mvn | maven-daemon | mvnd | gradle
chsrc set clojure | clojars
chsrc set dart    | pub
chsrc set flutter
chsrc set haskell | hackage | cabal | stack
chsrc set ocaml   | opam

# 同时会为 bioconductor 换源
chsrc set r | cran
chsrc set julia
```

<br>

## 操作系统

```bash
sudo chsrc set ubuntu
sudo chsrc set zorinos
sudo chsrc set linuxmint
sudo chsrc set debian
sudo chsrc set fedora
# 同时支持 Leap 和 Tumbleweed
sudo chsrc set opensuse
sudo chsrc set kali
sudo chsrc set arch
sudo chsrc set archlinuxcn
sudo chsrc set manjaro
sudo chsrc set gentoo
sudo chsrc set rocky | rockylinux
sudo chsrc set alma  | almalinux
sudo chsrc set alpine
sudo chsrc set voidlinux
sudo chsrc set solus
sudo chsrc set ros   | ros2
sudo chsrc set trisquel
sudo chsrc set linuxlite
sudo chsrc set raspi | raspberrypi
sudo chsrc set armbian
sudo chsrc set openwrt

sudo chsrc set openeuler
sudo chsrc set openanolis | anolis
sudo chsrc set openkylin
sudo chsrc set deepin

chsrc set msys2 | msys

# Android
chsrc set termux

# BSD
sudo chsrc set freebsd
sudo chsrc set openbsd
sudo chsrc set netbsd
```

<br>

## 软件

```bash
chsrc set winget
chsrc set brew      | homebrew
chsrc set cocoapods | cocoa | pod
chsrc set dockerhub | docker
chsrc set flathub   | flatpak
chsrc set nix
chsrc set guix
chsrc set emacs  | elpa
chsrc set tex    | ctan | latex | texlive | miktex
chsrc set conda  | anaconda
```

<br>

## 📝 许可证

- `chsrc` 主程序采用 `GPL-3.0-or-later` 许可证，保证该软件的永久自由
- `xy.h` 使用 `MIT` 许可证，保证该库可以在尽可能多的情况下复用

<br>

## ❤️ 致谢

感谢各个镜像站提供的优质免费镜像服务

1. [mirror.c](./src/framework/mirror.c) 包含了通用的镜像站信息
2. 各个recipe内部定义的专用镜像站

另外特别感谢以下组织或项目:

1. [校园网联合镜像站(MirrorZ)](https://help.mirrors.cernet.edu.cn/)
2. [清华大学 Tuna](https://mirrors.tuna.tsinghua.edu.cn/)
3. [上海交通大学软件源镜像服务](https://mirrors.sjtug.sjtu.edu.cn/)
4. [中国科学技术大学 Linux 用户协会](https://github.com/ustclug)
5. [Thanks Mirror 项目](https://github.com/eryajf/Thanks-Mirror) by [@eryajf](https://github.com/eryajf)

<br>

## 🚀 赞赏支持

你是否因为 `chsrc` 而受到启发、节省了时间精力 or whatever?

爱发电主页: <https://afdian.com/a/ccmywish>

<img src="https://raw.githubusercontent.com/ccmywish/support-my-oss-work/main/wechat-reward.png" alt="wechat-reward" style="width:300px;"/>

<br>

[rawstr4c]:        https://github.com/RubyMetric/rawstr4c
[chsrc-bootstrap]: ./bootstrap/

[@Aaron-212]:      https://github.com/Aaron-212
[@chenrui333]:     https://github.com/chenrui333
[@niheaven]:       https://github.com/niheaven
[@rocascent]:      https://github.com/rocascent
[@Jerry-Terrasse]: https://github.com/Jerry-Terrasse
[@Efterklang]:     https://github.com/Efterklang
[@wickdynex]:      https://github.com/wickdynex
[@YU-7]:           https://github.com/YU-7
[@sanchuanhehe]:   https://github.com/sanchuanhehe
[@Dragon1573]:     https://github.com/Dragon1573

---

### Overview (`.vscode/README.md`)

# Dev in VS Code

首先需要安装好 [just](https://github.com/casey/just)，而不再硬性需要 `make`

1. `Ctrl-Shift-B` 直接构建
2. `F5` 直接开始 Debug

---

### Overview (`bootstrap/README.md`)

# Bootstrap

```ruby
begin
  download_prebuilt_chsrc_binary_for_my_platform
rescue NoReadyMadeBinary => e
  bootstrap! e.my_platform
end
```

<br>



## 预编译产生的死锁问题

我们支持预编译的操作系统目前只有 `Windows`, `Linux`, `macOS`，支持的架构请参考[项目 README](../README.md)

某些操作系统如 BSD 家族，甚至是更小众的操作系统, 或者上述操作系统的某些架构，无法享受直接下载二进制立即使用的便利性，这导致用户需要自己编译 `chsrc`.

然而用户自己编译则面临着一个问题: **需要提前安装项目依赖**

1. 把代码 `git clone` 下来 或 下载 `zip` 包进行解压缩
2. C语言编译器
3. `GNU make` 或 `just` (这二者非强制，但是有了更好)

可是如果用户还没有换源，他/她又如何获得上述这些程序呢？**这是一把死锁，导致用户最终回到手动换源的原始农耕时代。**

<br>



## `chsrc-bootstrap` to the Rescue

`chsrc-bootstrap` 是一组使用原生脚本语言的脚本，每个脚本称为 `bootstrapper`，用来完成两件事情:

1. 帮助用户进行最基本的换源，让用户能够立即开始使用该系统安装其他软件

2. 用户自行决定是否需要安装 `chsrc`

    - 若不需要: 流程直接结束，用户已可以完成基本日常工作

    - 若需要: 帮助用户安装好所需的最少依赖，并编译安装 `chsrc`

注意，最基本的换源，即不测速，由维护者暂时决定先切换到某一个具体的源，先让系统跑起来。

### 支持的语言

上述提到的原生脚本语言只能是这些:

1. Windows: `PowerShell`, `CMD`

2. Linux: `Bash`, `sh`

    备选: `Perl`

3. macOS: `Zsh`, `Bash`, `sh`

    备选: `Ruby`, `Perl`

4. BSD: `sh`

    备选: 待议

5. 其他平台: 一切该平台支持的脚本语言，无需额外安装

<br>



## `chsrc` 与 `chsrc-bootstrap`

`chsrc` 需要实现 `chsrc-bootstrap` 中支持的平台。这是因为，`chsrc-bootstrap` 只换到了某一个具体的源，只是临时性的，后续用户可能还想要换到其他源，此时 `chsrc` 就可以接管。

而事实上，`chsrc-bootstrap` 可以完成一些操作，使得系统已经满足一些前置条件，这样的话 `chsrc` 可以在这些前置条件存在时接着换源，从而大幅减轻 `recipe` 的实现难度。

<br>



## 帮助

1. [FreeBSD 的换源](https://github.com/RubyMetric/chsrc/issues/11) 从项目一开始就是我们的目标之一，然而由于其:

    - 换源所需的步骤太多
    - 面临着特有的鸡蛋困境
    - BSD 工具和 GNU 工具总是有不兼容之处
    - 在C语言中实现困难重重

    因此我们一直没有很好的办法去实现

2. 任何你所在的平台，都可以添加到此

---

### Overview (`doc/README.md`)

# 文档说明

E2E (End-to-End) 开发文档:

- 开发环境准备，如何编译和测试，请参考 [01-开发与构建.md](./01-开发与构建.md)
- 直接推送还是提交 PR，请参考 [02-提交与贡献.md](./02-提交与贡献.md)
- 代码风格，请参考 [03-为什么拒绝使用代码格式化工具.md](./03-为什么拒绝使用代码格式化工具.md)

<br>

具体 recipe 相关:

- 如何编写一个具体的 recipe，请参考 [10-如何编写recipe.md](./10-如何编写recipe.md)
- 如何修改换源链接、模糊/精准测速链接，请参考 [11-如何设置换源链接与测速链接.md](./11-如何设置换源链接与测速链接.md)

<br>

- 关于维护者身份的说明，请参考 [50-协作者与维护者.md](./50-协作者与维护者.md)

<br>

用户手册：

1. [chsrc.1](./chsrc.1)
2. [chsrc.texi](./chsrc.texi)

<br>

## 贡献指导

若有任何问题，可在 [GitHub discussions](https://github.com/RubyMetric/chsrc/discussions) 中询问和讨论

<br>

---

### Overview (`pkg/README.md`)

# Packages

## 分发情况

- [x] `Homebrew`
- [x] `Scoop`
- [x] `WinGet`
- [x] `AUR`
- [ ] `Flatpak`
- [ ] `snap`
- [ ] ...

<br>

```bash
$ brew install chsrc

$ scoop install chsrc

$ winget install RubyMetric.chsrc

yay -S chsrc-bin # Binary from GitHub Release
yay -S chsrc     # Build  from GitHub Release
yay -S chsrc-git # Build  from the latest main branch (stable)
```

<br>

- Homebrew

  https://github.com/Homebrew/homebrew-core/blob/master/Formula/c/chsrc.rb

- Scoop

  https://github.com/ScoopInstaller/Main/blob/master/bucket/chsrc.json

- WinGet

  https://github.com/microsoft/winget-pkgs/tree/master/manifests/r/RubyMetric/chsrc

- AUR:

  - https://aur.archlinux.org/packages/chsrc-bin

  - https://aur.archlinux.org/packages/chsrc

  - https://aur.archlinux.org/packages/chsrc-git

<br>


## 打包情况

- [x] `deb`

<br>

---

### Overview (`tool/README.md`)

# 工具说明

1. `installer.sh`

    Bash 编写的一键安装工具

2. `installer.ps1`

    PowerShell 编写的一键安装工具

3. `download-pre-on-GitHub.ps1`

    从 GitHub `pre` release 上下载所有附件

4. `completion/` 目录

    Shell 自动补全文件

<br>

## `rawstr4c`

C语言字符串生成工具，本身是为了本项目而开发，是放在本仓库下的一个完整子项目。但为了维护更方便，拆分到新的仓库: <https://github.com/RubyMetric/rawstr4c>

---

### Overview (`pkg/AUR/README.md`)

# AUR package

本文档说明了 `chsrc` 项目的 AUR 包的相关情况

<br>

## 相关文件

CI 维护者 [@Jerry-Terrasse](https://github.com/Jerry-Terrasse)

- [.github/workflows/pub-AUR-chsrc-git.yml](../../.github/workflows/pub-AUR-chsrc-git.yml)
- [.github/workflows/pub-AUR-chsrc-and-chsrc-bin.yml`](../../.github/workflows/pub-AUR-chsrc-git.yml)

<br>

## 分发

位于 https://aur.archlinux.org/packages

- [chsrc-bin](https://aur.archlinux.org/packages/chsrc-bin): 从 GitHub Releases 直接下载的二进制文件

- [chsrc](https://aur.archlinux.org/packages/chsrc)：从 GitHub Releases 的代码构建

- [chsrc-git](https://aur.archlinux.org/packages/chsrc-git)：从最新源码构建的版本，偶尔可能不稳定

---

### Overview (`pkg/deb/README.md`)

# deb package

本文档说明了 `chsrc` 项目的 deb 包的相关情况

<br>

## 相关文件

- `.github/workflows/pkg-deb.yml` - CI 配置文件
- `./CI.md` - CI 情况说明

<wbr>

- `./debian/` - deb 包构建配置目录
- `./BUILD.md` - 如何手动构建
- `./Makefile` - deb 包构建 Makefile
- `./deb-installation-test.sh` - deb 包 **已正确安装** 测试脚本

<br>


## 安装

如果你是普通用户，你应该从 [GitHub Releases](https://github.com/RubyMetric/chsrc/releases) 下载合适的 deb 包，然后运行以下命令安装：

```bash
sudo dpkg -i chsrc_*.deb
sudo apt-get install -f  # Fix any dependency issues
```

如果你是高级用户，你可以自己阅读本目录下的 [./BUILD.md](./BUILD.md) 来自己构建 deb 包并按照上述同样的方式安装。

<br>


## `debian/` 目录结构

```
debian/
├── changelog      # 版本更新日志
├── compat         # debhelper 兼容性版本
├── control        # 包控制信息和依赖
├── copyright      # 版权信息
├── postinst       # 安装后脚本
├── prerm          # 卸载前脚本
└── rules          # 构建规则
```

其中，最后三个是 `+x` 的可执行文件。

<br>

---

### Overview (`src/recipe/lang/Ruby/README.md`)

# Ruby 换源问题

<https://github.com/ustclug/discussions/issues/438>


- Ruby China: 于2026年7月21日暂停服务 (<https://ruby-china.org/topics/44619>)

- 清华、北京外国语: 不可用，原因是: 实现不足 https://github.com/tuna/issues/issues/374

- 腾讯: 不可用，原因是:  缺乏 `versions` 文件
- 阿里: 不可用，原因是:  缺乏 `versions` 文件

- 华为: 不可用，原因是：版本太过老旧，应该是没有同步

---

### Overview (`src/recipe/ware/Docker/README.md`)

# Docker

- USTC 与 SJTUG 于 2024-06-06 停止支持 DockerHub
- NJU 于 2024-06-07 停止支持 DockerHub

---

### Overview (`src/recipe/lang/Python/uv/README.md`)

# uv 换源实现说明

`chsrc set uv` 同时配置两类下载地址：

1. Python 包索引，即 `uv.toml` 的 `[[index]]` 或 `pyproject.toml` 的 `[[tool.uv.index]]`
2. uv 管理的 CPython 下载地址，即 `python-install-mirror`

<br>

## 配置文件选择

项目作用域只修改当前目录，不向父目录查找并修改配置：

1. 当前目录存在 `uv.toml` 时修改 `uv.toml`
2. 否则，当前目录存在 `pyproject.toml` 时修改其中的 `[tool.uv]`
3. 两者都不存在时创建 `uv.toml`

这个顺序与 uv 的行为一致：同一目录同时存在 `uv.toml` 与 `pyproject.toml` 的 `[tool.uv]` 时，uv 优先使用 `uv.toml` 中的对应字段。

用户作用域使用 uv 的用户配置目录：Windows 为 `%APPDATA%\uv\uv.toml`，Linux 和 macOS 优先使用 `$XDG_CONFIG_HOME/uv/uv.toml`，未设置时使用 `~/.config/uv/uv.toml`。

<br>

## Python 包索引

索引 URL 必须指向兼容 Python Simple Repository API 的地址，通常以 `/simple` 结尾；uv 不要求 URL 必须以 `/` 结尾。

`default = true` 表示该 index 替代 uv 内置的 PyPI，并且始终具有最低 index 优先级。它不表示“文本中的第一个”或“最高优先级”。配置中存在多个 index 时，chsrc 优先更新 `default = true` 的 index；没有 default index 时才更新第一个 index。

默认的 `first-index` 策略会在第一个包含目标包的 index 停止搜索。私有源与公共镜像并存时，不应把它理解成跨所有 index 选择全局最新版本。

<br>

## Python 下载镜像

`python-install-mirror` 是 `https://github.com/astral-sh/python-build-standalone/releases/download` 的替换前缀。配置值必须是镜像侧对应的 `releases/download` 基址，不能是仓库主页、某个具体构建日期或某个归档文件。uv 会在其后追加构建日期和
归档文件名。

官方示例使用不带尾部 `/` 的基址，chsrc 内置源也遵循该形式。

<br>

## reset 与备份

`chsrc set uv` 修改已有配置前会创建 `.bak` 备份。

`chsrc reset uv` 把 chsrc 管理的 index 与 `python-install-mirror` 写回默认上游：index 恢复为 `https://pypi.org/simple`，
`python-install-mirror` 恢复为 `https://github.com/astral-sh/python-build-standalone/releases/download`。
其他用户配置原样保留，不依赖 `.bak` 恢复旧 URL。

指定镜像代码时，若该代码同时提供 PyPI 与 Python 下载镜像（例如 `nju`），两部分使用同一镜像代码；仅提供其中一类时，另一类自动测速。用户自定义 URL 只解释为 PyPI index URL，因为 Python 下载镜像要求完全不同的 releases 目录布局。

`default = true` 的 index（不存在时取第一个）被视为 PyPI 替代源，reset 只修改这一处；私有 index 不受影响。

<br>

## 实现边界

配置改写器只解析 chsrc 使用的 TOML 子集，但支持常见的行首缩进、CRLF、行尾注释、多个 index，以及位于 `[tool.uv.sources]` 等子表之后的 `[[tool.uv.index]]`。读取时换行统一为 LF 处理，写入时按系统平台输出行尾（Windows 为 CRLF，其余为 LF）。多行字符串和完整 TOML 转义语义不属于该轻量改写器的支持范围。

参考：

- [uv index 设置](https://docs.astral.sh/uv/reference/settings/#index)
- [uv python-install-mirror 设置](https://docs.astral.sh/uv/reference/settings/#python-install-mirror)
- [uv 配置文件](https://docs.astral.sh/uv/concepts/configuration-files/)
- [uv package indexes](https://docs.astral.sh/uv/concepts/indexes/)

<br>

---

### Doc 01 开发与构建 (`doc/01-开发与构建.md`)

# 开发 chsrc

## 依赖与开发环境

请安装好：

  1. `GCC` 或 `Clang`
  2. [just] 或 `make`
  3. `curl`
  4. [rawstr4c] (可选)

**我推荐你使用 VS Code 开发，你可以在一分钟内成功编译、运行和 Debug `chsrc`**

  1. `Ctrl-Shift-B` 直接构建
  2. `F5` 直接开始 Debug

<br>



## 获取代码

**请务必使用 dev 分支开发**

```bash
git clone https://gitee.com/RubyMetric/chsrc.git -b dev
```

关于分支的说明，可参考 [./03-CONTRIBUTING.md](./03-CONTRIBUTING.md)

<br>



## 编译运行

共有四种构建模式：

1. **`DEV mode`**
2. **`DEBUG mode`**
3. **`RELEASE mode`**
4. **`CI-RELEASE mode`**

开发时只需要前两种模式；第四种模式只在 GitHub Actions 使用。

**如果你使用 `just`，可以在 VS Code 中获得更好的体验，按 `Ctrl-Shift-B` 直接使用 DEV mode 构建**

**注意: `DEBUG` 模式下, 执行任意一个 `recipe` 的任意操作，会额外检查所有 `_prepare()` 是否能正常工作，如: `./chsrc-debug ls <recipe>`**

```bash
just (b)      # 在Windows上默认使用 gcc 编译，在macOS上默认使用 clang 编译，在其他系统上默认使用 cc 编译
just CC=clang # 使用 clang 编译
just CC=gcc   # 使用 gcc   编译

# 编译出 debug 版本: chsrc-debug
just bd
# 编译出 release 版本: chsrc-release
just br
```

<br>

`make` 用户:

```bash
make (b)      # 在Windows上默认使用 cc 编译，在macOS上默认使用 clang 编译，在其他系统上默认使用 cc 编译
make CC=clang # 使用 clang 编译
make CC=gcc   # 使用 gcc   编译

# 编译出 debug 版本: chsrc-debug
make bd
# 编译出 release 版本: chsrc-release
make br
```

<br>



## Debug

**如果你使用 `just`，可以在 VS Code 中获得更好的体验，按 F5 即可立即开始 Debug**

```bash
# 重新编译出 ./chsrc-debug，并启动 GDB 调试 (在macOS上启动 LLDB 调试)
$ just debug

# 重新编译出 ./chsrc-debug，并启动 LLDB 调试
$ just DEBUGGER=lldb debug
```

<br>

`make` 用户:

```bash
# 重新编译出 ./chsrc-debug，并启动 GDB 调试 (在macOS上启动 LLDB 调试)
$ make debug

# 重新编译出 ./chsrc-debug，并启动 LLDB 调试
$ make debug DEBUGGER=lldb
```

<br>



## 测试

`just` 用户只需要替换下述 `make` 为 `just`

```bash
make test-xy  # 测试 xy.h
make test-fw  # 测试 framework
make test     # 测试上述两个
make test-cli # 测试命令
make clean
```

<br>



## 提交 PR

关于分支的说明以及如何提交代码，请参考 [./03-CONTRIBUTING.md](./03-CONTRIBUTING.md)

<br>



[rawstr4c]: https://github.com/RubyMetric/rawstr4c
[just]: https://github.com/casey/just

---

### Doc 02 提交与贡献 (`doc/02-提交与贡献.md`)

# 贡献说明

## 分支

- `gh-build`：仅仅在发布版本时由 `@ccmywish` 推送，触发编译到 GitHub Releases 中
- `main`: stable，代码一定是可以编译运行的，我们假设 end users 在其他条件都得不到二进制时，会自己编译这个分支来运行 `chsrc`
- `dev`：开发分支，工作分支，在此分支上解决冲突

<br>



## 提交与审阅

当你提交 PR 的时候，一定要将 PR 指定 chsrc 原仓库的 `dev` 分支。

提交的代码分两种情况考虑。（1）recipe 相关的 （2）framework 相关的

（1）

 需要先搜索你修改的部分涉及到的 recipe，然后提 issue @ 所有相关的 recipe chefs 来 review

---

（2）

如果涉及了所有 recipe，则需要 @ 项目创建者或者协作者，而无需把所有 recipe 的 chefs 都喊过来，但是如果觉得有必要，可以 @ 任意你觉得有能力 review 和能给出建议的人来 review

<br>

---

### Doc 03 为什么拒绝使用代码格式化工具 (`doc/03-为什么拒绝使用代码格式化工具.md`)

# chsrc 代码风格

Ruby 的语法优美性在编程行业中具有标杆地位。Matz（松本行弘）提出的 **代码应该为人类而写，偶尔为机器执行** 这一理念，已经成为现代编程语言设计的重要指导原则。`chsrc` 项目的第一作者深受 **Ruby** 语言哲学的影响。

本项目起源于 AI 编程尚未流行的时代，所有代码全部依赖人类的耐心来维护。现在，我们的代码以及这篇文章不仅会由人类阅读，也会由 AI 阅读。我们始终坚持：**代码的可读性和维护性是项目长期发展的根本保障**。

<br>



## 为什么我们坚持不使用代码格式化工具

代码格式化工具（code formatter）在多人协作的代码仓库中确实有其价值，**参与的人越多，统一格式的需求越迫切**。然而，`chsrc` 项目经过深思熟虑后，拒绝使用代码格式化工具。让我来说明这一决定背后的深层原因。

### 被强迫使用

像 `Prettier` 这样的工具表面上带来了统一性，但其代价是什么？**它是极度专制的（opiniated）**，我们必须**完全交出代码审美的自主权**。今天我们大部分人使用 `Prettier`，**并非出于真心的认同，而是因为整个前端生态圈的集体胁迫——不用就意味着被边缘化**。

这种现象的本质令人深思：**少数 `Prettier` 维护者的个人偏好，竟然决定了全球数百万开发者的代码美学标准。这显然是一种技术独裁，坚决拒绝向格式化工具的霸权低头**。

<br>

### 一致性 ≠ 美观 ≠ 可读

格式化工具只保证了表面的一致性，就像一些校服，一致不一定代表美。同样，一致不一定代表代码就是最易读易懂的。

每一个有追求的程序员都应该保留**对代码美学的最后决定权，格式化工具的便利性不应该以牺牲美观性和可维护性为代价**。

<br>

### 满足不了我们的需求

C语言的格式化工具通常选择 `clang-format`，它的配置选项十分丰富，比 `Prettier` 要理性得多。然而，即便如此，**其配置的复杂性和局限性仍然无法满足 chsrc 对代码格式的严苛要求**。如果你是一位 `clang-format` 的配置专家，我们诚挚邀请您告诉我们如何优雅地处理以下代码场景，**也许这能改变我的立场**。

<br>



### 挑战案例

以下是我认为自动格式化工具很难完美处理的代码场景：

`=` 对齐：

```c
char *name  = va_arg (args, char*);
char *email = va_arg (args, char*);
```

复杂逻辑的 `=` 对齐：

```c
         bool matched = iterate_menu (chsrc_pl_menu, input, &dish_tmp);
if (!matched) matched = iterate_menu (chsrc_os_menu, input, &dish_tmp);
if (!matched) matched = iterate_menu (chsrc_wr_menu, input, &dish_tmp);
```

预处理指令的层次缩进：

```c
#ifdef _WIN32
  #define XY_Build_On_Windows 1
  #define xy_on_windows true
  #ifdef XY_DEBUG
    #define xy_debug_mode 1
  #endif
#endif
```

...... 等等

<br>



## C语言代码风格

- 整体上基于 `GNU style`，但我们坚持自己的美学原则，在细节上有所改进

- 类型名: `PascalCase_t`，即 `UpperCamelCase_t`

- 函数定义和调用时，**函数名和`()`之间始终保持一个空格**，如果是在宏中，可紧凑一些，无硬性规定

- 函数和函数定义之间**一般保持2个空行**

    - 若函数之间有高度关联性，**可用1个空行**
    - 若一系列函数和一系列函数存在主题性区别，**可用3个空行**

<br>



## Markdown 写作风格

维护者很多时候不是从渲染好的界面来看 Markdown 文件的，而是阅读 Markdown 源文件，所以 Markdown 在源文件层面也要易读。

我们保持每个主题之间 **1个`<br>` + 3个空行** 的简单风格。

拒绝使用 VS Code 的 `markdownlint` 插件，**因为它总是用它狭隘的标准给我们增加了巨多的黄色下划线**。

<br>



## 其他语言代码风格

我们秉承 **入乡随俗、尊重传统** 的原则，尊重每种语言社区的既定传统。比如，`YAML` 使用2个空格，`JSON`使用4个空格，`Perl` 使用 Larry Wall 钟爱的4个空格。

我们使用 `.editorconfig` 来确保这些格式的应用。

<br>

---

### Doc 10 如何编写Recipe (`doc/10-如何编写recipe.md`)

# Write A Recipe Even If You Don't Know C

## 介绍

**`chsrc` 不仅是一个命令行工具，同时也是一个体现了 Ruby on Rails 思想的 MVC 换源框架，它甚至使你能够在不了解C语言的情况下编写出新的换源方法(recipe)。**

<br>

我鼓励你为新的软件添加换源支持，因为通过 `chsrc` 框架，这将比写 shell 脚本更加轻松，你的贡献也将非常有价值。理论上每一个 `recipe` 都需要有专人长时间维护 ([招募](https://github.com/RubyMetric/chsrc/issues/275))。

- 本项目采用 `GPLv3+` 协议，是真正的**自由软件**，而非仅仅是开源软件
- 代码规范灵活遵循 `GNU` 标准（若标准干扰了可维护性，则并不采纳）
- 高度模块化，目录结构清晰易懂
- 极小依赖，极易构建，只需要 `GCC` 或 `Clang` 即可编译 (`make` 和 `just`可简化编译，但不是必需的)
- 易于将 `shell` 脚本转换为等价的 `recipe`
- 已有大量 `recipe` 可提供参考，并提供了 [recipe template] 供直接使用
- 本仓库外的子项目 [rawstr4c] 帮助你在C语言中维护复杂的字符串
- [chsrc-bootstrap] 帮助你在没有预编译 `chsrc` 的平台上 bootstrap 自己

<br>

成功案例:

- [Armbian](../src/recipe/os/APT/Armbian.c)
- [uv](../src/recipe/lang/Python/uv.c)

<br>

## 基本概念

- `dish`: 所要换源的菜品
- `combo dish`: 一个 `dish` 包含了多个子 `dish`，比如 `Python` 包含了该语言的多个包管理器

- `category`: 是 `dish category` 的简写，即 `dish` 所属的类别，可以是 **编程语言**，**操作系统**，**软件** 三类之一

    1. 在目录中，三者分别为 `lang`, `os`, `ware`
    2. 在代码中，三者前缀分别为 `pl`, `os`, `wr`

- `mirror`: 是 `mirror site` 的简写，指镜像站，如清华大学开源软件镜像站
- `source`: 该 `dish` 所能换的具体的源，由 `mirror` 提供服务，往往一个 `mirror` 会提供许多 `source`
- `recipe`: 是为一个 `dish` 定义的具体换源方法，请参考 `src` 目录中的 `recipe` 目录

- `chef DSL`：是 `chef Domain Specific Language` 的简写，这是一组以 `chef_` 开头的函数，用来定义维护者信息、可用源等元信息

- **换源链接**: 指镜像站所提供的某一个具体的换源使用的URL
- **测速链接**: 用来测速的URL，与 "换源链接" 不同，可分为 **精准测速** 和 **模糊测速**

    1. 在代码中，测速链接一般使用 `smURL` (即 `speed measure URL`) 或 `speed_measure_url` 来指代
    2. 在代码中，换源链接一般使用 `repoURL` (即 `repository URL`) 或直接用 `url` 来指代

        - 为什么不用 `regurl`，因为使用术语 `repository` 的 dish 远多于使用术语 `registry` 的。
        - 为什么莫名其妙使用了大小写混合的API? 因为 `smurl` 和 `repourl` 的可读性太差

- **镜像源**: 为了方便，**偶尔**我们将直接称`mirror`和/或`source`为**镜像源**，这只是一种方便性的称呼，可以统称二者，也可以根据上下文指代二者之一

<br>

## 编写 `recipe` 步骤

1. 确定你要编写的 `dish` 的标准名称，创建 `Dish-Name.c` 文件

    大小写需严格按官方，若名称包含空格，需使用 `-` 代替空格

2. 根据类别将上述文件放在 `recipe/` 目录的某个子目录中

3. 复制 [recipe template] 的内容到上述文件中，并替换 `<...>` 占位符

4. 参考现有 `recipe` 的写法

    1. 看一眼就能上手的参照物是 [PHP recipe](../src/recipe/lang/PHP.c)
    2. 最好的参照物是 [Ruby recipe](../src/recipe/lang/Ruby/Ruby.c)
    3. 组换源参照物是 [JS combo recipe](../src/recipe/lang/JavaScript/JavaScript.c)

5. 在 [Wiki] 中记录的镜像站中寻找可用源；可以额外补充镜像站

6. 使用 chef DSL 定义 `_prepare()` 函数

    该函数将填充 `dish` 所有的必要信息，包括维护信息、换源信息

7. [设置/修改 "换源链接" 和 "测速链接" (how?)](./11-如何设置换源链接与测速链接.md)

8. 按需实现 `_setsrc()` `_getsrc()` `_resetsrc()`， 可以使用这些函数:

    1. `framework/*.c` 中以 `chsrc_`, `chef_`, `hp_` 开头的所有函数或宏
    2. `xy.h` 中以 `xy_` 开头的所有函数或宏

    一个简单的方法是，在 VS Code 中按快捷键 `Ctrl-T` 搜索上述三种前缀

9. 在 `recipe/menu.c` 中登记此 `dish`

10. [编译、运行、测试 (how?)](./01-开发与构建.md)，若无问题可提交 Pull Request

<br>

## 开发准则

1. 代码高度可移植

2. Convention over Configuration

3. [NO UFO 原则: 不要乱丢文件到$HOME等目录，尤其是使用各种隐晦的文件名](https://www.yuque.com/ccmywish/blog/no-ufo)

    `chsrc` 主程序不提供配置文件，不提供数据文件，干净无污染。那么在实现 `recipe` 的时候，除了备份文件外，也不要污染用户环境。

## 其它

如果你借助 AI 进行开发，让 AI 阅读 [copilot-instructions.md](../.github/copilot-instructions.md) 并将它作为项目规范，该文件明确了很多在 AI 辅助开发时需要注意的问题。

<br>

[rawstr4c]: https://github.com/RubyMetric/rawstr4c
[chsrc-bootstrap]: ../bootstrap/
[recipe template]: ../src/recipe/recipe-template.c
[Wiki]: https://github.com/RubyMetric/chsrc/wiki

---

### Doc 11 如何设置换源链接与测速链接 (`doc/11-如何设置换源链接与测速链接.md`)

# 新增/修改 "换源链接"

在 `_prepare()` 函数中，在 `def_sources_begin()` 的位置的**第二列**，新增/修改你想要替换的链接。

**注: 以下代码仅起解释作用，JavaScript换源的真正实现可能不同**

```c
def_sources_begin()
{&UpstreamProvider, "https://registry.npmjs.org/",                     FeedByPrepare},
{&NpmMirror,        "https://registry.npmmirror.com",                  FeedByPrepare},
{&Huawei,           "https://mirrors.huaweicloud.com/repository/npm/", FeedByPrepare},
{&Tencent,          "https://mirrors.cloud.tencent.com/npm/",          FeedByPrepare},
{&某新镜像站,       "某镜像站提供的换源链接"，                         FeedByPrepare}
def_sources_end()

//

// 调整上述某一个镜像站的所提供源的 "换源链接"
chef_set_repoURL (this, &UpstreamProvider, "新的换源链接");
```

<br>


# 设置/修改 "测速链接"

在 `_prepare()` 函数中，在 `def_sources_begin()` 的位置的**第三列**，设置/修改你想要替换的链接。

1. 在下面代码的第一行中，我们直接给了一个链接，**这就是精准测速链接**
2. 在下面代码的第二行和第三行中，我们都设置了一个宏 `DelegateToMirror`，这意味着我们没有直接提供精准测速链接，而是让 `chsrc` 去测试其对应镜像站定义的测速链接

    - `NpmMirror` 是专用镜像站，所以其测速链接被设置为了 `ACCURATE`，即精准测速
    - `Huawei` 是通用镜像站，所以其测速链接被设置为了 `ROUGH `，即模糊测速

3. 在下面代码的第四行中，我们设置了一个宏 `FeedByPrepare`，这意味着我们将在 `_prepare()` 函数的后续动态计算 URL

**注: 以下代码仅起解释作用，JavaScript换源的真正实现可能不同**

```c
def_sources_begin()
{&UpstreamProvider, "https://registry.npmjs.org/",                     "https://registry.npmjs.org/BigFile.tar.gz"},
{&NpmMirror,        "https://registry.npmmirror.com",                  DelegateToMirror},
{&Huawei,           "https://mirrors.huaweicloud.com/repository/npm/", DelegateToMirror},
{&Tencent,          "https://mirrors.cloud.tencent.com/npm/",          FeedByPrepare},
def_sources_end()

//

// 调整/设置上述某一个镜像站的所提供源的 "精准测速链接"
chef_set_smURL (this, &UpstreamProvider, "新的测速链接");
// 设置上述某一个镜像站的所提供源的 "精准测速链接" 设置为 "换源链接" + postfix
chef_set_smURL_with_postfix (this, &UpstreamProvider, "/dir/BigFile.tar.gz");
// 基于 "换源链接" 做更自定义的操作
chef_set_smURL_with_func (this, &UpstreamProvider, func, data);

// 把所有上述源中还未设置 "精准测速链接" 的源进行设置
chef_set_rest_smURL_with_postfix (this, "/dir/BigFile.tar.gz");
chef_set_rest_smURL_with_func (this, func, data);

// 调整某一个镜像站(Provider)的 "测速链接"
chef_set_provider_smURL (&Tencent, "https://mirrors.cloud.tencent.com/npm/BigFile.tar.gz");
// 调整某一个镜像站(Provider)的 "测速精度"
chef_set_provider_sm_accuracy (&UpstreamProvider, ROUGH);
```

---

### Doc 50 协作者与维护者 (`doc/50-协作者与维护者.md`)

## 协作者与维护者

想要达到最理想的维护状态，每一个 recipe 都需要有专人长时间维护。**我们的代码里使用了 recipe (某个菜的烹饪方法) 这个词，因而整个项目便和 "饮食" 有关，比如 `menu`: 汇集了所有的 dish 的菜单。因此，我们的维护者和贡献者身份依然使用了这个惯例：**

1. **Chef**

    主厨: 一个 recipe 的主要作者

2. **Saucier**

    调味：一个 recipe 的次要贡献者

<br>



## 第一次贡献者

### 注册身份信息

在 `src/chsrc-main.c` 的 `chsrc_register_contributors()` 函数里，在最后（我们按参与本项目的时间顺序排列）添加一行：

```c
chef_register_contributor ("@ID: 你的GitHub/Gitee用户名或任意不与其他贡献者冲突的名字",
  "你的真实姓名",
  "你的邮箱地址",
  "若 chsrc ls <recipe> 的时候不想使用真实姓名，可以用这个参数的字符串来代替");
```


### 更新 Recipe 信息

在你修改的 recipe 文件的 `_prepare()` 函数里，需要做以下更新：

1. **更新 recipe 修改时间**（每次修改 recipe 代码都要更新）：
   ```c
   chef_set_recipe_last_updated (this, "YYYY-MM-DD");
   ```

2. **更新镜像源信息时间**（仅当你修改了镜像源列表时才更新）：
   ```c
   chef_set_sources_last_updated (this, "YYYY-MM-DD");
   ```

3. **将自己加入 `sauciers`**（次要贡献者列表，将计数加一并添加自己的 `@ID`）：
   ```c
   // 原来是 0 个 saucier：
   chef_set_sauciers (this, 0);
   // 改为添加你自己：
   chef_set_sauciers (this, 1, "@你刚注册的ID");

   // 原来已有 1 个 saucier：
   chef_set_sauciers (this, 1, "@Someone");
   // 改为添加你自己：
   chef_set_sauciers (this, 2, "@Someone", "@你刚注册的ID");
   ```

4. **验证上述信息正确**

   ```sh
   # 应当能看到你的信息
   ./chsrc ls <recipe>
   ```

<br>

---

--- METRICS ---
- Files Extracted: 17
- Estimated Token Budget: ~7922 tokens
- Canonical Reference: https://codewiki.google/github.com/RubyMetric/chsrc
