base-cli 0.4.2__tar.gz → 0.4.3__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.
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/workflows/compatibility.yml +10 -1
- base_cli-0.4.3/.github/workflows/dependency-matrix.yml +48 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/workflows/docs.yml +18 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/workflows/package.yml +109 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/workflows/tests.yml +8 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/CHANGELOG.md +78 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/PKG-INFO +41 -12
- {base_cli-0.4.2 → base_cli-0.4.3}/README.md +32 -8
- base_cli-0.4.3/VERSION +1 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/README.md +12 -5
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/adopter-readiness.md +8 -7
- base_cli-0.4.3/docs/adoption-evidence.md +67 -0
- base_cli-0.4.3/docs/api-reference.md +1974 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/api-stability.md +11 -7
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/cache-ownership-and-layout.md +3 -2
- base_cli-0.4.3/docs/compatibility-dashboard.md +53 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/consumer-profiles.md +5 -3
- base_cli-0.4.3/docs/coverage-policy.md +22 -0
- base_cli-0.4.3/docs/dependency-support.md +41 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/extensions.md +29 -0
- base_cli-0.4.3/docs/framework-choice.md +45 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/index.md +18 -4
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/json-contracts.md +11 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/local-config.md +2 -1
- base_cli-0.4.3/docs/migration-argparse.md +70 -0
- base_cli-0.4.3/docs/migration-cement.md +80 -0
- base_cli-0.4.3/docs/migration-click.md +75 -0
- base_cli-0.4.3/docs/migration-typer.md +72 -0
- base_cli-0.4.3/docs/migrations.md +93 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/output-contracts.md +16 -2
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/platform-support.md +12 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/releasing.md +60 -4
- base_cli-0.4.3/docs/schemas.md +33 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/security-threat-model.md +1 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/typer-adapter.md +2 -2
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/nested_click_app/README.md +2 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/__init__.py +24 -0
- base_cli-0.4.3/lib/python/base_cli/_app_core.py +1567 -0
- base_cli-0.4.3/lib/python/base_cli/_attach.py +613 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/_click_compat.py +19 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/_dependencies.py +4 -2
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/_lifecycle.py +9 -12
- base_cli-0.4.3/lib/python/base_cli/_lifecycle_install.py +854 -0
- base_cli-0.4.3/lib/python/base_cli/_run.py +431 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/_runtime.py +1 -1
- base_cli-0.4.3/lib/python/base_cli/app.py +31 -0
- base_cli-0.4.3/lib/python/base_cli/asyncio_adapter.py +39 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/command_protocol.py +12 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/config.py +4 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/extensions.py +70 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/history.py +55 -11
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/json_contracts.py +5 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/output.py +62 -10
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/redaction.py +24 -3
- base_cli-0.4.3/lib/python/base_cli/schemas/v1/command-protocol.schema.json +15 -0
- base_cli-0.4.3/lib/python/base_cli/schemas/v1/error.schema.json +17 -0
- base_cli-0.4.3/lib/python/base_cli/schemas/v1/inspection.schema.json +15 -0
- base_cli-0.4.3/lib/python/base_cli/schemas/v1/log.schema.json +18 -0
- base_cli-0.4.3/lib/python/base_cli/schemas/v1/ndjson.schema.json +13 -0
- base_cli-0.4.3/lib/python/base_cli/schemas/v1/output.schema.json +17 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/testing.py +4 -4
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli.egg-info/PKG-INFO +41 -12
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli.egg-info/SOURCES.txt +42 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli.egg-info/requires.txt +5 -2
- {base_cli-0.4.2 → base_cli-0.4.3}/pyproject.toml +23 -4
- base_cli-0.4.3/scripts/generate_api_reference.py +148 -0
- base_cli-0.4.3/scripts/generate_compatibility_dashboard.py +176 -0
- base_cli-0.4.3/scripts/generate_release_metadata.py +150 -0
- base_cli-0.4.3/scripts/record_compatibility_evidence.py +58 -0
- base_cli-0.4.3/scripts/validate_changelog.py +129 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/scripts/validate_consumers.py +2 -2
- base_cli-0.4.3/scripts/validate_contract_fixtures.py +98 -0
- base_cli-0.4.3/scripts/validate_coverage.py +72 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/scripts/validate_docs.py +51 -1
- {base_cli-0.4.2 → base_cli-0.4.3}/scripts/validate_package_artifact.py +15 -1
- base_cli-0.4.3/scripts/validate_release_metadata.py +69 -0
- base_cli-0.4.3/scripts/validate_release_ref.py +60 -0
- base_cli-0.4.3/scripts/validate_schemas.py +61 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_adversarial_regressions.py +6 -2
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_api_stability.py +12 -0
- base_cli-0.4.3/tests/test_app_module_boundaries.py +28 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_run_metadata.py +11 -8
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_command_protocol.py +38 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_extensions.py +50 -1
- base_cli-0.4.3/tests/test_generate_compatibility_dashboard.py +36 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_generic_core.py +27 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_history.py +26 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_json_contracts.py +169 -0
- base_cli-0.4.3/tests/test_optional_yaml_dependency.py +42 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_output.py +100 -6
- base_cli-0.4.3/tests/test_platform_edge_paths.py +209 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_public_api.py +3 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_redaction_security.py +60 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_run_bundle_retention.py +16 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_testing.py +40 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_typed_contracts.py +37 -0
- base_cli-0.4.3/tests/test_validate_changelog.py +64 -0
- base_cli-0.4.3/tests/test_validate_docs.py +33 -0
- base_cli-0.4.3/tests/test_validate_release_ref.py +57 -0
- base_cli-0.4.3/tests/test_validate_schemas.py +42 -0
- base_cli-0.4.2/VERSION +0 -1
- base_cli-0.4.2/docs/migrations.md +0 -53
- base_cli-0.4.2/lib/python/base_cli/app.py +0 -3175
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/ISSUE_TEMPLATE/support.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/base-project.yml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/pull_request_template.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/workflows/examples.yml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/workflows/issue-branch-policy.yml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/.github/workflows/project-intake.yml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/CONTRIBUTING.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/LICENSE +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/MANIFEST.in +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/SECURITY.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/base_manifest.yaml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/atlas_click/README.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/atlas_click/pyproject.toml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/atlas_click/src/atlas_click/__init__.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/atlas_click/src/atlas_click/cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/atlas_click/tests/test_consumer.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/beacon_typer/README.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/beacon_typer/pyproject.toml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/beacon_typer/src/beacon_typer/__init__.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/beacon_typer/src/beacon_typer/cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/beacon_typer/tests/test_consumer.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/cinder_automation/README.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/cinder_automation/pyproject.toml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/cinder_automation/src/cinder_automation/__init__.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/cinder_automation/src/cinder_automation/cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/cinder_automation/tests/test_consumer.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/compatibility/consumers/manifest.json +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/integrations.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/performance.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/security-review.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/docs/user-config-typing.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/README.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/automation_observability_app/README.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/automation_observability_app/pyproject.toml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/automation_observability_app/src/automation_observability_app/__init__.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/automation_observability_app/src/automation_observability_app/cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/automation_observability_app/tests/test_cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/minimal_cli/README.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/minimal_cli/pyproject.toml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/minimal_cli/src/minimal_cli/__init__.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/minimal_cli/src/minimal_cli/cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/minimal_cli/tests/test_cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/nested_click_app/pyproject.toml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/nested_click_app/src/nested_click_app/__init__.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/nested_click_app/src/nested_click_app/cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/nested_click_app/src/nested_click_app/plugin.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/nested_click_app/tests/test_cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/typed_consumer.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/typer_app/README.md +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/typer_app/pyproject.toml +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/typer_app/src/typer_app/__init__.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/typer_app/src/typer_app/cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/typer_app/tests/test_cli.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/examples/typer_consumer.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/_cleanup.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/_private_files.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/attachment.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/command_filters.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/context.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/deprecations.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/errors.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/exit_codes.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/experimental.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/inspection.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/integrations.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/lifecycle_options.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/logging.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/paths.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/profile.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/py.typed +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/runtime.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli/typer.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli.egg-info/dependency_links.txt +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/lib/python/base_cli.egg-info/top_level.txt +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/scripts/benchmark_runtime.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/scripts/validate_examples.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/scripts/validate_installed_package.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/setup.cfg +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/conftest.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_dry_run.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_lifecycle.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_log_retention.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_quiet.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_registration.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_run.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_runtime_boundary.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_runtime_errors.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_security_boundaries.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_startup_transaction.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_app_subcommands.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_batteries_included_config.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_benchmark_runtime.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_cleanup_security.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_click_tree_attachment.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_command_filters.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_context_workspace.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_explicit_config_validation.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_inspection.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_integrations.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_invocation_parity.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_lifecycle_options.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_logging.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_paths.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_profile.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_security_documentation.py +0 -0
- {base_cli-0.4.2 → base_cli-0.4.3}/tests/test_typer_adapter.py +0 -0
|
@@ -20,7 +20,7 @@ jobs:
|
|
|
20
20
|
fail-fast: false
|
|
21
21
|
matrix:
|
|
22
22
|
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
23
|
-
typer-version: ["0.25.1", "0.26.0", "0.27.1"]
|
|
23
|
+
typer-version: ["0.25.1", "0.26.0", "0.27.1", "0.27.2"]
|
|
24
24
|
steps:
|
|
25
25
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
26
26
|
- name: Set up Python
|
|
@@ -66,3 +66,12 @@ jobs:
|
|
|
66
66
|
for tests in compatibility/consumers/*/tests; do
|
|
67
67
|
python -m pytest "$tests"
|
|
68
68
|
done
|
|
69
|
+
- name: Record dated compatibility evidence
|
|
70
|
+
run: python scripts/record_compatibility_evidence.py > compatibility-evidence.json
|
|
71
|
+
- name: Upload compatibility evidence
|
|
72
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
73
|
+
with:
|
|
74
|
+
name: base-cli-compatibility-evidence-${{ github.run_id }}
|
|
75
|
+
path: compatibility-evidence.json
|
|
76
|
+
if-no-files-found: error
|
|
77
|
+
retention-days: 90
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: Dependency compatibility
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
core:
|
|
16
|
+
name: Click ${{ matrix.click-version }} / PyYAML ${{ matrix.pyyaml-version }} / Python ${{ matrix.python-version }}
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
timeout-minutes: 15
|
|
19
|
+
strategy:
|
|
20
|
+
fail-fast: false
|
|
21
|
+
matrix:
|
|
22
|
+
python-version: ["3.10", "3.14"]
|
|
23
|
+
click-version: ["8.1.*", "8.2.*", "8.3.*", "8.4.*"]
|
|
24
|
+
pyyaml-version: ["6.0.*"]
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
27
|
+
- name: Set up Python
|
|
28
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
29
|
+
with:
|
|
30
|
+
python-version: ${{ matrix.python-version }}
|
|
31
|
+
- name: Install framework and test dependencies
|
|
32
|
+
run: python -m pip install "setuptools<77" "wheel" ".[dev]"
|
|
33
|
+
- name: Select tested core dependency lines
|
|
34
|
+
run: |
|
|
35
|
+
python -m pip install --upgrade --force-reinstall \
|
|
36
|
+
"click==${{ matrix.click-version }}" \
|
|
37
|
+
"PyYAML==${{ matrix.pyyaml-version }}"
|
|
38
|
+
- name: Verify resolved dependency contract
|
|
39
|
+
run: |
|
|
40
|
+
python - <<'PY'
|
|
41
|
+
from importlib.metadata import version
|
|
42
|
+
|
|
43
|
+
click_version = version("click")
|
|
44
|
+
yaml_version = version("PyYAML")
|
|
45
|
+
print(f"Click {click_version}; PyYAML {yaml_version}")
|
|
46
|
+
PY
|
|
47
|
+
- name: Run core suite
|
|
48
|
+
run: python -m pytest
|
|
@@ -11,6 +11,16 @@ on:
|
|
|
11
11
|
- "mkdocs.yml"
|
|
12
12
|
- "pyproject.toml"
|
|
13
13
|
- "scripts/validate_docs.py"
|
|
14
|
+
- "scripts/validate_changelog.py"
|
|
15
|
+
- "scripts/generate_compatibility_dashboard.py"
|
|
16
|
+
- ".github/workflows/tests.yml"
|
|
17
|
+
- ".github/workflows/dependency-matrix.yml"
|
|
18
|
+
- ".github/workflows/compatibility.yml"
|
|
19
|
+
- "scripts/generate_api_reference.py"
|
|
20
|
+
- "scripts/generate_compatibility_dashboard.py"
|
|
21
|
+
- ".github/workflows/tests.yml"
|
|
22
|
+
- ".github/workflows/dependency-matrix.yml"
|
|
23
|
+
- ".github/workflows/compatibility.yml"
|
|
14
24
|
- "tests/validate.sh"
|
|
15
25
|
- ".github/workflows/docs.yml"
|
|
16
26
|
pull_request:
|
|
@@ -21,6 +31,7 @@ on:
|
|
|
21
31
|
- "mkdocs.yml"
|
|
22
32
|
- "pyproject.toml"
|
|
23
33
|
- "scripts/validate_docs.py"
|
|
34
|
+
- "scripts/generate_api_reference.py"
|
|
24
35
|
- "tests/validate.sh"
|
|
25
36
|
- ".github/workflows/docs.yml"
|
|
26
37
|
workflow_dispatch:
|
|
@@ -50,7 +61,13 @@ jobs:
|
|
|
50
61
|
run: python -m pip install ".[docs]"
|
|
51
62
|
|
|
52
63
|
- name: Validate repository links and examples
|
|
53
|
-
run:
|
|
64
|
+
run: |
|
|
65
|
+
python scripts/validate_docs.py
|
|
66
|
+
python scripts/validate_changelog.py
|
|
67
|
+
python scripts/generate_compatibility_dashboard.py --check
|
|
68
|
+
|
|
69
|
+
- name: Validate generated public API reference
|
|
70
|
+
run: python scripts/generate_api_reference.py --check
|
|
54
71
|
|
|
55
72
|
- name: Build documentation with strict warnings
|
|
56
73
|
run: python -m mkdocs build --strict --site-dir site
|
|
@@ -12,6 +12,11 @@ on:
|
|
|
12
12
|
- "scripts/validate_package_artifact.py"
|
|
13
13
|
- "scripts/validate_installed_package.py"
|
|
14
14
|
- "scripts/validate_examples.py"
|
|
15
|
+
- "scripts/generate_release_metadata.py"
|
|
16
|
+
- "scripts/validate_release_metadata.py"
|
|
17
|
+
- "scripts/validate_changelog.py"
|
|
18
|
+
- "scripts/validate_release_ref.py"
|
|
19
|
+
- "CHANGELOG.md"
|
|
15
20
|
- "examples/**"
|
|
16
21
|
- "compatibility/**"
|
|
17
22
|
- "docs/releasing.md"
|
|
@@ -78,6 +83,15 @@ jobs:
|
|
|
78
83
|
- name: Validate repository baseline
|
|
79
84
|
run: ./tests/validate.sh
|
|
80
85
|
|
|
86
|
+
- name: Validate changelog
|
|
87
|
+
run: python scripts/validate_changelog.py
|
|
88
|
+
|
|
89
|
+
- name: Validate tagged release notes
|
|
90
|
+
if: ${{ github.ref_type == 'tag' }}
|
|
91
|
+
env:
|
|
92
|
+
RELEASE_TAG: ${{ github.ref_name }}
|
|
93
|
+
run: python scripts/validate_release_ref.py
|
|
94
|
+
|
|
81
95
|
- name: Prepare clean artifact destination
|
|
82
96
|
run: |
|
|
83
97
|
git clean -ffdx
|
|
@@ -95,14 +109,37 @@ jobs:
|
|
|
95
109
|
- name: Validate package indexes
|
|
96
110
|
run: python -m twine check dist/*
|
|
97
111
|
|
|
112
|
+
- name: Generate release checksums and SPDX SBOM
|
|
113
|
+
env:
|
|
114
|
+
SOURCE_REVISION: ${{ github.sha }}
|
|
115
|
+
SOURCE_DATE_EPOCH: ${{ github.event.head_commit.timestamp || '0' }}
|
|
116
|
+
run: python scripts/generate_release_metadata.py dist
|
|
117
|
+
|
|
118
|
+
- name: Validate release checksums and SPDX SBOM
|
|
119
|
+
env:
|
|
120
|
+
SOURCE_REVISION: ${{ github.sha }}
|
|
121
|
+
run: python scripts/validate_release_metadata.py dist
|
|
122
|
+
|
|
98
123
|
- name: Upload reviewed distributions
|
|
99
124
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
100
125
|
with:
|
|
101
126
|
name: base-cli-dist-${{ github.run_id }}
|
|
102
|
-
path:
|
|
127
|
+
path: |
|
|
128
|
+
dist/*.whl
|
|
129
|
+
dist/*.tar.gz
|
|
103
130
|
if-no-files-found: error
|
|
104
131
|
retention-days: 14
|
|
105
132
|
|
|
133
|
+
- name: Upload release metadata
|
|
134
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
135
|
+
with:
|
|
136
|
+
name: base-cli-release-metadata-${{ github.run_id }}
|
|
137
|
+
path: |
|
|
138
|
+
dist/SBOM.spdx.json
|
|
139
|
+
dist/SHA256SUMS
|
|
140
|
+
if-no-files-found: error
|
|
141
|
+
retention-days: 90
|
|
142
|
+
|
|
106
143
|
smoke:
|
|
107
144
|
name: Install smoke test (Python ${{ matrix.python-version }})
|
|
108
145
|
needs: build
|
|
@@ -184,3 +221,74 @@ jobs:
|
|
|
184
221
|
uses: pypa/gh-action-pypi-publish@4bb033805d9e19112d8c697528791ff53f6c2f74
|
|
185
222
|
with:
|
|
186
223
|
packages-dir: dist
|
|
224
|
+
|
|
225
|
+
attest:
|
|
226
|
+
name: Attest reviewed release
|
|
227
|
+
needs: [build, smoke]
|
|
228
|
+
if: ${{ (github.event_name == 'push' && github.ref_type == 'tag') || github.event_name == 'workflow_dispatch' }}
|
|
229
|
+
runs-on: ubuntu-latest
|
|
230
|
+
timeout-minutes: 10
|
|
231
|
+
permissions:
|
|
232
|
+
contents: read
|
|
233
|
+
id-token: write
|
|
234
|
+
attestations: write
|
|
235
|
+
steps:
|
|
236
|
+
- name: Download reviewed distributions
|
|
237
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
238
|
+
with:
|
|
239
|
+
name: base-cli-dist-${{ github.run_id }}
|
|
240
|
+
path: dist
|
|
241
|
+
|
|
242
|
+
- name: Download release metadata
|
|
243
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
244
|
+
with:
|
|
245
|
+
name: base-cli-release-metadata-${{ github.run_id }}
|
|
246
|
+
path: dist
|
|
247
|
+
|
|
248
|
+
- name: Attest artifact provenance
|
|
249
|
+
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4
|
|
250
|
+
with:
|
|
251
|
+
subject-checksums: dist/SHA256SUMS
|
|
252
|
+
|
|
253
|
+
- name: Attest SPDX SBOM
|
|
254
|
+
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4
|
|
255
|
+
with:
|
|
256
|
+
subject-checksums: dist/SHA256SUMS
|
|
257
|
+
sbom-path: dist/SBOM.spdx.json
|
|
258
|
+
|
|
259
|
+
release:
|
|
260
|
+
name: Create GitHub Release
|
|
261
|
+
needs: [build, smoke, publish, attest]
|
|
262
|
+
if: ${{ github.event_name == 'push' && github.ref_type == 'tag' }}
|
|
263
|
+
runs-on: ubuntu-latest
|
|
264
|
+
timeout-minutes: 10
|
|
265
|
+
permissions:
|
|
266
|
+
contents: write
|
|
267
|
+
steps:
|
|
268
|
+
- name: Download reviewed distributions
|
|
269
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
270
|
+
with:
|
|
271
|
+
name: base-cli-dist-${{ github.run_id }}
|
|
272
|
+
path: dist
|
|
273
|
+
|
|
274
|
+
- name: Download release metadata
|
|
275
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
276
|
+
with:
|
|
277
|
+
name: base-cli-release-metadata-${{ github.run_id }}
|
|
278
|
+
path: dist
|
|
279
|
+
|
|
280
|
+
- name: Create or update GitHub Release
|
|
281
|
+
env:
|
|
282
|
+
GH_TOKEN: ${{ github.token }}
|
|
283
|
+
run: |
|
|
284
|
+
tag="$GITHUB_REF_NAME"
|
|
285
|
+
assets=(dist/*.whl dist/*.tar.gz dist/SHA256SUMS dist/SBOM.spdx.json)
|
|
286
|
+
if gh release view "$tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
|
287
|
+
gh release upload "$tag" "${assets[@]}" --clobber --repo "$GITHUB_REPOSITORY"
|
|
288
|
+
else
|
|
289
|
+
gh release create "$tag" "${assets[@]}" \
|
|
290
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
291
|
+
--title "$tag" \
|
|
292
|
+
--generate-notes \
|
|
293
|
+
--notes "Published distributions and release metadata for $tag. See CHANGELOG.md for the reviewed release notes."
|
|
294
|
+
fi
|
|
@@ -65,10 +65,17 @@ jobs:
|
|
|
65
65
|
python -m mypy --strict examples/typed_consumer.py
|
|
66
66
|
python -m mypy --strict lib/python/base_cli
|
|
67
67
|
python scripts/validate_docs.py
|
|
68
|
+
python scripts/validate_changelog.py
|
|
69
|
+
python scripts/validate_schemas.py
|
|
70
|
+
python scripts/validate_contract_fixtures.py
|
|
71
|
+
node scripts/validate_contract_fixtures.mjs
|
|
72
|
+
python scripts/generate_compatibility_dashboard.py --check
|
|
68
73
|
python scripts/benchmark_runtime.py --check
|
|
69
74
|
python -m compileall -q examples
|
|
70
75
|
- name: Run tests with coverage threshold
|
|
71
|
-
run: python -m pytest --cov=base_cli --cov-report=term-missing --cov-fail-under=80
|
|
76
|
+
run: python -m pytest --cov=base_cli --cov-report=term-missing --cov-report=json:coverage.json --cov-fail-under=80
|
|
77
|
+
- name: Enforce high-risk module coverage floors
|
|
78
|
+
run: python scripts/validate_coverage.py coverage.json
|
|
72
79
|
- name: Run static security checks
|
|
73
80
|
run: |
|
|
74
81
|
bandit -q -r lib/python/base_cli scripts -lll -iii
|
|
@@ -11,6 +11,76 @@ and versions are tracked in the repo-root `VERSION` file.
|
|
|
11
11
|
|
|
12
12
|
- Continue compatibility hardening and adoption work for the next release.
|
|
13
13
|
|
|
14
|
+
## [0.4.3] - 2026-08-29
|
|
15
|
+
|
|
16
|
+
This is a compatible pre-1.0 patch release. It contains lifecycle hardening,
|
|
17
|
+
security fixes, versioned machine-readable contracts, and adoption tooling
|
|
18
|
+
after 0.4.2; it does not introduce a new API or JSON-contract compatibility
|
|
19
|
+
boundary. Existing Click and Typer command trees remain supported.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Add branch-aware coverage reporting with documented floors for lifecycle,
|
|
24
|
+
filesystem, compatibility, history, and contract modules.
|
|
25
|
+
- Decompose the application implementation behind a compatibility facade into
|
|
26
|
+
focused core, lifecycle-installation, attachment, and invocation-runner
|
|
27
|
+
modules without changing the public import surface.
|
|
28
|
+
- Bound the core Click and PyYAML dependency windows, publish the tested
|
|
29
|
+
compatibility matrix, and document the dependency update policy.
|
|
30
|
+
- Validate Click 8.1 through 8.4 on the supported Python floor and ceiling,
|
|
31
|
+
and reject unvalidated Click 8.5+ versions through package metadata.
|
|
32
|
+
- Move PyYAML behind the optional `base-cli[yaml]` extra and provide an
|
|
33
|
+
actionable installation hint when YAML configuration or output is selected.
|
|
34
|
+
- Add an explicit `App.async_command()` adapter and `run_async()` helper for
|
|
35
|
+
deterministic async callbacks without changing the synchronous core.
|
|
36
|
+
- Add versioned NDJSON output and typed writer protocols for bounded,
|
|
37
|
+
flush-per-record machine output.
|
|
38
|
+
- Formalize typed extension callback protocols, entry-point capability metadata,
|
|
39
|
+
and pre-load API-version negotiation.
|
|
40
|
+
|
|
41
|
+
### Security
|
|
42
|
+
|
|
43
|
+
- Redact recognized secret keys embedded in query strings, comma-separated
|
|
44
|
+
values, and header-style `key: value` arguments before they reach logs or
|
|
45
|
+
persisted history.
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- Keep the Typer adapter compatible with Typer 0.27.2's vendored exit
|
|
50
|
+
exception layout and validate that release in the compatibility matrix.
|
|
51
|
+
- Apply the documented count-only 20-bundle retention default to implicit JSON
|
|
52
|
+
mode while preserving explicit retention policies, human-mode safe defaults,
|
|
53
|
+
and the `max_log_files` compatibility path.
|
|
54
|
+
- Honor combined positive/negative JSON option declarations and explicit
|
|
55
|
+
`--no-json` values when deciding whether pre-parse errors use JSON output.
|
|
56
|
+
- Isolate malformed third-party entry-point metadata so one invalid extension
|
|
57
|
+
cannot prevent healthy extensions from being discovered.
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- Automate GitHub Releases from matching version tags with reviewed
|
|
62
|
+
distributions, checksums, SBOM metadata, and generated comparison notes.
|
|
63
|
+
- Publish a generated dependency and platform compatibility dashboard linked
|
|
64
|
+
from the README and documentation site.
|
|
65
|
+
- Add framework-specific migration guides for Click, Typer, Cement, and
|
|
66
|
+
`argparse`, with rollout and rollback checklists.
|
|
67
|
+
- Add golden success, error, inspection, log, NDJSON, and command-protocol
|
|
68
|
+
fixtures with Python and Node.js validators for cross-language consumers.
|
|
69
|
+
- Publish versioned JSON Schema artifacts for output, error, inspection, log,
|
|
70
|
+
NDJSON, and decoded command-protocol contracts in the package and docs site.
|
|
71
|
+
- Add a framework choice guide, five-minute evaluation path, and clearer
|
|
72
|
+
production-lifecycle positioning for Click and Typer adopters.
|
|
73
|
+
- Add deterministic SPDX SBOMs, artifact checksums, and OIDC-backed GitHub
|
|
74
|
+
attestations to protected release workflows.
|
|
75
|
+
- Add a generated public API reference and a strict CI drift check so every
|
|
76
|
+
stable facade export remains searchable and documented.
|
|
77
|
+
- Add a permissioned-adopter evidence policy and dated compatibility-run
|
|
78
|
+
artifacts without presenting maintained fixtures as customer adoption.
|
|
79
|
+
|
|
80
|
+
- Align the README, documentation landing page, package metadata, and search
|
|
81
|
+
keywords around the production lifecycle layer positioning for Click and
|
|
82
|
+
Typer CLIs.
|
|
83
|
+
|
|
14
84
|
## [0.4.2] - 2026-08-08
|
|
15
85
|
|
|
16
86
|
This is a compatible pre-1.0 patch release. It contains correctness fixes,
|
|
@@ -234,6 +304,14 @@ the API stability policy and migration guide before upgrading from `0.3.x`.
|
|
|
234
304
|
- Initialized the repository with the Base-managed repo baseline.
|
|
235
305
|
- Added the guarded package build, artifact validation, and protected
|
|
236
306
|
TestPyPI/PyPI publication workflow.
|
|
307
|
+
|
|
308
|
+
[Unreleased]: https://github.com/basefoundry/base-cli/compare/v0.4.3...HEAD
|
|
309
|
+
[0.4.3]: https://github.com/basefoundry/base-cli/compare/v0.4.2...v0.4.3
|
|
310
|
+
[0.4.2]: https://github.com/basefoundry/base-cli/compare/v0.4.1...v0.4.2
|
|
311
|
+
[0.4.1]: https://github.com/basefoundry/base-cli/compare/v0.4.0...v0.4.1
|
|
312
|
+
[0.4.0]: https://github.com/basefoundry/base-cli/compare/v0.3.0...v0.4.0
|
|
313
|
+
[0.3.0]: https://github.com/basefoundry/base-cli/compare/v0.2.0...v0.3.0
|
|
314
|
+
[0.2.0]: https://github.com/basefoundry/base-cli/releases/tag/v0.2.0
|
|
237
315
|
- Exposed `base_cli.__version__` from the repository and installed package
|
|
238
316
|
version contract.
|
|
239
317
|
- Pinned the build backend to metadata compatible with the bundled publication
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: base-cli
|
|
3
|
-
Version: 0.4.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.3
|
|
4
|
+
Summary: The production lifecycle layer for Click and Typer Python CLIs
|
|
5
5
|
Author: Base Foundry
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
Project-URL: Homepage, https://github.com/basefoundry/base-cli
|
|
@@ -9,6 +9,7 @@ Project-URL: Repository, https://github.com/basefoundry/base-cli
|
|
|
9
9
|
Project-URL: Issues, https://github.com/basefoundry/base-cli/issues
|
|
10
10
|
Project-URL: Documentation, https://basefoundry.github.io/base-cli/
|
|
11
11
|
Project-URL: Code of Conduct, https://github.com/basefoundry/base-cli/blob/main/CODE_OF_CONDUCT.md
|
|
12
|
+
Keywords: cli,python-cli,command-line,command-line-interface,cli-framework,click,typer,framework,lifecycle,logging,structured-logging,configuration
|
|
12
13
|
Classifier: Development Status :: 4 - Beta
|
|
13
14
|
Classifier: Intended Audience :: Developers
|
|
14
15
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
@@ -23,15 +24,19 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
23
24
|
Classifier: Programming Language :: Python :: 3.13
|
|
24
25
|
Classifier: Programming Language :: Python :: 3.14
|
|
25
26
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
28
|
+
Classifier: Topic :: System :: Shells
|
|
26
29
|
Requires-Python: >=3.10
|
|
27
30
|
Description-Content-Type: text/markdown
|
|
28
31
|
License-File: LICENSE
|
|
29
|
-
Requires-Dist: click
|
|
30
|
-
|
|
32
|
+
Requires-Dist: click<8.5,>=8.1
|
|
33
|
+
Provides-Extra: yaml
|
|
34
|
+
Requires-Dist: PyYAML<7,>=6.0; extra == "yaml"
|
|
31
35
|
Provides-Extra: dev
|
|
32
36
|
Requires-Dist: build>=1.2; extra == "dev"
|
|
33
37
|
Requires-Dist: hypothesis<7,>=6.100; extra == "dev"
|
|
34
38
|
Requires-Dist: mypy<2,>=1.17; extra == "dev"
|
|
39
|
+
Requires-Dist: PyYAML<7,>=6.0; extra == "dev"
|
|
35
40
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
36
41
|
Requires-Dist: types-PyYAML<7,>=6.0; extra == "dev"
|
|
37
42
|
Provides-Extra: typer
|
|
@@ -58,9 +63,18 @@ Requires-Dist: mkdocs-material<10,>=9.5; extra == "docs"
|
|
|
58
63
|
|
|
59
64
|
| Version | License | Install | Release notes |
|
|
60
65
|
| --- | --- | --- | --- |
|
|
61
|
-
| `0.4.
|
|
66
|
+
| `0.4.3` | [Apache-2.0](LICENSE) | `python -m pip install base-cli` | [v0.4.3](https://github.com/basefoundry/base-cli/releases/tag/v0.4.3) |
|
|
62
67
|
|
|
63
|
-
`base-cli` is the
|
|
68
|
+
`base-cli` is the production lifecycle layer for Click and Typer Python CLIs.
|
|
69
|
+
It standardizes context, logging, configuration, cleanup, and machine-readable
|
|
70
|
+
contracts while leaving command and product policy in the consumer application.
|
|
71
|
+
The PyPI distribution is `base-cli`; import it in Python as `base_cli`.
|
|
72
|
+
|
|
73
|
+
It is for teams shipping operational CLIs that need the same diagnostics,
|
|
74
|
+
configuration boundary, cleanup behavior, and automation contracts in every
|
|
75
|
+
command. It is not a parser replacement or an application scaffold: Click and
|
|
76
|
+
Typer still own parsing and command definitions, while the consuming project
|
|
77
|
+
owns its domain policy and services.
|
|
64
78
|
|
|
65
79
|
Install it with:
|
|
66
80
|
|
|
@@ -71,6 +85,11 @@ python -m pip install base-cli
|
|
|
71
85
|
Read the complete documentation at
|
|
72
86
|
<https://basefoundry.github.io/base-cli/>.
|
|
73
87
|
|
|
88
|
+
Compatibility results and the permissioned-adopter policy are documented in
|
|
89
|
+
the [adoption and compatibility evidence guide](https://basefoundry.github.io/base-cli/adoption-evidence/).
|
|
90
|
+
The [compatibility dashboard](https://basefoundry.github.io/base-cli/compatibility-dashboard/)
|
|
91
|
+
shows the declared and CI-tested dependency and platform support boundaries.
|
|
92
|
+
|
|
74
93
|
## Quick start
|
|
75
94
|
|
|
76
95
|
Create a small command with a consistent context, logging, and cleanup
|
|
@@ -107,10 +126,9 @@ documented in [`docs/releasing.md`](https://basefoundry.github.io/base-cli/relea
|
|
|
107
126
|
The package is distributed under the Apache License 2.0. Base itself remains
|
|
108
127
|
licensed separately under AGPL-3.0-or-later.
|
|
109
128
|
|
|
110
|
-
`base_cli` is
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
library, not part of its generic contract.
|
|
129
|
+
`base_cli` is designed to be embedded by applications rather than to define
|
|
130
|
+
an application's project model. Base is one consumer of the library, not part
|
|
131
|
+
of its generic contract.
|
|
114
132
|
|
|
115
133
|
It is intentionally thin. Click still owns argument parsing and command
|
|
116
134
|
execution, while `base_cli` provides reusable lifecycle behavior:
|
|
@@ -137,6 +155,8 @@ The supported public facade, compatibility promises, deprecation warning
|
|
|
137
155
|
mechanism, and migration requirements are documented in
|
|
138
156
|
[`docs/api-stability.md`](https://basefoundry.github.io/base-cli/api-stability/) and
|
|
139
157
|
[`docs/migrations.md`](https://basefoundry.github.io/base-cli/migrations/).
|
|
158
|
+
The complete generated facade is listed in the
|
|
159
|
+
[`public API reference`](https://basefoundry.github.io/base-cli/api-reference/).
|
|
140
160
|
|
|
141
161
|
Security reporting, runtime trust boundaries, threat assumptions, and the
|
|
142
162
|
release security checklist are documented in [`SECURITY.md`](SECURITY.md),
|
|
@@ -283,6 +303,10 @@ catalog](examples/README.md). It covers a minimal command, nested/plugin Click,
|
|
|
283
303
|
Typer, and automation/observability flows; each example has its own packaging,
|
|
284
304
|
tests, completion, release, and troubleshooting guidance.
|
|
285
305
|
|
|
306
|
+
Teams comparing frameworks can start with the [framework choice guide](docs/framework-choice.md),
|
|
307
|
+
which explains what base-cli adds to Click or Typer and when a different
|
|
308
|
+
framework is a better fit.
|
|
309
|
+
|
|
286
310
|
Teams evaluating adoption can follow the [adopter readiness and migration
|
|
287
311
|
guide](https://basefoundry.github.io/base-cli/adopter-readiness/) and run the three independent
|
|
288
312
|
[downstream compatibility consumers](compatibility/README.md).
|
|
@@ -753,6 +777,10 @@ command execution as `130` without a traceback. After the command outcome has
|
|
|
753
777
|
settled, history, metadata, and cleanup are best-effort teardown: even a second
|
|
754
778
|
interrupt there cannot replace the primary result.
|
|
755
779
|
|
|
780
|
+
Terminal lifecycle status is `ok` for exit code `0`, `aborted` for the
|
|
781
|
+
interrupt exit code `130`, and `error` for other nonzero exit codes. The
|
|
782
|
+
technical outcome remains precise: Ctrl+C is recorded as `interrupted`.
|
|
783
|
+
|
|
756
784
|
An unexpected exception returns `1` with a stable, detail-free message. The run
|
|
757
785
|
ID and diagnostic-log path are included when context and file logging are
|
|
758
786
|
available. The traceback is kept in the persistent log when enabled and is
|
|
@@ -1106,8 +1134,9 @@ stdout or stderr for expected usage or application failures.
|
|
|
1106
1134
|
|
|
1107
1135
|
`invoke()` sets `HOME` plus the relevant `USERPROFILE`, `LOCALAPPDATA`, and
|
|
1108
1136
|
`XDG_CACHE_HOME` values when requested, and supplies `cwd` to the invocation for
|
|
1109
|
-
the duration of the test.
|
|
1110
|
-
|
|
1137
|
+
the duration of the test. All helper calls are serialized because `cwd` is
|
|
1138
|
+
process-global: a no-`cwd` call cannot observe another call's temporary
|
|
1139
|
+
directory, and the caller's cwd is restored afterward. Do not use it
|
|
1111
1140
|
concurrently with code that changes cwd outside `invoke()` or from threads
|
|
1112
1141
|
spawned by the invoked command. A generic profile should receive project
|
|
1113
1142
|
fixtures through its `discover_project` callback. The helper does not create or
|
|
@@ -7,9 +7,18 @@
|
|
|
7
7
|
|
|
8
8
|
| Version | License | Install | Release notes |
|
|
9
9
|
| --- | --- | --- | --- |
|
|
10
|
-
| `0.4.
|
|
10
|
+
| `0.4.3` | [Apache-2.0](LICENSE) | `python -m pip install base-cli` | [v0.4.3](https://github.com/basefoundry/base-cli/releases/tag/v0.4.3) |
|
|
11
11
|
|
|
12
|
-
`base-cli` is the
|
|
12
|
+
`base-cli` is the production lifecycle layer for Click and Typer Python CLIs.
|
|
13
|
+
It standardizes context, logging, configuration, cleanup, and machine-readable
|
|
14
|
+
contracts while leaving command and product policy in the consumer application.
|
|
15
|
+
The PyPI distribution is `base-cli`; import it in Python as `base_cli`.
|
|
16
|
+
|
|
17
|
+
It is for teams shipping operational CLIs that need the same diagnostics,
|
|
18
|
+
configuration boundary, cleanup behavior, and automation contracts in every
|
|
19
|
+
command. It is not a parser replacement or an application scaffold: Click and
|
|
20
|
+
Typer still own parsing and command definitions, while the consuming project
|
|
21
|
+
owns its domain policy and services.
|
|
13
22
|
|
|
14
23
|
Install it with:
|
|
15
24
|
|
|
@@ -20,6 +29,11 @@ python -m pip install base-cli
|
|
|
20
29
|
Read the complete documentation at
|
|
21
30
|
<https://basefoundry.github.io/base-cli/>.
|
|
22
31
|
|
|
32
|
+
Compatibility results and the permissioned-adopter policy are documented in
|
|
33
|
+
the [adoption and compatibility evidence guide](https://basefoundry.github.io/base-cli/adoption-evidence/).
|
|
34
|
+
The [compatibility dashboard](https://basefoundry.github.io/base-cli/compatibility-dashboard/)
|
|
35
|
+
shows the declared and CI-tested dependency and platform support boundaries.
|
|
36
|
+
|
|
23
37
|
## Quick start
|
|
24
38
|
|
|
25
39
|
Create a small command with a consistent context, logging, and cleanup
|
|
@@ -56,10 +70,9 @@ documented in [`docs/releasing.md`](https://basefoundry.github.io/base-cli/relea
|
|
|
56
70
|
The package is distributed under the Apache License 2.0. Base itself remains
|
|
57
71
|
licensed separately under AGPL-3.0-or-later.
|
|
58
72
|
|
|
59
|
-
`base_cli` is
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
library, not part of its generic contract.
|
|
73
|
+
`base_cli` is designed to be embedded by applications rather than to define
|
|
74
|
+
an application's project model. Base is one consumer of the library, not part
|
|
75
|
+
of its generic contract.
|
|
63
76
|
|
|
64
77
|
It is intentionally thin. Click still owns argument parsing and command
|
|
65
78
|
execution, while `base_cli` provides reusable lifecycle behavior:
|
|
@@ -86,6 +99,8 @@ The supported public facade, compatibility promises, deprecation warning
|
|
|
86
99
|
mechanism, and migration requirements are documented in
|
|
87
100
|
[`docs/api-stability.md`](https://basefoundry.github.io/base-cli/api-stability/) and
|
|
88
101
|
[`docs/migrations.md`](https://basefoundry.github.io/base-cli/migrations/).
|
|
102
|
+
The complete generated facade is listed in the
|
|
103
|
+
[`public API reference`](https://basefoundry.github.io/base-cli/api-reference/).
|
|
89
104
|
|
|
90
105
|
Security reporting, runtime trust boundaries, threat assumptions, and the
|
|
91
106
|
release security checklist are documented in [`SECURITY.md`](SECURITY.md),
|
|
@@ -232,6 +247,10 @@ catalog](examples/README.md). It covers a minimal command, nested/plugin Click,
|
|
|
232
247
|
Typer, and automation/observability flows; each example has its own packaging,
|
|
233
248
|
tests, completion, release, and troubleshooting guidance.
|
|
234
249
|
|
|
250
|
+
Teams comparing frameworks can start with the [framework choice guide](docs/framework-choice.md),
|
|
251
|
+
which explains what base-cli adds to Click or Typer and when a different
|
|
252
|
+
framework is a better fit.
|
|
253
|
+
|
|
235
254
|
Teams evaluating adoption can follow the [adopter readiness and migration
|
|
236
255
|
guide](https://basefoundry.github.io/base-cli/adopter-readiness/) and run the three independent
|
|
237
256
|
[downstream compatibility consumers](compatibility/README.md).
|
|
@@ -702,6 +721,10 @@ command execution as `130` without a traceback. After the command outcome has
|
|
|
702
721
|
settled, history, metadata, and cleanup are best-effort teardown: even a second
|
|
703
722
|
interrupt there cannot replace the primary result.
|
|
704
723
|
|
|
724
|
+
Terminal lifecycle status is `ok` for exit code `0`, `aborted` for the
|
|
725
|
+
interrupt exit code `130`, and `error` for other nonzero exit codes. The
|
|
726
|
+
technical outcome remains precise: Ctrl+C is recorded as `interrupted`.
|
|
727
|
+
|
|
705
728
|
An unexpected exception returns `1` with a stable, detail-free message. The run
|
|
706
729
|
ID and diagnostic-log path are included when context and file logging are
|
|
707
730
|
available. The traceback is kept in the persistent log when enabled and is
|
|
@@ -1055,8 +1078,9 @@ stdout or stderr for expected usage or application failures.
|
|
|
1055
1078
|
|
|
1056
1079
|
`invoke()` sets `HOME` plus the relevant `USERPROFILE`, `LOCALAPPDATA`, and
|
|
1057
1080
|
`XDG_CACHE_HOME` values when requested, and supplies `cwd` to the invocation for
|
|
1058
|
-
the duration of the test.
|
|
1059
|
-
|
|
1081
|
+
the duration of the test. All helper calls are serialized because `cwd` is
|
|
1082
|
+
process-global: a no-`cwd` call cannot observe another call's temporary
|
|
1083
|
+
directory, and the caller's cwd is restored afterward. Do not use it
|
|
1060
1084
|
concurrently with code that changes cwd outside `invoke()` or from threads
|
|
1061
1085
|
spawned by the invoked command. A generic profile should receive project
|
|
1062
1086
|
fixtures through its `discover_project` callback. The helper does not create or
|
base_cli-0.4.3/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.4.3
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Downstream compatibility consumers
|
|
2
2
|
|
|
3
|
-
These are three
|
|
4
|
-
evidence
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
These are three maintained reference consumer fixtures used as compatibility
|
|
4
|
+
evidence. They are deliberately separate packages with separate names, entry
|
|
5
|
+
points, and test suites; none imports another fixture or Base product code.
|
|
6
|
+
They are not independent adopters and must not be presented as customer
|
|
7
|
+
outcomes.
|
|
7
8
|
|
|
8
9
|
| Consumer | Shape | Use case | Compatibility outcome |
|
|
9
10
|
| --- | --- | --- | --- |
|
|
@@ -20,6 +21,12 @@ own dependencies, and runs each consumer's tests. This catches import,
|
|
|
20
21
|
packaging, adapter, and contract regressions without relying on repository
|
|
21
22
|
source imports.
|
|
22
23
|
|
|
24
|
+
The downstream job records a dated JSON result as the
|
|
25
|
+
`base-cli-compatibility-evidence-<run-id>` artifact. It binds the result to the
|
|
26
|
+
framework revision and version and lists the exact fixture and matrix that
|
|
27
|
+
passed. See [`adoption-evidence.md`](../docs/adoption-evidence.md) for the
|
|
28
|
+
claim and permission boundary.
|
|
29
|
+
|
|
23
30
|
The same workflow runs the Typer adapter and Beacon fixture against Typer
|
|
24
31
|
0.25.1, 0.26.0, and 0.27.1 on Python 3.10 through 3.14. This matrix covers the
|
|
25
32
|
transition from Click's public command classes to Typer's vendored Click fork.
|
|
@@ -35,4 +42,4 @@ for tests in compatibility/consumers/*/tests; do python -m pytest "$tests"; done
|
|
|
35
42
|
```
|
|
36
43
|
|
|
37
44
|
The fixtures are not customer claims. A permissioned public adopter can be
|
|
38
|
-
|
|
45
|
+
added as a separate record while retaining the same downstream contract tests.
|
|
@@ -11,7 +11,8 @@ Before the first production pilot, the adopter should be able to check every
|
|
|
11
11
|
box below:
|
|
12
12
|
|
|
13
13
|
- [ ] Pin a supported `base-cli` minor release (for example, `~=0.4.0`) and
|
|
14
|
-
record Click,
|
|
14
|
+
record Click, the optional YAML extra (when used), and any other integration
|
|
15
|
+
versions in a lock file.
|
|
15
16
|
- [ ] Run the adopter's command suite on CPython 3.10--3.14 on every platform
|
|
16
17
|
the product supports; retain at least one installed-wheel smoke job.
|
|
17
18
|
- [ ] Use only the documented `base_cli` facade and module `__all__` exports;
|
|
@@ -72,18 +73,18 @@ release-blocking finding back to the compatibility register.
|
|
|
72
73
|
|
|
73
74
|
## Evidence and downstream compatibility
|
|
74
75
|
|
|
75
|
-
The repository does not claim a customer identity without permission.
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
The repository does not claim a customer identity without permission. Three
|
|
77
|
+
maintained reference fixtures provide compatibility evidence, but they are not
|
|
78
|
+
independent adopters or customer outcomes:
|
|
78
79
|
|
|
79
80
|
- **Atlas** — a Click inventory command migrated without rebuilding its tree;
|
|
80
81
|
- **Beacon** — a typed Typer deployment command using the optional adapter; and
|
|
81
82
|
- **Cinder** — a scheduled reconciliation command with dry-run and JSON output.
|
|
82
83
|
|
|
83
84
|
Each fixture has its own package metadata and tests, is installed against the
|
|
84
|
-
published framework wheel in CI, and records a stable invocation outcome.
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
published framework wheel in CI, and records a stable invocation outcome. The
|
|
86
|
+
[adoption and compatibility evidence](adoption-evidence.md) guide defines the
|
|
87
|
+
permissioned adopter program and the public-claim boundary.
|
|
87
88
|
|
|
88
89
|
## Adoption friction and release gate
|
|
89
90
|
|