diff --git a/README.md b/README.md index ee3275c..532bfce 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ For an unpublished regional runtime, use matching local source and package-recip ./bin/omarchy-iso-make --region cn --no-boot-offer --local-source /path/to/omarchy /path/to/omarchy-pkgs ``` -China builds keep the channel mirror first, append the USTC Arch mirror, and add ArchLinuxCN with its verified keyring. These are a practical bridge until Omarchy runs its own mirror in China; USTC is rolling, not a matching stable/RC snapshot, so fallback version compatibility is not guaranteed. The region architecture also stages optional new-user defaults before user creation, including deferred setup, without touching existing homes. The China profile currently ships repository defaults only; language, timezone, and input-method defaults come as separate changes. See `docs/regions.md` in the companion runtime checkout. +China builds keep the channel mirror first, append the USTC Arch mirror, and add ArchLinuxCN with its verified keyring. These are a practical bridge until Omarchy runs its own mirror in China; USTC is rolling, not a matching stable/RC snapshot, so fallback version compatibility is not guaranteed. The region architecture also stages optional new-user defaults before user creation, including deferred setup, without touching existing homes. The China profile ships repository defaults and preselects `Asia/Shanghai` as the timezone; language and input-method defaults come as separate changes. See `docs/regions.md` in the companion runtime checkout. Non-global cache and ISO names gain a `-cn` suffix. A runtime without the selected profile fails the build. These builds require an x86_64 Arch container environment; packaging checks on another architecture do not substitute for a fresh build, offline installation, and graphical acceptance run. diff --git a/configs/airootfs/root/configurator b/configs/airootfs/root/configurator index 2960c06..34351cc 100644 --- a/configs/airootfs/root/configurator +++ b/configs/airootfs/root/configurator @@ -24,6 +24,16 @@ if [[ ! -r $SETUP_FORM ]]; then fi source "$SETUP_FORM" +# A regional ISO carries its profile here (builder/prepare-region.sh copies it); +# the form preselects the profile's timezone when there is no geo guess, which +# is every offline install. +REGION_TIMEZONE="${REGION_TIMEZONE:-/usr/share/omarchy-iso/region/timezone}" +region_timezone() { + if [[ -r $REGION_TIMEZONE ]]; then + head -n 1 "$REGION_TIMEZONE" + fi +} + # Partition creation helpers, shared with test/partition-numbering-test.sh so # the numbering logic can be exercised without a real disk. DISK_PARTITIONING="${DISK_PARTITIONING:-/usr/share/omarchy-iso/disk-partitioning.sh}" @@ -270,7 +280,7 @@ user_form() { omarchy_prompt_identity || return $? omarchy_prompt_hostname || return $? - omarchy_prompt_timezone || return $? + omarchy_prompt_timezone "$(region_timezone)" || return $? } # Returns 0 on confirmed account details, or as soon as the keyboard screen diff --git a/test/unit/test_region.py b/test/unit/test_region.py index f070fff..3beae82 100644 --- a/test/unit/test_region.py +++ b/test/unit/test_region.py @@ -1,6 +1,7 @@ """Region bootstrap contracts without Docker, pacman, or a running guest.""" import os +import re import shutil import subprocess import sys @@ -97,6 +98,7 @@ class RegionBuildTest(unittest.TestCase): (self.profile / "packages").write_text("archlinuxcn-keyring\nexample-regional-package\n") (self.profile / "pacman/pacman.conf.append").write_text("[archlinuxcn]\nServer = https://mirrors.ustc.edu.cn/archlinuxcn/$arch\n") (self.profile / "pacman/mirrorlist.append").write_text("Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch\n") + (self.profile / "timezone").write_text("Asia/Shanghai\n") self.iso = self.root / "iso" self.payload = self.iso / "usr/share/omarchy-iso" self.payload.mkdir(parents=True) @@ -126,6 +128,7 @@ class RegionBuildTest(unittest.TestCase): self.assertEqual(self.packages.read_text(), "base\n\narchlinuxcn-keyring\nexample-regional-package\n") self.assertEqual(self.config.read_bytes(), self.original_config + b"\n[archlinuxcn]\nServer = https://mirrors.ustc.edu.cn/archlinuxcn/$arch\n") self.assertEqual((self.payload / "region/packages").read_text(), "archlinuxcn-keyring\nexample-regional-package\n") + self.assertEqual((self.payload / "region/timezone").read_text(), "Asia/Shanghai\n") self.assertEqual(self.log.read_text().splitlines(), [f"pacman --config {self.config} --noconfirm -Sy --needed archlinuxcn-keyring", "pacman-key --populate archlinuxcn"]) with mock.patch.object(phases_impl, "Path", return_value=self.packages), \ mock.patch.object(phases_impl, "_package_targets", return_value={"runtime": "omarchy-dev", "settings": "omarchy-settings-dev", "nvim": "omarchy-nvim"}): @@ -250,3 +253,34 @@ done if __name__ == "__main__": unittest.main() + + +class ConfiguratorRegionTimezoneTest(unittest.TestCase): + """The configurator hands the ISO's regional timezone to the setup form.""" + + def setUp(self): + configurator = (ROOT / "configs/airootfs/root/configurator").read_text() + helper = re.search(r"^region_timezone\(\) \{\n.*?^\}", configurator, re.M | re.S) + self.assertIsNotNone(helper) + self.helper = helper.group(0) + self.configurator = configurator + tmp = tempfile.TemporaryDirectory() + self.addCleanup(tmp.cleanup) + self.file = Path(tmp.name) / "timezone" + + def region_timezone(self): + return subprocess.run( + ["bash", "-c", f"set -euo pipefail\n{self.helper}\nregion_timezone"], + env={**os.environ, "REGION_TIMEZONE": str(self.file)}, + capture_output=True, text=True, check=True, + ).stdout + + def test_global_iso_offers_no_timezone(self): + self.assertEqual(self.region_timezone(), "") + + def test_regional_iso_offers_its_profile_timezone(self): + self.file.write_text("Asia/Shanghai\n") + self.assertEqual(self.region_timezone(), "Asia/Shanghai\n") + + def test_user_form_passes_it_to_the_timezone_prompt(self): + self.assertIn('omarchy_prompt_timezone "$(region_timezone)"', self.configurator)