Skip to content
Draft
Changes from all commits
Commits
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
122 changes: 96 additions & 26 deletions src/recipe/os/pacman/Omarchy.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,38 @@

#define OS_Pacman_Omarchy_Conf "/etc/pacman.conf"

#define OS_Omarchy_Upstream "https://pkgs.omarchy.org"
#define OS_Omarchy_CN "https://pkgs.omarchy.cn"

/* 仅取 [omarchy] 段内容,供通道检测与写后校验复用 */
#define OS_Omarchy_Section_Cmd \
"awk '/^\\[omarchy\\]/{f=1;next} /^\\[/{f=0} f' " OS_Pacman_Omarchy_Conf

/* 仅重写 [omarchy] 段: 删除段内全部 Server 行后,再按 target / fallback 写入 */
#define OS_Omarchy_Awk_Rewrite \
"/^\\[omarchy\\]/{print; print \"Server = \" target; " \
"if (fallback != \"\") print \"Server = \" fallback; insec=1; next} " \
"/^\\[/{insec=0} " \
"insec && /^[[:space:]]*Server[[:space:]]*=/{next} " \
"{print}"

Comment on lines +10 to +21

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不要这么写,参考python的办法,用rawstr4c写,避免在c内写命令以避免转义符号与难以看懂的问题
https://github.com/RubyMetric/chsrc/blob/main/src/recipe/lang/Python/rawstr4c.md


/** ------------------------------------------------------------
* omarchy dish (换 OPR 专属仓库)
*
* Omarchy 的 Arch Linux 主仓库源与 arch 完全一致,请额外使用
* `chsrc set arch` 来更换;本 dish 只负责 [omarchy] 段 (OPR)。
* Omarchy 的 Arch 主仓库由 Omarchy 按通道管理:stable/rc 使用快照镜像
* (stable-mirror/rc-mirror.omarchy.org),edge 使用滚动镜像(mirror.omarchy.org)。
* 本 dish 只负责 [omarchy] 段 (OPR);OPR 的官方中国镜像由阿里云 CDN 提供。
* ------------------------------------------------------------*/

/* 测速链接固定用 stable 的 omarchy.db:同通道 cn/org 内容一致,三通道体积相当(约 55-61 KB),不代表当前通道 */
static MirrorSite_t OmarchyCN =
{
IS_DedicatedMirrorSite,
"omarchycn", "Omarchy Ali", "Omarchy 阿里云镜像源", "https://pkgs.omarchy.cn/",
{NotSkip, NA, NA, "https://pkgs.omarchy.cn/stable/x86_64/omarchy.db", ACCURATE}
};

def_dish(os_omarchy, "omarchy");

void
Expand All @@ -20,7 +44,7 @@ os_omarchy_prepare ()
chef_prep_this_dish (os_omarchy, gsr);

chef_set_recipe_created_on (this, "2026-09-04");
chef_set_recipe_last_updated (this, "2026-09-06");
chef_set_recipe_last_updated (this, "2026-11-04");

chef_set_chefs (this, 1, "@yayoinoyume");
chef_set_sauciers (this, 0);
Expand All @@ -30,15 +54,14 @@ os_omarchy_prepare ()
chef_allow_user_define(this);

