kanon-cli 3.2.0__tar.gz → 3.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.github/actions/setup-kanon/action.yml +36 -32
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.github/workflows/main-validation.yml +28 -27
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.github/workflows/pr-validation.yml +9 -12
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.github/workflows/publish.yml +8 -9
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.gitignore +3 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.tool-versions +1 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/CHANGELOG.md +327 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/CONTRIBUTING.md +6 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/Makefile +21 -14
- kanon_cli-3.2.0/README.md → kanon_cli-3.3.2/PKG-INFO +67 -0
- kanon_cli-3.2.0/PKG-INFO → kanon_cli-3.3.2/README.md +45 -22
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/cli-reference.md +79 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/coming-from-pip-npm-cargo.md +1 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/configuration.md +73 -3
- kanon_cli-3.3.2/docs/privacy.md +90 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/testing/matrix-traceability.md +2 -2
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/git-hooks/pre-push +5 -5
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/pyproject.toml +20 -2
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/__init__.py +1 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/cli.py +75 -8
- kanon_cli-3.3.2/src/kanon_cli/commands/list.py +560 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/constants.py +182 -2
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/cli_args.py +21 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/install.py +109 -59
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/lockfile.py +99 -14
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/marketplace.py +5 -3
- kanon_cli-3.3.2/src/kanon_cli/core/telemetry.py +1109 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/update_check.py +61 -6
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/progress.py +2 -2
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/project.py +1 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/conftest.py +93 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/completion/expected-bash.sh +11 -3
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/completion/expected-powershell.ps1 +1 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/completion/expected-zsh.sh +17 -0
- kanon_cli-3.3.2/tests/fixtures/help/kanon-list.txt +35 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-toplevel.txt +3 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/conftest.py +5 -3
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_help_snapshots.py +1 -0
- kanon_cli-3.3.2/tests/functional/test_list.py +196 -0
- kanon_cli-3.3.2/tests/functional/test_list_telemetry.py +119 -0
- kanon_cli-3.3.2/tests/functional/test_telemetry_journey.py +309 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_ci_validation.py +17 -10
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_clean_lifecycle.py +12 -7
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_cli_entry_points.py +16 -13
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_completion_bash.py +12 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_full_lifecycle_synthetic.py +8 -3
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_after_add.py +5 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_marketplace_registration.py +90 -19
- kanon_cli-3.3.2/tests/integration/test_list_command_json.py +141 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_marketplace_orphan_prune.py +19 -6
- kanon_cli-3.3.2/tests/regression/test_linkfile_samefile_regression.py +233 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/conftest.py +4 -3
- kanon_cli-3.3.2/tests/scenarios/test_install_graph_capture.py +101 -0
- kanon_cli-3.3.2/tests/scenarios/test_list_journey.py +151 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_marketplace_direct_checkout.py +7 -8
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_medium_files_boost.py +31 -27
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_progress.py +35 -8
- kanon_cli-3.3.2/tests/unit/test_build_project_entries.py +156 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_ci_workflows.py +81 -38
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_cli.py +156 -6
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_constants.py +3 -3
- kanon_cli-3.3.2/tests/unit/test_constants_list.py +106 -0
- kanon_cli-3.3.2/tests/unit/test_list.py +466 -0
- kanon_cli-3.3.2/tests/unit/test_lockfile_reconcile.py +132 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_pre_push_hook.py +8 -5
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_pyproject_build_config.py +42 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_search.py +15 -25
- kanon_cli-3.3.2/tests/unit/test_telemetry.py +1087 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_update_check.py +85 -8
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/uv.lock +876 -2
- kanon_cli-3.2.0/requirements-dev.txt +0 -11
- kanon_cli-3.2.0/requirements.txt +0 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.claude/settings.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/.devcontainer.postcreate.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/VERSION +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/catalog-entry.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/devcontainer-functions.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/devcontainer.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/fix-line-endings.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/nix-family-os/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/nix-family-os/tinyproxy-daemon.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/nix-family-os/tinyproxy.conf.template +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/postcreate-wrapper.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/project-setup.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/wsl-family-os/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/wsl-family-os/tinyproxy-daemon.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.devcontainer/wsl-family-os/tinyproxy.conf.template +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.github/CODEOWNERS +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.github/workflows/codeql-analysis.yml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.markdownlint.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.pre-commit-config.yaml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/.yamllint +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/CLAUDE.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/LICENSE +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/architecture.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/catalog-author-guide.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/catalog-format-versioning.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/catalogs-explained.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/claude-marketplaces-guide.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/cli/catalog-audit.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/cli/doctor.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/cli/validate.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/cli.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/contributing.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/creating-manifest-repos.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/creating-packages.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/doctor.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/exit-codes.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/git-auth-setup.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/how-it-works.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/installation.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/integration-testing.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/lifecycle.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/list-and-add.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/lockfile.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/migrating-existing-kanon-files.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/migration-to-add.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/multi-source-guide.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/outdated-and-why.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/pipeline-integration.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/repo/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/repo/internal-fs-layout.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/repo/manifest-format.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/repo/python-support.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/repo/repo-hooks.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/repo/smart-sync.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/repo/windows.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/security-model.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/setup-guide.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/shell-completion.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/test-coverage.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/troubleshooting.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/url-canonicalization.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/docs/version-resolution.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/git-hooks/pre-commit +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/link +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/scripts/check_archive_no_duplicates.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/__main__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/add.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/clean.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/completion.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/doctor.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/marketplace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/outdated.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/remove.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/repo.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/search.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/validate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/commands/why.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/cached_catalogs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/catalog_entries.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/catalog_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/lockfile_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/midtoken.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/pep440_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/powershell.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/preamble.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/project_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/sanitize.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/completions/source_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/clean.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/discover.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/git_runner.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/include_walker.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/kanon_hash.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/kanonenv.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/kanonenv_writer.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/manifest_vars.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/marketplace_validator.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/remote_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/core/xml_validator.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/color.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/editor.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/error.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/event_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/fetch.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/git_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/git_config.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/git_refs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/git_ssh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/git_superproject.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/git_trace2_event_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/git_trace2_event_log_base.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/hooks/commit-msg +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/hooks/pre-auto-gc +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/hooks.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/main.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/manifest_xml.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/pager.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/platform_utils.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/platform_utils_win32.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/repo +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/repo_logging.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/repo_trace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/requirements.jsonc +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/ssh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/abandon.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/branches.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/checkout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/cherry_pick.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/diff.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/diffmanifests.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/download.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/envsubst.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/forall.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/gc.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/grep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/help.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/info.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/init.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/list.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/overview.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/prune.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/rebase.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/selfupdate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/smartsync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/stage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/start.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/status.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/sync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/subcmds/upload.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/version_constraints.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/repo/wrapper.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/utils/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/utils/concurrency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/utils/levenshtein.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/utils/lock_file_path.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/utils/spawn.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/src/kanon_cli/version.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/duplicate-child-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/missing-recommended-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/missing-required-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/multiple-blocks-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/dotted-name-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/hyphenated-name-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/uppercase-name-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-a-1-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-a-2-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-b-1-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-b-2-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/file-url-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/query-string-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/unresolvable-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/legacy-catalog-dir/catalog/sample-entry/.kanon +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalog/legacy-catalog-dir/repo-specs/sample.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalogs/zero-pep440-tags/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/catalogs/zero-pep440-tags/repo-specs/entry-a/entry-a-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/completion/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/errors/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/errors/conflict-detected.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/errors/entry-not-found.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/errors/lockfile-hash-mismatch.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/errors/lockfile-sha-unreachable.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/errors/missing-catalog-source.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/errors/missing-required-metadata-field.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/errors/source-collision.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/errors/zero-pep440-tags-under-prefix.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-add.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-catalog-audit.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-catalog.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-clean.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-completion.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-doctor.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-install.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-marketplace.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-outdated.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-remove.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-search.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/help/kanon-why.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/repo/.gitignore +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/repo/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/repo/linter-test-bad.invalid-yaml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/repo/linter-test-bad.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/repo/linter-test-bad.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/repo/sample-manifest.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/repo/sample-project-config.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/repo/test.gitconfig +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/fixtures/repo/version_constraints_data.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_add_alias_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_alias_consumer_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_argparse_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_argparse_help.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_ci_runs_operator_path_tests.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_clean_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_cli_entry_point.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_completion_snapshots.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_default_branch_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_env_int_guard_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_error_snapshots.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_exit_code_matrix.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_groups_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_help_text_contract.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_home_flag_unwritable_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_init_default_branch_prerequisite_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_install_hermetic_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_install_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_install_real_kanon.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_install_v3_lock_fail_fast_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_kanon_home_store_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_kanon_repo_cli.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_kanon_repo_e2e.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_kanon_repo_lifecycle_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_lifecycle_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_make_operator_path_targets.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_marketplace_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_matrix_traceability_complete.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_provider_agnostic.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_abandon_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_abandon_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_abandon_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_branches_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_branches_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_branches_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_checkout_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_checkout_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_checkout_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_cherry_pick_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_cherry_pick_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_cherry_pick_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_diff_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_diff_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_diff_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_diffmanifests_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_diffmanifests_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_diffmanifests_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_dir_override.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_download_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_download_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_download_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_envsubst_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_envsubst_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_envsubst_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_exit_codes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_forall_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_forall_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_forall_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_gc_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_gc_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_gc_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_grep_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_grep_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_grep_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_help_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_help_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_help_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_info_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_info_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_info_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_init_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_init_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_init_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_init_mirror.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_list_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_list_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_list_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_manifest_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_manifest_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_manifest_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_manifest_revision_as_tag.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_overview_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_overview_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_overview_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_passthrough.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_prune_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_prune_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_prune_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_rebase_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_rebase_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_rebase_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_selfupdate_disabled.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_selfupdate_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_selfupdate_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_selfupdate_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_smartsync_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_smartsync_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_smartsync_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_stage_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_stage_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_stage_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_start_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_start_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_start_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_status_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_status_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_status_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_sync_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_sync_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_sync_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_upload_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_upload_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_repo_upload_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_singular_catalog_source_inert.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_stdout_stderr_discipline.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_update_alert_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_validate_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_validate_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_validate_lockfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_validate_marketplace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_validate_xml_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_validate_xml_repo_root.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/functional/test_zero_source_clean_error.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/fixtures/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/fixtures/synthetic/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/fixtures/synthetic/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/fixtures/synthetic/drift.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/fixtures/synthetic/test_synthetic_pytest_fixtures.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/fixtures/synthetic/upgrade_versioned.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/provider_allowlist.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_bug_fixes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_consolidated_constraints_e2e.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_envsubst_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_import_functional.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_linkfile_copyfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_linkfile_exclude_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_manifest_parsing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_process_isolation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_repo_module_smoke.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_repo_pipeline.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_repo_run_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_repo_sync_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_version_constraints_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_annotation_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_contactinfo_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_copyfile_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_default_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_extend_project_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_include_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_linkfile_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_manifest_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_manifest_server_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_notice_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_project_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_remote_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_remove_project_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_repo_hooks_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_submanifest_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/repo/test_xml_superproject_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_add_core.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_add_dry_run.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_add_env_var_detection.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_add_zero_tags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_auto_discovery.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_background_refresh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_cache_clock_skew.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_cache_layout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_catalog_audit_entry_uniqueness.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_catalog_audit_framework.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_catalog_audit_legacy_dir.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_catalog_audit_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_catalog_audit_remote_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_catalog_audit_source_name.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_catalog_audit_strict.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_catalog_audit_tag_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_catalog_constraints.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_clean_env_override_cleanup.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_clean_paths.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_complete_cached_catalogs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_complete_catalog_entries.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_complete_catalog_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_complete_lockfile_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_complete_project_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_complete_source_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_completion_powershell_subcommand.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_completion_subcommand.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_completion_zsh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_concurrency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_concurrency_serialization.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_copyfile_fs_effects.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_cross_platform_contract.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_doc_validation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_doctor_cache_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_doctor_cache_flags_workspace_independent.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_doctor_consistency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_doctor_default_subcheck_output.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_doctor_effective_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_doctor_prune_cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_doctor_remote_check.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_envsubst_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_fs_fault_extended.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_fs_fault_injection.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_full_user_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_git_fault_injection.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_git_retry_env.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_gitignore_idempotency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_home_flag_store_relocation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_env_var_resolution.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_include_cycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_include_diamond.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_lock_file_derivation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_lockfile_replay.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_no_kanon_remediation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_optional_vars.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_path_conflict_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_paths.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_per_alias_gitbase.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_reconcile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_refresh_lock.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_refresh_lock_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_remote_url_policy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_required_vars.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_install_strict.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_json_output_stream_discipline.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_kanon_add_placeholder_handling.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_kanon_clean_embedded.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_kanon_dir_collision.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_kanon_full_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_kanon_install_embedded.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_kanonenv_parsing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_lifecycle_recovery.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_linkfile_fs_effects.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_list_all_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_list_all_versions_canonical.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_list_all_versions_malformed_revision_resilience.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_list_default.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_list_detail.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_list_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_list_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_list_synthetic_catalog_variants.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_list_tree.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_lockfile_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_marketplace_install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_marketplace_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_midtoken_bash.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_midtoken_zsh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_misc_features.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_multi_source_aggregation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_no_bundled_catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_no_default_catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_no_hardcoded_org_values.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_observability.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_outdated.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_outdated_branch_drift.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_outdated_fail_on_upgrade.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_outdated_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_outdated_refs_tags_revision_parsing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_platform_parity.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_preamble_bash.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_preamble_zsh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_remove_core.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_remove_dry_run.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_remove_force_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_signal_handling.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_synthetic_drift_fixture.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_synthetic_upgrade_versioned_fixture.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_unicode_encoding.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_validate_marketplace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_validate_marketplace_revision_existence.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_validate_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_validate_xml.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_version_resolution.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_version_widened_bare_pep440.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_wheel_e2e.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_why_ambiguous.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_why_chain_walker.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_why_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_why_live_resolve.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_why_not_found_suggestion.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/integration/test_workspace_dir_env.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f1_s2_t5_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f5_s2_t7_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s1_t1_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s1_t2_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s1_t3_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s1_t4_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s2_t1_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s2_t2_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s2_t3_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s2_t4_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s2_t5_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s2_t6_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s3_t1_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_f6_s3_t2_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/regression/test_e0_install_relative_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/_rp_helpers.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_ad.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_bs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_cd.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_content_pins.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_cs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_doctor_cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_doctor_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_ec.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_ep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_ev.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_hv.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_ic.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_id.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_ks.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_lf.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_lockfile_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_mk.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_ms.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_ns_marketplace_and_global_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_outdated_two_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_pk.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rc.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_refresh_lock_existing_checkout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rls_exact_vs_range.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_abandon.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_branches.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_checkout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_cherry_pick.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_diff.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_diffmanifests.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_download.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_envsubst.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_forall.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_gc.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_grep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_help.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_info.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_init.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_list.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_overview.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_prune.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_rebase.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_smartsync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_stage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_start.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_status.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_sync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_upload.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rp_wrap.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_rx.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_scenario_coverage_meta.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_search_multi_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_tc_bootstrap.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_tc_clean.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_tc_install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_tc_validate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_uj.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_va.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_va_validate_lockfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_why_surface_query.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_why_url_path.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/scenarios/test_why_url_path_placeholder.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/security/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/security/test_security_hardening.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/test_wheel_layout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/commands/test_repo_dir_resolution.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/fixtures/.gitignore +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/fixtures/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/fixtures/sample-manifest.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/fixtures/sample-project-config.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/fixtures/test.gitconfig +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/fixtures/version_constraints_data.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/functional/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/functional/test_features.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/subcmds/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/subcmds/test_init_mirror.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/subcmds/test_manifest_revision_as_tag.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/subcmds/test_manifest_revision_as_tag_pep440.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/subcmds/test_selfupdate_stub.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_abandon_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_branches_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug10_selfupdate_incompatible.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug11_race_condition.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug12_backup_preserved.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug13_init_reinit_warning.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug14_non_tty_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug15_prerelease_docs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug16_nested_var_warning.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug18_envsubst_double_parse.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug19_glob_src_error.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug1_envsubst_malformed_xml.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug20_glob_dest_file.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug2_linkfile_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug3_execv_replaces_process.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug4_symlink_overwrite.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug5_empty_envsubst_list.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug6_undefined_env_vars.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug7_git_ls_remote_retry.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug8_ls_remote_stderr.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_bug9_constraint_resolution_cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_checklocalpath_rules_1_5.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_checklocalpath_rules_6_11.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_checkout_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_cherrypick_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_color.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_conftest_fixtures.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_diffmanifests_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_doc_validate_git_preconditions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_download_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_editor.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_embedded_mode.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_envsubst_basic.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_envsubst_edge.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_envsubst_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_error.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_event_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_event_log_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_fetch.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_fixture_files.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_forall_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_git_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_git_config.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_git_refs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_git_superproject.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_git_trace2_event_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_gitconfig_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_grep_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_harness_smoke.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_hooks.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_import_verification.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_imports.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_include_path_resolution.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_info_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_init_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_list_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_main.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_main_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_main_init_download_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_makefile_lint_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_makefile_structure.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_makefile_test_targets.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_manifest_coverage_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_manifest_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_manifest_doc_rp_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_manifest_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_manifest_subcmd_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_manifest_xml.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_manifest_xml_pep440.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_mkdtemp_cleanup.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_overview_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_package_structure.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_pager.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_parselist.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_pep440_edge_1.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_pep440_edge_2.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_pep440_ops_ge.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_pep440_ops_rest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_platform_utils.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_process_isolation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_coverage_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_coverage_threshold.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_deep_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_final_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_metaproject_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_methods.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_project_sync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_prune_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_rebase_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_remaining_coverage_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_repo_envsubst_api.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_repo_logging.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_repo_run_api.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_repo_sync_api.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_repo_trace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_revision_inheritance.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_revision_tag_branch_sha.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_ruff_config.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_selfupdate_embedded.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_selfupdate_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_small_files_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_ssh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_ssh_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_stage_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_stage_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_start_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_status_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_status_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_status_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmd_imports.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_abandon.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_branches.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_checkout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_cherry_pick.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_diff.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_diffmanifests.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_download.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_envsubst.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_forall.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_gc.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_grep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_help.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_info.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_init.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_list.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_overview.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_prune.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_rebase.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_selfupdate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_smartsync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_stage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_start.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_status.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_sync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_subcmds_upload.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_superproject_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_sync_coverage_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_sync_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_sync_deep_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_sync_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_upload_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_version_consolidation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_version_constraints.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_wheel_contents.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_wrapper.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_annotation_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_annotation_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_annotation_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_contactinfo_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_contactinfo_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_contactinfo_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_copyfile_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_copyfile_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_copyfile_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_default_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_default_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_default_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_extend_project_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_extend_project_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_extend_project_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_fault_malformed.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_fault_structural.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_include_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_include_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_include_cycles.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_include_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_linkfile_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_linkfile_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_linkfile_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_manifest_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_manifest_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_manifest_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_manifest_server_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_manifest_server_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_manifest_server_flow.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_manifest_server_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_notice_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_notice_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_notice_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_project_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_project_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_project_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_remote_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_remote_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_remote_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_remove_project_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_remove_project_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_remove_project_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_repo_hooks_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_repo_hooks_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_repo_hooks_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_submanifest_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_submanifest_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_submanifest_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_superproject_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_superproject_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_superproject_flow.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xml_superproject_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xmlbool.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_xmlint.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/repo/test_yamllint_config.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_accessed_at_coalescing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_add.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_add_collision.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_add_zero_tags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_background_refresh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_bare_semver_to_tag.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_cache_layout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_cache_ttl.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_cached_catalogs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_check_parser.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_entry_uniqueness.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_framework.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_legacy_dir.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_project_tag_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_remote_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_source_name.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_strict.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_audit_tag_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_catalog_source_parsing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_check_no_comments.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_clean.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_clean_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_cli_args.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_cli_help_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_cli_json_stream_discipline.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_complete_cached_catalogs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_complete_catalog_entries.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_complete_catalog_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_complete_lockfile_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_complete_project_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_complete_source_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_completion.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_completion_sanitization.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_completion_subcommand.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_concurrency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_conftest_scrubber.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_constants_doctor_subcheck.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_constants_env_int.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_constants_install_after_add.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_constants_outdated_refs_tags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_constants_why_lockfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_coverage_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_derive_source_name.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_discover.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_discover_source_names_missing_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_docs_embedded_architecture.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_docs_remaining_and_catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_doctor.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_doctor_cache_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_doctor_completion_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_doctor_completion_staleness.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_doctor_consistency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_doctor_coverage_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_doctor_effective_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_doctor_remote_reachability.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_env_isolation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_envsubst_subcommand.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_git_runner.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_home_flag.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_include_walker.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_color_default.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_conflict_detection.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_https_enforcement.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_placeholder_validation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_reconcile_decision.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_refresh_lock.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_refresh_lock_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_state_matrix.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_strict_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_install_strict_lock_orphan_naming.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_integration_testing_doc_manifest_paths.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_integration_testing_doc_s2_t14.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_integration_testing_doc_s2_t4.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_integration_testing_doc_s2_t5.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_integration_testing_doc_s2_t6.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_integration_testing_doc_s2_t7.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_integration_testing_doc_s2_tier1.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_isolation_fixtures.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_kanon_hash.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_kanonenv.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_kanonenv_advanced_edge_cases.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_kanonenv_edge_cases.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_kanonenv_writer.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_levenshtein.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_lock_file_path.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_lockfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_lockfile_coverage_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_lockfile_schema_migration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_marketplace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_marketplace_cmd.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_marketplace_install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_marketplace_non_plugin_skip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_marketplace_validator.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_midtoken_splitter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_outdated.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_outdated_branch_pinned.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_outdated_fail_on_upgrade.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_outdated_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_pep440_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_powershell.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_preamble.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_preamble_semver_tags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_provider_agnosticism.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_remote_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_remove.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_remove_dry_run.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_remove_force.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_remove_line_endings.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_repo.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_repo_abspath.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_repo_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_resolve_catalog_dir.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_revision_resolve.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_rx_catalog_sub_repo.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_sanitize.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_search_all_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_search_coverage_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_search_detail.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_search_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_search_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_search_tree.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_spawn.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_validate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_validate_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_validate_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_version.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_version_constraint_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_why.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_why_ambiguity.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_why_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_why_suggestions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tests/unit/test_xml_validator.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tools/lint/check_no_comments.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.2}/tools/test_tmp_monitor.py +0 -0
|
@@ -3,11 +3,17 @@ description: |
|
|
|
3
3
|
Composite action shared by every job in pr-validation.yml and
|
|
4
4
|
main-validation.yml. Handles checkout, optional simulate-merge,
|
|
5
5
|
Python install, asdf bootstrap (plus plugin install per
|
|
6
|
-
.tool-versions),
|
|
7
|
-
|
|
8
|
-
action once before invoking its own
|
|
9
|
-
|
|
10
|
-
drift between jobs is impossible.
|
|
6
|
+
.tool-versions), uv install with an uv.lock-keyed cache, and the
|
|
7
|
+
dependency install itself (`uv sync --locked --all-groups`). Each
|
|
8
|
+
parallel CI job calls this action once before invoking its own
|
|
9
|
+
singular Make target, so the per-job step list stays minimal and
|
|
10
|
+
setup drift between jobs is impossible.
|
|
11
|
+
|
|
12
|
+
Every job resolves dependencies from uv.lock and nowhere else. Jobs
|
|
13
|
+
must invoke Make targets rather than calling pytest/ruff/bandit
|
|
14
|
+
directly, because those targets run tools through `uv run`; a bare
|
|
15
|
+
invocation picks up whatever is on PATH and reintroduces the drift
|
|
16
|
+
this action exists to prevent.
|
|
11
17
|
|
|
12
18
|
inputs:
|
|
13
19
|
base-ref:
|
|
@@ -108,15 +114,20 @@ runs:
|
|
|
108
114
|
asdf install
|
|
109
115
|
asdf reshim
|
|
110
116
|
|
|
111
|
-
- name:
|
|
112
|
-
|
|
117
|
+
- name: Install uv
|
|
118
|
+
# uv must be installed BEFORE the dependency step, because that step is
|
|
119
|
+
# now `uv sync`. It is also required at test time:
|
|
120
|
+
# `tests/unit/repo/test_wheel_contents.py`,
|
|
121
|
+
# `tests/integration/test_wheel_e2e.py`, and
|
|
122
|
+
# `tests/integration/test_ci_validation.py` shell out to `uv build` to
|
|
123
|
+
# produce the wheel under test.
|
|
124
|
+
# `enable-cache` replaces the previous actions/cache pip step; keying on
|
|
125
|
+
# uv.lock means the cache is invalidated by exactly the file that decides
|
|
126
|
+
# which versions get installed.
|
|
127
|
+
uses: astral-sh/setup-uv@v6
|
|
113
128
|
with:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
~/.local/lib/python*/site-packages
|
|
117
|
-
key: ${{ runner.os }}-pip-${{ hashFiles('requirements-dev.txt', 'pyproject.toml') }}
|
|
118
|
-
restore-keys: |
|
|
119
|
-
${{ runner.os }}-pip-
|
|
129
|
+
enable-cache: true
|
|
130
|
+
cache-dependency-glob: uv.lock
|
|
120
131
|
|
|
121
132
|
- name: Install zsh (for shell-completion integration tests)
|
|
122
133
|
if: runner.os == 'Linux'
|
|
@@ -140,22 +151,15 @@ runs:
|
|
|
140
151
|
shell: bash
|
|
141
152
|
run: |
|
|
142
153
|
set -euo pipefail
|
|
143
|
-
|
|
144
|
-
# `
|
|
145
|
-
#
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
# `tests/unit/repo/test_wheel_contents.py`,
|
|
156
|
-
# `tests/integration/test_wheel_e2e.py`, and
|
|
157
|
-
# `tests/integration/test_ci_validation.py` shell out to
|
|
158
|
-
# `uv build` to produce the wheel under test; uv must be on
|
|
159
|
-
# PATH for any job that runs those suites (including the
|
|
160
|
-
# full-suite regression job that runs every test together).
|
|
161
|
-
uses: astral-sh/setup-uv@v6
|
|
154
|
+
# Single dependency-resolution path for every job. Previously this was
|
|
155
|
+
# `pip install -r requirements-dev.txt`, which resolved from PyPI at run
|
|
156
|
+
# time and ignored uv.lock, while `make test` / `make test-scenarios`
|
|
157
|
+
# ran under `uv run` and honoured it. The two disagreed -- the pip leg
|
|
158
|
+
# installed pytest 8.3 and an unbounded shtab, so a shtab release broke
|
|
159
|
+
# the completion golden fixtures in the pip-based jobs only.
|
|
160
|
+
#
|
|
161
|
+
# `--locked` fails the job if uv.lock is stale rather than silently
|
|
162
|
+
# re-resolving, so a dependency change cannot reach CI unlocked.
|
|
163
|
+
# `uv sync` needs no GNU make, so the Windows leg no longer needs a
|
|
164
|
+
# separate branch.
|
|
165
|
+
uv sync --locked --all-groups
|
|
@@ -103,17 +103,14 @@ jobs:
|
|
|
103
103
|
with:
|
|
104
104
|
fetch-depth: 0
|
|
105
105
|
- uses: ./.github/actions/setup-kanon
|
|
106
|
-
- name: Run unit tests with
|
|
106
|
+
- name: Run unit tests with coverage gate
|
|
107
107
|
shell: bash
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
echo "Error: Code coverage is below 90% threshold ($coverage_percent%)"
|
|
115
|
-
exit 1
|
|
116
|
-
fi
|
|
108
|
+
# Delegates to the Make target so the threshold lives in one place
|
|
109
|
+
# (Makefile: COVERAGE_MIN) instead of being duplicated across both
|
|
110
|
+
# workflow files, and so the run resolves from uv.lock like every other
|
|
111
|
+
# job. pytest-cov's own --cov-fail-under replaces the hand-rolled
|
|
112
|
+
# coverage-json + bc comparison.
|
|
113
|
+
run: make test-unit-cov
|
|
117
114
|
|
|
118
115
|
integration-tests-linux:
|
|
119
116
|
name: Integration tests (Linux)
|
|
@@ -127,7 +124,7 @@ jobs:
|
|
|
127
124
|
- uses: ./.github/actions/setup-kanon
|
|
128
125
|
- name: Run integration tests
|
|
129
126
|
shell: bash
|
|
130
|
-
run:
|
|
127
|
+
run: make test-integration
|
|
131
128
|
|
|
132
129
|
functional-tests-linux:
|
|
133
130
|
name: Functional tests (Linux)
|
|
@@ -141,7 +138,7 @@ jobs:
|
|
|
141
138
|
- uses: ./.github/actions/setup-kanon
|
|
142
139
|
- name: Run functional tests
|
|
143
140
|
shell: bash
|
|
144
|
-
run:
|
|
141
|
+
run: make test-functional
|
|
145
142
|
|
|
146
143
|
scenario-tests-linux:
|
|
147
144
|
name: Scenario tests (Linux, docs/integration-testing.md)
|
|
@@ -276,22 +273,19 @@ jobs:
|
|
|
276
273
|
asdf install
|
|
277
274
|
asdf reshim
|
|
278
275
|
|
|
279
|
-
- name:
|
|
280
|
-
|
|
276
|
+
- name: Install uv
|
|
277
|
+
# Same single resolution path as .github/actions/setup-kanon: deps come
|
|
278
|
+
# from uv.lock via `make install-dev` (`uv sync --locked`). Replaces the
|
|
279
|
+
# previous pip cache, which keyed on a requirements-dev.txt that no
|
|
280
|
+
# longer exists.
|
|
281
|
+
uses: astral-sh/setup-uv@v6
|
|
281
282
|
with:
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
~/.local/lib/python*/site-packages
|
|
285
|
-
key: ${{ runner.os }}-pip-release-${{ hashFiles('requirements-dev.txt', 'pyproject.toml') }}
|
|
286
|
-
restore-keys: |
|
|
287
|
-
${{ runner.os }}-pip-release-
|
|
288
|
-
${{ runner.os }}-pip-
|
|
283
|
+
enable-cache: true
|
|
284
|
+
cache-dependency-glob: uv.lock
|
|
289
285
|
|
|
290
286
|
- name: Install dependencies
|
|
291
287
|
shell: bash
|
|
292
|
-
run:
|
|
293
|
-
pip install --upgrade pip
|
|
294
|
-
make install-dev
|
|
288
|
+
run: make install-dev
|
|
295
289
|
|
|
296
290
|
- name: Compute next version
|
|
297
291
|
id: semantic-release
|
|
@@ -299,7 +293,7 @@ jobs:
|
|
|
299
293
|
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
|
300
294
|
shell: bash
|
|
301
295
|
run: |
|
|
302
|
-
NEW_VERSION=$(python -m semantic_release version --print | sed 's/^v//')
|
|
296
|
+
NEW_VERSION=$(uv run python -m semantic_release version --print | sed 's/^v//')
|
|
303
297
|
echo "New version: $NEW_VERSION"
|
|
304
298
|
if [[ -z "$NEW_VERSION" ]]; then
|
|
305
299
|
echo "No new version detected, using current version"
|
|
@@ -313,7 +307,7 @@ jobs:
|
|
|
313
307
|
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
|
314
308
|
shell: bash
|
|
315
309
|
run: |
|
|
316
|
-
python -m semantic_release version --no-push --no-vcs-release --no-commit
|
|
310
|
+
uv run python -m semantic_release version --no-push --no-vcs-release --no-commit
|
|
317
311
|
|
|
318
312
|
NEW_VERSION=$(grep '^version = ' pyproject.toml | sed 's/.*version = "\([^"]*\)".*/\1/')
|
|
319
313
|
echo "Updated version: $NEW_VERSION"
|
|
@@ -321,6 +315,13 @@ jobs:
|
|
|
321
315
|
sed -i "s/__version__ = \"[^\"]*\"/__version__ = \"$NEW_VERSION\"/" src/kanon_cli/__init__.py
|
|
322
316
|
echo "Updated __init__.py to version: $NEW_VERSION"
|
|
323
317
|
|
|
318
|
+
# uv.lock records the project's own version, so a bump leaves it stale.
|
|
319
|
+
# Every job installs with `uv sync --locked`, which refuses a stale lock,
|
|
320
|
+
# so the refresh has to land in the same commit as the version bump --
|
|
321
|
+
# otherwise the tag build fails in "Build and publish to PyPI".
|
|
322
|
+
uv lock
|
|
323
|
+
echo "Refreshed uv.lock to version: $NEW_VERSION"
|
|
324
|
+
|
|
324
325
|
sed -i 's/[[:space:]]*$//' CHANGELOG.md pyproject.toml src/kanon_cli/__init__.py
|
|
325
326
|
|
|
326
327
|
rm -rf dist/ build/ src/kanon_cli.egg-info/
|
|
@@ -346,7 +347,7 @@ jobs:
|
|
|
346
347
|
echo "Git status before staging:"
|
|
347
348
|
git status --porcelain
|
|
348
349
|
|
|
349
|
-
git add CHANGELOG.md pyproject.toml src/kanon_cli/__init__.py
|
|
350
|
+
git add CHANGELOG.md pyproject.toml src/kanon_cli/__init__.py uv.lock
|
|
350
351
|
|
|
351
352
|
echo "Git status after staging:"
|
|
352
353
|
STAGED=$(git status --porcelain)
|
|
@@ -130,17 +130,14 @@ jobs:
|
|
|
130
130
|
with:
|
|
131
131
|
base-ref: ${{ github.base_ref }}
|
|
132
132
|
head-sha: ${{ github.event.pull_request.head.sha }}
|
|
133
|
-
- name: Run unit tests with
|
|
133
|
+
- name: Run unit tests with coverage gate
|
|
134
134
|
shell: bash
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
echo "Error: Code coverage is below 90% threshold ($coverage_percent%)"
|
|
142
|
-
exit 1
|
|
143
|
-
fi
|
|
135
|
+
# Delegates to the Make target so the threshold lives in one place
|
|
136
|
+
# (Makefile: COVERAGE_MIN) instead of being duplicated across both
|
|
137
|
+
# workflow files, and so the run resolves from uv.lock like every other
|
|
138
|
+
# job. pytest-cov's own --cov-fail-under replaces the hand-rolled
|
|
139
|
+
# coverage-json + bc comparison.
|
|
140
|
+
run: make test-unit-cov
|
|
144
141
|
|
|
145
142
|
integration-tests-linux:
|
|
146
143
|
name: Integration tests (Linux)
|
|
@@ -157,7 +154,7 @@ jobs:
|
|
|
157
154
|
head-sha: ${{ github.event.pull_request.head.sha }}
|
|
158
155
|
- name: Run integration tests
|
|
159
156
|
shell: bash
|
|
160
|
-
run:
|
|
157
|
+
run: make test-integration
|
|
161
158
|
|
|
162
159
|
functional-tests-linux:
|
|
163
160
|
name: Functional tests (Linux)
|
|
@@ -174,7 +171,7 @@ jobs:
|
|
|
174
171
|
head-sha: ${{ github.event.pull_request.head.sha }}
|
|
175
172
|
- name: Run functional tests
|
|
176
173
|
shell: bash
|
|
177
|
-
run:
|
|
174
|
+
run: make test-functional
|
|
178
175
|
|
|
179
176
|
scenario-tests-linux:
|
|
180
177
|
name: Scenario tests (Linux, docs/integration-testing.md)
|
|
@@ -84,19 +84,18 @@ jobs:
|
|
|
84
84
|
with:
|
|
85
85
|
python-version: '3.14'
|
|
86
86
|
|
|
87
|
-
- name:
|
|
88
|
-
|
|
87
|
+
- name: Install uv
|
|
88
|
+
# Same single resolution path as .github/actions/setup-kanon: deps come
|
|
89
|
+
# from uv.lock via `make install-dev` (`uv sync --locked`). Replaces the
|
|
90
|
+
# previous pip cache, which keyed on a requirements-dev.txt that no
|
|
91
|
+
# longer exists.
|
|
92
|
+
uses: astral-sh/setup-uv@v6
|
|
89
93
|
with:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
~/.local/lib/python*/site-packages
|
|
93
|
-
key: ${{ runner.os }}-pip-${{ hashFiles('requirements-dev.txt', 'pyproject.toml') }}
|
|
94
|
-
restore-keys: |
|
|
95
|
-
${{ runner.os }}-pip-
|
|
94
|
+
enable-cache: true
|
|
95
|
+
cache-dependency-glob: uv.lock
|
|
96
96
|
|
|
97
97
|
- name: Install build dependencies
|
|
98
98
|
run: |
|
|
99
|
-
pip install --upgrade pip
|
|
100
99
|
make install-dev
|
|
101
100
|
asdf reshim
|
|
102
101
|
shell: bash
|
|
@@ -2,8 +2,329 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
## v3.3.2 (2026-08-05)
|
|
6
|
+
|
|
7
|
+
### Fix
|
|
8
|
+
|
|
9
|
+
* fix(ci): refresh uv.lock during the release version bump (#107)
|
|
10
|
+
|
|
11
|
+
`Build and publish to PyPI` failed on the 3.3.1 tag:
|
|
12
|
+
|
|
13
|
+
uv sync --locked --all-groups
|
|
14
|
+
error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided.
|
|
15
|
+
|
|
16
|
+
uv.lock records the project's own version alongside its dependencies.
|
|
17
|
+
semantic-release bumps `pyproject.toml` and `src/kanon_cli/__init__.py`
|
|
18
|
+
via version_toml / version_variable, but knows nothing about uv.lock, and
|
|
19
|
+
the release job staged only those two files plus CHANGELOG.md. Every
|
|
20
|
+
release therefore left uv.lock one version behind: after 3.3.1,
|
|
21
|
+
pyproject.toml said 3.3.1 and uv.lock still said 3.3.0.
|
|
22
|
+
|
|
23
|
+
The drift is not new -- before #97, uv.lock said 2.1.0 against a
|
|
24
|
+
pyproject at 3.3.0, six releases of silent skew. What is new is that
|
|
25
|
+
`make install-dev` is now `uv sync --locked`, which refuses a stale lock
|
|
26
|
+
instead of quietly re-resolving, so a latent inconsistency became a hard
|
|
27
|
+
failure at tag-build time.
|
|
28
|
+
|
|
29
|
+
The release job now runs `uv lock` immediately after the version bump and
|
|
30
|
+
stages uv.lock with the other version files, so the release commit is
|
|
31
|
+
self-consistent and the tag it points at can be installed. Verified that
|
|
32
|
+
`uv lock` against the current tree changes exactly one line
|
|
33
|
+
(kanon-cli 3.3.0 -> 3.3.1) with no dependency churn, so this does not turn
|
|
34
|
+
a release into an unrelated dependency update.
|
|
35
|
+
|
|
36
|
+
uv.lock is also corrected here so main is self-consistent again.
|
|
37
|
+
|
|
38
|
+
Adds `test_uv_lock_records_the_declared_project_version`, which compares
|
|
39
|
+
the kanon-cli entry in uv.lock against `[project] version`. Verified RED
|
|
40
|
+
against the stale lock, failing with the same mismatch the publish job
|
|
41
|
+
hit. It has to be run without `uv run` to fail, which is the reason this
|
|
42
|
+
class of drift stays invisible in local development: `uv run` implicitly
|
|
43
|
+
re-locks before executing, so a developer never sees the inconsistency
|
|
44
|
+
that a `--locked` install in CI rejects.
|
|
45
|
+
|
|
46
|
+
Note the existing 3.3.1 tag still points at a commit carrying the stale
|
|
47
|
+
lock, so republishing that exact tag will keep failing until the tag is
|
|
48
|
+
moved or a further release is cut. ([`00714e6`](https://github.com/caylent-solutions/kanon/commit/00714e648a42bea706945e7a38a66fa6dca8df28))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## v3.3.1 (2026-08-04)
|
|
52
|
+
|
|
53
|
+
### Chore
|
|
54
|
+
|
|
55
|
+
* chore(release): 3.3.1 ([`71621d5`](https://github.com/caylent-solutions/kanon/commit/71621d50a72c412cae40b1886f6c73adc08e9fc0))
|
|
56
|
+
|
|
57
|
+
* chore(git): ignore local settings files ([`61ceade`](https://github.com/caylent-solutions/kanon/commit/61ceade79f79a73b11316866572a71b3abce3052))
|
|
58
|
+
|
|
59
|
+
* chore: add uv to toolchain via asdf
|
|
60
|
+
|
|
61
|
+
Pin uv 0.12.1 in .tool-versions alongside the project's existing
|
|
62
|
+
asdf-managed tools, and refresh uv.lock's kanon-cli editable entry
|
|
63
|
+
to match the current pyproject.toml version. ([`300b979`](https://github.com/caylent-solutions/kanon/commit/300b979ae0dae98f200efd21be99fad0b5106658))
|
|
64
|
+
|
|
65
|
+
### Fix
|
|
66
|
+
|
|
67
|
+
* fix: let repo sync own <linkfile>, removing the duplicate copy pass (#105)
|
|
68
|
+
|
|
69
|
+
* fix: skip linkfile copy when dest already resolves to src
|
|
70
|
+
|
|
71
|
+
repo sync materializes every <linkfile> as a symlink before
|
|
72
|
+
_process_manifest_linkfiles runs. For a file-level src the helper then
|
|
73
|
+
called shutil.copy2 on the same inode pair, raising SameFileError and
|
|
74
|
+
aborting the install with exit 1.
|
|
75
|
+
|
|
76
|
+
Closes #93
|
|
77
|
+
|
|
78
|
+
* fix: let repo sync own <linkfile>, removing the duplicate copy pass
|
|
79
|
+
|
|
80
|
+
`_process_manifest_linkfiles` re-processed the same `<linkfile>` elements
|
|
81
|
+
`repo sync` had just materialized. It read only the root manifest's direct
|
|
82
|
+
`<project>` children (no `<include>` traversal) and skipped any non-file
|
|
83
|
+
`src`, so in a real install it covered a strict subset of what sync had
|
|
84
|
+
already done. Its three possible outcomes were: crash on the same inode
|
|
85
|
+
(issue 93), write through a foreign symlink and clobber that link's target,
|
|
86
|
+
or nothing. It had no branch that produced a correct result sync had not
|
|
87
|
+
already produced.
|
|
88
|
+
|
|
89
|
+
It existed to compensate for tests that replace `repo_sync` with a no-op,
|
|
90
|
+
which its own docstring stated. The compensation belongs in the double, not
|
|
91
|
+
in production, so it moves to `tests.conftest.materialize_linkfiles_for_sync`
|
|
92
|
+
-- delegating to the production `_LinkFile` so the double cannot drift from
|
|
93
|
+
what `repo` does. Mocked-sync tests now leave a symlink where a real sync
|
|
94
|
+
leaves one, instead of a copy.
|
|
95
|
+
|
|
96
|
+
Runtime behaviour is unchanged for every input except the crash: with
|
|
97
|
+
`repo sync` succeeding, the deleted pass was already a no-op. No exported
|
|
98
|
+
symbol is removed; `__all__` is byte-identical.
|
|
99
|
+
|
|
100
|
+
Replaces the unit-level regression test, which imported the deleted
|
|
101
|
+
function, with one that drives a real `repo init` + `repo sync` against
|
|
102
|
+
local file:// fixtures. Verified RED against the pre-fix code: it reproduces
|
|
103
|
+
`shutil.SameFileError` on the flagged/file-src case only, matching the scope
|
|
104
|
+
table in issue 93.
|
|
105
|
+
|
|
106
|
+
`test_only_flagged_source_registers_marketplace` asserted that an unflagged
|
|
107
|
+
source cannot register a marketplace. Under a sync that behaves like the real
|
|
108
|
+
one it registers anyway: `run_repo_sync` is unconditional, `_LinkFile._Link`
|
|
109
|
+
knows nothing about kanon flags, `CLAUDE_MARKETPLACES_DIR` is exported to
|
|
110
|
+
every source, and `install_marketplace_plugins` scans the directory once with
|
|
111
|
+
no per-source attribution. The flag genuinely gates only
|
|
112
|
+
`register_direct_checkout_marketplaces`, so the fixture now uses
|
|
113
|
+
direct-checkout entries and the docstring records what the flag does not gate.
|
|
114
|
+
|
|
115
|
+
Closes #93
|
|
116
|
+
|
|
117
|
+
* ci: resolve every job from uv.lock, deleting the pip dependency path
|
|
118
|
+
|
|
119
|
+
CI resolved dependencies two ways. The tiered test jobs ran bare
|
|
120
|
+
`python -m pytest` against a `pip install -r requirements-dev.txt`
|
|
121
|
+
environment, which resolves from PyPI at run time; `make test` and
|
|
122
|
+
`make test-scenarios` ran under `uv run`, which honours uv.lock. The two
|
|
123
|
+
manifests disagreed -- requirements-dev.txt pinned pytest ~=8.3.0 while
|
|
124
|
+
[dependency-groups] dev asked for >=9.0.3, so the same suite ran on two
|
|
125
|
+
different runners depending on the job.
|
|
126
|
+
|
|
127
|
+
That split is what let a shtab release break CI. `shtab>=1.7.0` had no
|
|
128
|
+
upper bound, shtab 1.9.0 (2026-07-31) changed its generated output, and
|
|
129
|
+
the pip-based jobs installed 1.9.3 against completion golden fixtures
|
|
130
|
+
generated with 1.8.0. The uv-based jobs stayed on uv.lock's 1.8.0 and
|
|
131
|
+
passed. main has not run CI since 2026-07-17, before that release, so it
|
|
132
|
+
is green in history and broken in fact; every PR branched from it fails
|
|
133
|
+
the same two tests.
|
|
134
|
+
|
|
135
|
+
Reproduced directly: a venv built from requirements-dev.txt resolves
|
|
136
|
+
shtab 1.9.3 and pytest 8.3.5, and fails
|
|
137
|
+
test_completion_stdout_matches_committed_golden[bash,zsh] with the same
|
|
138
|
+
16098-vs-15657 byte mismatch CI reports. Installing shtab==1.8.0 into
|
|
139
|
+
that same venv turns it green.
|
|
140
|
+
|
|
141
|
+
9869ee7 pins shtab, which fixes the instance. This removes the cause:
|
|
142
|
+
|
|
143
|
+
- [dependency-groups] dev absorbs ruff, bandit, twine, pre-commit and
|
|
144
|
+
python-semantic-release, the tools only requirements-dev.txt declared.
|
|
145
|
+
Existing pins carry over unchanged. ruff stays ~=0.11.0 for the same
|
|
146
|
+
reason shtab is pinned: `ruff format --check` is a byte-level gate.
|
|
147
|
+
- requirements-dev.txt is deleted rather than kept in sync.
|
|
148
|
+
- requirements.txt is deleted too. It declared packaging and nothing
|
|
149
|
+
else, one of three runtime dependencies, and `make install` was
|
|
150
|
+
referenced nowhere; pyproject's [project] dependencies supersedes it.
|
|
151
|
+
- Every Makefile target invokes its tools through `uv run`. Previously
|
|
152
|
+
`make security-scan` was `uv run bandit` with bandit in no dependency
|
|
153
|
+
group, so uv fell through to PATH and silently ran a system-wide
|
|
154
|
+
bandit -- verified resolving to /usr/local/py-utils/bin/bandit.
|
|
155
|
+
- The unit coverage gate moves into `make test-unit-cov` behind a
|
|
156
|
+
COVERAGE_MIN variable, replacing the coverage-json + bc comparison
|
|
157
|
+
duplicated across both workflow files with pytest-cov's own
|
|
158
|
+
--cov-fail-under.
|
|
159
|
+
- setup-kanon installs uv before dependencies and runs
|
|
160
|
+
`uv sync --locked --all-groups`; --locked fails the job on a stale
|
|
161
|
+
lock instead of silently re-resolving. setup-uv's cache, keyed on
|
|
162
|
+
uv.lock, replaces the pip cache. The Windows leg no longer needs its
|
|
163
|
+
own branch because uv sync does not require GNU make.
|
|
164
|
+
- The release and publish jobs move to the same path, and
|
|
165
|
+
`python -m semantic_release` becomes `uv run python -m semantic_release`.
|
|
166
|
+
|
|
167
|
+
The CI-shape tests are updated rather than loosened. The tier assertions
|
|
168
|
+
followed the existing `make test-scenarios` precedent and now check both
|
|
169
|
+
halves of the contract: the workflow invokes the tier's Make target
|
|
170
|
+
exactly once with no per-OS override, and that target selects the bare
|
|
171
|
+
marker. Previously the marker was asserted but the delegation was not;
|
|
172
|
+
now both are. test_ci_includes_repo_tests searches the Makefile as well,
|
|
173
|
+
since --cov=kanon_cli moved there.
|
|
174
|
+
|
|
175
|
+
Verified from a clean `uv sync --locked --all-groups`: ruff, bandit,
|
|
176
|
+
twine, pre-commit and pytest all resolve inside .venv with no PATH
|
|
177
|
+
fallthrough. All ten CI jobs pass locally with counts identical to the
|
|
178
|
+
pre-change baseline -- full suite 17168 passed / 0 failed / 95%, unit
|
|
179
|
+
11712 passed / 93.22%, integration 1947, functional 3089, scenario 413.
|
|
180
|
+
|
|
181
|
+
---------
|
|
182
|
+
|
|
183
|
+
Co-authored-by: Ryan Gross <ryan.gross@caylent.com> ([`23b320e`](https://github.com/caylent-solutions/kanon/commit/23b320e7818bf564cbc3b9dcb65acc3e7f4626ef))
|
|
184
|
+
|
|
185
|
+
* fix: pin shtab to exact version to stop completion-fixture CI drift
|
|
186
|
+
|
|
187
|
+
pyproject.toml declared shtab>=1.7.0 with no upper bound. CI installs
|
|
188
|
+
dependencies via `pip install -r requirements-dev.txt` (-e .), resolving
|
|
189
|
+
shtab independently of uv.lock's exact pin; PyPI's latest shtab (1.9.2)
|
|
190
|
+
changed its generated output, breaking the byte-for-byte comparison
|
|
191
|
+
against the committed completion golden fixtures in both the
|
|
192
|
+
integration and functional test suites. Exact-pinning to 1.8.0 (already
|
|
193
|
+
locked in uv.lock) makes both install paths deterministic. ([`9869ee7`](https://github.com/caylent-solutions/kanon/commit/9869ee7b720829c329ad3c1afdcf2057a14427aa))
|
|
194
|
+
|
|
195
|
+
* fix(test): put safeguards in place for pre-commit failures in devcontainer environment on macos ([`1f38b25`](https://github.com/caylent-solutions/kanon/commit/1f38b25ea3205cac983c0952baed76c4a976b3ee))
|
|
196
|
+
|
|
197
|
+
* fix(tests): patch to avoid ioctl environment issues when running tests in devcontainer under uv ([`4931c10`](https://github.com/caylent-solutions/kanon/commit/4931c101c4cec06e778958e62b1af68ee9ada022))
|
|
198
|
+
|
|
199
|
+
### Unknown
|
|
200
|
+
|
|
201
|
+
* Merge pull request #106 from caylent-solutions/release-3.3.1
|
|
202
|
+
|
|
203
|
+
Release 3.3.1 ([`35f709f`](https://github.com/caylent-solutions/kanon/commit/35f709f1f5e0c26a2bcf6317e573ca56303e49bd))
|
|
204
|
+
|
|
205
|
+
* Merge pull request #97 from caylent-solutions/chore/add-uv-tool-version
|
|
206
|
+
|
|
207
|
+
chore: add uv toolchain support and fix progress-bar ioctl crash
|
|
208
|
+
|
|
209
|
+
Includes the issue-93 linkfile fix and the CI dependency-resolution
|
|
210
|
+
consolidation merged into this branch via #105. ([`bfab7a3`](https://github.com/caylent-solutions/kanon/commit/bfab7a319ade76111057696ee049b6d6ab5c41ab))
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
## v3.3.0 (2026-07-17)
|
|
214
|
+
|
|
215
|
+
### Chore
|
|
216
|
+
|
|
217
|
+
* chore(release): 3.3.0 ([`5100db5`](https://github.com/caylent-solutions/kanon/commit/5100db56a01818a5914474d7ddb95c96b7ab6de9))
|
|
218
|
+
|
|
219
|
+
### Feature
|
|
220
|
+
|
|
221
|
+
* feat: kanon list command + usage telemetry, full install-graph capture, and update-warning enhancement (#91)
|
|
222
|
+
|
|
223
|
+
* feat: add usage telemetry, full install-graph capture, and update-warning enhancement
|
|
224
|
+
|
|
225
|
+
Emit one structured usage-telemetry event per CLI command to the Caylent
|
|
226
|
+
collector, fully capturing what was installed (every direct source plus every
|
|
227
|
+
transitive repo package with URLs and resolved content SHAs), and enhance the
|
|
228
|
+
"update available" warning.
|
|
229
|
+
|
|
230
|
+
Telemetry (new core/telemetry.py):
|
|
231
|
+
- Hooked via try/finally around dispatch in cli.py; captures command, subcommand,
|
|
232
|
+
boolean flag names, allowlisted flag values, outcome (exit code/status/error
|
|
233
|
+
class/duration), runtime environment, and credential-stripped git provenance.
|
|
234
|
+
- OTLP/HTTP logs JSON with one log record whose body is a flat
|
|
235
|
+
{tool,timestamp,event_type,payload} object (payload a JSON string); POSTed via
|
|
236
|
+
stdlib urllib in a detached, non-blocking, silent, never-fail background
|
|
237
|
+
process (utils/spawn.spawn_detached), HTTPS-only guard, timeouts + body cap.
|
|
238
|
+
- Auto opted-in by default; the only opt-out is KANON_TELEMETRY_DISABLED (no
|
|
239
|
+
--no-telemetry flag). KANON_TELEMETRY_ENDPOINT / --telemetry-endpoint and
|
|
240
|
+
KANON_TELEMETRY_DEBUG / --telemetry-debug are supported.
|
|
241
|
+
- Zero-secret allowlist: never raw argv, keys, tokens, credentials, env-var
|
|
242
|
+
values, or file contents; every URL is credential-stripped.
|
|
243
|
+
|
|
244
|
+
Full install-graph capture (core/install.py):
|
|
245
|
+
- Populate SourceEntry.projects on install by resolving project -> remote -> URL
|
|
246
|
+
from the already-synced manifests (walk_includes_collecting_remotes +
|
|
247
|
+
join_project_repo_url + canonicalize_repo_url) joined with the captured content
|
|
248
|
+
pins. This also fixes `kanon why` showing an empty project layer on
|
|
249
|
+
install-written lockfiles. Telemetry emits payload.install_graph and a
|
|
250
|
+
flattened payload.installed_packages[] (direct + transitive), capped under the
|
|
251
|
+
collector body limit with install_graph_truncated on overflow.
|
|
252
|
+
|
|
253
|
+
Update-warning enhancement (core/update_check.py):
|
|
254
|
+
- Yellow banner with the current version in red and the latest in green; a red
|
|
255
|
+
"no internet access -- could not check for updates" notice on a failed fetch,
|
|
256
|
+
shown at most once per window; default KANON_UPDATE_CHECK_TTL lowered to 3h.
|
|
257
|
+
|
|
258
|
+
Docs: new docs/privacy.md (collected fields, encryption, opt-out) linked from
|
|
259
|
+
README; telemetry rows in docs/cli-reference.md and docs/configuration.md;
|
|
260
|
+
regenerated help + completion snapshots.
|
|
261
|
+
|
|
262
|
+
* test: include telemetry global flags in bash completion expectation
|
|
263
|
+
|
|
264
|
+
The new --telemetry-debug / --telemetry-endpoint global flags now appear in the
|
|
265
|
+
top-level bash completion, so the exact-match global_flags row in
|
|
266
|
+
test_completion_bash.py is extended to include them.
|
|
267
|
+
|
|
268
|
+
* test: use provider-neutral remote name in build_project_entries fixture
|
|
269
|
+
|
|
270
|
+
The provider-agnostic host gate forbids the bare token 'gh'; rename the fixture
|
|
271
|
+
manifest remote from 'gh' to 'origin' so the manifest XML fixtures carry no
|
|
272
|
+
provider-specific reference.
|
|
273
|
+
|
|
274
|
+
* fix: record real command outcome in telemetry and emit for --version/--help/bare invocations
|
|
275
|
+
|
|
276
|
+
* feat: add kanon list command (declared vs installed source inventory)
|
|
277
|
+
|
|
278
|
+
Add `kanon list`, the flat inventory command that reconciles the sources
|
|
279
|
+
declared in .kanon against those installed in .kanon.lock and tags each one
|
|
280
|
+
installed / not-installed / orphan -- the kanon analogue of `pip list` /
|
|
281
|
+
`npm ls` / `poetry show`.
|
|
282
|
+
|
|
283
|
+
Flags: --declared, --tree, --status <installed|not-installed|orphan>,
|
|
284
|
+
--format <table|json>, --kanon-file, --lock-file. Every failure path yields a
|
|
285
|
+
clean single-prefixed ERROR (no traceback). The command emits usage telemetry
|
|
286
|
+
like every other command (command=list, --tree flag, --format/--status values
|
|
287
|
+
via the flag-value allowlist).
|
|
288
|
+
|
|
289
|
+
The declared-vs-installed partition reuses a new non-raising
|
|
290
|
+
reconcile_declared_installed() extracted from check_lockfile_consistency (one
|
|
291
|
+
source of truth). Covered by unit/functional/integration/scenario tests plus a
|
|
292
|
+
real-git add->install->edit->list journey; list.py at 100% coverage. Help and
|
|
293
|
+
shell-completion snapshots and docs updated.
|
|
294
|
+
|
|
295
|
+
The 3.0.0 list->search rename left guards asserting `list` is an unknown
|
|
296
|
+
command; those are updated to reflect `list` now being a distinct command.
|
|
297
|
+
|
|
298
|
+
* test: isolate test subprocesses from coverage subprocess measurement
|
|
299
|
+
|
|
300
|
+
Under `pytest --cov` (make test) pytest-cov and coverage export COV_CORE_* /
|
|
301
|
+
COVERAGE_PROCESS_* so spawned subprocesses auto-start coverage. A measured
|
|
302
|
+
`kanon` subprocess then writes a .coverage-data directory into its working
|
|
303
|
+
directory -- resolved relative to the child CWD on some filesystems -- which
|
|
304
|
+
behavioural subprocess tests that inspect the child filesystem
|
|
305
|
+
(`kanon repo status --orphans`) or parse its stderr (`--telemetry-debug` JSON)
|
|
306
|
+
then trip over, non-deterministically across OS / filesystem.
|
|
307
|
+
|
|
308
|
+
Strip the coverage subprocess-trigger variables from the child environment in
|
|
309
|
+
the functional and scenario subprocess runners and the telemetry-journey env
|
|
310
|
+
builder via a shared strip_subprocess_coverage_env helper. Behavioural CLI
|
|
311
|
+
subprocess tests do not need coverage of the child; the 90% coverage gate is
|
|
312
|
+
measured in-process on the unit tier, which uses its own runner and is
|
|
313
|
+
unaffected. ([`57246f8`](https://github.com/caylent-solutions/kanon/commit/57246f8a8a46b99ad2b35a954289d7a9e7d1966c))
|
|
314
|
+
|
|
315
|
+
### Unknown
|
|
316
|
+
|
|
317
|
+
* Merge pull request #92 from caylent-solutions/release-3.3.0
|
|
318
|
+
|
|
319
|
+
Release 3.3.0 ([`56f49b9`](https://github.com/caylent-solutions/kanon/commit/56f49b9c98b2dfd9b5fac5d847fcb6350a6fafe4))
|
|
320
|
+
|
|
321
|
+
|
|
5
322
|
## v3.2.0 (2026-07-13)
|
|
6
323
|
|
|
324
|
+
### Chore
|
|
325
|
+
|
|
326
|
+
* chore(release): 3.2.0 ([`b503e3c`](https://github.com/caylent-solutions/kanon/commit/b503e3cf92479b6192b186ad6b2481563c916074))
|
|
327
|
+
|
|
7
328
|
### Feature
|
|
8
329
|
|
|
9
330
|
* feat(clean): ~/.kanon-home store rename, .kanon-dir guard, --purge/--purge-all (store-only teardown with no .kanon), no unconditional .gitignore (#89)
|
|
@@ -85,6 +406,12 @@ lifecycle also documents clean --purge-all running without a .kanon.
|
|
|
85
406
|
|
|
86
407
|
Co-authored-by: t <t@e.x> ([`d9b0ad1`](https://github.com/caylent-solutions/kanon/commit/d9b0ad1856ab58487b7ed3efdc3ff9d87b60b193))
|
|
87
408
|
|
|
409
|
+
### Unknown
|
|
410
|
+
|
|
411
|
+
* Merge pull request #90 from caylent-solutions/release-3.2.0
|
|
412
|
+
|
|
413
|
+
Release 3.2.0 ([`fb944e2`](https://github.com/caylent-solutions/kanon/commit/fb944e251cf650020070e29cb28a26cbffc886da))
|
|
414
|
+
|
|
88
415
|
|
|
89
416
|
## v3.1.1 (2026-06-27)
|
|
90
417
|
|
|
@@ -15,6 +15,12 @@ Thank you for your interest in contributing to the Kanon CLI! This document prov
|
|
|
15
15
|
make install-dev
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
This runs `uv sync --locked --all-groups`, so the toolchain comes from
|
|
19
|
+
`uv.lock` and matches CI exactly. [uv](https://docs.astral.sh/uv/) is a
|
|
20
|
+
prerequisite. Every `make` target invokes its tools through `uv run`; running
|
|
21
|
+
`ruff`, `pytest`, or `bandit` directly picks up whatever is on your `PATH`
|
|
22
|
+
instead of the locked version, which is how CI and local results drift apart.
|
|
23
|
+
|
|
18
24
|
3. Set up git hooks to ensure code quality:
|
|
19
25
|
```bash
|
|
20
26
|
make install-hooks
|