From 94760f9401ec2644fbb23a0c6401a2dd229403db Mon Sep 17 00:00:00 2001 From: Clint M Date: Thu, 16 Jul 2026 10:32:09 -0600 Subject: [PATCH 1/2] move application code to src/ and tests to tests/ (#29) git mv only; no logic changes. Reference updates: - pyproject.toml: pytest pythonpath=["src"], testpaths=["tests"] - Ritefile.yml: --cov=src, pylint src/*.py tests/*.py, python src/publish.py - macprefs.template.rb: libexec.install Dir["src/*"] (flatten keeps sibling imports working in the installed layout) - ci/scripts/brew-build-test.sh: PYTHONPATH=src for the version import - tests: execute_module paths now src/macprefs and src/publish.py (paths resolve relative to cwd, which is repo root under rite) --- Ritefile.yml | 6 +++--- ci/scripts/brew-build-test.sh | 2 +- macprefs.template.rb | 2 +- pyproject.toml | 2 ++ .../app_store_preferences.py | 0 config.py => src/config.py | 0 dotfiles.py => src/dotfiles.py | 0 internet_accounts.py => src/internet_accounts.py | 0 macprefs => src/macprefs | 0 preferences.py => src/preferences.py | 0 publish.py => src/publish.py | 0 shared_file_lists.py => src/shared_file_lists.py | 0 ssh_files.py => src/ssh_files.py | 0 startup_items.py => src/startup_items.py | 0 system_preferences.py => src/system_preferences.py | 0 utils.py => src/utils.py | 0 version.py => src/version.py | 0 .../test_app_store_preferences.py | 0 test_config.py => tests/test_config.py | 0 test_dotfiles.py => tests/test_dotfiles.py | 0 .../test_internet_accounts.py | 0 test_macprefs.py => tests/test_macprefs.py | 10 +++++----- test_preferences.py => tests/test_preferences.py | 0 test_publish.py => tests/test_publish.py | 2 +- .../test_shared_file_lists.py | 0 test_ssh_files.py => tests/test_ssh_files.py | 0 test_startup_items.py => tests/test_startup_items.py | 0 .../test_system_preferences.py | 0 test_utils.py => tests/test_utils.py | 0 29 files changed, 13 insertions(+), 11 deletions(-) rename app_store_preferences.py => src/app_store_preferences.py (100%) rename config.py => src/config.py (100%) rename dotfiles.py => src/dotfiles.py (100%) rename internet_accounts.py => src/internet_accounts.py (100%) rename macprefs => src/macprefs (100%) rename preferences.py => src/preferences.py (100%) rename publish.py => src/publish.py (100%) rename shared_file_lists.py => src/shared_file_lists.py (100%) rename ssh_files.py => src/ssh_files.py (100%) rename startup_items.py => src/startup_items.py (100%) rename system_preferences.py => src/system_preferences.py (100%) rename utils.py => src/utils.py (100%) rename version.py => src/version.py (100%) rename test_app_store_preferences.py => tests/test_app_store_preferences.py (100%) rename test_config.py => tests/test_config.py (100%) rename test_dotfiles.py => tests/test_dotfiles.py (100%) rename test_internet_accounts.py => tests/test_internet_accounts.py (100%) rename test_macprefs.py => tests/test_macprefs.py (93%) rename test_preferences.py => tests/test_preferences.py (100%) rename test_publish.py => tests/test_publish.py (99%) rename test_shared_file_lists.py => tests/test_shared_file_lists.py (100%) rename test_ssh_files.py => tests/test_ssh_files.py (100%) rename test_startup_items.py => tests/test_startup_items.py (100%) rename test_system_preferences.py => tests/test_system_preferences.py (100%) rename test_utils.py => tests/test_utils.py (100%) diff --git a/Ritefile.yml b/Ritefile.yml index a6bafae..2e67774 100644 --- a/Ritefile.yml +++ b/Ritefile.yml @@ -32,7 +32,7 @@ tasks: aliases: [t] deps: [setup] cmds: - - uv run pytest --cov=. --cov-report xml:cov.xml --cov-report term-missing + - uv run pytest --cov=src --cov-report xml:cov.xml --cov-report term-missing test:watch: desc: Re-run tests on file changes @@ -46,7 +46,7 @@ tasks: aliases: [l] deps: [setup] cmds: - - uv run pylint *.py + - uv run pylint src/*.py tests/*.py build: desc: Build the brew package from committed HEAD, install, verify, uninstall @@ -66,7 +66,7 @@ tasks: aliases: [p] deps: [test] cmds: - - uv run python publish.py + - uv run python src/publish.py teardown: desc: Remove the local dev environment (counterpart to setup) diff --git a/ci/scripts/brew-build-test.sh b/ci/scripts/brew-build-test.sh index 576d453..e09a1de 100755 --- a/ci/scripts/brew-build-test.sh +++ b/ci/scripts/brew-build-test.sh @@ -7,7 +7,7 @@ # the real install) unless FORCE=1 is set. set -euo pipefail -VERSION=$(python3 -c "import version; print(version.__version__.lstrip('v'))") +VERSION=$(PYTHONPATH=src python3 -c "import version; print(version.__version__.lstrip('v'))") TMP=$(mktemp -d) trap 'rm -rf "$TMP"' EXIT diff --git a/macprefs.template.rb b/macprefs.template.rb index 067893d..5a2a08c 100644 --- a/macprefs.template.rb +++ b/macprefs.template.rb @@ -7,7 +7,7 @@ class Macprefs < Formula depends_on "python@3.13" def install - libexec.install Dir["*"] + libexec.install Dir["src/*"] bin.write_exec_script libexec/"macprefs" end diff --git a/pyproject.toml b/pyproject.toml index b1c872f..20fefbc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,8 @@ package = false [tool.pytest.ini_options] addopts = "--maxfail=2 -s --tb=native -v -m 'not integration'" markers = ["integration: integration tests"] +pythonpath = ["src"] +testpaths = ["tests"] [tool.pylint.main] jobs = 1 diff --git a/app_store_preferences.py b/src/app_store_preferences.py similarity index 100% rename from app_store_preferences.py rename to src/app_store_preferences.py diff --git a/config.py b/src/config.py similarity index 100% rename from config.py rename to src/config.py diff --git a/dotfiles.py b/src/dotfiles.py similarity index 100% rename from dotfiles.py rename to src/dotfiles.py diff --git a/internet_accounts.py b/src/internet_accounts.py similarity index 100% rename from internet_accounts.py rename to src/internet_accounts.py diff --git a/macprefs b/src/macprefs similarity index 100% rename from macprefs rename to src/macprefs diff --git a/preferences.py b/src/preferences.py similarity index 100% rename from preferences.py rename to src/preferences.py diff --git a/publish.py b/src/publish.py similarity index 100% rename from publish.py rename to src/publish.py diff --git a/shared_file_lists.py b/src/shared_file_lists.py similarity index 100% rename from shared_file_lists.py rename to src/shared_file_lists.py diff --git a/ssh_files.py b/src/ssh_files.py similarity index 100% rename from ssh_files.py rename to src/ssh_files.py diff --git a/startup_items.py b/src/startup_items.py similarity index 100% rename from startup_items.py rename to src/startup_items.py diff --git a/system_preferences.py b/src/system_preferences.py similarity index 100% rename from system_preferences.py rename to src/system_preferences.py diff --git a/utils.py b/src/utils.py similarity index 100% rename from utils.py rename to src/utils.py diff --git a/version.py b/src/version.py similarity index 100% rename from version.py rename to src/version.py diff --git a/test_app_store_preferences.py b/tests/test_app_store_preferences.py similarity index 100% rename from test_app_store_preferences.py rename to tests/test_app_store_preferences.py diff --git a/test_config.py b/tests/test_config.py similarity index 100% rename from test_config.py rename to tests/test_config.py diff --git a/test_dotfiles.py b/tests/test_dotfiles.py similarity index 100% rename from test_dotfiles.py rename to tests/test_dotfiles.py diff --git a/test_internet_accounts.py b/tests/test_internet_accounts.py similarity index 100% rename from test_internet_accounts.py rename to tests/test_internet_accounts.py diff --git a/test_macprefs.py b/tests/test_macprefs.py similarity index 93% rename from test_macprefs.py rename to tests/test_macprefs.py index 52216f9..fba966f 100644 --- a/test_macprefs.py +++ b/tests/test_macprefs.py @@ -6,14 +6,14 @@ import utils # load as module -macprefs = utils.execute_module('macprefs', 'macprefs') +macprefs = utils.execute_module('macprefs', 'src/macprefs') @patch('sys.stdout', new_callable=StringIO) def test_invoke_help(mock_stdout): try: sys.argv = ['macprefs', '-h'] # invoke as script - utils.execute_module('__main__', 'macprefs') + utils.execute_module('__main__', 'src/macprefs') assert False, 'expected SystemExit' except SystemExit as e: assert_correct_std_out(e, mock_stdout) @@ -48,7 +48,7 @@ def test_invoke_no_args(mock_stdout): try: sys.argv = ['macprefs'] # invoke as script - utils.execute_module('__main__', 'macprefs') + utils.execute_module('__main__', 'src/macprefs') assert False, 'expected SystemExit' except SystemExit as e: assert_correct_std_out(e, mock_stdout) @@ -126,7 +126,7 @@ def test_intergration(): try: sys.argv = ['macprefs', 'backup'] # invoke as script - utils.execute_module('__main__', 'macprefs') + utils.execute_module('__main__', 'src/macprefs') assert False, 'expected SystemExit' except SystemExit as e: assert e.code == 0 @@ -137,7 +137,7 @@ def test_restore_intergration(): try: sys.argv = ['macprefs', 'restore'] # invoke as script - utils.execute_module('__main__', 'macprefs') + utils.execute_module('__main__', 'src/macprefs') assert False, 'expected SystemExit' except SystemExit as e: assert e.code == 0 ''' diff --git a/test_preferences.py b/tests/test_preferences.py similarity index 100% rename from test_preferences.py rename to tests/test_preferences.py diff --git a/test_publish.py b/tests/test_publish.py similarity index 99% rename from test_publish.py rename to tests/test_publish.py index 2da6de1..560d6d5 100644 --- a/test_publish.py +++ b/tests/test_publish.py @@ -12,7 +12,7 @@ def test_invoke_help(): old_argv = sys.argv sys.argv = ['publish', '-test'] # invoke as script - utils.execute_module('__main__', 'publish.py') + utils.execute_module('__main__', 'src/publish.py') sys.argv = old_argv diff --git a/test_shared_file_lists.py b/tests/test_shared_file_lists.py similarity index 100% rename from test_shared_file_lists.py rename to tests/test_shared_file_lists.py diff --git a/test_ssh_files.py b/tests/test_ssh_files.py similarity index 100% rename from test_ssh_files.py rename to tests/test_ssh_files.py diff --git a/test_startup_items.py b/tests/test_startup_items.py similarity index 100% rename from test_startup_items.py rename to tests/test_startup_items.py diff --git a/test_system_preferences.py b/tests/test_system_preferences.py similarity index 100% rename from test_system_preferences.py rename to tests/test_system_preferences.py diff --git a/test_utils.py b/tests/test_utils.py similarity index 100% rename from test_utils.py rename to tests/test_utils.py From 83748073469c016dc6d1d964570ecbd6a79168f0 Mon Sep 17 00:00:00 2001 From: Clint M Date: Thu, 16 Jul 2026 10:35:45 -0600 Subject: [PATCH 2/2] review: lint the extensionless src/macprefs entrypoint (fix its consider-using-in finding), document mise activation in README --- README.md | 1 + Ritefile.yml | 4 +++- src/macprefs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ea9fcb4..e727969 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ chmod -R o=-x ~/Dropbox - Fork and clone then cd to this git repository - Install [mise](https://mise.jdx.dev/) if you don't have it: `curl https://mise.run | sh` - Run `mise install` — installs the pinned toolchain (python, [uv](https://docs.astral.sh/uv/), and the [rite](https://github.com/clintmod/rite) task runner) +- If mise isn't [activated in your shell](https://mise.jdx.dev/getting-started.html#activate-mise), prefix the commands below with `mise exec --` (e.g. `mise exec -- rite setup`) - Run `rite setup` — creates `.venv` and installs the dev dependencies from `uv.lock` Run `rite` (no arguments) to list all available tasks. diff --git a/Ritefile.yml b/Ritefile.yml index 2e67774..afdf130 100644 --- a/Ritefile.yml +++ b/Ritefile.yml @@ -46,7 +46,9 @@ tasks: aliases: [l] deps: [setup] cmds: - - uv run pylint src/*.py tests/*.py + # src/macprefs is listed explicitly: it has no .py extension, so the + # glob misses it, but pylint lints any file passed by name. + - uv run pylint src/*.py src/macprefs tests/*.py build: desc: Build the brew package from committed HEAD, install, verify, uninstall diff --git a/src/macprefs b/src/macprefs index 029cd22..65be02e 100755 --- a/src/macprefs +++ b/src/macprefs @@ -68,7 +68,7 @@ def restore(choices=[]): def invoke_func(args): if args.func is not None: - if args.name == 'backup' or args.name == 'restore': + if args.name in ('backup', 'restore'): args.func(args.t) else: args.func()