splent-cli 1.50.1__tar.gz → 1.52.0__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.50.1/src/splent_cli.egg-info → splent_cli-1.52.0}/PKG-INFO +1 -1
- {splent_cli-1.50.1 → splent_cli-1.52.0}/pyproject.toml +1 -1
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_release.py +29 -12
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/release/release_resume.py +41 -1
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/frontend.py +4 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/registry.py +17 -11
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/release.py +16 -1
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/release_gate.py +2 -2
- splent_cli-1.52.0/src/splent_cli/services/release_workspace.py +180 -0
- splent_cli-1.52.0/src/splent_cli/services/source_mirror.py +356 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0/src/splent_cli.egg-info}/PKG-INFO +1 -1
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli.egg-info/SOURCES.txt +2 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/COPYING +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/COPYING.LESSER +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/README.md +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/setup.cfg +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/__main__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/cli.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/cache/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/cache/cache_clear.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/cache/cache_orphans.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/cache/cache_outdated.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/cache/cache_prune.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/cache/cache_size.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/cache/cache_status.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/cache/cache_usage.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/cache/cache_versions.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_contracts.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_deps.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_docker.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_env.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_features.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_github.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_infra.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_product.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_pypi.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_pyproject.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_releases.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/check/check_vendor.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/clear/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/clear/clear_build.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/clear/clear_log.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/clear/clear_uploads.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/command/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/command/command_create.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/coverage.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/database/db_console.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/database/db_dump.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/database/db_migrate.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/database/db_reset.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/database/db_restore.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/database/db_rollback.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/database/db_seed.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/database/db_status.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/database/db_upgrade.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/doctor.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/env/env_list.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/env/env_set.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/env/env_show.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/export/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/export/export_puml.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_add.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_attach.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_clean.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_clone.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_compat.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_compile.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_contract.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_create.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_delete.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_detach.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_discard.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_drift.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_env.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_fork.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_frontend_init.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_git.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_hook_add.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_hook_remove.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_hooks.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_impact.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_info.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_inject_config.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_install.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_list.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_npm.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_order.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_outdated.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_pin.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_pip_install.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_pull.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_refine.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_release.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_remove.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_rename.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_search.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_security.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_status.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_sync_template.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_test.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_translate.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_unlock.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_upgrade.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_versions.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/feature/feature_xray.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/lint.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/locust.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/marketplace/login.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/marketplace/logout.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/marketplace/marketplace_auth_utils.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/marketplace/marketplace_index.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/marketplace/whoami.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_auto_require.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_build.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_clean.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_commands.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_config.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_configure.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_console.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_containers.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_create.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_deploy.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_derive.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_deselect.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_down.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_drift.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_env.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_frontend_audit.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_list.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_logs.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_missing.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_params.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_port.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_resolve.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_restart.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_routes.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_run.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_select.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_shell.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_signals.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_sync_template.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_test.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_up.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/product/product_validate.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/release/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/release/release_core.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/selenium.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_add_constraints.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_add_feature.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_compare.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_configurations.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_create.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_deps.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_features.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_fetch.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_info.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_list.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_outdated.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_pin.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_publish.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_remove_feature.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/spl/spl_utils.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/storage/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/storage/storage_migrate.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/tokens_setup.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/uvl/uvl_utils.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/commands/version.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/compose.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/context.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/credentials.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/deploy_bundle.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/editable_refresh.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/image_registry.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/index_refresh.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/marketplace.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/marketplace_api.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/marketplace_url.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/neutral_app.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/own_commands.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/preflight.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/pypi_quota.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/release_dry_run.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/security_scan.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/spl_store.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/services/web_container.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_.gitignore.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_MANIFEST.in.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_README.md.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_commands.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_config.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_docker-compose.dev.yml.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_docker-compose.prod.yml.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_docker.env.example.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_forms.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_frontend.npmrc.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_frontend_scripts.js.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_hooks.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_init.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_init_config.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_init_light.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_init_service.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_migrations_alembic.ini.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_migrations_env.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_migrations_script.py.mako.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_models.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_pyproject.toml.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_pyproject_minimal.toml.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_repositories.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_routes.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_scripts.js.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_seeders.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_services.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_services_service.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_signals.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_templates_index.html.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_tests_conftest.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_tests_e2e.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_tests_functional.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_tests_integration.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_tests_locustfile.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_tests_unit.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/feature/feature_webpack.config.js.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/licenses/COPYING +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/licenses/COPYING.LESSER +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_.env.dev.example.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_.env.prod.example.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_.gitignore.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_00_core_requirements_dev.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_00_install_features.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_01_compile_assets.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_02_0_db_wait_connection.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_02_1_db_create_db_test.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_02_2_db_create_splent_migrations.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_03_initialize_migrations.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_04_handle_migrations.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_05_0_start_app_dev.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_05_1_start_app_prod.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_400.html +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_401.html +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_404.html +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_500.html +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_Dockerfile.dev.dockerignore.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_Dockerfile.dev.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_Dockerfile.prod.dockerignore.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_Dockerfile.prod.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_README.md.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_app.css +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_app.js +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_base_template.html +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_ci_upgrade.yml.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_ci_validate.yml.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_config.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_docker-compose.dev.yml.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_docker-compose.prod.yml.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_dropzone.css +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_entrypoint.dev.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_entrypoint.prod.sh.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_errors.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_favicon.svg +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_init.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_logging.py.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_own.css +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_package.json.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_pyproject.toml.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/templates/product/product_uvl.j2 +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/toolchain/Dockerfile.frontend +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/toolchain/frontend/package-lock.json +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/toolchain/frontend/package.json +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/toolchain/frontend/splent/build.js +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/toolchain/frontend/splent/legacy.js +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/toolchain/frontend/splent/lint.js +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/toolchain/frontend/splent/plugin.js +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/toolchain/frontend/splent/preset.js +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/toolchain/frontend/splent/singletons.json +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/__init__.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/archetype.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/cache_utils.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/ci_services.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/ci_workflow.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/command_loader.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/contract_freshness.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/db_client.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/db_utils.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/decorators.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/deploy_freshness.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/dynamic_imports.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/feature_installer.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/feature_naming.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/feature_params.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/feature_requirements.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/feature_resolution.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/feature_utils.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/forge.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/frontend_check.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/frontend_licenses.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/git_url.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/integrity.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/io_utils.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/lifecycle.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/manifest.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/menu_keys.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/migration_lock.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/npm_semver.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/path_utils.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/proc.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/redact.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/refinement_facts.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/running_version.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/template_drift.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/toml_edit.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/upgrade_plan.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/uvl_diagnosis.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli/utils/uvl_params.py +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli.egg-info/dependency_links.txt +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli.egg-info/entry_points.txt +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli.egg-info/requires.txt +0 -0
- {splent_cli-1.50.1 → splent_cli-1.52.0}/src/splent_cli.egg-info/top_level.txt +0 -0
|
@@ -6,6 +6,7 @@ import contextlib
|
|
|
6
6
|
import json
|
|
7
7
|
import os
|
|
8
8
|
import subprocess
|
|
9
|
+
import sys
|
|
9
10
|
import tempfile
|
|
10
11
|
|
|
11
12
|
import click
|
|
@@ -28,6 +29,8 @@ from splent_cli.services import (
|
|
|
28
29
|
image_registry,
|
|
29
30
|
release,
|
|
30
31
|
release_gate,
|
|
32
|
+
release_workspace,
|
|
33
|
+
source_mirror,
|
|
31
34
|
)
|
|
32
35
|
from splent_cli.utils.proc import run, require_docker
|
|
33
36
|
|
|
@@ -39,19 +42,9 @@ def _guard_all_features_pinned(product_path: str):
|
|
|
39
42
|
features_prod declare, so an editable entry in any of them makes the
|
|
40
43
|
release irreproducible, not only one in the base list.
|
|
41
44
|
"""
|
|
42
|
-
from splent_cli.utils.feature_utils import
|
|
43
|
-
FEATURE_LIST_KEYS,
|
|
44
|
-
load_product_pyproject,
|
|
45
|
-
read_feature_list,
|
|
46
|
-
)
|
|
45
|
+
from splent_cli.utils.feature_utils import load_product_pyproject
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
editable = [
|
|
50
|
-
(key, entry)
|
|
51
|
-
for key in FEATURE_LIST_KEYS
|
|
52
|
-
for entry in read_feature_list(data, key)
|
|
53
|
-
if "@" not in entry
|
|
54
|
-
]
|
|
47
|
+
editable = release_workspace.editable_features(load_product_pyproject(product_path))
|
|
55
48
|
if not editable:
|
|
56
49
|
return
|
|
57
50
|
|
|
@@ -385,6 +378,12 @@ def _left_out_flags(channels) -> list[str]:
|
|
|
385
378
|
is_flag=True,
|
|
386
379
|
help="Do not build or push the Docker image for this version.",
|
|
387
380
|
)
|
|
381
|
+
@click.option(
|
|
382
|
+
"--no-mirror",
|
|
383
|
+
is_flag=True,
|
|
384
|
+
help="Do not publish to [tool.splent.release.source_mirror] now, for when it "
|
|
385
|
+
"is down. splent release:resume does it later.",
|
|
386
|
+
)
|
|
388
387
|
@click.option(
|
|
389
388
|
"--allow-unfinished",
|
|
390
389
|
is_flag=True,
|
|
@@ -403,6 +402,7 @@ def product_release(
|
|
|
403
402
|
no_forge,
|
|
404
403
|
no_github,
|
|
405
404
|
no_docker,
|
|
405
|
+
no_mirror,
|
|
406
406
|
allow_unfinished,
|
|
407
407
|
wait,
|
|
408
408
|
):
|
|
@@ -419,8 +419,16 @@ def product_release(
|
|
|
419
419
|
click.secho(f" error: pyproject.toml not found in {product}", fg="red")
|
|
420
420
|
raise SystemExit(1)
|
|
421
421
|
|
|
422
|
+
if release_workspace.in_development_mode(product_path):
|
|
423
|
+
raise SystemExit(
|
|
424
|
+
release_workspace.run_from_head(
|
|
425
|
+
product, product_path, str(context.workspace()), sys.argv[1:]
|
|
426
|
+
)
|
|
427
|
+
)
|
|
428
|
+
|
|
422
429
|
_guard_all_features_pinned(product_path)
|
|
423
430
|
_guard_deployable(str(context.workspace()), product, product_path)
|
|
431
|
+
mirror = None if no_mirror else _declared_source_mirror(product_path)
|
|
424
432
|
|
|
425
433
|
# Determine org/repo for the semver wizard
|
|
426
434
|
repo = release.get_repo_from_path(product_path)
|
|
@@ -502,7 +510,16 @@ def product_release(
|
|
|
502
510
|
),
|
|
503
511
|
post_pypi_hook=_docker_hook,
|
|
504
512
|
wait=wait,
|
|
513
|
+
source_mirror=mirror,
|
|
505
514
|
)
|
|
506
515
|
|
|
507
516
|
|
|
517
|
+
def _declared_source_mirror(product_path: str):
|
|
518
|
+
try:
|
|
519
|
+
return source_mirror.declared(os.path.join(product_path, "pyproject.toml"))
|
|
520
|
+
except source_mirror.MirrorDeclarationError as e:
|
|
521
|
+
click.secho(f" error: {e}", fg="red")
|
|
522
|
+
raise SystemExit(1)
|
|
523
|
+
|
|
524
|
+
|
|
508
525
|
cli_command = product_release
|
|
@@ -33,11 +33,18 @@ import contextlib
|
|
|
33
33
|
import os
|
|
34
34
|
import shutil
|
|
35
35
|
import subprocess
|
|
36
|
+
import sys
|
|
36
37
|
import tempfile
|
|
37
38
|
|
|
38
39
|
import click
|
|
39
40
|
|
|
40
|
-
from splent_cli.services import
|
|
41
|
+
from splent_cli.services import (
|
|
42
|
+
context,
|
|
43
|
+
release,
|
|
44
|
+
release_gate,
|
|
45
|
+
release_workspace,
|
|
46
|
+
source_mirror,
|
|
47
|
+
)
|
|
41
48
|
from splent_cli.utils import forge
|
|
42
49
|
from splent_cli.utils.git_url import _non_interactive_env
|
|
43
50
|
|
|
@@ -322,6 +329,13 @@ def release_resume(target, assume_yes, no_pypi, no_forge, no_github, no_docker,
|
|
|
322
329
|
no_forge = release.no_forge_requested(no_forge, no_github)
|
|
323
330
|
workspace = str(context.workspace())
|
|
324
331
|
path, label, kind = resolve_target(target, workspace)
|
|
332
|
+
if kind == "product" and release_workspace.in_development_mode(path):
|
|
333
|
+
raise SystemExit(
|
|
334
|
+
release_workspace.run_from_head(
|
|
335
|
+
os.path.basename(path), path, workspace, sys.argv[1:]
|
|
336
|
+
)
|
|
337
|
+
)
|
|
338
|
+
|
|
325
339
|
# What the hints this run prints tell the operator to run next. A withheld
|
|
326
340
|
# image stays withheld.
|
|
327
341
|
hint_target = f"{target} --no-docker" if no_docker else target
|
|
@@ -539,6 +553,27 @@ def release_resume(target, assume_yes, no_pypi, no_forge, no_github, no_docker,
|
|
|
539
553
|
if make_snapshot:
|
|
540
554
|
steps.append(f"create the local snapshot for {tag}")
|
|
541
555
|
|
|
556
|
+
# The product's official repository, once the forge has what it copies.
|
|
557
|
+
mirror = None
|
|
558
|
+
if kind == "product" and release_gate.FORGE in channels:
|
|
559
|
+
try:
|
|
560
|
+
mirror = source_mirror.declared(pyproject)
|
|
561
|
+
if mirror:
|
|
562
|
+
mirror_steps = source_mirror.missing(mirror, path, tag)
|
|
563
|
+
steps.extend(mirror_steps)
|
|
564
|
+
mirror = mirror if mirror_steps else None
|
|
565
|
+
except source_mirror.MirrorDeclarationError as e:
|
|
566
|
+
click.secho(f" error: {e}", fg="red")
|
|
567
|
+
raise SystemExit(1)
|
|
568
|
+
except source_mirror.MirrorUnreachable as e:
|
|
569
|
+
stuck.append(
|
|
570
|
+
release_gate.ChannelStatus(
|
|
571
|
+
source_mirror.CHANNEL,
|
|
572
|
+
summary=f"could not ask {mirror.web_url} what it has ({e})",
|
|
573
|
+
)
|
|
574
|
+
)
|
|
575
|
+
mirror = None
|
|
576
|
+
|
|
542
577
|
click.echo()
|
|
543
578
|
if not steps:
|
|
544
579
|
if stuck:
|
|
@@ -675,6 +710,11 @@ def release_resume(target, assume_yes, no_pypi, no_forge, no_github, no_docker,
|
|
|
675
710
|
if failure:
|
|
676
711
|
failures.append(f"the release for {tag} on the forge ({failure})")
|
|
677
712
|
|
|
713
|
+
if mirror:
|
|
714
|
+
failure = source_mirror.publish(mirror, path, tag)
|
|
715
|
+
if failure:
|
|
716
|
+
failures.append(f"{tag} on {mirror.web_url} ({failure})")
|
|
717
|
+
|
|
678
718
|
if push_image:
|
|
679
719
|
from splent_cli.commands.product.product_release import release_docker_image
|
|
680
720
|
|
|
@@ -740,6 +740,10 @@ def verify_assets(assets, *, lock=None, production: bool = False) -> list[str]:
|
|
|
740
740
|
if dist.is_dir():
|
|
741
741
|
for path in sorted(dist.rglob("*")):
|
|
742
742
|
name = path.relative_to(dist).as_posix()
|
|
743
|
+
# pip compiles the .py a bundle ships to the browser (a pyodide
|
|
744
|
+
# wrapper) where it installs it: that bytecode is no file of it.
|
|
745
|
+
if "__pycache__" in path.parts:
|
|
746
|
+
continue
|
|
743
747
|
if path.is_file() and name not in listed:
|
|
744
748
|
problems.append(f"assets/dist/{name} is not in the manifest")
|
|
745
749
|
if lock is not None and Path(lock).is_file():
|
|
@@ -402,27 +402,33 @@ def github_create_release(
|
|
|
402
402
|
draft: bool = False,
|
|
403
403
|
prerelease: bool = False,
|
|
404
404
|
timeout: int = 30,
|
|
405
|
+
api_base: str | None = None,
|
|
406
|
+
generate_notes: bool = False,
|
|
405
407
|
) -> ReleaseResult:
|
|
406
|
-
"""Create a release for *tag* on the configured forge
|
|
408
|
+
"""Create a release for *tag* on the configured forge, or at *api_base*.
|
|
407
409
|
|
|
408
410
|
Returns the outcome instead of raising for HTTP failures, so the caller can
|
|
409
411
|
tell "already there" (idempotent rerun) from "refused" (a divergence, since
|
|
410
412
|
the tag exists by the time this runs). Raises :class:`RegistryError` only
|
|
411
413
|
when the forge cannot be reached at all.
|
|
414
|
+
|
|
415
|
+
``generate_notes`` asks GitHub to append what changed since the last release
|
|
416
|
+
to *body*. Only GitHub knows it.
|
|
412
417
|
"""
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
418
|
+
fields = {
|
|
419
|
+
"tag_name": tag,
|
|
420
|
+
"name": name,
|
|
421
|
+
"body": body,
|
|
422
|
+
"draft": draft,
|
|
423
|
+
"prerelease": prerelease,
|
|
424
|
+
}
|
|
425
|
+
if generate_notes:
|
|
426
|
+
fields["generate_release_notes"] = True
|
|
427
|
+
payload = json.dumps(fields).encode()
|
|
422
428
|
headers = _github_headers(token)
|
|
423
429
|
headers["Content-Type"] = "application/json"
|
|
424
430
|
req = _forge_request(
|
|
425
|
-
f"{forge.api_base()}/repos/{org}/{repo}/releases",
|
|
431
|
+
f"{api_base or forge.api_base()}/repos/{org}/{repo}/releases",
|
|
426
432
|
data=payload,
|
|
427
433
|
headers=headers,
|
|
428
434
|
method="POST",
|
|
@@ -16,6 +16,7 @@ import tomllib
|
|
|
16
16
|
import click
|
|
17
17
|
|
|
18
18
|
from splent_cli.services import release_gate
|
|
19
|
+
from splent_cli.services import source_mirror as source_mirror_service
|
|
19
20
|
from splent_cli.utils import forge
|
|
20
21
|
from splent_cli.utils.git_url import _non_interactive_env
|
|
21
22
|
from splent_cli.utils.io_utils import atomic_write
|
|
@@ -1619,6 +1620,7 @@ def run_release_pipeline(
|
|
|
1619
1620
|
post_pypi_hook=None,
|
|
1620
1621
|
wait: bool = False,
|
|
1621
1622
|
neutral: bool = False,
|
|
1623
|
+
source_mirror=None,
|
|
1622
1624
|
):
|
|
1623
1625
|
"""Run the standard release pipeline.
|
|
1624
1626
|
|
|
@@ -1634,7 +1636,8 @@ def run_release_pipeline(
|
|
|
1634
1636
|
7. Commit (local, revertible)
|
|
1635
1637
|
8. Build and upload to PyPI
|
|
1636
1638
|
9. Push the branch, the tag, and create the release on the git host
|
|
1637
|
-
10. (optional)
|
|
1639
|
+
10. (optional) the same on source_mirror, the product's official repository
|
|
1640
|
+
11. (optional) post_pypi_hook, e.g. the snapshot or the Docker image
|
|
1638
1641
|
|
|
1639
1642
|
The order of 8 and 9 is the point. A PyPI version can never be replaced or
|
|
1640
1643
|
removed; a tag that was never pushed costs nothing. Uploading first means a
|
|
@@ -1714,6 +1717,10 @@ def run_release_pipeline(
|
|
|
1714
1717
|
deep=deep,
|
|
1715
1718
|
allow_unfinished=allow_unfinished,
|
|
1716
1719
|
)
|
|
1720
|
+
if source_mirror and to_forge:
|
|
1721
|
+
report.statuses.append(
|
|
1722
|
+
source_mirror_service.check(source_mirror, path, tag)
|
|
1723
|
+
)
|
|
1717
1724
|
release_gate.render(report, header=header)
|
|
1718
1725
|
if not report.ok:
|
|
1719
1726
|
release_gate.refuse(report, resume_target=target)
|
|
@@ -1852,6 +1859,14 @@ def run_release_pipeline(
|
|
|
1852
1859
|
)
|
|
1853
1860
|
if failure:
|
|
1854
1861
|
failures.append(f"the release for {tag} on the git host ({failure})")
|
|
1862
|
+
# Before the image: the version the image reaches production with
|
|
1863
|
+
# must already have its page where the app links to it.
|
|
1864
|
+
if source_mirror:
|
|
1865
|
+
failure = source_mirror_service.publish(source_mirror, path, tag)
|
|
1866
|
+
if failure:
|
|
1867
|
+
failures.append(f"{tag} on {source_mirror.web_url} ({failure})")
|
|
1868
|
+
else:
|
|
1869
|
+
accepted.append(source_mirror.web_url)
|
|
1855
1870
|
else:
|
|
1856
1871
|
create_and_push_tag(path, tag, push=False)
|
|
1857
1872
|
click.secho(
|
|
@@ -195,7 +195,7 @@ def canonical_channel(name) -> str:
|
|
|
195
195
|
return CHANNEL_ALIASES.get(key, key)
|
|
196
196
|
|
|
197
197
|
|
|
198
|
-
_RELEASE_KEYS = {"channels", "registries", "mirrors"}
|
|
198
|
+
_RELEASE_KEYS = {"channels", "registries", "mirrors", "source_mirror"}
|
|
199
199
|
|
|
200
200
|
|
|
201
201
|
def declared_channels(pyproject_path: str) -> tuple[str, ...]:
|
|
@@ -234,7 +234,7 @@ def declared_channels(pyproject_path: str) -> tuple[str, ...]:
|
|
|
234
234
|
raise ChannelDeclarationError(
|
|
235
235
|
"[tool.splent.release] has unknown key(s) "
|
|
236
236
|
+ ", ".join(unknown)
|
|
237
|
-
+ ". The keys are 'channels', 'registries' and '
|
|
237
|
+
+ ". The keys are 'channels', 'registries', 'mirrors' and 'source_mirror', so this was "
|
|
238
238
|
"ignored silently before."
|
|
239
239
|
)
|
|
240
240
|
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"""Releasing what HEAD holds while the checkout is in development mode.
|
|
2
|
+
|
|
3
|
+
A product under development lists its features without a version in
|
|
4
|
+
pyproject.toml, uncommitted, so the app mounts their working copies. HEAD keeps
|
|
5
|
+
them pinned. Such a checkout cannot release as it is, and it should not have to
|
|
6
|
+
change either: a release is what is committed.
|
|
7
|
+
|
|
8
|
+
So product:release and release:resume run from a temporary workspace of their
|
|
9
|
+
own, a worktree of HEAD next to the cache and the product line's model, and the
|
|
10
|
+
checkout moves forward afterwards with its pyproject.toml as it was, bar what
|
|
11
|
+
the release changed in it.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import glob
|
|
17
|
+
import os
|
|
18
|
+
import shutil
|
|
19
|
+
import subprocess
|
|
20
|
+
import sys
|
|
21
|
+
import tempfile
|
|
22
|
+
import tomllib
|
|
23
|
+
|
|
24
|
+
import click
|
|
25
|
+
|
|
26
|
+
from splent_cli.utils.feature_utils import (
|
|
27
|
+
FEATURE_LIST_KEYS,
|
|
28
|
+
load_product_pyproject,
|
|
29
|
+
read_feature_list,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
PYPROJECT = "pyproject.toml"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def editable_features(data: dict) -> list[tuple[str, str]]:
|
|
36
|
+
"""``(list, entry)`` of every feature of a pyproject with no version pinned.
|
|
37
|
+
|
|
38
|
+
Every list counts. A release runs whatever features, features_dev and
|
|
39
|
+
features_prod declare.
|
|
40
|
+
"""
|
|
41
|
+
return [
|
|
42
|
+
(key, entry)
|
|
43
|
+
for key in FEATURE_LIST_KEYS
|
|
44
|
+
for entry in read_feature_list(data, key)
|
|
45
|
+
if "@" not in entry
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _git(path: str, *args: str) -> subprocess.CompletedProcess:
|
|
50
|
+
return subprocess.run(["git", *args], cwd=path, capture_output=True, text=True)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def in_development_mode(product_path: str) -> bool:
|
|
54
|
+
"""Whether the checkout has editable features and HEAD has none."""
|
|
55
|
+
if not editable_features(load_product_pyproject(product_path)):
|
|
56
|
+
return False
|
|
57
|
+
head = _git(product_path, "show", f"HEAD:{PYPROJECT}")
|
|
58
|
+
if head.returncode != 0:
|
|
59
|
+
return False
|
|
60
|
+
try:
|
|
61
|
+
return not editable_features(tomllib.loads(head.stdout))
|
|
62
|
+
except tomllib.TOMLDecodeError:
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _splent(args: list[str], env: dict) -> int:
|
|
67
|
+
"""Run the CLI in the temporary workspace, in this terminal."""
|
|
68
|
+
return subprocess.run(
|
|
69
|
+
[sys.executable, "-m", "splent_cli", *args], env=env
|
|
70
|
+
).returncode
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _merged_pyproject(path: str, ours: str, base: str, theirs: str) -> str | None:
|
|
74
|
+
"""Three-way merge of the checkout's pyproject.toml, None on a conflict."""
|
|
75
|
+
with tempfile.TemporaryDirectory(prefix="splent_pyproject_") as tmp:
|
|
76
|
+
names = []
|
|
77
|
+
for name, content in (("ours", ours), ("base", base), ("theirs", theirs)):
|
|
78
|
+
names.append(os.path.join(tmp, name))
|
|
79
|
+
with open(names[-1], "w", encoding="utf-8") as f:
|
|
80
|
+
f.write(content)
|
|
81
|
+
merged = _git(path, "merge-file", "-p", *names)
|
|
82
|
+
return merged.stdout if merged.returncode == 0 else None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _bring_checkout_forward(product_path: str, start: str, end: str) -> None:
|
|
86
|
+
"""Move the checkout to *end*, its development pyproject.toml kept.
|
|
87
|
+
|
|
88
|
+
Says so when it cannot, and leaves the checkout exactly as it found it.
|
|
89
|
+
"""
|
|
90
|
+
hint = f"Your checkout stays where it was. When it can, run git merge --ff-only {end[:12]}."
|
|
91
|
+
if _git(product_path, "rev-parse", "HEAD").stdout.strip() != start:
|
|
92
|
+
click.secho(f" checkout HEAD moved during the release. {hint}", fg="yellow")
|
|
93
|
+
return
|
|
94
|
+
pyproject = os.path.join(product_path, PYPROJECT)
|
|
95
|
+
with open(pyproject, encoding="utf-8") as f:
|
|
96
|
+
ours = f.read()
|
|
97
|
+
merged = _merged_pyproject(
|
|
98
|
+
product_path,
|
|
99
|
+
ours,
|
|
100
|
+
_git(product_path, "show", f"{start}:{PYPROJECT}").stdout,
|
|
101
|
+
_git(product_path, "show", f"{end}:{PYPROJECT}").stdout,
|
|
102
|
+
)
|
|
103
|
+
if merged is None:
|
|
104
|
+
click.secho(
|
|
105
|
+
f" checkout your {PYPROJECT} and the release's do not merge. {hint}",
|
|
106
|
+
fg="yellow",
|
|
107
|
+
)
|
|
108
|
+
return
|
|
109
|
+
|
|
110
|
+
result = merged
|
|
111
|
+
moved = False
|
|
112
|
+
try:
|
|
113
|
+
_git(product_path, "checkout", "--", PYPROJECT)
|
|
114
|
+
forward = _git(product_path, "merge", "--ff-only", "--quiet", end)
|
|
115
|
+
moved = forward.returncode == 0
|
|
116
|
+
if not moved:
|
|
117
|
+
result = ours
|
|
118
|
+
click.secho(
|
|
119
|
+
f" checkout {forward.stderr.strip()}\n checkout {hint}", fg="yellow"
|
|
120
|
+
)
|
|
121
|
+
except OSError as e:
|
|
122
|
+
result = ours
|
|
123
|
+
click.secho(f" checkout {e}. {hint}", fg="yellow")
|
|
124
|
+
finally:
|
|
125
|
+
with open(pyproject, "w", encoding="utf-8") as f:
|
|
126
|
+
f.write(result)
|
|
127
|
+
if moved:
|
|
128
|
+
click.echo(f" checkout now at {end[:12]}, your {PYPROJECT} is kept")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def run_from_head(
|
|
132
|
+
product: str, product_path: str, workspace: str, argv: list[str]
|
|
133
|
+
) -> int:
|
|
134
|
+
"""Run this command in a temporary workspace holding HEAD. Its exit code.
|
|
135
|
+
|
|
136
|
+
The checkout ends where a release run in it would have, commit included
|
|
137
|
+
when the command stopped halfway, so release:resume can go on from it.
|
|
138
|
+
"""
|
|
139
|
+
start = _git(product_path, "rev-parse", "HEAD").stdout.strip()
|
|
140
|
+
click.secho(
|
|
141
|
+
f" checkout {product} has editable features, so this works from what HEAD "
|
|
142
|
+
f"holds ({start[:12]}).",
|
|
143
|
+
fg="cyan",
|
|
144
|
+
)
|
|
145
|
+
status = _git(product_path, "status", "--porcelain").stdout.splitlines()
|
|
146
|
+
left_out = [line[3:] for line in status if line[3:] != PYPROJECT]
|
|
147
|
+
if left_out:
|
|
148
|
+
click.secho(
|
|
149
|
+
" checkout uncommitted, so left out: "
|
|
150
|
+
+ ", ".join(left_out[:5])
|
|
151
|
+
+ (" ..." if len(left_out) > 5 else ""),
|
|
152
|
+
fg="yellow",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
temporary = tempfile.mkdtemp(prefix="splent_release_")
|
|
156
|
+
worktree = os.path.join(temporary, product)
|
|
157
|
+
try:
|
|
158
|
+
cache = os.path.join(workspace, ".splent_cache")
|
|
159
|
+
for path in [cache, *glob.glob(os.path.join(workspace, "splent_spl_*"))]:
|
|
160
|
+
if os.path.exists(path):
|
|
161
|
+
os.symlink(path, os.path.join(temporary, os.path.basename(path)))
|
|
162
|
+
added = _git(product_path, "worktree", "add", "--detach", worktree, start)
|
|
163
|
+
if added.returncode != 0:
|
|
164
|
+
click.secho(f" error: {added.stderr.strip()}", fg="red")
|
|
165
|
+
return 1
|
|
166
|
+
|
|
167
|
+
env = {**os.environ, "WORKING_DIR": temporary, "SPLENT_APP": product}
|
|
168
|
+
code = _splent(["product:resolve", "--prod", "--strict"], env)
|
|
169
|
+
if code != 0:
|
|
170
|
+
return code
|
|
171
|
+
code = _splent(argv, env)
|
|
172
|
+
|
|
173
|
+
end = _git(worktree, "rev-parse", "HEAD").stdout.strip()
|
|
174
|
+
if end and end != start:
|
|
175
|
+
_bring_checkout_forward(product_path, start, end)
|
|
176
|
+
return code
|
|
177
|
+
finally:
|
|
178
|
+
_git(product_path, "worktree", "remove", "--force", worktree)
|
|
179
|
+
_git(product_path, "worktree", "prune")
|
|
180
|
+
shutil.rmtree(temporary, ignore_errors=True)
|