Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0557a9b
避免markdownlint扩展频繁警告Markdown格式问题
Mikachu2333 Oct 28, 2026
95ba4f4
显式后置链接Windows 导入库并排除 Android 交叉编译
Mikachu2333 Oct 28, 2026
98d1952
统一 XY_Build_On_Windows 与 xy.on_windows 的平台判定与用法
Mikachu2333 Oct 28, 2026
342c9d6
修复 chsrc_ensure_root 的 $EUID 与误判 root 缺陷并新增 chsrc_is_root
Mikachu2333 Oct 28, 2026
1300da6
修复文件写入族函数空串写入失败、句柄泄漏与双语提示
Mikachu2333 Oct 28, 2026
4069ad0
改进 chsrc_backup 与 chsrc_ensure_dir 的路径规范化及引号保护
Mikachu2333 Oct 28, 2026
03f2d23
修复 CLI -scope 缺参崩溃与 --version 选项解析缺陷
Mikachu2333 Oct 28, 2026
1139b88
补齐 reset 作用域能力校验并支持 ScopeCap_Able_But_Just_Docs 与英文提示
Mikachu2333 Oct 28, 2026
db3a296
新增 framework/env.c 实现 POSIX 环境变量精确读写与持久化查看
Mikachu2333 Oct 28, 2026
ab99ad6
实现 env.c 的 Windows 注册表后端、.reg 备份回滚与设置变更广播
Mikachu2333 Oct 28, 2026
0aebcff
迁移 rustup、Pub、Flutter、nvm、Homebrew 至 env 模块并移除旧逻辑
Mikachu2333 Oct 28, 2026
c7fdbdc
补充 env 模块单元测试、CLI 幂等回归测试与开发文档
Mikachu2333 Oct 28, 2026
9d1165a
使用#ifdef避免在win上未编译的函数导致报错
Mikachu2333 Oct 28, 2026
c140f05
增加env模块的常用函数注释
Mikachu2333 Oct 28, 2026
afc0437
更改环境变量检测行为为优先持久化配置,仅都存在时提示
Mikachu2333 Oct 28, 2026
bef9d10
固化env,避免临时环境变量影响测试
Mikachu2333 Oct 28, 2026
c1f8c20
使用chsrc_view_env替换chsrc_get_env消歧义
Mikachu2333 Oct 28, 2026
634bd96
临时文件改用宽字符 API 独占创建,删除走 DeleteFileW
Mikachu2333 Oct 28, 2026
bcdf7d7
环境变量注册表备份目录改为随机名独占创建,抽出通用 chsrc_make_tmpdir
Mikachu2333 Oct 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ just test / test-cli / fastcheck
## 架构速览

- `src/chsrc-main.c` — 入口:`main()`、CLI 解析、输出显示
- `src/framework/` — 核心骨架:`struct.h`(`Dish_t`/`Source_t`/`MirrorSite_t`/Chef DSL 宏定义)、`core.c`(全局状态、测速)、`chef.c`(Chef DSL 实现)、`helper.c`(`hp_*` 辅助函数)、`mirror.c`(通用镜像站)
- `src/framework/` — 核心骨架:`struct.h`(`Dish_t`/`Source_t`/`MirrorSite_t`/Chef DSL 宏定义)、`base.c`/`OS.c`/`source.c`/`waiter.c`(全局状态、系统与文件操作、测速与命令分派)、`env.c`(跨平台环境变量幂等持久化读写:`chsrc_set_env`/`chsrc_set_env_block`/`chsrc_get_env`)、`chef.c`(Chef DSL 实现)、`helper.c`(`hp_*` 辅助函数)、`mirror.c`(通用镜像站)
- `src/recipe/{lang,os,ware}/` — 按类别(`pl`/`os`/`wr`)组织的 recipe;新 recipe 须在 `src/recipe/menu.c` 中注册(`#include` + `add()`)才会出现在菜单中
- `lib/xy.h` — 独立 C11 工具库(MIT):字符串、系统检测、日志、数据结构、文件 I/O。约定 `return caller-free` 表示调用方必须释放返回值
- 执行流程:`main()` → `chsrc_init_framework()` → 解析 CLI → 在 `pl`/`os`/`wr` 菜单中匹配 dish → `preparefn()` → 按操作分派 `getfn`/`setfn`/`resetfn`
Expand Down
7 changes: 7 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"MD012": false,
"MD013": false,
"MD033": false,
"MD041": false,
"MD045": false
}
17 changes: 11 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# | @Mikachu2333
# |
# Created On : <2023-08-28>
# Last Modified : <2026-08-14>
# Last Modified : <2026-10-28>
#
# 请阅读 ./doc/01-开发与构建.md 来使用
# --------------------------------------------------------------
Expand Down Expand Up @@ -66,6 +66,11 @@ ifeq ($(On-Windows), 1)
# 非 MSYS2 环境 (独立 LLVM) 下回退到 x86_64
Windows-Clang-Arch = $(if $(MSYSTEM_CARCH),$(MSYSTEM_CARCH),x86_64)
CFLAGS_clang = -target $(Windows-Clang-Arch)-pc-windows-gnu

