splent-cli 1.27.0__tar.gz → 1.27.1__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.
- {splent_cli-1.27.0/src/splent_cli.egg-info → splent_cli-1.27.1}/PKG-INFO +2 -2
- {splent_cli-1.27.0 → splent_cli-1.27.1}/pyproject.toml +2 -2
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/database/db_migrate.py +2 -3
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_refine.py +9 -119
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_status.py +46 -13
- splent_cli-1.27.1/src/splent_cli/utils/integrity.py +433 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1/src/splent_cli.egg-info}/PKG-INFO +2 -2
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli.egg-info/requires.txt +1 -1
- splent_cli-1.27.0/src/splent_cli/utils/integrity.py +0 -241
- {splent_cli-1.27.0 → splent_cli-1.27.1}/LICENSE +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/README.md +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/setup.cfg +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/__main__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/cli.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/cache/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/cache/cache_clear.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/cache/cache_orphans.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/cache/cache_outdated.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/cache/cache_prune.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/cache/cache_size.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/cache/cache_status.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/cache/cache_usage.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/cache/cache_versions.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_contracts.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_deps.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_docker.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_env.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_features.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_github.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_infra.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_product.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_pypi.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_pyproject.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/check/check_releases.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/clear/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/clear/clear_build.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/clear/clear_log.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/clear/clear_uploads.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/command/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/command/command_create.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/coverage.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/database/db_console.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/database/db_dump.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/database/db_reset.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/database/db_restore.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/database/db_rollback.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/database/db_seed.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/database/db_status.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/database/db_upgrade.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/doctor.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/env/env_list.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/env/env_set.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/env/env_show.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/export/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/export/export_puml.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_add.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_attach.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_clean.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_clone.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_compat.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_compile.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_contract.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_create.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_delete.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_detach.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_discard.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_drift.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_env.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_fork.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_git.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_hook_add.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_hook_remove.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_hooks.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_impact.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_info.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_inject_config.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_install.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_list.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_order.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_outdated.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_pin.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_pip_install.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_pull.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_release.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_remove.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_rename.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_search.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_sync_template.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_test.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_translate.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_unlock.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_upgrade.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_versions.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/feature/feature_xray.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/lint.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/locust.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/marketplace/login.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/marketplace/logout.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/marketplace/marketplace_auth_utils.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/marketplace/marketplace_index.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/marketplace/whoami.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_auto_require.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_build.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_clean.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_commands.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_config.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_configure.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_console.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_containers.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_create.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_deploy.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_derive.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_deselect.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_down.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_drift.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_env.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_list.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_logs.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_missing.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_port.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_release.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_resolve.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_restart.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_routes.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_run.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_select.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_shell.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_signals.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_sync_template.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_test.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_up.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/product/product_validate.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/release/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/release/release_core.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/release/release_resume.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/selenium.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_add_constraints.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_add_feature.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_compare.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_configurations.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_create.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_deps.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_features.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_fetch.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_info.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_list.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_outdated.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_pin.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_publish.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_remove_feature.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/spl/spl_utils.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/tokens_setup.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/uvl/uvl_utils.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/commands/version.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/compose.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/context.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/credentials.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/index_refresh.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/marketplace.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/marketplace_api.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/marketplace_url.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/preflight.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/pypi_quota.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/registry.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/release.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/release_dry_run.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/release_gate.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/services/spl_store.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/__init__.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/archetype.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/cache_utils.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/command_loader.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/contract_freshness.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/db_utils.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/decorators.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/dynamic_imports.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/feature_installer.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/feature_utils.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/forge.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/git_url.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/io_utils.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/lifecycle.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/manifest.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/path_utils.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/proc.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/redact.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli/utils/template_drift.py +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli.egg-info/SOURCES.txt +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli.egg-info/dependency_links.txt +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli.egg-info/entry_points.txt +0 -0
- {splent_cli-1.27.0 → splent_cli-1.27.1}/src/splent_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: splent_cli
|
|
3
|
-
Version: 1.27.
|
|
3
|
+
Version: 1.27.1
|
|
4
4
|
Summary: SPLENT-CLI is a CLI to be able to work on your development more easily.
|
|
5
5
|
Author-email: DiversoLab <diversolab@us.es>
|
|
6
6
|
Project-URL: Homepage, https://github.com/diverso-lab/splent_cli
|
|
@@ -14,7 +14,7 @@ Requires-Dist: packaging>=24.0
|
|
|
14
14
|
Requires-Dist: python-dotenv>=1.0
|
|
15
15
|
Requires-Dist: pyyaml>=6.0
|
|
16
16
|
Requires-Dist: requests>=2.31.0
|
|
17
|
-
Requires-Dist: splent_framework<2,>=1.16.
|
|
17
|
+
Requires-Dist: splent_framework<2,>=1.16.1
|
|
18
18
|
Requires-Dist: tomli_w>=1.0.0
|
|
19
19
|
Provides-Extra: dev
|
|
20
20
|
Requires-Dist: setuptools==80.3.1; extra == "dev"
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "splent_cli"
|
|
7
|
-
version = "1.27.
|
|
7
|
+
version = "1.27.1"
|
|
8
8
|
description = "SPLENT-CLI is a CLI to be able to work on your development more easily."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13"
|
|
@@ -24,7 +24,7 @@ dependencies = [
|
|
|
24
24
|
"requests>=2.31.0",
|
|
25
25
|
# The CLI drives the framework (paths, feature order, migrations, the
|
|
26
26
|
# app factory) and only works with the same major version of it.
|
|
27
|
-
"splent_framework>=1.16.
|
|
27
|
+
"splent_framework>=1.16.1,<2",
|
|
28
28
|
"tomli_w>=1.0.0",
|
|
29
29
|
]
|
|
30
30
|
|
|
@@ -110,8 +110,7 @@ def _hand_to_directory_owner(path: str) -> None:
|
|
|
110
110
|
is_flag=True,
|
|
111
111
|
help=(
|
|
112
112
|
"Generate a blank migration (no autogenerate) and keep it for manual "
|
|
113
|
-
"editing
|
|
114
|
-
"feature's table — Alembic cannot autodetect runtime-injected mixins."
|
|
113
|
+
"editing (data migrations or hand-written changes)."
|
|
115
114
|
),
|
|
116
115
|
)
|
|
117
116
|
@context.requires_product
|
|
@@ -243,7 +242,7 @@ def db_migrate(feature, message, empty):
|
|
|
243
242
|
)
|
|
244
243
|
|
|
245
244
|
# A blank migration requested with --empty is intentional: keep it so the
|
|
246
|
-
# user can fill in upgrade()/downgrade() by hand (e.g.
|
|
245
|
+
# user can fill in upgrade()/downgrade() by hand (e.g. a data migration).
|
|
247
246
|
if empty:
|
|
248
247
|
if newest:
|
|
249
248
|
_format_migration(newest)
|
|
@@ -6,7 +6,6 @@ Reads the base feature's contract, presents extensible points,
|
|
|
6
6
|
and generates the [tool.splent.refinement] section in pyproject.toml.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
import ast
|
|
10
9
|
import os
|
|
11
10
|
import re
|
|
12
11
|
import tomllib
|
|
@@ -521,137 +520,28 @@ def _scaffold_init(
|
|
|
521
520
|
return True
|
|
522
521
|
|
|
523
522
|
|
|
524
|
-
def _model_table_name(class_name: str) -> str:
|
|
525
|
-
"""Default table name of a model class: CamelCase to snake_case."""
|
|
526
|
-
return re.sub(r"(?<!^)(?=[A-Z])", "_", class_name).lower()
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
def _own_tables(models_path: str) -> set[str]:
|
|
530
|
-
"""Tables the refiner's own models.py declares (db.Model subclasses).
|
|
531
|
-
|
|
532
|
-
``__tablename__`` wins when it is a string literal; abstract models and
|
|
533
|
-
mixins (classes that do not subclass db.Model) declare no table.
|
|
534
|
-
"""
|
|
535
|
-
try:
|
|
536
|
-
with open(models_path, "r", encoding="utf-8") as f:
|
|
537
|
-
tree = ast.parse(f.read())
|
|
538
|
-
except (OSError, SyntaxError, ValueError):
|
|
539
|
-
return set()
|
|
540
|
-
|
|
541
|
-
tables = set()
|
|
542
|
-
for node in tree.body:
|
|
543
|
-
if not isinstance(node, ast.ClassDef):
|
|
544
|
-
continue
|
|
545
|
-
is_model = any(
|
|
546
|
-
(isinstance(b, ast.Attribute) and b.attr == "Model")
|
|
547
|
-
or (isinstance(b, ast.Name) and b.id == "Model")
|
|
548
|
-
for b in node.bases
|
|
549
|
-
)
|
|
550
|
-
if not is_model:
|
|
551
|
-
continue
|
|
552
|
-
name = _model_table_name(node.name)
|
|
553
|
-
abstract = False
|
|
554
|
-
for stmt in node.body:
|
|
555
|
-
if not isinstance(stmt, ast.Assign) or not isinstance(
|
|
556
|
-
stmt.value, ast.Constant
|
|
557
|
-
):
|
|
558
|
-
continue
|
|
559
|
-
for target in stmt.targets:
|
|
560
|
-
if not isinstance(target, ast.Name):
|
|
561
|
-
continue
|
|
562
|
-
if target.id == "__tablename__" and isinstance(stmt.value.value, str):
|
|
563
|
-
name = stmt.value.value
|
|
564
|
-
elif target.id == "__abstract__" and stmt.value.value is True:
|
|
565
|
-
abstract = True
|
|
566
|
-
if not abstract:
|
|
567
|
-
tables.add(name)
|
|
568
|
-
return tables
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
def _update_env_py(
|
|
572
|
-
feature_path: str,
|
|
573
|
-
ns: str,
|
|
574
|
-
feature_name: str,
|
|
575
|
-
extend_models: list[tuple[str, str]],
|
|
576
|
-
) -> bool:
|
|
577
|
-
"""Update the feature's migrations/env.py to include refined tables.
|
|
578
|
-
|
|
579
|
-
Alembic's autogenerate only detects changes in tables listed in
|
|
580
|
-
FEATURE_TABLES. Refinement features add columns to tables owned by
|
|
581
|
-
the base feature, so we need to include those tables explicitly. An
|
|
582
|
-
explicit set turns the framework's auto-detection off, so the
|
|
583
|
-
refiner's own tables (from its models.py) are listed as well, and a set
|
|
584
|
-
written before is merged rather than replaced.
|
|
585
|
-
|
|
586
|
-
Returns True when env.py was written. FEATURE_TABLES that is missing,
|
|
587
|
-
spread over several lines or computed is left alone (False), since
|
|
588
|
-
rewriting it could lose what the developer put there.
|
|
589
|
-
"""
|
|
590
|
-
ns_safe = normalize_namespace(ns)
|
|
591
|
-
pkg_dir = os.path.join(feature_path, "src", ns_safe, feature_name)
|
|
592
|
-
env_path = os.path.join(pkg_dir, "migrations", "env.py")
|
|
593
|
-
if not os.path.isfile(env_path):
|
|
594
|
-
return False
|
|
595
|
-
|
|
596
|
-
# CamelCase → snake_case: "Notes" → "notes", "UserProfile" → "user_profile"
|
|
597
|
-
table_names = {_model_table_name(model_name) for model_name, _ in extend_models}
|
|
598
|
-
table_names |= _own_tables(os.path.join(pkg_dir, "models.py"))
|
|
599
|
-
|
|
600
|
-
with open(env_path, "r", encoding="utf-8") as f:
|
|
601
|
-
content = f.read()
|
|
602
|
-
|
|
603
|
-
pattern = re.compile(r"^FEATURE_TABLES\s*=\s*(set\(\)|\{[^}\n]*\})", re.MULTILINE)
|
|
604
|
-
match = pattern.search(content)
|
|
605
|
-
if not match:
|
|
606
|
-
return False
|
|
607
|
-
current = match.group(1)
|
|
608
|
-
if current != "set()":
|
|
609
|
-
try:
|
|
610
|
-
existing = ast.literal_eval(current)
|
|
611
|
-
except (SyntaxError, ValueError):
|
|
612
|
-
return False
|
|
613
|
-
if not isinstance(existing, set) or not all(
|
|
614
|
-
isinstance(t, str) for t in existing
|
|
615
|
-
):
|
|
616
|
-
return False
|
|
617
|
-
table_names |= existing
|
|
618
|
-
|
|
619
|
-
tables_str = ", ".join(f'"{t}"' for t in sorted(table_names))
|
|
620
|
-
content = (
|
|
621
|
-
content[: match.start()]
|
|
622
|
-
+ f"FEATURE_TABLES = {{{tables_str}}}"
|
|
623
|
-
+ content[match.end() :]
|
|
624
|
-
)
|
|
625
|
-
|
|
626
|
-
with open(env_path, "w", encoding="utf-8") as f:
|
|
627
|
-
f.write(content)
|
|
628
|
-
return True
|
|
629
|
-
|
|
630
|
-
|
|
631
523
|
def _extend_migration_scope(
|
|
632
524
|
feature_path: str,
|
|
633
525
|
ns: str,
|
|
634
526
|
feature_name: str,
|
|
635
527
|
extend_models: list[tuple[str, str]],
|
|
636
528
|
):
|
|
637
|
-
"""
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
529
|
+
"""Say how the refiner's migrations will cover the columns it injects.
|
|
530
|
+
|
|
531
|
+
env.py is not touched. The framework puts in scope the refiner's own
|
|
532
|
+
tables and the columns its mixins inject into the base tables (with
|
|
533
|
+
their indexes and foreign keys), whatever FEATURE_TABLES holds: an
|
|
534
|
+
explicit set only adds tables to that.
|
|
535
|
+
"""
|
|
641
536
|
pkg_dir = os.path.join(feature_path, "src", normalize_namespace(ns), feature_name)
|
|
642
537
|
if not os.path.isfile(os.path.join(pkg_dir, "migrations", "env.py")):
|
|
643
538
|
click.echo(
|
|
644
539
|
click.style(" skipped: ", dim=True) + "migrations/env.py (not found)"
|
|
645
540
|
)
|
|
646
541
|
return
|
|
647
|
-
# An explicit FEATURE_TABLES turns auto-detection off, so the refiner's
|
|
648
|
-
# own tables have to be listed as well as the extended base tables.
|
|
649
|
-
wanted = {_model_table_name(m) for m, _ in extend_models}
|
|
650
|
-
wanted |= _own_tables(os.path.join(pkg_dir, "models.py"))
|
|
651
|
-
tables = ", ".join(f'"{t}"' for t in sorted(wanted))
|
|
652
542
|
click.echo(
|
|
653
543
|
click.style(" kept: ", dim=True)
|
|
654
|
-
+
|
|
544
|
+
+ "migrations/env.py (the framework migrates the columns the mixin injects)"
|
|
655
545
|
)
|
|
656
546
|
|
|
657
547
|
|
|
@@ -1213,7 +1103,7 @@ def feature_refinement(refiner_name):
|
|
|
1213
1103
|
# Clean up scaffold files that are not needed for refinement features
|
|
1214
1104
|
_clean_scaffold_for_refinement(refiner_path, ns, refiner_name)
|
|
1215
1105
|
|
|
1216
|
-
#
|
|
1106
|
+
# Say how the refiner's migrations cover the columns its mixins inject
|
|
1217
1107
|
if extend_models:
|
|
1218
1108
|
_extend_migration_scope(refiner_path, ns, refiner_name, extend_models)
|
|
1219
1109
|
|
|
@@ -380,13 +380,26 @@ def feature_status(as_json, integrity, do_fix, timeline):
|
|
|
380
380
|
|
|
381
381
|
# ── Integrity check ──────────────────────────────────────────
|
|
382
382
|
if integrity or do_fix:
|
|
383
|
-
from splent_cli.utils.integrity import
|
|
383
|
+
from splent_cli.utils.integrity import (
|
|
384
|
+
check_feature_integrity,
|
|
385
|
+
fix_feature,
|
|
386
|
+
resolve_pip_env,
|
|
387
|
+
)
|
|
384
388
|
|
|
385
389
|
click.echo()
|
|
386
390
|
click.secho(" Integrity check", bold=True)
|
|
387
391
|
click.echo(click.style(f" {'─' * 66}", fg="bright_black"))
|
|
388
392
|
|
|
389
|
-
|
|
393
|
+
# The pip checks look where the product runs: its web container.
|
|
394
|
+
pip_env = resolve_pip_env(product, product_path, context.resolve_env())
|
|
395
|
+
if pip_env["kind"] == "unavailable":
|
|
396
|
+
click.echo(
|
|
397
|
+
click.style(
|
|
398
|
+
f" pip checks not verified, {pip_env['reason']}.", dim=True
|
|
399
|
+
)
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
total_ok = total_fail = total_skip = 0
|
|
390
403
|
|
|
391
404
|
for key, entry in sorted(features.items()):
|
|
392
405
|
name = entry.get("name", key)
|
|
@@ -395,38 +408,58 @@ def feature_status(as_json, integrity, do_fix, timeline):
|
|
|
395
408
|
state = entry.get("state", "declared")
|
|
396
409
|
|
|
397
410
|
results = check_feature_integrity(
|
|
398
|
-
product_path, ns_safe, name, version, state
|
|
411
|
+
product_path, ns_safe, name, version, state, pip_env=pip_env
|
|
399
412
|
)
|
|
400
413
|
|
|
401
|
-
|
|
402
|
-
|
|
414
|
+
issues = [r for r in results if r["ok"] is False]
|
|
415
|
+
skipped = any(r["ok"] is None for r in results)
|
|
416
|
+
name_color = "red" if issues else "yellow" if skipped else "green"
|
|
403
417
|
click.echo(f"\n {click.style(name, fg=name_color, bold=True)}")
|
|
404
418
|
|
|
405
419
|
for r in results:
|
|
406
|
-
if r["ok"]:
|
|
420
|
+
if r["ok"] is True:
|
|
407
421
|
total_ok += 1
|
|
408
422
|
click.echo(
|
|
409
423
|
click.style(" [✔] ", fg="green")
|
|
410
424
|
+ f"{r['check']}: {r['detail']}"
|
|
411
425
|
)
|
|
412
|
-
|
|
426
|
+
elif r["ok"] is False:
|
|
413
427
|
total_fail += 1
|
|
414
428
|
click.echo(
|
|
415
429
|
click.style(" [✖] ", fg="red")
|
|
416
430
|
+ f"{r['check']}: {r['detail']}"
|
|
417
431
|
)
|
|
432
|
+
else:
|
|
433
|
+
total_skip += 1
|
|
434
|
+
click.echo(
|
|
435
|
+
click.style(
|
|
436
|
+
f" [-] {r['check']}: {r['detail']}", dim=True
|
|
437
|
+
)
|
|
438
|
+
)
|
|
418
439
|
|
|
419
|
-
if
|
|
420
|
-
|
|
421
|
-
|
|
440
|
+
if issues and do_fix:
|
|
441
|
+
fix_feature(
|
|
442
|
+
product_path,
|
|
443
|
+
workspace,
|
|
444
|
+
ns_safe,
|
|
445
|
+
name,
|
|
446
|
+
version,
|
|
447
|
+
issues,
|
|
448
|
+
pip_env=pip_env,
|
|
449
|
+
)
|
|
422
450
|
|
|
423
451
|
click.echo()
|
|
424
|
-
if total_fail == 0:
|
|
452
|
+
if total_fail == 0 and total_skip == 0:
|
|
425
453
|
click.secho(f" ✅ All {total_ok} checks passed.", fg="green")
|
|
426
454
|
else:
|
|
455
|
+
parts = [f"{total_ok} passed"]
|
|
456
|
+
if total_fail:
|
|
457
|
+
parts.append(f"{total_fail} failed")
|
|
458
|
+
if total_skip:
|
|
459
|
+
parts.append(f"{total_skip} not verified")
|
|
427
460
|
click.secho(
|
|
428
|
-
f" {
|
|
429
|
-
fg="red" if total_fail else "
|
|
461
|
+
f" {', '.join(parts)}.",
|
|
462
|
+
fg="red" if total_fail else "yellow",
|
|
430
463
|
)
|
|
431
464
|
|
|
432
465
|
else:
|