atdd 0.2.0__tar.gz → 0.2.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.
- {atdd-0.2.0/src/atdd.egg-info → atdd-0.2.2}/PKG-INFO +1 -1
- {atdd-0.2.0 → atdd-0.2.2}/pyproject.toml +2 -2
- atdd-0.2.2/src/atdd/__init__.py +6 -0
- atdd-0.2.2/src/atdd/__main__.py +4 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/cli.py +11 -1
- atdd-0.2.2/src/atdd/version_check.py +126 -0
- {atdd-0.2.0 → atdd-0.2.2/src/atdd.egg-info}/PKG-INFO +1 -1
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd.egg-info/SOURCES.txt +2 -0
- atdd-0.2.2/src/atdd.egg-info/entry_points.txt +2 -0
- atdd-0.2.0/src/atdd/tester/validators/__init__.py +0 -0
- atdd-0.2.0/src/atdd.egg-info/entry_points.txt +0 -2
- {atdd-0.2.0 → atdd-0.2.2}/LICENSE +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/README.md +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/setup.cfg +0 -0
- {atdd-0.2.0/src/atdd → atdd-0.2.2/src/atdd/coach}/__init__.py +0 -0
- {atdd-0.2.0/src/atdd/coach → atdd-0.2.2/src/atdd/coach/commands}/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/add_persistence_metadata.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/analyze_migrations.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/consumers.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/infer_governance_status.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/initializer.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/interface.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/inventory.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/migration.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/registry.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/session.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/sync.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/test_interface.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/test_runner.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/tests/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/tests/test_telemetry_array_validation.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/commands/traceability.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/conventions/session.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/overlays/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/overlays/claude.md +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/schemas/config.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/schemas/manifest.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/templates/ATDD.md +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/templates/SESSION-TEMPLATE.md +0 -0
- {atdd-0.2.0/src/atdd/coach/commands → atdd-0.2.2/src/atdd/coach/utils}/__init__.py +0 -0
- {atdd-0.2.0/src/atdd/coach/utils → atdd-0.2.2/src/atdd/coach/utils/graph}/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/utils/graph/urn.py +0 -0
- {atdd-0.2.0/src/atdd/coach/utils/graph → atdd-0.2.2/src/atdd/coach/validators}/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/validators/shared_fixtures.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/validators/test_enrich_wagon_registry.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/validators/test_registry.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/validators/test_session_validation.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/validators/test_traceability.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/validators/test_update_feature_paths.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coach/validators/test_validate_contract_consumers.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/adapter.recipe.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/backend.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/boundaries.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/commons.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/complexity.recipe.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/component-naming.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/design.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/design.recipe.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/dto.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/frontend.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/green.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/presentation.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/refactor.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/technology.convention.yaml +0 -0
- {atdd-0.2.0/src/atdd/coach/validators → atdd-0.2.2/src/atdd/coder/conventions/tests}/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/tests/test_adapter_recipe.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/tests/test_complexity_recipe.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/tests/test_component_taxonomy.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/tests/test_component_urn_naming.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/tests/test_thinness_recipe.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/thinness.recipe.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/train.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/conventions/verification.protocol.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/schemas/design_system.schema.json +0 -0
- {atdd-0.2.0/src/atdd/coder/conventions/tests → atdd-0.2.2/src/atdd/coder/validators}/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_commons_structure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_complexity.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_cross_language_consistency.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_design_system_compliance.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_dto_testing_patterns.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_green_cross_stack_layers.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_green_layer_dependencies.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_green_python_layer_structure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_green_supabase_layer_structure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_import_boundaries.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_init_file_urns.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_preact_layer_boundaries.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_presentation_convention.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_python_architecture.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_quality_metrics.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_station_master_pattern.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_train_infrastructure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_train_urns.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_typescript_architecture.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_usecase_structure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/coder/validators/test_wagon_boundaries.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/conftest.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/acceptance.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/appendix.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/artifact-naming.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/component.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/criteria.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/feature.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/interface.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/steps.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/train.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/wagon.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/conventions/wmbt.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/schemas/acceptance.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/schemas/appendix.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/schemas/component.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/schemas/feature.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/schemas/train.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/schemas/wagon.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/schemas/wmbt.schema.json +0 -0
- {atdd-0.2.0/src/atdd/coder → atdd-0.2.2/src/atdd/planner}/validators/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/conftest.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/test_draft_wagon_registry.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/test_plan_cross_refs.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/test_plan_uniqueness.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/test_plan_urn_resolution.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/test_plan_wagons.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/test_train_validation.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/test_wagon_urn_chain.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/test_wmbt_consistency.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/planner/validators/test_wmbt_vocabulary.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/conventions/artifact.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/conventions/contract.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/conventions/filename.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/conventions/migration.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/conventions/red.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/conventions/routing.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/conventions/telemetry.convention.yaml +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/a11y.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/artifact.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/contract.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/contract.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/db.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/e2e.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/edge_function.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/event.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/http.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/job.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/load.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/metric.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/pack.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/realtime.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/rls.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/script.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/sec.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/storage.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/telemetry.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/telemetry_tracking_manifest.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/test_filename.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/test_intent.schema.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/unit.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/visual.tmpl.json +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/schemas/ws.tmpl.json +0 -0
- {atdd-0.2.0/src/atdd/planner/validators → atdd-0.2.2/src/atdd/tester/utils}/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/utils/filename.py +0 -0
- {atdd-0.2.0/src/atdd/tester/utils → atdd-0.2.2/src/atdd/tester/validators}/__init__.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/cleanup_duplicate_headers.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/cleanup_duplicate_headers_v2.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/conftest.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/coverage_gap_report.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/fix_dual_ac_references.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/remove_duplicate_lines.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_acceptance_urn_filename_mapping.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_acceptance_urn_separator.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_artifact_naming_category.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_contract_schema_compliance.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_contracts_structure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_coverage_adequacy.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_dual_ac_reference.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_fixture_validity.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_isolation.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_migration_coverage.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_migration_criteria.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_migration_generation.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_python_test_naming.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_red_layer_validation.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_red_python_layer_structure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_red_supabase_layer_structure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_telemetry_structure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_typescript_test_naming.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_typescript_test_structure.py +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd.egg-info/dependency_links.txt +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd.egg-info/requires.txt +0 -0
- {atdd-0.2.0 → atdd-0.2.2}/src/atdd.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "atdd"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "ATDD Platform - Acceptance Test Driven Development toolkit"
|
|
9
9
|
requires-python = ">=3.10"
|
|
10
10
|
readme = "README.md"
|
|
@@ -15,7 +15,7 @@ dependencies = ["pyyaml"]
|
|
|
15
15
|
dev = ["pytest", "pytest-xdist"]
|
|
16
16
|
|
|
17
17
|
[project.scripts]
|
|
18
|
-
atdd = "atdd.cli:
|
|
18
|
+
atdd = "atdd.cli:cli"
|
|
19
19
|
|
|
20
20
|
[tool.setuptools.packages.find]
|
|
21
21
|
where = ["src"]
|
|
@@ -41,6 +41,7 @@ from atdd.coach.commands.registry import RegistryUpdater
|
|
|
41
41
|
from atdd.coach.commands.initializer import ProjectInitializer
|
|
42
42
|
from atdd.coach.commands.session import SessionManager
|
|
43
43
|
from atdd.coach.commands.sync import AgentConfigSync
|
|
44
|
+
from atdd.version_check import print_update_notice
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
class ATDDCoach:
|
|
@@ -400,5 +401,14 @@ Phase descriptions:
|
|
|
400
401
|
return 0
|
|
401
402
|
|
|
402
403
|
|
|
404
|
+
def cli() -> int:
|
|
405
|
+
"""CLI entry point with version check."""
|
|
406
|
+
try:
|
|
407
|
+
result = main()
|
|
408
|
+
finally:
|
|
409
|
+
print_update_notice()
|
|
410
|
+
return result
|
|
411
|
+
|
|
412
|
+
|
|
403
413
|
if __name__ == "__main__":
|
|
404
|
-
sys.exit(
|
|
414
|
+
sys.exit(cli())
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Version check for ATDD CLI.
|
|
3
|
+
|
|
4
|
+
Checks PyPI for newer versions and notifies users. Uses a cached check
|
|
5
|
+
to avoid adding latency to every command.
|
|
6
|
+
|
|
7
|
+
Cache location: ~/.atdd/version_cache.json
|
|
8
|
+
Disable: Set ATDD_NO_UPDATE_CHECK=1 environment variable
|
|
9
|
+
"""
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
import time
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Optional, Tuple
|
|
16
|
+
from urllib.request import urlopen
|
|
17
|
+
from urllib.error import URLError
|
|
18
|
+
|
|
19
|
+
from atdd import __version__
|
|
20
|
+
|
|
21
|
+
# Check once per day (86400 seconds)
|
|
22
|
+
CHECK_INTERVAL = 86400
|
|
23
|
+
CACHE_DIR = Path.home() / ".atdd"
|
|
24
|
+
CACHE_FILE = CACHE_DIR / "version_cache.json"
|
|
25
|
+
PYPI_URL = "https://pypi.org/pypi/atdd/json"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _parse_version(version: str) -> Tuple[int, ...]:
|
|
29
|
+
"""Parse version string into tuple for comparison."""
|
|
30
|
+
try:
|
|
31
|
+
return tuple(int(x) for x in version.split(".")[:3])
|
|
32
|
+
except (ValueError, AttributeError):
|
|
33
|
+
return (0, 0, 0)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _is_newer(latest: str, current: str) -> bool:
|
|
37
|
+
"""Check if latest version is newer than current."""
|
|
38
|
+
return _parse_version(latest) > _parse_version(current)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _load_cache() -> dict:
|
|
42
|
+
"""Load version cache from disk."""
|
|
43
|
+
try:
|
|
44
|
+
if CACHE_FILE.exists():
|
|
45
|
+
with open(CACHE_FILE) as f:
|
|
46
|
+
return json.load(f)
|
|
47
|
+
except (json.JSONDecodeError, OSError):
|
|
48
|
+
pass
|
|
49
|
+
return {}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _save_cache(data: dict) -> None:
|
|
53
|
+
"""Save version cache to disk."""
|
|
54
|
+
try:
|
|
55
|
+
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
|
56
|
+
with open(CACHE_FILE, "w") as f:
|
|
57
|
+
json.dump(data, f)
|
|
58
|
+
except OSError:
|
|
59
|
+
pass # Silently fail if we can't write cache
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _fetch_latest_version() -> Optional[str]:
|
|
63
|
+
"""Fetch latest version from PyPI."""
|
|
64
|
+
try:
|
|
65
|
+
with urlopen(PYPI_URL, timeout=2) as response:
|
|
66
|
+
data = json.loads(response.read().decode())
|
|
67
|
+
return data.get("info", {}).get("version")
|
|
68
|
+
except (URLError, json.JSONDecodeError, OSError, TimeoutError):
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def check_for_updates() -> Optional[str]:
|
|
73
|
+
"""
|
|
74
|
+
Check for updates if cache is stale.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Message to display if update available, None otherwise.
|
|
78
|
+
"""
|
|
79
|
+
# Respect disable flag
|
|
80
|
+
if os.environ.get("ATDD_NO_UPDATE_CHECK", "").lower() in ("1", "true", "yes"):
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
# Skip if running in development (version 0.0.0)
|
|
84
|
+
if __version__ == "0.0.0":
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
cache = _load_cache()
|
|
88
|
+
now = time.time()
|
|
89
|
+
last_check = cache.get("last_check", 0)
|
|
90
|
+
cached_latest = cache.get("latest_version")
|
|
91
|
+
|
|
92
|
+
# Check if cache is fresh
|
|
93
|
+
if now - last_check < CHECK_INTERVAL and cached_latest:
|
|
94
|
+
latest = cached_latest
|
|
95
|
+
else:
|
|
96
|
+
# Fetch from PyPI
|
|
97
|
+
latest = _fetch_latest_version()
|
|
98
|
+
if latest:
|
|
99
|
+
_save_cache({
|
|
100
|
+
"last_check": now,
|
|
101
|
+
"latest_version": latest,
|
|
102
|
+
})
|
|
103
|
+
elif cached_latest:
|
|
104
|
+
# Use cached version if fetch failed
|
|
105
|
+
latest = cached_latest
|
|
106
|
+
else:
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
# Compare versions
|
|
110
|
+
if latest and _is_newer(latest, __version__):
|
|
111
|
+
return (
|
|
112
|
+
f"\nA new version of atdd is available: {__version__} → {latest}\n"
|
|
113
|
+
f"Run `pip install --upgrade atdd` to update."
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def print_update_notice() -> None:
|
|
120
|
+
"""Print update notice to stderr if available."""
|
|
121
|
+
try:
|
|
122
|
+
notice = check_for_updates()
|
|
123
|
+
if notice:
|
|
124
|
+
print(notice, file=sys.stderr)
|
|
125
|
+
except Exception:
|
|
126
|
+
pass # Never fail the main command due to version check
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{atdd-0.2.0/src/atdd/coach/validators → atdd-0.2.2/src/atdd/coder/conventions/tests}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{atdd-0.2.0/src/atdd/coder/conventions/tests → atdd-0.2.2/src/atdd/coder/validators}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{atdd-0.2.0 → atdd-0.2.2}/src/atdd/tester/validators/test_acceptance_urn_filename_mapping.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|