# 注意: Android 交叉编译同样在 Windows/MSYS2 下进行, 必须排除 Windows 导入库
ifneq ($(CROSS_BUILD_WINDOWS_FOR_ANDROID), 1)
LDLIBS_win = -ladvapi32 -lkernel32 -luser32 -lshell32
endif
endif

ifeq ($(CC), clang)
Expand Down Expand Up @@ -161,13 +166,13 @@ c: clean
#============ Target 定义开始 ================

# 编译开始结束时的提示信息
Starting-Echo-Info = echo Starting: Build in ${1} mode: \'$(CC)\' $(CFLAGS) -o ${2}
Starting-Echo-Info = echo Starting: Build in ${1} mode: \'$(CC)\' $(CFLAGS) $(LDLIBS_win) -o ${2}
Finished-Echo-Info = echo Finished: Build in ${1} mode

# 真正的编译命令
Build-Command = $(CC) src/chsrc-main.c $(CFLAGS) $(CFLAGS_warning) -o $(1)
Build-Command = $(CC) src/chsrc-main.c $(CFLAGS) $(CFLAGS_warning) $(LDLIBS_win) -o $(1)

Build-Command-For-Release = $(CC) src/chsrc-main.c ${Windows-Res-File} $(CFLAGS) $(CFLAGS_warning) -o $(1)
Build-Command-For-Release = $(CC) src/chsrc-main.c ${Windows-Res-File} $(CFLAGS) $(CFLAGS_warning) $(LDLIBS_win) -o $(1)



Expand Down Expand Up @@ -237,12 +242,12 @@ test-make-var:
# 这两个测试文件都用 DEBUG mode
test-xy: CFLAGS += $(CFLAGS_debug)
test-xy:
@$(CC) test/xy.c $(CFLAGS) -o xy
@$(CC) test/xy.c $(CFLAGS) $(LDLIBS_win) -o xy
@./xy

test-fw: CFLAGS += $(CFLAGS_debug)
test-fw:
@$(CC) test/fw.c $(CFLAGS) -o fw
@$(CC) test/fw.c $(CFLAGS) $(LDLIBS_win) -o fw
@./fw

check: test
Expand Down
8 changes: 7 additions & 1 deletion doc/10-如何编写recipe.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
! Contributors : @Mikachu2333
! |
! Created On : <2024-08-19>
! Last Modified : <2026-09-01>
! Last Modified : <2026-10-28>
! ---------------------------------------------------------- -->

# Write A Recipe Even If You Don't Know C
Expand Down Expand Up @@ -82,6 +82,7 @@
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)
4. 环境变量型换源参照物是单变量的 [Pub recipe](../src/recipe/lang/Dart/Pub.c) 与多变量的 [rustup recipe](../src/recipe/lang/Rust/rustup.c)

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

Expand All @@ -95,6 +96,11 @@

