splent-cli 1.45.0__tar.gz → 1.46.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.45.0/src/splent_cli.egg-info → splent_cli-1.46.0}/PKG-INFO +1 -1
- {splent_cli-1.45.0 → splent_cli-1.46.0}/pyproject.toml +1 -1
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_compile.py +172 -11
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_create.py +58 -4
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_drift.py +6 -4
- splent_cli-1.46.0/src/splent_cli/commands/feature/feature_frontend_init.py +311 -0
- splent_cli-1.46.0/src/splent_cli/commands/feature/feature_npm.py +80 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_release.py +149 -23
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_sync_template.py +7 -4
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_unlock.py +22 -1
- splent_cli-1.46.0/src/splent_cli/services/frontend.py +871 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/release_dry_run.py +120 -5
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_.gitignore.j2 +12 -3
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_MANIFEST.in.j2 +15 -3
- splent_cli-1.46.0/src/splent_cli/templates/feature/feature_frontend.npmrc.j2 +9 -0
- splent_cli-1.46.0/src/splent_cli/templates/feature/feature_frontend_scripts.js.j2 +15 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_base_template.html +7 -0
- splent_cli-1.46.0/src/splent_cli/utils/frontend_licenses.py +296 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/template_drift.py +24 -1
- {splent_cli-1.45.0 → splent_cli-1.46.0/src/splent_cli.egg-info}/PKG-INFO +1 -1
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli.egg-info/SOURCES.txt +6 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/COPYING +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/COPYING.LESSER +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/README.md +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/setup.cfg +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/__main__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/cli.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/cache/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/cache/cache_clear.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/cache/cache_orphans.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/cache/cache_outdated.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/cache/cache_prune.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/cache/cache_size.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/cache/cache_status.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/cache/cache_usage.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/cache/cache_versions.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_contracts.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_deps.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_docker.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_env.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_features.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_github.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_infra.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_product.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_pypi.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_pyproject.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_releases.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/check/check_vendor.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/clear/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/clear/clear_build.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/clear/clear_log.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/clear/clear_uploads.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/command/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/command/command_create.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/coverage.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/database/db_console.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/database/db_dump.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/database/db_migrate.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/database/db_reset.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/database/db_restore.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/database/db_rollback.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/database/db_seed.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/database/db_status.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/database/db_upgrade.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/doctor.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/env/env_list.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/env/env_set.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/env/env_show.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/export/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/export/export_puml.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_add.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_attach.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_clean.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_clone.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_compat.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_contract.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_delete.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_detach.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_discard.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_env.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_fork.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_git.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_hook_add.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_hook_remove.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_hooks.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_impact.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_info.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_inject_config.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_install.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_list.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_order.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_outdated.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_pin.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_pip_install.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_pull.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_refine.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_remove.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_rename.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_search.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_status.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_test.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_translate.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_upgrade.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_versions.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/feature/feature_xray.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/lint.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/locust.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/marketplace/login.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/marketplace/logout.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/marketplace/marketplace_auth_utils.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/marketplace/marketplace_index.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/marketplace/whoami.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_auto_require.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_build.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_clean.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_commands.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_config.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_configure.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_console.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_containers.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_create.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_deploy.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_derive.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_deselect.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_down.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_drift.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_env.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_list.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_logs.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_missing.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_params.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_port.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_release.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_resolve.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_restart.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_routes.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_run.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_select.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_shell.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_signals.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_sync_template.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_test.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_up.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/product/product_validate.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/release/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/release/release_core.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/release/release_resume.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/selenium.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_add_constraints.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_add_feature.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_compare.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_configurations.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_create.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_deps.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_features.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_fetch.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_info.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_list.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_outdated.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_pin.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_publish.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_remove_feature.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/spl/spl_utils.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/tokens_setup.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/uvl/uvl_utils.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/commands/version.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/compose.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/context.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/credentials.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/deploy_bundle.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/editable_refresh.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/image_registry.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/index_refresh.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/marketplace.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/marketplace_api.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/marketplace_url.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/neutral_app.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/own_commands.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/preflight.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/pypi_quota.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/registry.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/release.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/release_gate.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/spl_store.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/services/web_container.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_README.md.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_commands.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_config.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_docker-compose.dev.yml.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_docker-compose.prod.yml.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_docker.env.example.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_forms.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_hooks.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_init.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_init_config.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_init_light.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_init_service.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_migrations_alembic.ini.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_migrations_env.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_migrations_script.py.mako.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_models.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_pyproject.toml.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_pyproject_minimal.toml.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_repositories.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_routes.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_scripts.js.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_seeders.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_services.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_services_service.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_signals.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_templates_index.html.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_tests_conftest.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_tests_e2e.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_tests_functional.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_tests_integration.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_tests_locustfile.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_tests_unit.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/feature/feature_webpack.config.js.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/licenses/COPYING +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/licenses/COPYING.LESSER +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_.env.dev.example.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_.env.prod.example.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_.gitignore.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_00_core_requirements_dev.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_00_install_features.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_01_compile_assets.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_02_0_db_wait_connection.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_02_1_db_create_db_test.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_02_2_db_create_splent_migrations.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_03_initialize_migrations.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_04_handle_migrations.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_05_0_start_app_dev.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_05_1_start_app_prod.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_400.html +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_401.html +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_404.html +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_500.html +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_Dockerfile.dev.dockerignore.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_Dockerfile.dev.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_Dockerfile.prod.dockerignore.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_Dockerfile.prod.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_README.md.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_app.css +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_app.js +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_ci_upgrade.yml.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_ci_validate.yml.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_config.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_docker-compose.dev.yml.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_docker-compose.prod.yml.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_dropzone.css +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_entrypoint.dev.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_entrypoint.prod.sh.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_errors.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_favicon.svg +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_init.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_logging.py.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_own.css +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_package.json.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_pyproject.toml.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/templates/product/product_uvl.j2 +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/__init__.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/archetype.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/cache_utils.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/ci_services.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/ci_workflow.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/command_loader.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/contract_freshness.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/db_client.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/db_utils.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/decorators.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/deploy_freshness.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/dynamic_imports.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/feature_installer.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/feature_naming.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/feature_params.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/feature_requirements.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/feature_resolution.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/feature_utils.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/forge.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/git_url.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/integrity.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/io_utils.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/lifecycle.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/manifest.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/menu_keys.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/migration_lock.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/path_utils.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/proc.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/redact.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/refinement_facts.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/running_version.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/toml_edit.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/upgrade_plan.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/uvl_diagnosis.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli/utils/uvl_params.py +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli.egg-info/dependency_links.txt +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli.egg-info/entry_points.txt +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli.egg-info/requires.txt +0 -0
- {splent_cli-1.45.0 → splent_cli-1.46.0}/src/splent_cli.egg-info/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ import subprocess
|
|
|
6
6
|
|
|
7
7
|
import click
|
|
8
8
|
|
|
9
|
-
from splent_cli.services import compose, context
|
|
9
|
+
from splent_cli.services import compose, context, frontend
|
|
10
10
|
from splent_cli.utils.proc import run
|
|
11
11
|
from splent_cli.utils.feature_utils import (
|
|
12
12
|
get_features_from_pyproject,
|
|
@@ -196,17 +196,67 @@ def webpack_container(product: str, env: str, workspace: str) -> tuple[str | Non
|
|
|
196
196
|
"assets/dist, and fail when the feature has nothing to build. "
|
|
197
197
|
"feature:release runs it.",
|
|
198
198
|
)
|
|
199
|
-
|
|
199
|
+
@click.option(
|
|
200
|
+
"--verify",
|
|
201
|
+
is_flag=True,
|
|
202
|
+
help="Build nothing: check that assets/meta/manifest.json matches the "
|
|
203
|
+
"files of assets/dist and the lock, for each feature with frontend/.",
|
|
204
|
+
)
|
|
205
|
+
def feature_compile(feature_name, watch, env_dev, env_prod, release_build, verify):
|
|
200
206
|
if release_build and watch:
|
|
201
207
|
raise click.UsageError("--release builds the bundle once; drop --watch.")
|
|
208
|
+
if verify and (watch or release_build):
|
|
209
|
+
raise click.UsageError("--verify builds nothing; drop --watch and --release.")
|
|
202
210
|
production = (
|
|
203
211
|
os.getenv("FLASK_ENV", "develop") == "production" or env_prod or release_build
|
|
204
212
|
)
|
|
213
|
+
workspace = str(context.workspace())
|
|
205
214
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
)
|
|
215
|
+
# A feature with frontend/ of its own builds in the SPLENT toolchain and
|
|
216
|
+
# needs no product at all, so naming one is enough.
|
|
217
|
+
if feature_name and _frontend_root(workspace, _feature_ref(feature_name)):
|
|
218
|
+
features = [_feature_ref(feature_name)]
|
|
219
|
+
else:
|
|
220
|
+
features = (
|
|
221
|
+
[_feature_ref(feature_name)]
|
|
222
|
+
if feature_name
|
|
223
|
+
else get_features_from_pyproject()
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
if verify:
|
|
227
|
+
raise SystemExit(_verify_features(features, workspace))
|
|
228
|
+
|
|
229
|
+
frontend_features = [f for f in features if _frontend_root(workspace, f)]
|
|
230
|
+
legacy_features = [f for f in features if f not in frontend_features]
|
|
231
|
+
failed = [
|
|
232
|
+
feature
|
|
233
|
+
for feature in frontend_features
|
|
234
|
+
if not _compile_frontend(
|
|
235
|
+
_frontend_root(workspace, feature),
|
|
236
|
+
feature,
|
|
237
|
+
watch=watch,
|
|
238
|
+
production=production,
|
|
239
|
+
release_build=release_build,
|
|
240
|
+
)
|
|
241
|
+
]
|
|
242
|
+
|
|
243
|
+
if legacy_features:
|
|
244
|
+
failed += _compile_legacy(
|
|
245
|
+
legacy_features, watch, production, env_dev, env_prod, release_build
|
|
246
|
+
)
|
|
247
|
+
if failed and not watch:
|
|
248
|
+
click.secho(
|
|
249
|
+
f"Compilation failed for {len(failed)} feature(s): {', '.join(failed)}",
|
|
250
|
+
fg="red",
|
|
251
|
+
err=True,
|
|
252
|
+
)
|
|
253
|
+
raise SystemExit(1)
|
|
209
254
|
|
|
255
|
+
|
|
256
|
+
def _compile_legacy(features, watch, production, env_dev, env_prod, release_build):
|
|
257
|
+
"""Compile features without frontend/ (legacy mode): their own
|
|
258
|
+
webpack.config.js, run in the product's web container against the
|
|
259
|
+
product's node_modules. The features that failed."""
|
|
210
260
|
env = context.resolve_env(env_dev, env_prod)
|
|
211
261
|
product = context.require_app()
|
|
212
262
|
workspace = str(context.workspace())
|
|
@@ -218,7 +268,7 @@ def feature_compile(feature_name, watch, env_dev, env_prod, release_build):
|
|
|
218
268
|
# Every feature is attempted, so one run reports every broken bundle, and
|
|
219
269
|
# the exit code then says whether any failed: the production Dockerfile
|
|
220
270
|
# chains `splent feature:compile && ...` and must stop on a failure.
|
|
221
|
-
|
|
271
|
+
return [
|
|
222
272
|
feature
|
|
223
273
|
for feature in features
|
|
224
274
|
if not _compile_in_container(
|
|
@@ -232,13 +282,124 @@ def feature_compile(feature_name, watch, env_dev, env_prod, release_build):
|
|
|
232
282
|
release_build=release_build,
|
|
233
283
|
)
|
|
234
284
|
]
|
|
235
|
-
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def _split_ref(feature: str) -> tuple[str, str, str | None]:
|
|
288
|
+
"""``(namespace, name, version)`` of a feature ref, splent_io by default."""
|
|
289
|
+
parts = feature.split("/")
|
|
290
|
+
if len(parts) == 2:
|
|
291
|
+
org_raw, name_version = parts
|
|
292
|
+
org_safe = normalize_namespace(org_raw)
|
|
293
|
+
else:
|
|
294
|
+
org_safe, name_version = "splent_io", parts[0]
|
|
295
|
+
base_name, _, version = name_version.partition("@")
|
|
296
|
+
return org_safe, base_name, version or None
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def _frontend_root(workspace: str, feature: str) -> str | None:
|
|
300
|
+
"""The working copy at the workspace root of an unpinned FEATURE when it
|
|
301
|
+
has frontend/ of its own, else None. A pinned one is never compiled."""
|
|
302
|
+
_, base_name, version = _split_ref(feature)
|
|
303
|
+
if version:
|
|
304
|
+
return None
|
|
305
|
+
root = os.path.join(workspace, base_name)
|
|
306
|
+
return root if frontend.declares(root) else None
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def _compile_frontend(root, feature, *, watch, production, release_build) -> bool:
|
|
310
|
+
"""Build one feature's frontend/ in the SPLENT toolchain. False only
|
|
311
|
+
when the build failed or could not run.
|
|
312
|
+
|
|
313
|
+
Inside the product's web container there is no Docker daemon to run the
|
|
314
|
+
toolchain in. Its startup script compiles every feature with --watch,
|
|
315
|
+
and a feature with frontend/ is left to the CLI there, with a note.
|
|
316
|
+
"""
|
|
317
|
+
namespace, base_name, _ = _split_ref(feature)
|
|
318
|
+
if _is_product_container() and not release_build:
|
|
236
319
|
click.secho(
|
|
237
|
-
f"
|
|
238
|
-
|
|
239
|
-
|
|
320
|
+
f" {feature} builds in the SPLENT toolchain, not in this container: "
|
|
321
|
+
f"run splent feature:compile {base_name} --watch from the CLI.",
|
|
322
|
+
fg="bright_black",
|
|
240
323
|
)
|
|
241
|
-
|
|
324
|
+
return True
|
|
325
|
+
|
|
326
|
+
mode = "production" if production else "development"
|
|
327
|
+
click.echo(
|
|
328
|
+
click.style(f"🚀 Compiling {feature} in the SPLENT toolchain...", fg="cyan")
|
|
329
|
+
)
|
|
330
|
+
try:
|
|
331
|
+
image = frontend.ensure_toolchain()
|
|
332
|
+
frontend.install(root, image=image, force=release_build)
|
|
333
|
+
result = frontend.build(
|
|
334
|
+
root,
|
|
335
|
+
namespace,
|
|
336
|
+
base_name,
|
|
337
|
+
mode=mode,
|
|
338
|
+
watch=watch and not production,
|
|
339
|
+
image=image,
|
|
340
|
+
)
|
|
341
|
+
except click.ClickException as e:
|
|
342
|
+
click.secho(f"❌ Error compiling {feature}: {e.format_message()}", fg="red")
|
|
343
|
+
return False
|
|
344
|
+
if watch and not production:
|
|
345
|
+
if result.returncode != 0:
|
|
346
|
+
click.secho(
|
|
347
|
+
f"❌ The watch container of {feature} did not start:\n"
|
|
348
|
+
f"{(result.stderr or '').strip()}",
|
|
349
|
+
fg="red",
|
|
350
|
+
)
|
|
351
|
+
return False
|
|
352
|
+
name = frontend.watch_container(base_name)
|
|
353
|
+
click.echo(click.style(f"👀 Watching {feature} in {mode} mode...", fg="blue"))
|
|
354
|
+
click.echo(
|
|
355
|
+
click.style(
|
|
356
|
+
f" log: docker logs -f {name} stop: docker stop {name}",
|
|
357
|
+
fg="bright_black",
|
|
358
|
+
)
|
|
359
|
+
)
|
|
360
|
+
return True
|
|
361
|
+
if result.returncode != 0:
|
|
362
|
+
click.secho(f"❌ Error compiling {feature}: the build failed", fg="red")
|
|
363
|
+
return False
|
|
364
|
+
click.echo(
|
|
365
|
+
click.style(f"✅ Successfully compiled {feature} in {mode} mode!", fg="green")
|
|
366
|
+
)
|
|
367
|
+
return True
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
def _verify_features(features, workspace: str) -> int:
|
|
371
|
+
"""feature:compile --verify: 1 when the manifest of any feature with
|
|
372
|
+
frontend/ does not match its files, else 0. A pinned feature is checked
|
|
373
|
+
in the copy the product links, which is what its app serves."""
|
|
374
|
+
failed = 0
|
|
375
|
+
for feature in features:
|
|
376
|
+
namespace, base_name, version = _split_ref(feature)
|
|
377
|
+
if version:
|
|
378
|
+
product = context.require_app()
|
|
379
|
+
root = os.path.join(
|
|
380
|
+
workspace, product, "features", namespace, f"{base_name}@{version}"
|
|
381
|
+
)
|
|
382
|
+
else:
|
|
383
|
+
root = os.path.join(workspace, base_name)
|
|
384
|
+
if not frontend.declares(root):
|
|
385
|
+
click.echo(
|
|
386
|
+
click.style(
|
|
387
|
+
f" {feature} has no frontend/, nothing to verify.",
|
|
388
|
+
fg="bright_black",
|
|
389
|
+
)
|
|
390
|
+
)
|
|
391
|
+
continue
|
|
392
|
+
problems = frontend.verify(root, namespace, base_name)
|
|
393
|
+
if problems:
|
|
394
|
+
failed += 1
|
|
395
|
+
click.secho(
|
|
396
|
+
f"❌ {feature}: the bundle does not match its manifest", fg="red"
|
|
397
|
+
)
|
|
398
|
+
for problem in problems:
|
|
399
|
+
click.secho(f" {problem}", fg="red")
|
|
400
|
+
else:
|
|
401
|
+
click.secho(f"✅ {feature}: the bundle matches its manifest", fg="green")
|
|
402
|
+
return 1 if failed else 0
|
|
242
403
|
|
|
243
404
|
|
|
244
405
|
def _feature_ref(name: str) -> str:
|
|
@@ -200,13 +200,24 @@ JS_FILES = {
|
|
|
200
200
|
"assets/js/webpack.config.js": "feature/feature_webpack.config.js.j2",
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
# What --frontend writes instead: the entry point under the package, and
|
|
204
|
+
# frontend/ at the root of the repository, whose package.json
|
|
205
|
+
# (services/frontend.py writes it) declares the bundle and its dependencies.
|
|
206
|
+
FRONTEND_SRC_FILES = {
|
|
207
|
+
"assets/js/scripts.js": "feature/feature_frontend_scripts.js.j2",
|
|
208
|
+
}
|
|
209
|
+
FRONTEND_BASE_FILES = {
|
|
210
|
+
"frontend/.npmrc": "feature/feature_frontend.npmrc.j2",
|
|
211
|
+
}
|
|
212
|
+
|
|
203
213
|
|
|
204
|
-
def _build_file_map(feature_type, short_name, docker=False, js=False):
|
|
214
|
+
def _build_file_map(feature_type, short_name, docker=False, js=False, frontend=False):
|
|
205
215
|
"""Return (src_files, base_files) dicts for the given feature type.
|
|
206
216
|
|
|
207
217
|
``js`` adds the webpack entry point and config (JS_FILES). Code that
|
|
208
218
|
recognises what feature:create wrote passes it: a feature created with
|
|
209
|
-
--js, or by a CLI that always wrote them, has them.
|
|
219
|
+
--js, or by a CLI that always wrote them, has them. ``frontend`` adds the
|
|
220
|
+
entry point and frontend/ of a feature built by the SPLENT toolchain.
|
|
210
221
|
"""
|
|
211
222
|
T = "feature/" # template prefix
|
|
212
223
|
|
|
@@ -309,6 +320,9 @@ def _build_file_map(feature_type, short_name, docker=False, js=False):
|
|
|
309
320
|
# for nothing.
|
|
310
321
|
if js:
|
|
311
322
|
src = {**src, **JS_FILES}
|
|
323
|
+
if frontend:
|
|
324
|
+
src = {**src, **FRONTEND_SRC_FILES}
|
|
325
|
+
base_common = {**base_common, **FRONTEND_BASE_FILES}
|
|
312
326
|
|
|
313
327
|
# Merge common files (type-specific wins on conflict)
|
|
314
328
|
merged_src = {**src_common, **src}
|
|
@@ -341,13 +355,21 @@ def _build_file_map(feature_type, short_name, docker=False, js=False):
|
|
|
341
355
|
help="Also scaffold assets/js (scripts.js and webpack.config.js) for a "
|
|
342
356
|
"feature with a JavaScript bundle of its own.",
|
|
343
357
|
)
|
|
358
|
+
@click.option(
|
|
359
|
+
"--frontend",
|
|
360
|
+
is_flag=True,
|
|
361
|
+
default=False,
|
|
362
|
+
help="Also scaffold frontend/ (package.json and .npmrc) and assets/js/scripts.js "
|
|
363
|
+
"for a feature whose bundle the SPLENT toolchain builds, with JavaScript "
|
|
364
|
+
"dependencies of its own.",
|
|
365
|
+
)
|
|
344
366
|
@click.option(
|
|
345
367
|
"--no-git",
|
|
346
368
|
is_flag=True,
|
|
347
369
|
default=False,
|
|
348
370
|
help="Do not make the feature a git repository.",
|
|
349
371
|
)
|
|
350
|
-
def make_feature(full_name, feature_type, docker, js, no_git):
|
|
372
|
+
def make_feature(full_name, feature_type, docker, js, frontend, no_git):
|
|
351
373
|
"""
|
|
352
374
|
Creates a new feature in the workspace.
|
|
353
375
|
The name must follow the pattern <namespace>/<feature_name>.
|
|
@@ -371,6 +393,13 @@ def make_feature(full_name, feature_type, docker, js, no_git):
|
|
|
371
393
|
the feature has no bundle, and nothing compiles one for it. Plain
|
|
372
394
|
stylesheets and vendored libraries need neither (register_asset).
|
|
373
395
|
|
|
396
|
+
\b
|
|
397
|
+
--frontend adds frontend/package.json, which declares the bundle and the
|
|
398
|
+
npm packages it imports (splent feature:npm <feature> install <package>),
|
|
399
|
+
frontend/.npmrc and assets/js/scripts.js. The SPLENT toolchain builds it,
|
|
400
|
+
against the feature's own frontend/node_modules, with no webpack config
|
|
401
|
+
of the feature's. Not with --js, which writes the legacy one.
|
|
402
|
+
|
|
374
403
|
\b
|
|
375
404
|
The feature becomes a git repository on main, with the scaffold as its
|
|
376
405
|
first commit made with your git identity, unless it is created inside a
|
|
@@ -384,7 +413,13 @@ def make_feature(full_name, feature_type, docker, js, no_git):
|
|
|
384
413
|
splent feature:create splent-io/splent_feature_email_queue --type service
|
|
385
414
|
splent feature:create splent-io/splent_feature_rabbitmq --type service --docker
|
|
386
415
|
splent feature:create splent-io/splent_feature_charts --js
|
|
416
|
+
splent feature:create splent-io/splent_feature_charts --frontend
|
|
387
417
|
"""
|
|
418
|
+
if js and frontend:
|
|
419
|
+
raise click.UsageError(
|
|
420
|
+
"--js writes the legacy webpack.config.js and --frontend the "
|
|
421
|
+
"toolchain's frontend/: choose one."
|
|
422
|
+
)
|
|
388
423
|
|
|
389
424
|
# --- Validate input pattern ---
|
|
390
425
|
if "/" not in full_name:
|
|
@@ -452,11 +487,12 @@ def make_feature(full_name, feature_type, docker, js, no_git):
|
|
|
452
487
|
# inline turns a line that has to be read literally into noise.
|
|
453
488
|
"env_prefix": env_prefix,
|
|
454
489
|
"host_port_ref": "${" + env_prefix + "_HOST_PORT}",
|
|
490
|
+
"frontend": frontend,
|
|
455
491
|
}
|
|
456
492
|
|
|
457
493
|
# --- Build file maps for the selected type ---
|
|
458
494
|
src_files, base_files = _build_file_map(
|
|
459
|
-
feature_type, short_name, docker=docker, js=js
|
|
495
|
+
feature_type, short_name, docker=docker, js=js, frontend=frontend
|
|
460
496
|
)
|
|
461
497
|
|
|
462
498
|
# --- Create src structure ---
|
|
@@ -479,6 +515,14 @@ def make_feature(full_name, feature_type, docker, js, no_git):
|
|
|
479
515
|
|
|
480
516
|
write_license_files(feature_dir)
|
|
481
517
|
|
|
518
|
+
if frontend:
|
|
519
|
+
from splent_cli.services import frontend as toolchain
|
|
520
|
+
|
|
521
|
+
toolchain.write_package(
|
|
522
|
+
feature_dir,
|
|
523
|
+
toolchain.new_package(org_safe, feature_name, license_="LGPL-3.0-or-later"),
|
|
524
|
+
)
|
|
525
|
+
|
|
482
526
|
# --- src/__init__.py (namespace root) ---
|
|
483
527
|
src_root = os.path.join(feature_dir, "src")
|
|
484
528
|
os.makedirs(src_root, exist_ok=True)
|
|
@@ -517,6 +561,16 @@ def make_feature(full_name, feature_type, docker, js, no_git):
|
|
|
517
561
|
_report_git(*git_state, feature_dir)
|
|
518
562
|
click.echo()
|
|
519
563
|
|
|
564
|
+
if frontend:
|
|
565
|
+
click.echo(
|
|
566
|
+
click.style(" frontend/ ", fg="cyan")
|
|
567
|
+
+ "add a dependency with "
|
|
568
|
+
+ click.style(f"feature:npm {short_name} install <package>", bold=True)
|
|
569
|
+
+ ", build with "
|
|
570
|
+
+ click.style(f"feature:compile {short_name}", bold=True)
|
|
571
|
+
)
|
|
572
|
+
click.echo()
|
|
573
|
+
|
|
520
574
|
if docker:
|
|
521
575
|
click.echo(
|
|
522
576
|
click.style(" docker/ ", fg="cyan")
|
|
@@ -7,7 +7,7 @@ from splent_cli.services import context
|
|
|
7
7
|
from splent_cli.utils.feature_resolution import resolve_feature_ref
|
|
8
8
|
from splent_cli.utils.template_drift import (
|
|
9
9
|
CLI_VERSION,
|
|
10
|
-
|
|
10
|
+
feature_files,
|
|
11
11
|
count_changed_lines,
|
|
12
12
|
feature_ctx,
|
|
13
13
|
file_diff,
|
|
@@ -74,7 +74,8 @@ def _print_diff_lines(diff: list[str]) -> None:
|
|
|
74
74
|
def feature_drift(feature_identifier, verbose):
|
|
75
75
|
"""
|
|
76
76
|
Compare SPLENT-owned files in a feature against the current templates.
|
|
77
|
-
Only scaffold files are checked (webpack.config.js, MANIFEST.in, .gitignore
|
|
77
|
+
Only scaffold files are checked (webpack.config.js, MANIFEST.in, .gitignore;
|
|
78
|
+
for a feature with frontend/, MANIFEST.in, .gitignore and frontend/.npmrc).
|
|
78
79
|
Developer-owned source files are never touched.
|
|
79
80
|
Does not modify any files. Reads the editable copy at the workspace
|
|
80
81
|
root, or else the snapshot the product pins (or the newest one).
|
|
@@ -125,10 +126,11 @@ def feature_drift(feature_identifier, verbose):
|
|
|
125
126
|
)
|
|
126
127
|
)
|
|
127
128
|
|
|
128
|
-
|
|
129
|
+
files, extra = feature_files(cache_path)
|
|
130
|
+
ctx = feature_ctx(org_safe, feature_name, **extra)
|
|
129
131
|
any_drift = False
|
|
130
132
|
|
|
131
|
-
for rel_tpl, tpl_name in
|
|
133
|
+
for rel_tpl, tpl_name in files.items():
|
|
132
134
|
rel_path = resolve_feature_rel(rel_tpl, org_safe, feature_name)
|
|
133
135
|
abs_path = cache_path / rel_path
|
|
134
136
|
expected = render_template(tpl_name, ctx)
|