diff --git a/AGENTS.md b/AGENTS.md index fdfc350c..02b2004e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -98,9 +98,9 @@ Exceptions are allowed for migration and package-helper scripts where the helper # Region -- `/etc/omarchy/region` holds `china`; no file means Global. `omarchy-region` prints the region and switches it (`omarchy region china|global`); user-facing docs live in `manual/52-china.md`. -- `install/config/region.sh` is the one system leaf for both the ISO install (`OMARCHY_REGION`, from the configurator's `omarchy_install.region`) and the runtime switch: region file, the `default/region/china/` drop-ins it symlinks, the Rime packages, and the locale. `install/user/region.sh` runs `rime-ice-installer --asset-dir /opt/packages/rime-ice` only in the `iso-chroot` context, where the ISO bundles that data. -- `default/region/china/pacman.sed` puts a `.omarchy.cn` twin ahead of every `.omarchy.org` server; `omarchy-refresh-pacman`, `install/post-install/pacman.sh` and `omarchy-region` apply it. Nothing in `omarchy update` or migrations may change the region or `/etc/locale.conf`, and a migration that edits an `.omarchy.org` `Server` line must edit its `.cn` twin the same way. +- `/etc/omarchy/region` holds `cn`; no file means Global. `omarchy-region` prints the region and switches it (`omarchy region cn|global`); the profile lives in `default/regions/cn/`, its contract in `docs/regions.md`, user-facing docs in `manual/52-china.md`. +- `install/config/region.sh` is the one system leaf for both the ISO install (`OMARCHY_REGION`, from the configurator's `omarchy_install.region`) and the runtime switch: region file, the profile drop-ins it symlinks, the Rime packages, and the locale. `install/user/region.sh` runs `rime-ice-installer --asset-dir /opt/packages/rime-ice` only in the `iso-chroot` context, where the ISO bundles that data. +- `omarchy-apply-pacman` renders pacman for every caller: the channel templates, then the profile's `pacman/servers.sed` (a `.omarchy.cn` twin ahead of every `.omarchy.org` server) and its `*.append` files. Nothing in `omarchy update` or migrations may change the region or `/etc/locale.conf`, and a migration that edits an `.omarchy.org` `Server` line must edit its `.cn` twin the same way. - China-only menu rows carry `"when":"[[ \"$(omarchy-region)\" == \"China\" ]]"` on every row, not only the submenu, because search checks each row's own guard. - Chinese menu labels live in `default/omarchy/omarchy-menu.zh-cn.jsonc`, merged when `LANG` starts with `zh_CN`; give a new menu row with translatable words a label there. - Shell text goes through `I18n.tr("English %1", arg)` from `qs.Commons`, with its Chinese in `shell/Commons/I18nZh.js` keyed by the English. Notifications and OSD messages are worded by their sender with `omarchy-text "English %1" "$arg"` (Python: `text()`, QML: `I18n.tr`), which reads the same table; the shell shows them as given, so user text is never translated. `test/shell.d/shell-i18n-test.sh` fails on a missing entry. diff --git a/bin/omarchy-apply-pacman b/bin/omarchy-apply-pacman index e004637d..c8090fcf 100755 --- a/bin/omarchy-apply-pacman +++ b/bin/omarchy-apply-pacman @@ -56,6 +56,10 @@ cp "$OMARCHY_PATH/default/pacman/pacman-$channel.conf" "$staging/pacman.conf" cp "$OMARCHY_PATH/default/pacman/mirrorlist-$channel" "$staging/mirrorlist" if [[ $region != "global" ]]; then profile="$OMARCHY_PATH/default/regions/$region/pacman" + # A region's own copies of the channel servers go ahead of them. + if [[ -r $profile/servers.sed ]]; then + sed -i -f "$profile/servers.sed" "$staging/pacman.conf" "$staging/mirrorlist" + fi printf '\n' >> "$staging/pacman.conf" cat "$profile/pacman.conf.append" >> "$staging/pacman.conf" cat "$profile/mirrorlist.append" >> "$staging/mirrorlist" diff --git a/bin/omarchy-region b/bin/omarchy-region index 85e02fdd..fc26fbab 100755 --- a/bin/omarchy-region +++ b/bin/omarchy-region @@ -1,8 +1,8 @@ #!/bin/bash # omarchy:summary=Show or switch the region this machine is set up for -# omarchy:args=[global|china] -# omarchy:examples=omarchy region | omarchy region china +# omarchy:args=[global|cn] +# omarchy:examples=omarchy region | omarchy region cn # omarchy:requires-sudo=true set -euo pipefail @@ -12,7 +12,7 @@ region_file=/etc/omarchy/region if (($# == 0)); then if [[ ! -e $region_file ]]; then echo "Global" - elif [[ $(<"$region_file") == "china" ]]; then + elif [[ $(<"$region_file") == "cn" ]]; then echo "China" else echo "Unknown region in $region_file: $(<"$region_file")" >&2 @@ -21,34 +21,39 @@ if (($# == 0)); then exit 0 fi -if [[ $1 != "global" && $1 != "china" ]]; then - echo "Usage: omarchy-region [global|china]" >&2 +if [[ $1 != "global" && $1 != "cn" ]]; then + echo "Usage: omarchy-region [global|cn]" >&2 exit 1 fi -pacman_files=(/etc/pacman.conf /etc/pacman.d/mirrorlist) -drop_cn_servers='/^Server = https:\/\/[a-z-]*\.omarchy\.cn\//d' +channel=$(omarchy-version-channel) +if [[ $channel != "stable" && $channel != "rc" && $channel != "edge" ]]; then + echo "Cannot tell this machine's package channel ($channel); run omarchy channel set first" >&2 + exit 1 +fi -if [[ $1 == "china" ]]; then - # Mirrors move last, so a failed setup leaves the machine wholly Global. +if [[ $1 == "cn" ]]; then + # Packages first against current mirrors, so a failed install leaves the machine Global. omarchy-update-pacman -Syu --noconfirm - sudo env OMARCHY_REGION=china OMARCHY_PATH="$OMARCHY_PATH" bash -e "$OMARCHY_PATH/install/config/region.sh" - sudo sed -i -e "$drop_cn_servers" -f "$OMARCHY_PATH/default/region/china/pacman.sed" "${pacman_files[@]}" - echo "Package mirrors -> .cn first, .org after" + sudo env OMARCHY_REGION=cn OMARCHY_PATH="$OMARCHY_PATH" bash -e "$OMARCHY_PATH/install/config/region.sh" + # The refresh renders the cn profile: .cn mirrors first, USTC after, and ArchLinuxCN, whose keyring comes from it. + omarchy-refresh-pacman "$channel" + mapfile -t profile_packages < <(grep -Ev '^[[:space:]]*(#|$)' "$OMARCHY_PATH/default/regions/cn/packages") + omarchy-pkg-add "${profile_packages[@]}" + sudo pacman-key --populate archlinuxcn if [[ ! -f $HOME/.local/share/fcitx5/rime/rime_ice.schema.yaml ]]; then # A running fcitx5 only sees the new Rime addon after a restart. systemctl --user try-restart omarchy-fcitx5.service rime-ice-installer --yes fi else - sudo sed -i -e "$drop_cn_servers" "${pacman_files[@]}" - echo "Package mirrors -> .org only" sudo env OMARCHY_REGION=global OMARCHY_PATH="$OMARCHY_PATH" bash -e "$OMARCHY_PATH/install/config/region.sh" + omarchy-refresh-pacman "$channel" omarchy-setup-claude-api --remove fi # The language and the developer mirrors reach only a new session, so offer one in the new language. -if [[ $1 == "china" ]]; then +if [[ $1 == "cn" ]]; then prompt="立即注销,切换到中文界面和国内镜像?" log_out="立即注销" later="稍后" reminder="区域已设为中国。重新登录后切换到中文界面和国内镜像。" else diff --git a/default/omarchy/omarchy-menu.jsonc b/default/omarchy/omarchy-menu.jsonc index bbe9a1b2..4fde6cd0 100644 --- a/default/omarchy/omarchy-menu.jsonc +++ b/default/omarchy/omarchy-menu.jsonc @@ -178,7 +178,7 @@ "setup.default.editor.emacs": {"icon":" ","label":"Emacs","checked":"[[ \"$(omarchy-default-editor)\" == \"emacs\" ]]","action":"omarchy-default-editor emacs"}, "setup.region": {"icon":"󰇧","label":"Region"}, "setup.region.global": {"icon":"󰖟","label":"Global","checked":"[[ \"$(omarchy-region)\" == \"Global\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-region global'"}, - "setup.region.china": {"icon":"󰈻","label":"China","checked":"[[ \"$(omarchy-region)\" == \"China\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-region china'"}, + "setup.region.china": {"icon":"󰈻","label":"China","checked":"[[ \"$(omarchy-region)\" == \"China\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-region cn'"}, "setup.plugin": {"icon":"󰐱","label":"Plugins","aliases":["plugin","plugins"]}, "setup.plugin.enable": {"icon":"󰄬","label":"Enable Plugin","action":"omarchy-menu-plugin enable"}, "setup.plugin.disable": {"icon":"󰅖","label":"Disable Plugin","action":"omarchy-menu-plugin disable"}, diff --git a/default/region/china/cargo.toml b/default/regions/cn/cargo.toml similarity index 100% rename from default/region/china/cargo.toml rename to default/regions/cn/cargo.toml diff --git a/default/region/china/environment.conf b/default/regions/cn/environment.conf similarity index 81% rename from default/region/china/environment.conf rename to default/regions/cn/environment.conf index 2bb3dd16..60905de2 100644 --- a/default/region/china/environment.conf +++ b/default/regions/cn/environment.conf @@ -5,4 +5,4 @@ GOPROXY=https://mirrors.aliyun.com/goproxy/,direct RUSTUP_DIST_SERVER=https://mirrors.aliyun.com/rustup RUSTUP_UPDATE_ROOT=https://mirrors.aliyun.com/rustup/rustup BUNDLE_MIRROR__ALL=https://mirrors.aliyun.com/rubygems/ -MAVEN_ARGS=--global-settings /usr/share/omarchy/default/region/china/maven-settings.xml +MAVEN_ARGS=--global-settings /usr/share/omarchy/default/regions/cn/maven-settings.xml diff --git a/default/region/china/gemrc b/default/regions/cn/gemrc similarity index 100% rename from default/region/china/gemrc rename to default/regions/cn/gemrc diff --git a/default/region/china/maven-settings.xml b/default/regions/cn/maven-settings.xml similarity index 100% rename from default/region/china/maven-settings.xml rename to default/regions/cn/maven-settings.xml diff --git a/default/region/china/pacman.sed b/default/regions/cn/pacman/servers.sed similarity index 100% rename from default/region/china/pacman.sed rename to default/regions/cn/pacman/servers.sed diff --git a/docs/regions.md b/docs/regions.md index b7f330ff..84449e6d 100644 --- a/docs/regions.md +++ b/docs/regions.md @@ -6,28 +6,33 @@ Regions customize bootstrap defaults independently of update channels. Country i The ISO installer writes the selected region to `/etc/omarchy/region` before target finalization. It is plain text, not executable configuration. A missing file means `global`; an unsupported value is an error. -`omarchy-apply-pacman [target-root]` restores the selected channel's two pacman templates and appends `default/regions//pacman/{pacman.conf.append,mirrorlist.append}`. Both files are generated before either live file is replaced. Existing files are backed up with `.bak`. Dev uses the edge pacman channel, as before. +`omarchy-apply-pacman [target-root]` restores the selected channel's two pacman templates, runs `default/regions//pacman/servers.sed` over both when the profile has one, and appends `default/regions//pacman/{pacman.conf.append,mirrorlist.append}`. Both files are generated before either live file is replaced. Existing files are backed up with `.bak`. Dev uses the edge pacman channel, as before. Both installation finalization and `omarchy-refresh-pacman` use this command. Explicit refreshes and channel changes restore regional defaults; ordinary updates do not enforce them. The existing `pre-refresh-pacman` user hook runs after regeneration and before the update, so users can maintain overrides there. Switching to the dev channel refuses a checkout that lacks this machine's region profile, because that checkout's own refresh would otherwise drop the regional repositories. Users can edit the files directly or set the region to `global` before a refresh to stop applying regional repository defaults. This does not uninstall packages or rewrite anything in existing home directories. -The China profile keeps the channel's Omarchy Arch mirror first, appends USTC's regular Arch mirror, and adds the USTC ArchLinuxCN community repository. It does not change the `[omarchy]` package repository. USTC's mirror, run by the University of Science and Technology of China, and ArchLinuxCN, a long-standing community repository, are a practical bridge until Omarchy runs its own mirror in China. USTC is not a stable/RC snapshot replica: missing old packages and newer fallback databases remain compatibility risks. +The China profile's `servers.sed` puts a `.omarchy.cn` twin ahead of every `.omarchy.org` server, including the `[omarchy]` package repository, so the channel's own snapshot stays first and `.org` stays the fallback. It then appends USTC's regular Arch mirror and adds the USTC ArchLinuxCN community repository. USTC's mirror, run by the University of Science and Technology of China, and ArchLinuxCN, a long-standing community repository, are the last fallback behind Omarchy's own mirrors in China. USTC is not a stable/RC snapshot replica: missing old packages and newer fallback databases remain compatibility risks. + +## Switching an installed machine + +`omarchy-region cn|global` switches at runtime. China installs the input method, runs `install/config/region.sh` (region file, developer-mirror drop-ins, locale), refreshes pacman on the current channel, installs the profile `packages` and populates the ArchLinuxCN keyring. Global undoes the drop-ins and the locale and refreshes pacman back to the channel defaults. Neither touches home directories. ## ISO builder contract -The companion `omarchy-iso` repository accepts `--region global|cn`, passes `OMARCHY_REGION` into the build container, and records it in `/root/omarchy_region` on the ISO. Non-global artifact and offline-cache names gain a region suffix. Existing global names remain unchanged. +Every ISO carries the China profile, and the person picks the region on the installer's first screen. The companion `omarchy-iso` repository also accepts `--region global|cn`, which only preselects that choice, records it in `/root/omarchy_region`, and adds a region suffix to non-global artifact and offline-cache names. Existing global names remain unchanged. -Regional content comes from the same runtime used by the ISO: either the `--local-source` checkout or the downloaded runtime package. A China build against a runtime without regional support fails rather than silently producing a global installation. +Regional content comes from the same runtime used by the ISO: either the `--local-source` checkout or the downloaded runtime package. A build against a runtime without regional support fails rather than silently producing an ISO without the China choice. -- `packages`: additional target packages, one name per line, with blank lines and `#` comments allowed. The builder merges these into the ISO's copy of `omarchy-base.packages`, so they are both included in the offline repository and installed on the target. The source manifest is not modified. +- `packages`: additional target packages, one name per line, with blank lines and `#` comments allowed. The builder bundles them in the offline repository, and the installer installs them only when China is chosen. The source manifest is not modified. - `pacman/`: repository fragments used by the runtime finalizer. The builder also adds the community repository to its writable online config to obtain regional packages; it does not change its Arch channel mirrors. - `timezone` (optional): one zone name, such as `Asia/Shanghai`. The setup form preselects it in the timezone list when the network geo guess is unavailable, which is always the case offline. Both callers pass it: the ISO configurator from its copy of the profile, and first-boot setup from `default/regions//timezone` for the region in `/etc/omarchy/region`. A successful geo guess still wins, and the person can choose any other zone. +- `environment.conf`, `cargo.toml`, `gemrc`, `maven-settings.xml`: developer-mirror drop-ins that `install/config/region.sh` symlinks into `/etc` and `/.cargo`. - `skel/` (optional): new-user defaults. The ISO installer overlays these onto target `/etc/skel` after the base settings packages and before user creation, including installations that defer user creation until first boot. It never overlays existing home directories. For China, the builder installs `archlinuxcn-keyring` using the existing Arch trust chain before downloading other regional packages. Signature or keyring failures abort the build; no unverified keyserver trust or online signature bypass is added. The keyring is also installed on the target from the offline package set, then initialized and populated before online repositories are enabled. The ISO's existing offline repository verification policy is unchanged. ## Scope of the China profile -The China profile provides repository defaults and preselects `Asia/Shanghai` as the timezone. System language (Simplified Chinese) and input-method defaults are planned as separate changes on top of this mechanism: `packages` and `skel/` carry them into the ISO, and the installer stages `skel/` before any user exists. +The China profile provides repository and developer-mirror defaults and preselects `Asia/Shanghai` as the timezone. System language, the Rime input method and China Apps come from `install/config/region.sh` and `manual/52-china.md`, not from the profile files. ## Remaining release validation diff --git a/docs/update-process.md b/docs/update-process.md index 1a72454a..759045ab 100644 --- a/docs/update-process.md +++ b/docs/update-process.md @@ -279,7 +279,7 @@ There is no version file at runtime. `omarchy-version` derives the version from linked checkout, and `omarchy-version-channel` sniffs the mirrorlist and pacman.conf to answer which channel is active. -On a China machine (`/etc/omarchy/region` holds `china`), `omarchy-refresh-pacman` and the installer's `post-install/pacman.sh` run `default/region/china/pacman.sed` over the copied templates, which puts a `.omarchy.cn` twin ahead of every `.omarchy.org` server. The update never recopies these files, and a migration that edits a `Server` line must edit its `.cn` twin the same way, as `1788112314.sh` does, so the twins survive every `omarchy update`. +On a China machine (`/etc/omarchy/region` holds `cn`), `omarchy-apply-pacman` runs `default/regions/cn/pacman/servers.sed` over the copied templates, which puts a `.omarchy.cn` twin ahead of every `.omarchy.org` server. The update never recopies these files, and a migration that edits a `Server` line must edit its `.cn` twin the same way, as `1788112314.sh` does, so the twins survive every `omarchy update`. ## Update-related binaries diff --git a/install/config/region.sh b/install/config/region.sh index 84e2e0f9..f747b09a 100644 --- a/install/config/region.sh +++ b/install/config/region.sh @@ -1,4 +1,4 @@ -china_links=( +cn_links=( "environment.conf /etc/environment.d/90-omarchy-china.conf" "cargo.toml /.cargo/config.toml" "gemrc /etc/gemrc" @@ -8,17 +8,17 @@ case ${OMARCHY_REGION:-global} in global) rm -f /etc/omarchy/region sed -i 's/^LANG=zh_CN\.UTF-8$/LANG=en_US.UTF-8/' /etc/locale.conf - for link in "${china_links[@]}"; do + for link in "${cn_links[@]}"; do read -r _ target <<<"$link" - if [[ -L $target && $(readlink "$target") == */default/region/china/* ]]; then + if [[ -L $target && $(readlink "$target") == */default/regions/cn/* ]]; then rm "$target" fi done ;; -china) +cn) # Packages first, so a failed install leaves the machine Global. omarchy-pkg-add fcitx5-configtool fcitx5-rime librime opencc rime-ice-installer - for link in "${china_links[@]}"; do + for link in "${cn_links[@]}"; do read -r _ target <<<"$link" if [[ -e $target && ! -L $target ]]; then echo "Refusing to replace $target, which Omarchy did not create" >&2 @@ -26,11 +26,11 @@ china) fi done mkdir -p /etc/omarchy - echo china >/etc/omarchy/region - for link in "${china_links[@]}"; do + echo cn >/etc/omarchy/region + for link in "${cn_links[@]}"; do read -r source target <<<"$link" mkdir -p "${target%/*}" - ln -sfn "$OMARCHY_PATH/default/region/china/$source" "$target" + ln -sfn "$OMARCHY_PATH/default/regions/cn/$source" "$target" done sed -i 's/^#\(zh_CN\.UTF-8 UTF-8\)/\1/' /etc/locale.gen locale-gen diff --git a/install/provisioning/setup-form.sh b/install/provisioning/setup-form.sh index 8c4944f5..c391be0e 100644 --- a/install/provisioning/setup-form.sh +++ b/install/provisioning/setup-form.sh @@ -129,12 +129,15 @@ omarchy_prompt_region() { china="China 中国" header="Select region · 选择区域" fi - [[ $region == "china" ]] && selected=$china + [[ $region == "cn" ]] && selected=$china choice=$(printf '%s\n' Global "$china" | gum choose --selected "$selected" --header "$header") && status=0 || status=$? ((status == 0)) || return $status - region=${choice%% *} - region=${region,,} + if [[ $choice == "Global" ]]; then + region=global + else + region=cn + fi } omarchy_prompt_keyboard() { diff --git a/manual/52-china.md b/manual/52-china.md index b316cd07..be4d8a17 100644 --- a/manual/52-china.md +++ b/manual/52-china.md @@ -6,7 +6,7 @@ Omarchy is built to work in mainland China without a VPN. Pick _China_ on the fi | Area | China | Global | |------|-------|--------| -| Omarchy and Arch packages | `pkgs.omarchy.cn` and the `*-mirror.omarchy.cn` mirrors first, the `.org` servers right behind them | `.org` servers only | +| Omarchy and Arch packages | `pkgs.omarchy.cn` and the `*-mirror.omarchy.cn` mirrors first, the `.org` servers behind them, then USTC; the ArchLinuxCN repository | `.org` servers only | | Language | `LANG=zh_CN.UTF-8`, Chinese menu labels | English | | Input method | Fcitx5 with [Rime Ice](https://github.com/iDvel/rime-ice) and the Wanxiang grammar model; `Ctrl + Space` toggles between Chinese and English | Fcitx5 compose only | | Developer mirrors | npm, PyPI and uv, Go, rustup and crates.io, RubyGems and Bundler, Maven | Upstream registries | @@ -14,7 +14,7 @@ Omarchy is built to work in mainland China without a VPN. Pick _China_ on the fi Chinese text renders in the right Noto CJK variant everywhere: Simplified for Chinese, Traditional for Taiwan and Hong Kong, Japanese and Korean for those languages. That works in both regions. -Every package mirror lists the `.cn` server first and the `.org` server second. If the `.cn` mirror is unreachable, or a package is missing there, pacman falls through to `.org`, which works for anyone with their own VPN. `pkgs.omarchy.cn` serves the Omarchy packages today; until the Arch mirrors on `stable-mirror.omarchy.cn` and friends come online, Arch packages come from the `.org` servers. +Every package mirror lists the `.cn` server first and the `.org` server second. If the `.cn` mirror is unreachable, or a package is missing there, pacman falls through to `.org`, which works for anyone with their own VPN, and then to the USTC Arch mirror. The ArchLinuxCN community repository is enabled too. ## Input @@ -34,7 +34,7 @@ _Setup > Claude Code API_ points Claude Code at DeepSeek, Kimi Code, GLM, MiniMa ## Switching regions -_Setup > Region_ switches an installed machine either way, or run `omarchy region china` or `omarchy region global` from a terminal. Switching to China first runs a full system update, so the input method installs against current packages, then installs the input method packages, records the region, moves the package mirrors to `.cn` and downloads Rime Ice. If the packages fail to install, the machine stays Global; if the Rime Ice download fails, China stays selected and running the switch again finishes it. The language and the developer mirrors follow at the next login, so the switch then offers to log out at once. +_Setup > Region_ switches an installed machine either way, or run `omarchy region cn` or `omarchy region global` from a terminal. Switching to China first runs a full system update, so the input method installs against current packages, then installs the input method packages, records the region, moves the package mirrors to `.cn`, adds ArchLinuxCN and downloads Rime Ice. If the packages fail to install, the machine stays Global; if the Rime Ice download fails, China stays selected and running the switch again finishes it. The language and the developer mirrors follow at the next login, so the switch then offers to log out at once. Switching to Global moves packages back to the `.org` servers, the language back to English, and removes the developer mirrors, China Apps and the Claude Code API setup. It keeps the input method and the CJK fonts, so you can still type and read Chinese. `omarchy update` never changes the region or the language; only these switches do. diff --git a/migrations/1791387144.sh b/migrations/1791387144.sh new file mode 100644 index 00000000..d9c379b8 --- /dev/null +++ b/migrations/1791387144.sh @@ -0,0 +1,11 @@ +echo "Rename the China region to cn and follow its moved profile" + +[[ $(cat /etc/omarchy/region 2>/dev/null) == "china" ]] || exit 0 + +echo cn | sudo tee /etc/omarchy/region >/dev/null +for link in /etc/environment.d/90-omarchy-china.conf /.cargo/config.toml /etc/gemrc; do + old=$(readlink "$link" || true) + if [[ $old == */default/region/china/* ]]; then + sudo ln -sfn "$OMARCHY_PATH/default/regions/cn/${old##*/}" "$link" + fi +done diff --git a/test/shell.d/menu-test.sh b/test/shell.d/menu-test.sh index f2bcbd6d..b9fa73d4 100644 --- a/test/shell.d/menu-test.sh +++ b/test/shell.d/menu-test.sh @@ -302,7 +302,7 @@ assert( regionEntries.map(item => item.label).join('\0') === 'Global\0China' && regionEntries.every(item => item.checked.includes(`== \"${item.label}\"`) && !item.when) && defaultById['setup.region.global'].action.includes('omarchy-region global') - && defaultById['setup.region.china'].action.includes('omarchy-region china'), + && defaultById['setup.region.china'].action.includes('omarchy-region cn'), 'menu offers Global and China under Setup > Region' ) // Software you already have keeps its place in Install, dimmed rather than diff --git a/test/shell.d/region-pacman-test.sh b/test/shell.d/region-pacman-test.sh index d183e674..833bf2d3 100644 --- a/test/shell.d/region-pacman-test.sh +++ b/test/shell.d/region-pacman-test.sh @@ -32,18 +32,19 @@ for channel in stable rc edge; do edge) host=mirror.omarchy.org ;; esac apply "$channel" - expected=$(printf 'Server = https://%s/$repo/os/$arch\nServer = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch' "$host") + expected=$(printf 'Server = https://%s/$repo/os/$arch\nServer = https://%s/$repo/os/$arch\nServer = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch' "${host%.org}.cn" "$host") [[ $(<"$TARGET_ROOT/etc/pacman.d/mirrorlist") == "$expected" ]] || fail "$channel mirror order and variables" { - cat "$ROOT/default/pacman/pacman-$channel.conf" + sed -f "$ROOT/default/regions/cn/pacman/servers.sed" "$ROOT/default/pacman/pacman-$channel.conf" printf '\n[archlinuxcn]\nServer = https://mirrors.ustc.edu.cn/archlinuxcn/$arch\n' } > "$scratch/expected.conf" + grep -qx "Server = https://pkgs.omarchy.cn/$channel/\$arch" "$scratch/expected.conf" || fail "$channel lists the .cn Omarchy repository" cmp "$scratch/expected.conf" "$TARGET_ROOT/etc/pacman.conf" apply "$channel" cmp "$TARGET_ROOT/etc/pacman.conf.bak" "$TARGET_ROOT/etc/pacman.conf" cmp "$TARGET_ROOT/etc/pacman.d/mirrorlist.bak" "$TARGET_ROOT/etc/pacman.d/mirrorlist" done -pass "China keeps each channel first, appends only CN defaults, and is idempotent" +pass "China puts a .cn twin ahead of each channel server, appends the CN defaults, and is idempotent" cp "$TARGET_ROOT/etc/pacman.conf" "$scratch/before.conf" cp "$TARGET_ROOT/etc/pacman.d/mirrorlist" "$scratch/before.mirrors" @@ -75,7 +76,7 @@ mkdir -p "$scratch/rendered" "$ROOT/bin/omarchy-apply-pacman" --render rc "$scratch/rendered" "$TARGET_ROOT" rg -qxF 'Server = https://pkgs.omarchy.org/rc/$arch' "$scratch/rendered/pacman.conf" rg -qxF '[archlinuxcn]' "$scratch/rendered/pacman.conf" -[[ $(<"$scratch/rendered/mirrorlist") == $'Server = https://rc-mirror.omarchy.org/$repo/os/$arch\nServer = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch' ]] || +[[ $(<"$scratch/rendered/mirrorlist") == $'Server = https://rc-mirror.omarchy.cn/$repo/os/$arch\nServer = https://rc-mirror.omarchy.org/$repo/os/$arch\nServer = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch' ]] || fail "render keeps the channel mirror first" cmp "$scratch/before.conf" "$TARGET_ROOT/etc/pacman.conf" pass "render builds the regional channel files without touching the target" diff --git a/test/shell.d/region-switch-test.sh b/test/shell.d/region-switch-test.sh index e688af88..45bafca9 100755 --- a/test/shell.d/region-switch-test.sh +++ b/test/shell.d/region-switch-test.sh @@ -8,77 +8,68 @@ test_tmp=$(mktemp -d) trap 'rm -rf "$test_tmp"' EXIT root="$test_tmp/root" sandbox="$test_tmp/omarchy" calls="$test_tmp/calls" -mkdir -p "$root/etc/pacman.d" "$sandbox/bin" "$sandbox/install/config" "$sandbox/default/region" "$test_tmp/bin" "$test_tmp/home" -cp -r "$ROOT/default/region/china" "$sandbox/default/region/" +mkdir -p "$root/etc/pacman.d" "$sandbox/bin" "$sandbox/install/config" "$sandbox/default/regions" "$test_tmp/bin" "$test_tmp/home" +cp -r "$ROOT/default/regions/cn" "$sandbox/default/regions/" rewrite() { sed -e "s|/etc/|$root/etc/|g" -e "s| /\\.cargo/| $root/.cargo/|g" "$1" >"$2"; chmod +x "$2"; } rewrite "$ROOT/install/config/region.sh" "$sandbox/install/config/region.sh" rewrite "$ROOT/bin/omarchy-region" "$sandbox/bin/omarchy-region" -for command in omarchy-update-pacman omarchy-pkg-add locale-gen rime-ice-installer omarchy-setup-claude-api systemctl omarchy-system-logout; do +for command in omarchy-update-pacman omarchy-refresh-pacman locale-gen rime-ice-installer omarchy-setup-claude-api systemctl omarchy-system-logout pacman-key; do printf '#!/bin/bash\necho "%s $*" >>"%s"\n' "$command" "$calls" >"$test_tmp/bin/$command" done printf '#!/bin/bash\necho "omarchy-pkg-add $*" >>"%s"\n[[ -z ${STUB_PKG_FAIL:-} ]]\n' "$calls" >"$test_tmp/bin/omarchy-pkg-add" +printf '#!/bin/bash\necho "${STUB_CHANNEL:-stable}"\n' >"$test_tmp/bin/omarchy-version-channel" printf '#!/bin/bash\n[[ $1 == env ]] && shift\nexec env "$@"\n' >"$test_tmp/bin/sudo" printf '#!/bin/bash\necho "gum $*" >>"%s"\nexit "${GUM_ANSWER:-1}"\n' "$calls" >"$test_tmp/bin/gum" chmod +x "$test_tmp/bin"/* export PATH="$test_tmp/bin:$sandbox/bin:$PATH" OMARCHY_PATH="$sandbox" HOME="$test_tmp/home" -cp "$ROOT/default/pacman/pacman-stable.conf" "$root/etc/pacman.conf" -cp "$ROOT/default/pacman/mirrorlist-stable" "$root/etc/pacman.d/mirrorlist" printf '#zh_CN.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\n' >"$root/etc/locale.gen" printf 'LANG=en_US.UTF-8\n' >"$root/etc/locale.conf" -china_conf=$(sed -f "$ROOT/default/region/china/pacman.sed" "$ROOT/default/pacman/pacman-stable.conf") -china_mirrors=$(sed -f "$ROOT/default/region/china/pacman.sed" "$ROOT/default/pacman/mirrorlist-stable") - -omarchy-region china >/dev/null -[[ $(<"$root/etc/pacman.conf") == "$china_conf" && $(<"$root/etc/pacman.d/mirrorlist") == "$china_mirrors" ]] || - fail "switching to China lists the .cn mirrors first" -[[ $(omarchy-region) == "China" && $(<"$root/etc/locale.conf") == "LANG=zh_CN.UTF-8" ]] || fail "switching to China records it and sets the language" -[[ $(<"$calls") == $'omarchy-update-pacman -Syu --noconfirm\nomarchy-pkg-add fcitx5-configtool fcitx5-rime librime opencc rime-ice-installer\nlocale-gen \nsystemctl --user try-restart omarchy-fcitx5.service\nrime-ice-installer --yes' ]] || - fail "China upgrades in full before installing Rime, then sets Rime Ice up" "$(<"$calls")" -pass "switching to China sets mirrors, language and Rime Ice" +omarchy-region cn >/dev/null +[[ $(omarchy-region) == "China" && $(<"$root/etc/omarchy/region") == "cn" && $(<"$root/etc/locale.conf") == "LANG=zh_CN.UTF-8" ]] || + fail "switching to China records cn and sets the language" +[[ $(<"$calls") == $'omarchy-update-pacman -Syu --noconfirm\nomarchy-pkg-add fcitx5-configtool fcitx5-rime librime opencc rime-ice-installer\nlocale-gen \nomarchy-refresh-pacman stable\nomarchy-pkg-add archlinuxcn-keyring\npacman-key --populate archlinuxcn\nsystemctl --user try-restart omarchy-fcitx5.service\nrime-ice-installer --yes' ]] || + fail "China installs Rime against current packages, refreshes pacman into the cn profile, then trusts ArchLinuxCN and sets Rime Ice up" "$(<"$calls")" +pass "switching to China installs Rime, renders the cn profile on the current channel and trusts ArchLinuxCN" : >"$calls" mkdir -p "$HOME/.local/share/fcitx5/rime" && touch "$HOME/.local/share/fcitx5/rime/rime_ice.schema.yaml" -omarchy-region china >/dev/null -[[ $(<"$root/etc/pacman.conf") == "$china_conf" && $(<"$root/etc/pacman.d/mirrorlist") == "$china_mirrors" ]] || - fail "switching to China twice adds no second .cn line" +STUB_CHANNEL=edge omarchy-region cn >/dev/null +grep -qx 'omarchy-refresh-pacman edge' "$calls" || fail "the refresh keeps the machine's channel" "$(<"$calls")" grep -q '^rime-ice-installer\|^systemctl' "$calls" && fail "an existing Rime Ice setup is not redone" -pass "switching to China again changes nothing it already did" - -printf 'Server = https://stable-mirror.omarchy.cn/$repo/os/$arch\nServer = https://stable-mirror.omarchy.org/$repo/os/$arch\nServer = https://mirror.omarchy.org/$repo/os/$arch\n' >"$root/etc/pacman.d/mirrorlist" -omarchy-region china >/dev/null -[[ $(<"$root/etc/pacman.d/mirrorlist") == $'Server = https://stable-mirror.omarchy.cn/$repo/os/$arch\nServer = https://stable-mirror.omarchy.org/$repo/os/$arch\nServer = https://mirror.omarchy.cn/$repo/os/$arch\nServer = https://mirror.omarchy.org/$repo/os/$arch' ]] || - fail "a partly switched mirrorlist gets every missing .cn twin" "$(<"$root/etc/pacman.d/mirrorlist")" -cp "$ROOT/default/pacman/mirrorlist-stable" "$root/etc/pacman.d/mirrorlist" -sed -i -f "$ROOT/default/region/china/pacman.sed" "$root/etc/pacman.d/mirrorlist" -pass "every .org server ends up with exactly one .cn twin in front" +pass "switching to China again keeps the channel and redoes no Rime Ice setup" : >"$calls" omarchy-region global >/dev/null -[[ $(<"$root/etc/pacman.conf") == "$(<"$ROOT/default/pacman/pacman-stable.conf")" && $(<"$root/etc/pacman.d/mirrorlist") == "$(<"$ROOT/default/pacman/mirrorlist-stable")" ]] || - fail "switching to Global drops exactly the .cn mirrors" -[[ $(omarchy-region) == "Global" && $(<"$root/etc/locale.conf") == "LANG=en_US.UTF-8" ]] || fail "switching to Global records it and restores English" -[[ $(<"$calls") == "omarchy-setup-claude-api --remove" ]] || fail "Global removes the Claude Code third-party API and keeps Rime" "$(<"$calls")" +[[ $(omarchy-region) == "Global" && ! -e $root/etc/omarchy/region && $(<"$root/etc/locale.conf") == "LANG=en_US.UTF-8" ]] || + fail "switching to Global removes the region and restores English" +[[ $(<"$calls") == $'omarchy-refresh-pacman stable\nomarchy-setup-claude-api --remove' ]] || + fail "Global refreshes pacman back to the channel defaults and removes the Claude API setup" "$(<"$calls")" [[ -f $HOME/.local/share/fcitx5/rime/rime_ice.schema.yaml ]] || fail "Global keeps the input method" -pass "switching to Global restores mirrors and language, keeps Rime, removes the Claude API setup" +pass "switching to Global restores the channel's pacman defaults and English, keeps Rime, removes the Claude API setup" if output=$(omarchy-region mars 2>&1); then fail "an unknown region is refused" "$output" fi -pass "an unknown region is refused" +if output=$(STUB_CHANNEL="stable / edge" omarchy-region cn 2>&1); then + fail "a mixed channel is refused" "$output" +fi +[[ $(omarchy-region) == "Global" ]] || fail "a refused switch changes nothing" +pass "an unknown region or an unclear channel is refused" -if output=$(STUB_PKG_FAIL=1 omarchy-region china 2>&1); then +: >"$calls" +if output=$(STUB_PKG_FAIL=1 omarchy-region cn 2>&1); then fail "switching to China fails when its packages do not install" "$output" fi -[[ $(omarchy-region) == "Global" && $(<"$root/etc/pacman.conf") == "$(<"$ROOT/default/pacman/pacman-stable.conf")" && $(<"$root/etc/pacman.d/mirrorlist") == "$(<"$ROOT/default/pacman/mirrorlist-stable")" ]] || - fail "a failed switch to China leaves the region and the mirrors Global" +[[ $(omarchy-region) == "Global" ]] && ! grep -q '^omarchy-refresh-pacman' "$calls" || + fail "a failed switch to China leaves the region Global and pacman untouched" "$(<"$calls")" pass "a failed switch to China leaves the machine Global" grep -q '^gum' "$calls" && fail "a switch without a terminal asks nothing" "$(<"$calls")" : >"$calls" -output=$(GUM_ANSWER=1 script -qec "omarchy-region china" /dev/null) +output=$(GUM_ANSWER=1 script -qec "omarchy-region cn" /dev/null) grep -qxF 'gum confirm --affirmative 立即注销 --negative 稍后 立即注销,切换到中文界面和国内镜像?' "$calls" || fail "switching to China offers to log out, in Chinese" "$(<"$calls")" [[ $output == *"区域已设为中国。重新登录后切换到中文界面和国内镜像。"* ]] && ! grep -q '^omarchy-system-logout' "$calls" || @@ -93,7 +84,7 @@ rc_migration="$test_tmp/1788112314.sh" rewrite "$ROOT/migrations/1788112314.sh" "$rc_migration" cp "$ROOT/default/pacman/mirrorlist-rc" "$root/etc/pacman.d/mirrorlist" sed -e 's|pkgs.omarchy.org/rc/|pkgs.omarchy.org/edge/|' "$ROOT/default/pacman/pacman-rc.conf" | - sed -f "$ROOT/default/region/china/pacman.sed" >"$root/etc/pacman.conf" + sed -f "$ROOT/default/regions/cn/pacman/servers.sed" >"$root/etc/pacman.conf" bash -e "$rc_migration" >/dev/null [[ $(grep '^Server' "$root/etc/pacman.conf") == $'Server = https://pkgs.omarchy.cn/rc/$arch\nServer = https://pkgs.omarchy.org/rc/$arch' ]] || fail "the rc repository migration moves the .cn twin with its .org server" "$(grep '^Server' "$root/etc/pacman.conf")" diff --git a/test/shell.d/region-test.sh b/test/shell.d/region-test.sh index 12feb433..c4469416 100755 --- a/test/shell.d/region-test.sh +++ b/test/shell.d/region-test.sh @@ -7,7 +7,7 @@ source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" test_tmp=$(mktemp -d) trap 'rm -rf "$test_tmp"' EXIT -china_sed="$ROOT/default/region/china/pacman.sed" +china_sed="$ROOT/default/regions/cn/pacman/servers.sed" expected_stable_omarchy='Server = https://pkgs.omarchy.cn/stable/$arch Server = https://pkgs.omarchy.org/stable/$arch' @@ -44,9 +44,9 @@ chmod +x "$region_bin" [[ $("$region_bin") == "Global" ]] || fail "no region file reads as Global" pass "no region file reads as Global" -echo china >"$region_file" -[[ $("$region_bin") == "China" ]] || fail "china region file reads as China" -pass "china region file reads as China" +echo cn >"$region_file" +[[ $("$region_bin") == "China" ]] || fail "cn region file reads as China" +pass "cn region file reads as China" echo mars >"$region_file" if output=$("$region_bin" 2>&1); then @@ -75,8 +75,8 @@ printf '#zh_CN.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\n' >"$root/etc/locale.gen" printf 'LANG=en_US.UTF-8\nLC_TIME=en_DK.UTF-8\n' >"$root/etc/locale.conf" : >"$calls" -OMARCHY_REGION=china bash -e "$region_setup" -[[ $(<"$root/etc/omarchy/region") == "china" ]] || fail "install records the China region" +OMARCHY_REGION=cn bash -e "$region_setup" +[[ $(<"$root/etc/omarchy/region") == "cn" ]] || fail "install records the China region as cn" [[ $(<"$calls") == $'omarchy-pkg-add fcitx5-configtool fcitx5-rime librime opencc rime-ice-installer\nlocale-gen ' ]] || fail "China installs the Rime input method packages and generates the Chinese locale" "$(<"$calls")" [[ $(<"$root/etc/locale.gen") == $'zh_CN.UTF-8 UTF-8\nen_US.UTF-8 UTF-8' ]] || fail "China enables zh_CN in locale.gen" @@ -88,7 +88,7 @@ pass "install records the China region and installs the Rime packages the ISO ca for link in "environment.conf etc/environment.d/90-omarchy-china.conf" "cargo.toml .cargo/config.toml" "gemrc etc/gemrc"; do read -r source target <<<"$link" - [[ $(readlink "$root/$target") == "$ROOT/default/region/china/$source" ]] || fail "China links /$target to the shipped $source" + [[ $(readlink "$root/$target") == "$ROOT/default/regions/cn/$source" ]] || fail "China links /$target to the shipped $source" done pass "China links the developer mirror drop-ins" @@ -111,7 +111,7 @@ OMARCHY_REGION=global bash -e "$region_setup" [[ -L $root/etc/gemrc ]] || fail "Global keeps a gemrc link Omarchy did not create" rm "$root/etc/gemrc" echo ":sources: []" >"$root/etc/gemrc" -if output=$(OMARCHY_REGION=china bash -e "$region_setup" 2>&1); then +if output=$(OMARCHY_REGION=cn bash -e "$region_setup" 2>&1); then fail "China refuses to replace an admin's /etc/gemrc" "$output" fi [[ $output == "Refusing to replace $root/etc/gemrc, which Omarchy did not create" && $(<"$root/etc/gemrc") == ":sources: []" ]] || @@ -120,13 +120,13 @@ fi rm "$root/etc/gemrc" pass "region setup never touches mirror config Omarchy did not create" -if output=$(STUB_PKG_FAIL=1 OMARCHY_REGION=china bash -e "$region_setup" 2>&1); then +if output=$(STUB_PKG_FAIL=1 OMARCHY_REGION=cn bash -e "$region_setup" 2>&1); then fail "China fails when its packages do not install" "$output" fi [[ ! -e $root/etc/omarchy/region && ! -e $root/etc/gemrc && $(<"$root/etc/locale.conf") == "LANG=en_US.UTF-8" ]] || fail "a failed package install leaves the machine Global" pass "China installs its packages before it writes any region state" -OMARCHY_REGION=china bash -e "$region_setup" +OMARCHY_REGION=cn bash -e "$region_setup" env -u OMARCHY_REGION bash -e "$region_setup" [[ ! -e $root/etc/omarchy/region ]] || fail "an installer that passes no region installs Global" pass "Global and an unset region leave no region file" diff --git a/test/shell.d/setup-form-test.sh b/test/shell.d/setup-form-test.sh index b03a4b02..b01dad28 100755 --- a/test/shell.d/setup-form-test.sh +++ b/test/shell.d/setup-form-test.sh @@ -130,10 +130,10 @@ pass "the form publishes the 0/1/130 status contract and leads with English (US) run_prompt omarchy_prompt_region "0:China" assert_status 0 "region prompt succeeds" -[[ $(field region) == "china" ]] || fail "region prompt stores China as china" +[[ $(field region) == "cn" ]] || fail "region prompt stores China as cn" [[ $(<"$tmp_dir/stdin.1") == $'Global\nChina' ]] || fail "region prompt offers Global then China" grep -qxF -- 'choose --selected Global --header Select region' "$GUM_ARGS" || fail "region prompt preselects Global on a fresh form" -REGION=china run_prompt omarchy_prompt_region "0:Global" +REGION=cn run_prompt omarchy_prompt_region "0:Global" [[ $(field region) == "global" ]] || fail "region prompt stores Global as global" grep -qxF -- 'choose --selected China --header Select region' "$GUM_ARGS" || fail "region prompt preselects the region chosen on an earlier visit" pass "region prompt maps Global and China and preselects the current region" @@ -149,13 +149,13 @@ pass "region prompt propagates Esc and Ctrl+C without dying under set -e" OMARCHY_CJK_CONSOLE=1 run_prompt omarchy_prompt_region "0:China 中国" assert_status 0 "region prompt succeeds in a CJK console" -[[ $(field region) == "china" ]] || fail "region prompt stores China 中国 as china" +[[ $(field region) == "cn" ]] || fail "region prompt stores China 中国 as cn" [[ $(<"$tmp_dir/stdin.1") == $'Global\nChina 中国' ]] || fail "a CJK console offers the Chinese name" grep -qxF -- 'choose --selected Global --header Select region · 选择区域' "$GUM_ARGS" || fail "a CJK console asks in both languages" -OMARCHY_CJK_CONSOLE=1 REGION=china run_prompt omarchy_prompt_region "0:Global" +OMARCHY_CJK_CONSOLE=1 REGION=cn run_prompt omarchy_prompt_region "0:Global" [[ $(field region) == "global" ]] || fail "region prompt stores Global as global in a CJK console" grep -qxF -- 'choose --selected China 中国 --header Select region · 选择区域' "$GUM_ARGS" || fail "a CJK console preselects China by its shown name" -pass "a CJK console names China in Chinese and maps it back to china" +pass "a CJK console names China in Chinese and maps it back to cn" # Keyboard