chef_set_note (this,
"Omarchy 是基于 Arch Linux 开发的发行版,除官方专属软件包仓库 (OPR) 外,其余换源与 Arch 保持一致。"
"本菜品仅更换 OPR 源;Arch Linux 主仓库请另行 chsrc set arch,恢复官方 OPR 源请 chsrc reset omarchy。"
"注意: omarchy-refresh-pacman 更新脚本会覆盖此配置,换源后若被还原,请重新执行",
"Omarchy is an Arch Linux-based distro; apart from its official package repository (OPR), source switching is the same as Arch. "
"This dish only switches the OPR source; use chsrc set arch for the Arch Linux main source, and chsrc reset omarchy to restore the official OPR source. "
"Note: omarchy-refresh-pacman may overwrite this configuration; rerun if it reverts");
"仅更换 OPR 源;Arch 主仓库请勿使用 chsrc set arch。"
"Omarchy 4.5+ 中国区 Arch 镜像:将 /etc/omarchy/region 写为 cn,再运行 omarchy-refresh-pacman;它会覆盖本菜品设置,之后重跑 chsrc set omarchy omarchycn 即可。",
"Only switches the OPR source; do not use chsrc set arch for the Arch main repositories. "
"For China on Omarchy 4.5+, write cn to /etc/omarchy/region and run omarchy-refresh-pacman; it overwrites this dish's setting, so rerun chsrc set omarchy omarchycn afterward.");

def_sources_begin()
{&UpstreamProvider, "https://pkgs.omarchy.org/stable/$arch", DelegateToUpstream}
{&UpstreamProvider, OS_Omarchy_Upstream, DelegateToUpstream},
{&OmarchyCN, OS_Omarchy_CN, DelegateToMirror}
def_sources_end()
}

Expand All @@ -52,7 +75,8 @@ os_omarchy_getsrc (char *option)

/**
* @consult
* 1. https://github.com/basecamp/omarchy 官方 pacman.conf 模板 (仅 x86_64)
* 1. https://github.com/omacom/omarchy 官方 pacman.conf 模板 (仅 x86_64)
* 2. https://pkgs.omarchy.cn/ OPR 官方中国镜像 (stable/rc/edge)
*/
void
os_omarchy_setsrc (char *option)
Expand All @@ -69,24 +93,70 @@ os_omarchy_setsrc (char *option)

chsrc_use_this_source (os_omarchy);

chsrc_backup (OS_Pacman_Omarchy_Conf);
if (xy_run_get_status ("grep -q '^\\[omarchy\\]' " OS_Pacman_Omarchy_Conf) != 0)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我个人仍然不是很建议在程序内大量调用grep,非常容易造成后面维护困难,尤其是各种正则、语法、转义,前面写的越简练(超长的“一句话”替换语句),后面的人维护起来越难

我会建议你参考 pl_rust_cargo_getsrc,但是考虑到此处grep确实比较简练易懂(但是命令行转义加c内部转义还是很恶心),此处我保留意见,仅作为建议。

{
chsrc_error ("未在 " OS_Pacman_Omarchy_Conf " 中找到 [omarchy] 段");
exit (Exit_Unsupported);
}

/* 上游默认源基于 stable 通道,edge 通道用户换源后将切换到 stable */
bool is_edge = xy_run_get_status ("grep -q '^Server = https://pkgs.omarchy.org/edge/' " OS_Pacman_Omarchy_Conf) == 0;
if (is_edge && !source_is_userdefine (&source))
chsrc_warn2 ("检测到当前使用 edge 通道,上游默认源基于 stable 通道,继续执行将切换到 stable");
chsrc_backup (OS_Pacman_Omarchy_Conf);

/* 幂等: 替换 [omarchy] 段的 Server 行为所选源;已是所选源则跳过 */
char *exists_cmd = xy_strcat (3, "grep -qxF 'Server = ", source.url, "' " OS_Pacman_Omarchy_Conf);
if (xy_run_get_status (exists_cmd) == 0)
/* 从 [omarchy] 段反推当前通道,只看未注释的 Server 行,缺省为 stable */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ccmywish 你的意见?我认为本段代码写得没问题,质量挺好,但是对后来的维护者来说可读性和可维护性都有点太差了……

char *server_lines = xy_2strcat (OS_Omarchy_Section_Cmd,
" | grep -E '^[[:space:]]*Server[[:space:]]*='");
char *channel = "stable";
if (xy_run_get_status (xy_2strcat (server_lines, " | grep -q '/edge/'")) == 0)
channel = "edge";
else if (xy_run_get_status (xy_2strcat (server_lines, " | grep -q '/rc/'")) == 0)
channel = "rc";

