Omarchy 迁移(Migrations)机制详解:一次性修复脚本的设计、创建与测试 Omarchy 迁移Migrations机制详解一次性修复脚本的设计、创建与测试【免费下载链接】omarchyBeautiful, Modern Opinionated Linux项目地址: https://gitcode.com/GitHub_Trending/om/omarchy本文基于 Omarchy 仓库内的开发者技能文档 agents/skills/migrations.md完整讲解 Omarchy 迁移系统的工作模型迁移脚本放在哪里、由谁以什么时机触发、完成状态如何按用户记录以及如何规范地创建、验证和重放一个迁移。读完后你将理解 Omarchy 如何在不依赖 pacman 自身状态机制的前提下安全地对存量安装执行一次性修复并能按仓库规范编写幂等的迁移脚本。1. 迁移模型解决 pacman 管不了的状态Omarchy 的迁移migration是面向存量安装的一次性修复脚本。它们的定位很明确当一次包更新需要修改 pacman 无法安全独自拥有的状态时就通过迁移来完成这类变更。迁移脚本统一存放在migrations/*.sh它们通过omarchy-migrate以当前 Omarchy 用户身份执行通常在omarchy update期间运行。一个迁移可以触及用户/会话级状态~/.config、~/.local、用户级 systemd、浏览器/编辑器偏好、DBus/会话状态必要时也可以执行机器级machine-wide修复。完成状态是按用户隔离的记录在~/.local/state/omarchy/migrations/migration filename即每个迁移执行成功后runner 会在当前用户的 state 目录中落下一个与迁移文件同名的标记文件marker。这意味着每个用户都有机会跑一遍每一个迁移——第二个用户登录后自己的标记目录中仍缺失标记迁移会对该用户重新执行迁移以用户身份运行特权操作需要脚本自己调用相应的 helper 或提权提示迁移必须幂等如果某个用户已经完成了机器级修复同一迁移在另一个用户身上运行时应当检测到现状并直接 no-op。这一点在 runner 源码中可以得到印证bin/omarchy-migrate 中STATE_DIR默认取$HOME/.local/state/omarchy/migrations见 bin/omarchy-migrate 第 32 行pending_migrations()通过检查标记文件是否存在来判定哪些迁移待执行第 47–56 行。2. 迁移何时运行2.1omarchy update期间正常路径omarchy update是常规更新路径先执行包更新然后依次运行omarchy-migrate omarchy-hook post-update在 bin/omarchy-update 中可以看到完整的时序第 47–49 行omarchy-update-system-pkgs omarchy-migrate omarchy-hook post-update源码注释特别说明迁移随此处安装的包一起分发且是针对这些包编写的因此后续步骤都必须等待系统包更新完成如果一个升级中途停止更新本身会随之终止而不是带着旧包继续执行迁移。omarchy-migrate在开始执行前会等待任何正在进行的 pacman 事务结束。从 bin/omarchy-migrate 的wait_for_pacman_transaction()第 68–81 行可以看到实现细节它通过检查/var/lib/pacman/db.lck是否存在判断 pacman 是否在事务中最多轮询 900 次每次sleep 1即约 15 分钟若超时仍未结束打印提示并退出迁移留待下次登录再试——这是一个显式的降级策略而不是硬等或报错。2.2 图形登录时兜底路径每次图形登录都会在graphical-session.target之后启动omarchy-migrate-notify.service其单元文件 default/systemd/user/omarchy-migrate-notify.service 声明ConditionPathIsDirectory/usr/share/omarchy/migrations Aftergraphical-session.target Typeoneshot ExecStart/usr/bin/omarchy-migrate-notify WantedBygraphical-session.target通知器 bin/omarchy-migrate-notify 的行为链路是检查$XDG_RUNTIME_DIR/omarchy-update.lock是否被flock持有——只要omarchy update正持锁通知器保持沉默因为那次更新自己就会应用所有待执行迁移调用omarchy-migrate --pending列出待执行迁移统计数量等待 shell 抢到org.freedesktop.Notifications总线名omarchy-notification-wait避免通知发进虚空等待后重新检查更新锁等待时间足够长更新可能已经在我们脚下启动再发出一条 critical 级别通知点击后通过omarchy-launch-floating-terminal-with-presentation打开一个终端运行omarchy-migrate若通知无法交付则回退到终端打印待执行清单。单元文件注释解释了一个历史决策登录是唯一有意为之的触发点。仓库曾有一个omarchy-update-user-notify.path监视/usr/share/omarchy/migrations目录但 pacman 在每次更新包括被认可的omarchy update中都会重写该目录导致监视器对即将在可见更新终端中运行的迁移重复弹通知。按登录检查一次是唯一不会与正在运行的更新相撞的触发方式。这条兜底路径专门覆盖两类人群绕过 pacman 保护直接升级的用户例如执行过sudo env OMARCHY_ALLOW_DIRECT_PACMAN1 pacman -Syu跳过了omarchy update中的迁移步骤机器上的第二个用户其迁移标记按用户隔离在第一个用户完成更新后依然缺失。关键设计原则通知器绝不静默地在后台运行迁移它只把打开终端执行omarchy-migrate的邀请交给用户。2.3 手动执行用户可以随时安全地运行omarchy-migrate已完成的迁移会被自动跳过对应 runner 中[[ ! -f $marker ]]的判定重复执行没有副作用。3. 检查待执行迁移omarchy-migrate --pending源码中--check是其同义别名用于检查当前用户还有待执行的迁移。其退出码语义在 bin/omarchy-migrate 第 58–66 行实现退出码含义0存在一个或多个待执行迁移非零没有待执行迁移输出为每行一个待执行的迁移文件名1781158082.sh这个退出码约定是omarchy-migrate-notify能直接omarchy-migrate --pending 2/dev/null) || exit 0的原因——无待执行时自然走非零分支静默退出。4. 创建迁移4.1 使用 helper 生成文件omarchy-dev-add-migration --no-edit该命令对应 bin/omarchy-dev-add-migration会创建migrations/unix timestamp.sh时间戳文件名保证了迁移的全局有序性——bash的 glob 按字典序展开数字时间戳时即得到时间序。源码中可以看到该 helper 会提示migration scopes are no longer used即早期曾有的作用域概念已被废弃现在创建的就是一般的迁移。4.2 新迁移的格式规范文件权限必须是0644-rw-r--r--。迁移 runner 用bash -euo pipefail执行它们不依赖可执行位见 bin/omarchy-migrate 第 93 行bash -euo pipefail $file不要写 shebang 行以一个描述迁移用途的echo开头引用 Omarchy 目录时使用$OMARCHY_PATHrunner 会以环境变量形式注入默认/usr/share/omarchy必须幂等修改前先检查现状迁移是严格有序且同步的。无法完成的迁移必须非零退出、保持 pending 并停止队列——绝不标记依赖它尚未建立之状态的后续迁移为完成适合时优先使用 helper 命令omarchy-cmd-present、omarchy-cmd-missing、omarchy-pkg-add、omarchy-pkg-drop、omarchy-pkg-present、omarchy-pkg-missing永远不要重启 Omarchy shellomarchy update在迁移跑完后会无条件重启它而登录时启动的 shell 本身就在运行当前代码且热加载shell.json的编辑一次性修复工作中裸pacman、command -v和直接改配置文件是允许的。4.3 迁移示例一个真实的迁移 migrations/1781158082.sh 把 Neovim 主题链接从旧状态路径改指向新的current状态echo Relink Neovim theme to Omarchy current state theme_link$HOME/.config/nvim/lua/plugins/theme.lua legacy_absolute_target$HOME/.config/omarchy/current/theme/neovim.lua legacy_relative_target../../../omarchy/current/theme/neovim.lua legacy_home_target~/.config/omarchy/current/theme/neovim.lua current_relative_target../../../../.local/state/omarchy/current/theme/neovim.lua [[ -L $theme_link ]] || exit 0 target$(readlink $theme_link) || exit 0 case $target in $legacy_absolute_target|$legacy_relative_target|$legacy_home_target) ln -sfn $current_relative_target $theme_link ;; esac这个例子展示了规范要求的几个要素首行echo说明用途只处理符号链接[[ -L ... ]] || exit 0保证幂等且不误伤普通文件只匹配已知的三种遗留目标路径才改写其余情况 no-op。5. 测试迁移5.1 临时 HOME 下演练尽量在临时 home 中运行迁移HOME$(mktemp -d) bash -euo pipefail migrations/timestamp.sh这与 runner 的执行方式bash -euo pipefail保持一致能在演练中暴露严格模式下的失败。5.2 本地重放要本地重跑某个迁移删除其标记再运行 migratorrm ~/.local/state/omarchy/migrations/migration.sh omarchy-migrate仓库的测试 test/shell.d/migrate-scope-test.sh 系统性地验证了 runner 的关键行为可以作为迁移行为的权威参照首次运行时按文件名顺序依次执行所有迁移100-first.sh→200-second.sh并在$HOME/.local/state/omarchy/migrations/下写入同名标记第二次运行时全部跳过migration runner skips completed migrations某个迁移失败时set -euo pipefail下false之后不应再有语句执行runner非零退出、不写该迁移的标记队列在此停止——对应失败迁移保持 pending的规范每个迁移执行时都能收到正确的OMARCHY_PATH环境变量。5.3 关于 Omarchy 4.0 升级的例外Omarchy 4.0 通过bin/omarchy-upgrade-to-quattro完成升级而不是走常规迁移 runner。因此不要为旧安装器布局添加兼容性迁移4 之前的包布局过渡工作应放进升级命令而不是migrations/。6. 特例清理退役安装器遗留的特权文件文档最后一段定义了一个明确的例外规则清理某个退役安装器遗留在磁盘上的特权文件属于迁移的职责无论该安装器是否属于一次包布局过渡。理由在于执行覆盖面的不对称性升级命令只运行在仍正在跨越 3→4的机器上。任何放进升级命令的修复永远到不了已经完成跨越的机器也永远不会在安装器自行退役的机器上运行——而该安装器写入的文件仍留在那些机器上。由于升级命令最后会调用omarchy-migraterun_post_upgrade_migrations一个迁移能够触达所有人群放进升级命令只会产生同一判定条件的第二份拷贝需要长期保持同步。编写这类迁移的纪律要求必须明确写出所清除的缺陷并在删除前匹配旧安装器实际产出的内容安全的管理员自建文件administrator-authored files保持不动如果其中仍包含脆弱的特权动作应将其改存为一个不激活的名字而不是丢弃自定义内容或留下可执行的动作依赖同一条退役兼容路径的用户配置可以在同一迁移中一并修复——前提是能消除一个重叠的迁移且只能通过精确匹配并替换遗留路径、保留文件其余内容的方式完成。7. 相关文件索引内容路径本文对应的开发者技能文档agents/skills/migrations.md迁移 runner 实现bin/omarchy-migrate登录通知器实现bin/omarchy-migrate-notify登录触发单元default/systemd/user/omarchy-migrate-notify.service更新主流程含迁移调用时序bin/omarchy-update迁移创建 helperbin/omarchy-dev-add-migration真实迁移示例migrations/1781158082.shrunner 行为测试test/shell.d/migrate-scope-test.sh通知器测试test/shell.d/migrate-notify-test.sh更新时序测试test/shell.d/update-sequence-test.sh适用前提说明本文所有路径与行为均基于当前仓库快照。OMARCHY_PATH默认指向/usr/share/omarchy安装后的位置仓库内migrations/目录打包后会出现在该路径下开发环境可用环境变量OMARCHY_PATH与OMARCHY_MIGRATION_STATE重定向测试即依赖这一点。【免费下载链接】omarchyBeautiful, Modern Opinionated Linux项目地址: https://gitcode.com/GitHub_Trending/om/omarchy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考