feat: persist Chrome country overrides on macOS - #29
Open
hhh2210 wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds an optional macOS LaunchAgent (“persistence mode”) to periodically verify and re-apply Chrome’s country/eligibility overrides, and refactors Chrome shutdown/restart to be safer and more macOS-native.
Changes:
- Add
launchd.pyand CLI flags to install/uninstall a macOS LaunchAgent that runs at login and weekly. - Refactor Chrome process management into
chrome_processes.py, including reopening via LaunchServices on macOS. - Add unit tests for persistence/atomic writes and update READMEs with persistence-mode docs.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
main.py |
Adds CLI parsing, persistence install/remove commands, atomic Local State writes, and no-op short-circuiting when no patch is needed. |
launchd.py |
Implements LaunchAgent plist generation plus install/uninstall via launchctl. |
chrome_processes.py |
New module to detect, terminate, wait, and restart Chrome appropriately per platform (macOS uses open). |
tests/test_persistence.py |
New tests covering Local State patching/atomic write behavior, launchd install flow, and Chrome shutdown/restart helpers. |
README.md |
Documents macOS persistence mode and updated macOS restart/process-detection behavior. |
README.zh.md |
Same as above, in Chinese documentation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+28
to
+32
| 'StartCalendarInterval': { | ||
| 'Weekday': 0, | ||
| 'Hour': 4, | ||
| 'Minute': 0, | ||
| }, |
Comment on lines
+206
to
+210
| if not pending: | ||
| print('All Chrome profiles already match country %s' % args.country) | ||
| if not args.yes: | ||
| input('Enter to continue...') | ||
| return |
Comment on lines
+92
to
+100
| with mock.patch.dict(os.environ, {'HOME': directory.name}): | ||
| launchd.install_launch_agent('us', '/repo/main.py') | ||
| agent_path = launchd.launch_agent_path() | ||
| with open(agent_path, 'rb') as fp: | ||
| agent = plistlib.load(fp) | ||
|
|
||
| self.assertEqual(agent['Label'], launchd.LABEL) | ||
| self.assertEqual(agent['ProgramArguments'][-3:], ['--country', 'us', '--yes']) | ||
| domain = 'gui/%d' % os.getuid() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Chrome can replace
variations_countryafter an update or a new variations seed. Running the script again fixes it, but that currently requires manual intervention.This change adds an optional macOS LaunchAgent. It checks the configuration after installation, at login, and every Sunday at 04:00. The job exits without touching Chrome when the country and eligibility values are already correct.
The patch also fixes two problems in the existing restart path:
.appbundle through LaunchServices instead of starting the executable directly.Local Stateis changed. Remaining processes are killed after the timeout.Local Stateis written through a temporary file and replaced atomically. Chrome is reopened in afinallyblock if patching fails.Commands
The country defaults to
us.--country CCaccepts another two-letter country code.Removing the LaunchAgent stops future checks. It does not restore the previous Chrome values.
Validation
The LaunchAgent was also loaded and run on macOS 27.0 (26A5378n) with Chrome 150.0.7871.129. It exited with status 0, and the no-change path left the running Chrome process untouched.
Related: #23 and #25.
Backup and restore remain outside this patch and are tracked in #8. The broader Glic preference changes from #28 are also left unchanged.