/* 内置源跟随当前通道;用户自定义源原样使用,不做通道替换 */
bool is_cn = xy_streql (source.mirror->code, OmarchyCN.code);
bool is_user = source_is_userdefine (&source);

/* 用户自定义 URL 会被嵌入 shell 单引号参数,awk -v 还会转义反斜杠 */
if (is_user && (strchr (source.url, '\'') || strchr (source.url, '\\')
|| strchr (source.url, '\n') || strchr (source.url, '\r')))
{
chsrc_debug ("recipe", "所选 Server 行已存在,跳过 pacman.conf 修改");
chsrc_error ("用户自定义 URL 不能包含单引号、反斜杠或换行");
exit (Exit_UserCause);
}

char *target = NULL;
if (is_user)
target = source.url;
else
target = xy_strcat (4, source.url, "/", channel, "/$arch");

/* 中国镜像后追加同通道上游兜底行,上游同步延迟时仍可安装 */
char *fallback = is_cn ? xy_strcat (4, OS_Omarchy_Upstream, "/", channel, "/$arch") : "";

/* 只重写 [omarchy] 段,不触碰 [core]、[archlinuxcn] 等其他段 */
char *tmp_conf = xy_2strcat (OS_Pacman_Omarchy_Conf, ".chsrc-tmp");
char *awk_cmd = xy_strcat (7, "awk -v target='", target, "' -v fallback='", fallback,
"' '", OS_Omarchy_Awk_Rewrite, "' " OS_Pacman_Omarchy_Conf);
char *write_cmd = xy_strcat (6, awk_cmd, " > ", tmp_conf, " && mv ", tmp_conf,
" " OS_Pacman_Omarchy_Conf);
chsrc_run (write_cmd, RunOpt_Default);

/* 写后校验: [omarchy] 段首行必须是目标 URL,中国镜像还需带同通道兜底行 */
if (!in_dry_run_mode())
{
char *sed_cmd = xy_strcat (4, "sed -i 's|^Server = https://pkgs.omarchy.org/.*|Server = ",
source.url, "|' ", OS_Pacman_Omarchy_Conf);
chsrc_run (sed_cmd, RunOpt_Default);
char *expected = xy_2strcat ("Server = ", target);
char *first = xy_run (xy_2strcat (OS_Omarchy_Section_Cmd, " | grep -m1 '^Server = '"), 1);
bool ok = first && xy_streql (first, expected);

if (ok && is_cn)
{
char *fallback_cmd = xy_strcat (4, OS_Omarchy_Section_Cmd, " | grep -qxF 'Server = ", fallback, "'");
ok = xy_run_get_status (fallback_cmd) == 0;
}

if (!ok)
{
chsrc_error ("[omarchy] 段写入校验失败,请从 " OS_Pacman_Omarchy_Conf ".bak.* 恢复");
exit (Exit_ExternalError);
}
}

/* 清理本地陈旧 omarchy.db 缓存: 残留旧 sig 会导致 -Syy 验签失败 */
Expand All @@ -98,14 +168,14 @@ os_omarchy_setsrc (char *option)
chsrc_conclude (&source);

chsrc_note2 (ENGLISH
? "This dish only switches the OPR source; use chsrc set arch for the Arch Linux main source."
: "本菜品仅更换 OPR 源;Arch Linux 主仓库请另行 chsrc set arch。");
? xy_strcat (3, "Kept the current ", channel, " channel; the Arch main repositories are untouched.")
: xy_strcat (3, "已保持当前 ", channel, " 通道,Arch 主仓库未改动。"));
}


void
os_omarchy_resetsrc (char *option)
{
/* reset 模式下 chsrc_use_this_source 返回官方源,即恢复官方 stable 通道 */
/* reset 模式下 chsrc_use_this_source 返回官方源,即恢复官方源的当前通道 */
os_omarchy_setsrc (option);
}
Loading