1. `framework/*.c` 中以 `chsrc_`, `chef_`, `hp_` 开头的所有函数或宏
2. `xy.h` 中以 `xy_` 开头的所有函数或宏
3. 若菜品通过**环境变量**持久化换源,请统一使用 `framework/env.c` 提供的跨平台幂等接口,**切勿**手工向 `.bashrc`/`.zshrc` 追加字符串或直接调用 Windows `setx`:
- `chsrc_set_env (name, value)`:写入或更新单个持久化环境变量(传入 `NULL` 表示删除该变量,常用于 `_resetsrc()`)
- `chsrc_set_env_block (name1, value1, ..., NULL)`:原子写入或删除多个环境变量(一次备份、一次落盘/广播、一次提示)
- `chsrc_get_env (var1, ..., NULL)`:读取并打印已持久化的环境变量值(持久化缺失时回退当前终端值;两者同时存在且不一致时会提示)
- 作用域声明上,若某作用域官方支持但 `chsrc` 仅输出手工配置指引,可标记为 `ScopeCap_Able_But_Just_Docs`

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

Expand Down
12 changes: 8 additions & 4 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# | @NewbieXvwu
# |
# Created On : <2025-06-18>
# Last Modified : <2026-07-25>
# Last Modified : <2026-10-28>
#
# 该文件主要用于在原生Windows上执行项目的基本任务,而不借助于
# GNU make 以及相应的 MSYS2、Cygwin 环境
Expand Down Expand Up @@ -81,10 +81,14 @@ CFLAGS_chk_static := if STATIC == '1' {

CFLAGS_optimization := "-O2"

LDLIBS_win := if os() == 'windows' {
'-ladvapi32 -lkernel32 -luser32 -lshell32'
} else { '' }

CFLAGS_dev_mode_prompt := CFLAGS_base
CFLAGS_debug_mode_prompt := CFLAGS_base + ' ' + CFLAGS_debug
CFLAGS_release_mode_prompt := CFLAGS_base + ' ' + CFLAGS_optimization + ' ' + CFLAGS_chk_static

CFLAGS_dev_mode_prompt := CFLAGS_base + ' ' + LDLIBS_win
CFLAGS_debug_mode_prompt := CFLAGS_base + ' ' + CFLAGS_debug + ' ' + LDLIBS_win
CFLAGS_release_mode_prompt := CFLAGS_base + ' ' + CFLAGS_optimization + ' ' + CFLAGS_chk_static + ' ' + LDLIBS_win

CFLAGS_dev_mode := CFLAGS_dev_mode_prompt + ' ' + CFLAGS_warn
CFLAGS_debug_mode := CFLAGS_debug_mode_prompt + ' ' + CFLAGS_warn
Expand Down
99 changes: 41 additions & 58 deletions lib/xy.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* | AnonTokio <anontokio@163.com>
* |
* Created On : <2023-08-28>
* Last Modified : <2026-08-13>
* Last Modified : <2026-10-28>
*
*
* xy: 襄阳、咸阳
Expand Down Expand Up @@ -108,6 +108,11 @@ xy =



/**
* 平台判定约定:
* 1. 编译期 `#ifdef XY_Build_On_Windows` 仅用于包裹 Win32 SDK 专有头文件、类型与 API 调用
* 2. 运行期 `if (xy.on_windows)` 用于纯 C 跨平台分支逻辑,二者真值严格一致
*/
#ifdef _WIN32
#define XY_Build_On_Windows 1

Expand Down Expand Up @@ -1393,50 +1398,32 @@ xy_dir_exist (const char *path)
{
char *allocated_dir = NULL;
const char *dir = path;
if (xy.on_windows)

if (xy_str_start_with (path, "~"))
{
if (xy_str_start_with (path, "~"))
{
allocated_dir = xy_2strcat (xy_os_home, path + 1);
dir = allocated_dir;
}
allocated_dir = xy_2strcat (xy_os_home, path + 1);
dir = allocated_dir;
}

if (xy.on_windows)
{
#ifdef XY_Build_On_Windows
// 也可以用 opendir() #include <dirent.h>
DWORD attr = GetFileAttributesA (dir);
bool result = false;

bool result = false;
if (attr == INVALID_FILE_ATTRIBUTES)
{
// Q: 我们应该报错吗?
result = false;
}
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
{
result = true;
}
else
{
result = false;
}
if (allocated_dir) free (allocated_dir);
return result;
#endif
#ifdef XY_Build_On_Windows
DWORD attr = GetFileAttributesA (dir);
if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
{
result = true;
}
else
#else
DIR *d = opendir (dir);
if (d)
{
char *tmp_cmd = xy_2strcat ("test -d ", dir);
int status = system (tmp_cmd);
free (tmp_cmd);
bool result = (0==status);
if (allocated_dir) free (allocated_dir);
return result;
closedir (d);
result = true;
}
#endif

return false;
if (allocated_dir) free (allocated_dir);
return result;
}

/**
Expand Down Expand Up @@ -1546,29 +1533,25 @@ xy_parent_dir (const char *path)
void
_xy_detect_os ()
{
#ifdef XY_Build_On_Windows
/**
* 首先判断是否为 Windows
*
* SystemDrive 为 C:
* Windows 原生编译目标 (_WIN32)
* 使运行期 xy.on_windows 与编译期 XY_Build_On_Windows 严格等价
*/
char *drive = getenv ("SystemDrive");
if (drive)
{
char path[256];
/**
* C:\Users 目录都可能不存在!
* https://github.com/RubyMetric/chsrc/issues/361
*/
snprintf (path, sizeof (path), "%s\\Windows", drive);
DIR *d = opendir (path);
if (d)
{
xy.on_windows = true;
xy.os_family = "windows";
closedir (d);
return;
}
}
xy.on_windows = true;
xy.os_family = "windows";
return;
#endif

#if defined(__CYGWIN__) || defined(__MSYS__)
/**
* Cygwin / MSYS2 POSIX 运行时未定义 _WIN32,无 Win32 SDK 头与注册表约定,
* 归入 Unix 分支处理
*/
xy.on_linux = true;
xy.os_family = "unix";
return;
#endif

/* 判断 Linux */
FILE *fp = fopen ("/proc/version", "r");
Expand Down
19 changes: 14 additions & 5 deletions src/chsrc-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "framework/version.h"
#include "framework/base.c"
#include "framework/OS.c"
#include "framework/env.c"
#include "framework/dish.c"
#include "framework/chef.c"
#include "framework/source.c"
Expand Down Expand Up @@ -160,16 +161,24 @@ main (int argc, char const *argv[])
: " -local is deprecated, please use -scope=project";
chsrc_warn (msg);
}
else if (xy_str_start_with (argv[i], "-scope"))
else if ( xy_streql (argv[i], "-scope")
|| xy_str_start_with (argv[i], "-scope="))
{
const char *scope = NULL;
if (xy_streql (argv[i], "-scope"))
{
scope = argv[i+1];
if (i + 1 > argc)
{
char *msg = ENGLISH ? "Option -scope requires an argument. Valid scopes are: default, project, user, system"
: "-scope 选项缺少参数。有效的换源作用域为: default, project, user, system";
chsrc_error (msg);
return Exit_Unknown;
}
scope = argv[++i];
cli_arg_Dish_pos++;
cli_arg_Mirror_pos++;
}
else if (xy_str_start_with (argv[i], "-scope="))
else
{
scope = argv[i] + 7;
}
Expand Down Expand Up @@ -224,8 +233,8 @@ main (int argc, char const *argv[])
command = "help"; /* 交到下方处理 */
}
else if ( xy_streql (argv[i], "-v")
|| xy_streql (command, "-version")
|| xy_streql (command, "--version"))
|| xy_streql (argv[i], "-version")
|| xy_streql (argv[i], "--version"))
{
command = "version"; /* 交到下方处理 */
}
Expand Down
Loading
Loading