splent-cli 1.8.0__tar.gz → 1.9.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.8.0/src/splent_cli.egg-info → splent_cli-1.9.1}/PKG-INFO +1 -1
- {splent_cli-1.8.0 → splent_cli-1.9.1}/pyproject.toml +1 -1
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/database/db_migrate.py +39 -3
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_release.py +18 -1
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_xray.py +10 -7
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_deploy.py +6 -2
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_env.py +6 -1
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_add_feature.py +25 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/services/release.py +25 -3
- {splent_cli-1.8.0 → splent_cli-1.9.1/src/splent_cli.egg-info}/PKG-INFO +1 -1
- {splent_cli-1.8.0 → splent_cli-1.9.1}/LICENSE +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/README.md +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/setup.cfg +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/__main__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/cli.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/cache/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/cache/cache_clear.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/cache/cache_orphans.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/cache/cache_outdated.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/cache/cache_prune.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/cache/cache_size.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/cache/cache_status.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/cache/cache_usage.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/cache/cache_versions.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/check_deps.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/check_docker.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/check_env.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/check_features.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/check_github.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/check_infra.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/check_product.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/check_pypi.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/check/check_pyproject.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/clear/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/clear/clear_build.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/clear/clear_log.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/clear/clear_uploads.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/command/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/command/command_create.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/coverage.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/database/db_console.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/database/db_dump.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/database/db_reset.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/database/db_restore.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/database/db_rollback.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/database/db_seed.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/database/db_status.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/database/db_upgrade.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/doctor.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/env/env_list.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/env/env_set.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/env/env_show.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/export/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/export/export_puml.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_add.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_attach.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_clean.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_clone.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_compat.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_compile.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_contract.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_create.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_delete.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_detach.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_discard.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_drift.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_env.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_fork.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_git.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_hook_add.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_hook_remove.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_hooks.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_impact.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_inject_config.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_install.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_list.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_order.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_outdated.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_pin.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_pip_install.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_pull.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_refine.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_remove.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_rename.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_search.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_status.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_sync_template.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_test.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_translate.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_unlock.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_upgrade.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_versions.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/lint.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/locust.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_auto_require.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_build.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_clean.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_commands.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_config.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_configure.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_console.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_containers.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_create.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_derive.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_deselect.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_down.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_drift.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_list.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_logs.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_missing.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_port.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_release.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_resolve.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_restart.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_routes.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_run.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_select.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_shell.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_signals.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_sync_template.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_test.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_up.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_validate.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/release/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/release/release_core.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/selenium.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_add_constraints.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_configurations.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_create.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_deps.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_features.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_fetch.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_info.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_list.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/spl/spl_utils.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/tokens_setup.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/uvl/uvl_utils.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/version.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/services/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/services/compose.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/services/context.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/services/preflight.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/__init__.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/cache_utils.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/command_loader.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/contract_freshness.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/db_utils.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/decorators.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/dynamic_imports.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/feature_installer.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/feature_utils.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/git_url.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/integrity.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/lifecycle.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/manifest.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/path_utils.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/utils/template_drift.py +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli.egg-info/SOURCES.txt +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli.egg-info/dependency_links.txt +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli.egg-info/entry_points.txt +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli.egg-info/requires.txt +0 -0
- {splent_cli-1.8.0 → splent_cli-1.9.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.
|
|
3
|
+
Version: 1.9.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
|
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
|
|
3
3
|
import click
|
|
4
4
|
from flask_migrate import migrate as alembic_migrate
|
|
5
|
+
from flask_migrate import revision as alembic_revision
|
|
5
6
|
|
|
6
7
|
from splent_cli.utils.decorators import requires_db
|
|
7
8
|
from splent_cli.services import context
|
|
@@ -54,14 +55,31 @@ def _is_empty_migration(path: str) -> bool:
|
|
|
54
55
|
@click.option(
|
|
55
56
|
"-m", "message", default=None, help="Migration message (defaults to feature name)."
|
|
56
57
|
)
|
|
58
|
+
@click.option(
|
|
59
|
+
"--empty",
|
|
60
|
+
is_flag=True,
|
|
61
|
+
help=(
|
|
62
|
+
"Generate a blank migration (no autogenerate) and keep it for manual "
|
|
63
|
+
"editing. Required for refinement features that add columns to a base "
|
|
64
|
+
"feature's table — Alembic cannot autodetect runtime-injected mixins."
|
|
65
|
+
),
|
|
66
|
+
)
|
|
57
67
|
@context.requires_product
|
|
58
|
-
def db_migrate(feature, message):
|
|
68
|
+
def db_migrate(feature, message, empty):
|
|
59
69
|
"""
|
|
60
70
|
Generate new migration files for features that have schema changes,
|
|
61
71
|
then apply all pending migrations.
|
|
62
72
|
|
|
63
|
-
Empty migrations (no schema changes detected) are automatically removed
|
|
73
|
+
Empty migrations (no schema changes detected) are automatically removed,
|
|
74
|
+
unless ``--empty`` is passed, in which case a blank migration is created
|
|
75
|
+
and kept so you can write ``upgrade()``/``downgrade()`` by hand.
|
|
64
76
|
"""
|
|
77
|
+
if empty and not feature:
|
|
78
|
+
click.echo(
|
|
79
|
+
click.style("❌ --empty requires a FEATURE argument.", fg="red")
|
|
80
|
+
)
|
|
81
|
+
raise SystemExit(1)
|
|
82
|
+
|
|
65
83
|
if feature:
|
|
66
84
|
dirs = {}
|
|
67
85
|
mdir = MigrationManager.get_feature_migration_dir(feature)
|
|
@@ -108,7 +126,10 @@ def db_migrate(feature, message):
|
|
|
108
126
|
alembic_logger.setLevel(logging.WARNING)
|
|
109
127
|
|
|
110
128
|
try:
|
|
111
|
-
|
|
129
|
+
if empty:
|
|
130
|
+
alembic_revision(directory=mdir, message=message or feat)
|
|
131
|
+
else:
|
|
132
|
+
alembic_migrate(directory=mdir, message=message or feat)
|
|
112
133
|
except Exception as e:
|
|
113
134
|
if os.getenv("SPLENT_DEBUG"):
|
|
114
135
|
click.secho(
|
|
@@ -119,6 +140,21 @@ def db_migrate(feature, message):
|
|
|
119
140
|
|
|
120
141
|
after = _count_versions(mdir)
|
|
121
142
|
|
|
143
|
+
# A blank migration requested with --empty is intentional: keep it so the
|
|
144
|
+
# user can fill in upgrade()/downgrade() by hand (e.g. refinement columns).
|
|
145
|
+
if empty:
|
|
146
|
+
if after > before:
|
|
147
|
+
click.echo(
|
|
148
|
+
click.style(
|
|
149
|
+
f" 📝 {feat}: blank migration generated — "
|
|
150
|
+
f"edit upgrade()/downgrade() and run 'splent db:upgrade'",
|
|
151
|
+
fg="cyan",
|
|
152
|
+
)
|
|
153
|
+
)
|
|
154
|
+
else:
|
|
155
|
+
click.echo(click.style(f" ✔ {feat}: up to date", fg="green"))
|
|
156
|
+
continue
|
|
157
|
+
|
|
122
158
|
# If a new file was generated, check if it's empty (no real schema changes)
|
|
123
159
|
if after > before:
|
|
124
160
|
versions_dir = os.path.join(mdir, "versions")
|
|
@@ -237,10 +237,27 @@ def _extract_translations(translations_dir: Path) -> list[str]:
|
|
|
237
237
|
return locales
|
|
238
238
|
|
|
239
239
|
|
|
240
|
+
def _strip_docstrings_and_comments(text: str) -> str:
|
|
241
|
+
"""Remove triple-quoted strings (docstrings) and ``#`` comments.
|
|
242
|
+
|
|
243
|
+
Signal inference scans for ``define_signal("...")`` / ``connect_signal("...")``
|
|
244
|
+
calls. The scaffolded ``signals.py`` ships *examples* of those calls inside a
|
|
245
|
+
module docstring; without stripping them the inferred contract would list
|
|
246
|
+
example signal names the feature never actually emits (e.g. ``item-created``),
|
|
247
|
+
causing spurious collisions in ``feature:xray --validate``.
|
|
248
|
+
"""
|
|
249
|
+
# Drop triple-quoted blocks (both ''' and """).
|
|
250
|
+
text = re.sub(r'""".*?"""', "", text, flags=re.DOTALL)
|
|
251
|
+
text = re.sub(r"'''.*?'''", "", text, flags=re.DOTALL)
|
|
252
|
+
# Drop full-line and trailing comments.
|
|
253
|
+
text = re.sub(r"#.*", "", text)
|
|
254
|
+
return text
|
|
255
|
+
|
|
256
|
+
|
|
240
257
|
def _extract_signals(signals_path: Path) -> tuple[list[str], list[str]]:
|
|
241
258
|
if not signals_path.exists():
|
|
242
259
|
return [], []
|
|
243
|
-
text = signals_path.read_text()
|
|
260
|
+
text = _strip_docstrings_and_comments(signals_path.read_text())
|
|
244
261
|
provided = sorted(
|
|
245
262
|
set(re.findall(r"""define_signal\s*\(\s*['"]([^'"]+)['"]""", text))
|
|
246
263
|
)
|
|
@@ -478,16 +478,19 @@ def feature_xray(feature_ref, filter_cat, validate, full):
|
|
|
478
478
|
if not bp_collisions:
|
|
479
479
|
ok += 1
|
|
480
480
|
|
|
481
|
-
# 5. Commands:
|
|
482
|
-
|
|
481
|
+
# 5. Commands: feature-contributed commands are namespaced under
|
|
482
|
+
# ``feature:<name> <cmd>``, so the same command name in two different
|
|
483
|
+
# features (e.g. the scaffold's example ``hello``) never actually collides.
|
|
484
|
+
# We only flag a real duplicate *within* a single feature.
|
|
485
|
+
cmd_collisions = {}
|
|
483
486
|
for name, fdata in feature_data.items():
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
487
|
+
cmds = fdata["contract"].get("provides", {}).get("commands", [])
|
|
488
|
+
dupes = {c for c in cmds if cmds.count(c) > 1}
|
|
489
|
+
for c in dupes:
|
|
490
|
+
cmd_collisions.setdefault(f"{name}:{c}", []).append(name)
|
|
488
491
|
for cmd, features_list in cmd_collisions.items():
|
|
489
492
|
click.secho(
|
|
490
|
-
f" ❌ Command '{cmd}' —
|
|
493
|
+
f" ❌ Command '{cmd}' — duplicated within feature",
|
|
491
494
|
fg="red",
|
|
492
495
|
)
|
|
493
496
|
fail += 1
|
|
@@ -268,13 +268,17 @@ def product_deploy(down, ci):
|
|
|
268
268
|
import time
|
|
269
269
|
|
|
270
270
|
healthy = False
|
|
271
|
-
|
|
271
|
+
# The production web container is named ``<product>_web_deploy`` —
|
|
272
|
+
# NOT ``<product>_web`` (that is the dev container). A cold start runs
|
|
273
|
+
# migrations and compiles assets before gunicorn binds, so allow a
|
|
274
|
+
# generous window (~90s) before declaring the app unhealthy.
|
|
275
|
+
for attempt in range(45):
|
|
272
276
|
try:
|
|
273
277
|
result = subprocess.run(
|
|
274
278
|
[
|
|
275
279
|
"docker",
|
|
276
280
|
"exec",
|
|
277
|
-
f"{product}
|
|
281
|
+
f"{product}_web_deploy",
|
|
278
282
|
"bash",
|
|
279
283
|
"-c",
|
|
280
284
|
"curl -s -o /dev/null -w '%{http_code}' http://localhost:5000/",
|
|
@@ -172,7 +172,12 @@ def product_env(generate, merge, env_name, process_all):
|
|
|
172
172
|
)
|
|
173
173
|
raise SystemExit(1)
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
# Each environment writes to its own file so a `--prod` merge never
|
|
176
|
+
# clobbers the development `.env` (which the dev containers read via
|
|
177
|
+
# env_file). dev → .env, prod → .env.deploy.
|
|
178
|
+
target_env = os.path.join(
|
|
179
|
+
docker_dir, ".env.deploy" if env_name == "prod" else ".env"
|
|
180
|
+
)
|
|
176
181
|
if base_env != target_env:
|
|
177
182
|
shutil.copyfile(base_env, target_env)
|
|
178
183
|
|
|
@@ -74,6 +74,31 @@ def _scan_feature_deps(
|
|
|
74
74
|
) -> set[str]:
|
|
75
75
|
"""Scan a feature's source for dependencies. Returns set of short_names."""
|
|
76
76
|
deps = set()
|
|
77
|
+
|
|
78
|
+
# Refinement features declare the feature they refine in pyproject.toml
|
|
79
|
+
# ([tool.splent.refinement].refines). That is a hard dependency — the base
|
|
80
|
+
# feature must load first — so surface it as a constraint even when there is
|
|
81
|
+
# no Python import or FK between them.
|
|
82
|
+
pyproject_path = os.path.join(feature_path, "pyproject.toml")
|
|
83
|
+
if os.path.isfile(pyproject_path):
|
|
84
|
+
try:
|
|
85
|
+
import tomllib
|
|
86
|
+
|
|
87
|
+
with open(pyproject_path, "rb") as fh:
|
|
88
|
+
pydata = tomllib.load(fh)
|
|
89
|
+
refines = (
|
|
90
|
+
pydata.get("tool", {})
|
|
91
|
+
.get("splent", {})
|
|
92
|
+
.get("refinement", {})
|
|
93
|
+
.get("refines")
|
|
94
|
+
)
|
|
95
|
+
if refines and refines != feature_pkg and refines in all_packages:
|
|
96
|
+
short = pkg_to_short.get(refines)
|
|
97
|
+
if short:
|
|
98
|
+
deps.add(short)
|
|
99
|
+
except Exception:
|
|
100
|
+
pass
|
|
101
|
+
|
|
77
102
|
src_dir = os.path.join(feature_path, "src", "splent_io", feature_pkg)
|
|
78
103
|
if not os.path.isdir(src_dir):
|
|
79
104
|
return deps
|
|
@@ -260,17 +260,39 @@ def build_and_upload_pypi(path: str):
|
|
|
260
260
|
raise SystemExit(1)
|
|
261
261
|
|
|
262
262
|
click.echo(" pypi uploading...")
|
|
263
|
+
|
|
264
|
+
# Expand dist/* ourselves: subprocess runs without a shell, so a literal
|
|
265
|
+
# "dist/*" would be passed verbatim to twine and never match any file.
|
|
266
|
+
import glob
|
|
267
|
+
|
|
268
|
+
dist_files = sorted(glob.glob(os.path.join(path, "dist", "*")))
|
|
269
|
+
if not dist_files:
|
|
270
|
+
click.secho(" error: no built artifacts found in dist/", fg="red")
|
|
271
|
+
raise SystemExit(1)
|
|
272
|
+
|
|
273
|
+
# twine reads TWINE_USERNAME / TWINE_PASSWORD from the environment. The CLI
|
|
274
|
+
# loads them from the workspace .env (load_dotenv), so they are already in
|
|
275
|
+
# os.environ — pass it through explicitly. --non-interactive makes twine fail
|
|
276
|
+
# loudly instead of blocking on a credentials prompt; --skip-existing keeps
|
|
277
|
+
# re-runs idempotent (a half-uploaded release can be retried safely).
|
|
263
278
|
try:
|
|
264
279
|
subprocess.run(
|
|
265
|
-
[
|
|
280
|
+
[
|
|
281
|
+
sys.executable,
|
|
282
|
+
"-m",
|
|
283
|
+
"twine",
|
|
284
|
+
"upload",
|
|
285
|
+
"--non-interactive",
|
|
286
|
+
"--skip-existing",
|
|
287
|
+
*dist_files,
|
|
288
|
+
],
|
|
266
289
|
env=os.environ.copy(),
|
|
267
290
|
check=True,
|
|
268
291
|
cwd=path,
|
|
269
|
-
capture_output=True,
|
|
270
292
|
)
|
|
271
293
|
except subprocess.CalledProcessError as e:
|
|
272
294
|
click.secho(
|
|
273
|
-
f" error: PyPI upload failed
|
|
295
|
+
f" error: PyPI upload failed (exit {e.returncode}).",
|
|
274
296
|
fg="red",
|
|
275
297
|
)
|
|
276
298
|
click.secho(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: splent_cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.9.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
|
|
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
|
{splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_hook_remove.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_inject_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_pip_install.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/feature/feature_sync_template.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
|
{splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_auto_require.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
|
{splent_cli-1.8.0 → splent_cli-1.9.1}/src/splent_cli/commands/product/product_sync_template.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
|