quadkit-cli 0.0.2__tar.gz → 0.0.3__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.
- quadkit_cli-0.0.3/.gitignore +24 -0
- quadkit_cli-0.0.3/PKG-INFO +153 -0
- quadkit_cli-0.0.3/README.md +97 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/example.yaml +1 -1
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/pyproject.toml +3 -2
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/db_bootstrap.py +11 -10
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/db_commands_ops.py +2 -2
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/events.py +11 -9
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/meta.py +3 -24
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/system.py +2 -1
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/contributors/runtime.py +2 -30
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/exceptions.py +3 -1
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/lib/config_gen.py +27 -21
- quadkit_cli-0.0.3/src/quadkit/cli/package_names.py +82 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/database.py +3 -2
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/health_checks/providers.py +25 -31
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/presets.py +18 -22
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/provider_catalog.py +20 -18
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/provider_registry.py +19 -6
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/template.py +16 -34
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/scaffold.py +48 -33
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_cli_context.py +3 -1
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_cli_errors.py +2 -2
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_contributor_runtime.py +3 -3
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_db.py +3 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_generator_base.py +1 -1
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_new.py +7 -2
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_project_layout.py +4 -2
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_provider_registry.py +24 -24
- quadkit_cli-0.0.2/.gitignore +0 -190
- quadkit_cli-0.0.2/PKG-INFO +0 -194
- quadkit_cli-0.0.2/README.md +0 -138
- quadkit_cli-0.0.2/tests/helpers/runner.py +0 -153
- quadkit_cli-0.0.2/tests/unit/commands/test_events_cmd.py +0 -58
- quadkit_cli-0.0.2/tests/unit/lib/test_config_gen.py +0 -251
- quadkit_cli-0.0.2/tests/unit/registry/test_template.py +0 -177
- quadkit_cli-0.0.2/tests/unit/test_add.py +0 -131
- quadkit_cli-0.0.2/tests/unit/test_health_checks.py +0 -300
- quadkit_cli-0.0.2/tests/unit/test_public_surface.py +0 -85
- quadkit_cli-0.0.2/tests/unit/test_scaffold_and_validators.py +0 -301
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/LICENSE +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/NOTICE +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/assembly/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/assembly/assembler.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/add.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/config.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/config_utils.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/contrib.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/db.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/db_commands_data.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/db_commands_migrations.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/dev.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/gen.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/init.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/inspect.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/new.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/project.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/py.typed +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/run.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/commands/shell.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/config.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/constants.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/contributors/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/contributors/base.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/contributors/core.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/contributors/discovery.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/contributors/registry.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/decorators.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/di/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/di/provider.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/di/sub_providers/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/di/sub_providers/contributor.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/events.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/generators/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/generators/base.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/generators/field_parser.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/generators/provider.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/generators/test.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/hooks.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/layout.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/lib/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/lib/config_loader.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/lib/console.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/lib/entry_point.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/lib/naming.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/lib/templates.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/module.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/output/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/output/manager.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/protocols.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/py.typed +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/backend_base.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/command.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/completion.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/config.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/environment.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/formatter.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/generator.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/health.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/health_checks/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/health_checks/base.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/health_checks/deps.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/health_checks/project.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/health_checks/python_env.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/health_checks/tools.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/health_checks/vcs_docker.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/hook.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/inspect.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/migration.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/provider.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/secrets.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/serializer.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/server.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/task.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/telemetry.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/version.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/registry/watcher.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/runtime/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/runtime/context.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/runtime/error_handler.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/runtime/main.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/scaffold_package.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/templates/provider.py.jinja2 +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/templates/py.typed +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/templates/test_unit.py.jinja2 +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/cli/types.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/src/quadkit/py.typed +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/conftest.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/integration/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/integration/test_cli_lifecycle.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/test_package_structure_p1.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/_test_cli_contribution_system_support.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/commands/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/commands/test_config.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/commands/test_config_happy_paths.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/commands/test_contrib.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/commands/test_inspect.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/commands/test_meta.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/commands/test_run.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/commands/test_shell.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/commands/test_system.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/di/test_config_alignment.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/lib/test_templates.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/__init__.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_database.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_environment.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_formatter.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_health.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_hook.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_inspect_registry.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_migration.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_secrets.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_serializer.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_task.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_telemetry.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_version.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/registry/test_watcher.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_base_contributor.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_cli_constants.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_cli_contribution_system.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_cli_exceptions.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_cli_module.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_cli_types.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_config_async.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_config_loader.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_config_save.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_config_validate.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_contributor_registry.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_core_contributor.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_decorators.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_dev_command.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_error_handler.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_events.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_exception_handling.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_field_parser.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_gen.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_gen_controller.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_gen_provider.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_generator_registry.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_generators_contract.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_hooks.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_init_command.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_layout.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_main.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_output.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_output_json.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_project.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_round40_hardening.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_run_detection.py +0 -0
- {quadkit_cli-0.0.2 → quadkit_cli-0.0.3}/tests/unit/test_server_registry.py +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Generated public-repository ignore rules.
|
|
2
|
+
# Private monorepo paths are intentionally not referenced here.
|
|
3
|
+
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.py[cod]
|
|
6
|
+
*.so
|
|
7
|
+
*.egg-info/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
.env
|
|
11
|
+
.env.*
|
|
12
|
+
!.env.example
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.ruff_cache/
|
|
15
|
+
.mypy_cache/
|
|
16
|
+
.coverage
|
|
17
|
+
coverage.xml
|
|
18
|
+
htmlcov/
|
|
19
|
+
build/
|
|
20
|
+
dist/
|
|
21
|
+
*.log
|
|
22
|
+
.DS_Store
|
|
23
|
+
.idea/
|
|
24
|
+
.vscode/
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: quadkit-cli
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Summary: Command-line interface for Quadkit Framework - Project scaffolding, code generation, and development tools
|
|
5
|
+
Project-URL: Homepage, https://quadkit.dev
|
|
6
|
+
Project-URL: Repository, https://github.com/dbtinoy-/quadkit
|
|
7
|
+
Project-URL: Documentation, https://quadkit.dev
|
|
8
|
+
Project-URL: Issues, https://github.com/dbtinoy-/quadkit/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/dbtinoy-/quadkit/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: Quadkit Framework Team <team@quadkit.dev>
|
|
11
|
+
Maintainer-email: Quadkit Framework Team <team@quadkit.dev>
|
|
12
|
+
License: Apache-2.0
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
License-File: NOTICE
|
|
15
|
+
Keywords: cli,codegen,command-line,devtools,framework,scaffolding
|
|
16
|
+
Classifier: Development Status :: 3 - Alpha
|
|
17
|
+
Classifier: Environment :: Console
|
|
18
|
+
Classifier: Intended Audience :: Developers
|
|
19
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Classifier: Programming Language :: Python :: 3
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
26
|
+
Classifier: Topic :: Utilities
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.11
|
|
29
|
+
Requires-Dist: aiofiles>=23.0.0
|
|
30
|
+
Requires-Dist: httpx>=0.25.0
|
|
31
|
+
Requires-Dist: jinja2>=3.1.0
|
|
32
|
+
Requires-Dist: pydantic>=2.10.0
|
|
33
|
+
Requires-Dist: pyyaml>=6.0
|
|
34
|
+
Requires-Dist: quadkit-contracts>=0.0.2
|
|
35
|
+
Requires-Dist: quadkit>=0.0.2
|
|
36
|
+
Requires-Dist: rich>=13.0.0
|
|
37
|
+
Requires-Dist: shellingham>=1.5.0
|
|
38
|
+
Requires-Dist: tomli>=2.0.0
|
|
39
|
+
Requires-Dist: typer[all]>=0.9.0
|
|
40
|
+
Requires-Dist: watchfiles>=0.21.0
|
|
41
|
+
Provides-Extra: all
|
|
42
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'all'
|
|
43
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'all'
|
|
44
|
+
Requires-Dist: pytest>=8.0.0; extra == 'all'
|
|
45
|
+
Requires-Dist: quadkit-testing>=0.0.2; extra == 'all'
|
|
46
|
+
Provides-Extra: dev
|
|
47
|
+
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
48
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
49
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
50
|
+
Provides-Extra: test
|
|
51
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'test'
|
|
52
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'test'
|
|
53
|
+
Requires-Dist: pytest>=8.0.0; extra == 'test'
|
|
54
|
+
Requires-Dist: quadkit-testing>=0.0.2; extra == 'test'
|
|
55
|
+
Description-Content-Type: text/markdown
|
|
56
|
+
|
|
57
|
+
# quadkit-cli
|
|
58
|
+
|
|
59
|
+
The `quadkit` command line: project scaffolding, generators, a smart
|
|
60
|
+
runner, and administrative commands for every stage of the application
|
|
61
|
+
lifecycle. Contributor-based — other packages can register their own
|
|
62
|
+
commands.
|
|
63
|
+
|
|
64
|
+
For day-to-day Quadkit developers: scaffold, generate, run, inspect.
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
uv add quadkit-cli
|
|
70
|
+
# or as a standalone tool:
|
|
71
|
+
uv tool install quadkit-cli
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Requires **Python >= 3.11**.
|
|
75
|
+
|
|
76
|
+
## Minimal working example
|
|
77
|
+
|
|
78
|
+
There is no code to write — the product is the command line:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Create a new project (template defaults to web-api)
|
|
82
|
+
quadkit new project my-api
|
|
83
|
+
|
|
84
|
+
# Generate application code (list all generators: quadkit gen list)
|
|
85
|
+
quadkit gen provider MyProvider
|
|
86
|
+
quadkit gen controller Orders
|
|
87
|
+
|
|
88
|
+
# Serve the application; reload is on by default, pass --no-reload in prod
|
|
89
|
+
quadkit run my_app.app:create_app --host 0.0.0.0 --port 8000 --workers 4
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Global options: `--json` for machine-readable output, `--quiet`,
|
|
93
|
+
`--debug`, `--no-color`, and `--config <path>` to point at a specific
|
|
94
|
+
`application.yaml`.
|
|
95
|
+
|
|
96
|
+
## Command index
|
|
97
|
+
|
|
98
|
+
| Command | Purpose |
|
|
99
|
+
| --- | --- |
|
|
100
|
+
| `quadkit new project / module / package` | scaffold projects, bounded contexts, and `quadkit-*` extensions |
|
|
101
|
+
| `quadkit init` | initialize Quadkit in an existing project |
|
|
102
|
+
| `quadkit add <provider>` | add a provider to a project (e.g. `database`, `auth`) |
|
|
103
|
+
| `quadkit run [target]` | smart runner — auto-detects `create_app`, sets profile |
|
|
104
|
+
| `quadkit dev start` | production-server startup |
|
|
105
|
+
| `quadkit gen <what>` | code generation (controllers, providers, middleware, tests, more — see `quadkit gen list`) |
|
|
106
|
+
| `quadkit test` / `quadkit lint` | project-level checks |
|
|
107
|
+
| `quadkit db` / `quadkit events` | database / event-schema management |
|
|
108
|
+
| `quadkit config` / `quadkit inspect` / `quadkit shell` | configuration, runtime introspection, REPL |
|
|
109
|
+
| `quadkit project` / `quadkit contrib` / `quadkit system` | project tasks, contributors, system info |
|
|
110
|
+
| `quadkit version` | framework and package versions |
|
|
111
|
+
|
|
112
|
+
Per-distribution guide:
|
|
113
|
+
[quadkit-cli reference](../../docs/reference/quadkit-cli.md).
|
|
114
|
+
|
|
115
|
+
## Optional extras
|
|
116
|
+
|
|
117
|
+
Verified against the package's `pyproject.toml`: `[dev]`, `[test]`,
|
|
118
|
+
`[all]`.
|
|
119
|
+
|
|
120
|
+
## Configuration
|
|
121
|
+
|
|
122
|
+
The CLI reads `application.yaml` like any Quadkit application; its own
|
|
123
|
+
section is `cli` (fields include `default_template`, `default_database`,
|
|
124
|
+
`color`, `verbose`), overridable via `QK_CLI__*`, e.g.
|
|
125
|
+
`QK_CLI__COLOR=false`.
|
|
126
|
+
|
|
127
|
+
## Error handling
|
|
128
|
+
|
|
129
|
+
Commands report structured failures (use `--json` for machine-readable
|
|
130
|
+
envelopes) and non-zero exit codes; `--debug` surfaces full tracebacks.
|
|
131
|
+
|
|
132
|
+
## Testing
|
|
133
|
+
|
|
134
|
+
`quadkit test` runs the project suite; the CLI's own behavior is
|
|
135
|
+
covered by the public test set the release pipeline executes from the
|
|
136
|
+
exported tree.
|
|
137
|
+
|
|
138
|
+
## Security
|
|
139
|
+
|
|
140
|
+
The CLI reads configuration and scaffolds code — it does not serve
|
|
141
|
+
traffic. As with every distribution, keep the `0.x` line pinned and
|
|
142
|
+
review release notes on upgrade. Report vulnerabilities privately per
|
|
143
|
+
[SECURITY.md](../../SECURITY.md).
|
|
144
|
+
|
|
145
|
+
## Stability
|
|
146
|
+
|
|
147
|
+
Version `0.0.3` in the `0.x` series, released in lockstep with the
|
|
148
|
+
other four distributions; APIs may change between minor versions until
|
|
149
|
+
1.0 — pin an exact version (`quadkit-cli==0.0.3`) or a tight range
|
|
150
|
+
(`>=0.0.3,<0.1.0`). Full policy:
|
|
151
|
+
[stability and compatibility](../../docs/reference/stability.md).
|
|
152
|
+
|
|
153
|
+
Issues: <https://github.com/dbtinoy-/quadkit/issues>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# quadkit-cli
|
|
2
|
+
|
|
3
|
+
The `quadkit` command line: project scaffolding, generators, a smart
|
|
4
|
+
runner, and administrative commands for every stage of the application
|
|
5
|
+
lifecycle. Contributor-based — other packages can register their own
|
|
6
|
+
commands.
|
|
7
|
+
|
|
8
|
+
For day-to-day Quadkit developers: scaffold, generate, run, inspect.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uv add quadkit-cli
|
|
14
|
+
# or as a standalone tool:
|
|
15
|
+
uv tool install quadkit-cli
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Requires **Python >= 3.11**.
|
|
19
|
+
|
|
20
|
+
## Minimal working example
|
|
21
|
+
|
|
22
|
+
There is no code to write — the product is the command line:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Create a new project (template defaults to web-api)
|
|
26
|
+
quadkit new project my-api
|
|
27
|
+
|
|
28
|
+
# Generate application code (list all generators: quadkit gen list)
|
|
29
|
+
quadkit gen provider MyProvider
|
|
30
|
+
quadkit gen controller Orders
|
|
31
|
+
|
|
32
|
+
# Serve the application; reload is on by default, pass --no-reload in prod
|
|
33
|
+
quadkit run my_app.app:create_app --host 0.0.0.0 --port 8000 --workers 4
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Global options: `--json` for machine-readable output, `--quiet`,
|
|
37
|
+
`--debug`, `--no-color`, and `--config <path>` to point at a specific
|
|
38
|
+
`application.yaml`.
|
|
39
|
+
|
|
40
|
+
## Command index
|
|
41
|
+
|
|
42
|
+
| Command | Purpose |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `quadkit new project / module / package` | scaffold projects, bounded contexts, and `quadkit-*` extensions |
|
|
45
|
+
| `quadkit init` | initialize Quadkit in an existing project |
|
|
46
|
+
| `quadkit add <provider>` | add a provider to a project (e.g. `database`, `auth`) |
|
|
47
|
+
| `quadkit run [target]` | smart runner — auto-detects `create_app`, sets profile |
|
|
48
|
+
| `quadkit dev start` | production-server startup |
|
|
49
|
+
| `quadkit gen <what>` | code generation (controllers, providers, middleware, tests, more — see `quadkit gen list`) |
|
|
50
|
+
| `quadkit test` / `quadkit lint` | project-level checks |
|
|
51
|
+
| `quadkit db` / `quadkit events` | database / event-schema management |
|
|
52
|
+
| `quadkit config` / `quadkit inspect` / `quadkit shell` | configuration, runtime introspection, REPL |
|
|
53
|
+
| `quadkit project` / `quadkit contrib` / `quadkit system` | project tasks, contributors, system info |
|
|
54
|
+
| `quadkit version` | framework and package versions |
|
|
55
|
+
|
|
56
|
+
Per-distribution guide:
|
|
57
|
+
[quadkit-cli reference](../../docs/reference/quadkit-cli.md).
|
|
58
|
+
|
|
59
|
+
## Optional extras
|
|
60
|
+
|
|
61
|
+
Verified against the package's `pyproject.toml`: `[dev]`, `[test]`,
|
|
62
|
+
`[all]`.
|
|
63
|
+
|
|
64
|
+
## Configuration
|
|
65
|
+
|
|
66
|
+
The CLI reads `application.yaml` like any Quadkit application; its own
|
|
67
|
+
section is `cli` (fields include `default_template`, `default_database`,
|
|
68
|
+
`color`, `verbose`), overridable via `QK_CLI__*`, e.g.
|
|
69
|
+
`QK_CLI__COLOR=false`.
|
|
70
|
+
|
|
71
|
+
## Error handling
|
|
72
|
+
|
|
73
|
+
Commands report structured failures (use `--json` for machine-readable
|
|
74
|
+
envelopes) and non-zero exit codes; `--debug` surfaces full tracebacks.
|
|
75
|
+
|
|
76
|
+
## Testing
|
|
77
|
+
|
|
78
|
+
`quadkit test` runs the project suite; the CLI's own behavior is
|
|
79
|
+
covered by the public test set the release pipeline executes from the
|
|
80
|
+
exported tree.
|
|
81
|
+
|
|
82
|
+
## Security
|
|
83
|
+
|
|
84
|
+
The CLI reads configuration and scaffolds code — it does not serve
|
|
85
|
+
traffic. As with every distribution, keep the `0.x` line pinned and
|
|
86
|
+
review release notes on upgrade. Report vulnerabilities privately per
|
|
87
|
+
[SECURITY.md](../../SECURITY.md).
|
|
88
|
+
|
|
89
|
+
## Stability
|
|
90
|
+
|
|
91
|
+
Version `0.0.3` in the `0.x` series, released in lockstep with the
|
|
92
|
+
other four distributions; APIs may change between minor versions until
|
|
93
|
+
1.0 — pin an exact version (`quadkit-cli==0.0.3`) or a tight range
|
|
94
|
+
(`>=0.0.3,<0.1.0`). Full policy:
|
|
95
|
+
[stability and compatibility](../../docs/reference/stability.md).
|
|
96
|
+
|
|
97
|
+
Issues: <https://github.com/dbtinoy-/quadkit/issues>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
cli:
|
|
7
7
|
# Scaffolding Defaults
|
|
8
|
-
default_template: "web-api" # Template used by `
|
|
8
|
+
default_template: "web-api" # Template used by `qk new` (QK_CLI__DEFAULT_TEMPLATE)
|
|
9
9
|
default_database: "postgres" # Database driver scaffold uses (QK_CLI__DEFAULT_DATABASE)
|
|
10
10
|
|
|
11
11
|
# Output
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "quadkit-cli"
|
|
9
|
-
version = "0.0.
|
|
9
|
+
version = "0.0.3"
|
|
10
10
|
description = "Command-line interface for Quadkit Framework - Project scaffolding, code generation, and development tools"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
requires-python = ">=3.11"
|
|
@@ -104,7 +104,7 @@ test = [
|
|
|
104
104
|
]
|
|
105
105
|
|
|
106
106
|
[tool.ruff]
|
|
107
|
-
extend = "
|
|
107
|
+
extend = "../../pyproject.toml"
|
|
108
108
|
line-length = 88
|
|
109
109
|
target-version = "py311"
|
|
110
110
|
|
|
@@ -169,3 +169,4 @@ addopts = ["--cov=quadkit.cli", "--cov-report=term", "--cov-fail-under=84"]
|
|
|
169
169
|
packages = [
|
|
170
170
|
"src/quadkit",
|
|
171
171
|
]
|
|
172
|
+
|
|
@@ -8,12 +8,13 @@ from typing import Any
|
|
|
8
8
|
import typer
|
|
9
9
|
|
|
10
10
|
from quadkit.cli.output import OutputManager
|
|
11
|
+
from quadkit.cli.package_names import module_for
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
async def _bootstrap_migration_runner() -> tuple[Any, Any, Any]:
|
|
14
15
|
"""Used for direct migration execution (run/rollback/status) via the DI container.
|
|
15
16
|
|
|
16
|
-
Prefers the DI-managed runner when
|
|
17
|
+
Prefers the DI-managed runner when the database provider is available so that
|
|
17
18
|
connection pooling and observability hooks are active. Falls back to the
|
|
18
19
|
legacy factory when the package is not installed.
|
|
19
20
|
|
|
@@ -30,7 +31,7 @@ async def _bootstrap_migration_runner() -> tuple[Any, Any, Any]:
|
|
|
30
31
|
from quadkit.di.container import Container
|
|
31
32
|
from quadkit.di.orchestrator import ProviderOrchestrator
|
|
32
33
|
|
|
33
|
-
sql_provider_mod = importlib.import_module(
|
|
34
|
+
sql_provider_mod = importlib.import_module(module_for('sql', 'di.provider'))
|
|
34
35
|
DBDIProvider = sql_provider_mod.DatabaseProvider
|
|
35
36
|
|
|
36
37
|
container = Container()
|
|
@@ -45,15 +46,15 @@ async def _bootstrap_migration_runner() -> tuple[Any, Any, Any]:
|
|
|
45
46
|
return runner, orchestrator, container
|
|
46
47
|
|
|
47
48
|
except ImportError:
|
|
48
|
-
#
|
|
49
|
+
# Database provider not installed — fall back to legacy direct factory.
|
|
49
50
|
try:
|
|
50
|
-
db_cli = importlib.import_module(
|
|
51
|
+
db_cli = importlib.import_module(module_for('sql', 'cli'))
|
|
51
52
|
manager = db_cli.create_cli_migration_manager(db_url)
|
|
52
53
|
return manager, None, None
|
|
53
54
|
except ImportError as e:
|
|
54
55
|
out = OutputManager()
|
|
55
56
|
out.error(
|
|
56
|
-
f"
|
|
57
|
+
f"The optional database provider is required for database commands ({e})"
|
|
57
58
|
)
|
|
58
59
|
raise typer.Exit(1) from None
|
|
59
60
|
|
|
@@ -77,9 +78,9 @@ async def _bootstrap_db_provider() -> tuple[Any, Any]:
|
|
|
77
78
|
from quadkit.di.container import Container
|
|
78
79
|
from quadkit.di.orchestrator import ProviderOrchestrator
|
|
79
80
|
|
|
80
|
-
sql_provider_mod = importlib.import_module(
|
|
81
|
+
sql_provider_mod = importlib.import_module(module_for('sql', 'di.provider'))
|
|
81
82
|
DatabaseProvider = sql_provider_mod.DatabaseProvider
|
|
82
|
-
sql_config_mod = importlib.import_module(
|
|
83
|
+
sql_config_mod = importlib.import_module(module_for('sql', 'config'))
|
|
83
84
|
DatabaseConfig = sql_config_mod.DatabaseConfig
|
|
84
85
|
|
|
85
86
|
container = Container()
|
|
@@ -99,7 +100,7 @@ async def _bootstrap_db_provider() -> tuple[Any, Any]:
|
|
|
99
100
|
except ImportError as e:
|
|
100
101
|
out = OutputManager()
|
|
101
102
|
out.error(
|
|
102
|
-
f"
|
|
103
|
+
f"The optional database provider is required for database commands ({e})"
|
|
103
104
|
)
|
|
104
105
|
raise typer.Exit(1) from None
|
|
105
106
|
|
|
@@ -114,12 +115,12 @@ async def get_migration_manager() -> Any:
|
|
|
114
115
|
try:
|
|
115
116
|
import os
|
|
116
117
|
|
|
117
|
-
db_cli = importlib.import_module(
|
|
118
|
+
db_cli = importlib.import_module(module_for('sql', 'cli'))
|
|
118
119
|
db_url = os.environ.get("DATABASE_URL", "sqlite:///./dev.db")
|
|
119
120
|
return db_cli.create_cli_migration_manager(db_url)
|
|
120
121
|
except ImportError as e:
|
|
121
122
|
out = OutputManager()
|
|
122
|
-
out.error(f"Failed to import
|
|
123
|
+
out.error(f"Failed to import the optional database provider: {e}")
|
|
123
124
|
raise typer.Exit(1) from None
|
|
124
125
|
|
|
125
126
|
|
|
@@ -89,8 +89,8 @@ def inspect_(
|
|
|
89
89
|
out.table(["Column", "Type", "Nullable"], rows)
|
|
90
90
|
|
|
91
91
|
except ImportError as e:
|
|
92
|
-
out.error(f"
|
|
93
|
-
out.info("Install
|
|
92
|
+
out.error(f"The optional database provider is not installed: {e}")
|
|
93
|
+
out.info("Install the provider before retrying")
|
|
94
94
|
raise typer.Exit(1) from None
|
|
95
95
|
except Exception as e: # noqa: BLE001 — any inspect failure is a CLI error
|
|
96
96
|
out.error(f"Failed to inspect database: {e}")
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Provides ``quadkit events migrate`` and ``quadkit events status`` to
|
|
4
4
|
inspect and apply event-schema migrations managed by
|
|
5
|
-
:class
|
|
5
|
+
:class:`SchemaEvolution` from the optional event provider.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
@@ -13,6 +13,7 @@ from typing import Annotated, Any
|
|
|
13
13
|
import typer
|
|
14
14
|
|
|
15
15
|
from quadkit.cli.output import OutputManager
|
|
16
|
+
from quadkit.cli.package_names import module_for
|
|
16
17
|
from quadkit.cli.runtime import handle_errors
|
|
17
18
|
|
|
18
19
|
app = typer.Typer(name="events")
|
|
@@ -21,7 +22,7 @@ app = typer.Typer(name="events")
|
|
|
21
22
|
def _make_evolution() -> Any:
|
|
22
23
|
"""Bootstrap an in-memory SchemaRegistry and SchemaEvolution.
|
|
23
24
|
|
|
24
|
-
When
|
|
25
|
+
When the optional event provider is installed and discoverable, this returns a
|
|
25
26
|
properly wired instance. Raises :exc:`typer.Exit` with a readable error
|
|
26
27
|
message when the package is not available.
|
|
27
28
|
"""
|
|
@@ -29,15 +30,16 @@ def _make_evolution() -> Any:
|
|
|
29
30
|
try:
|
|
30
31
|
import importlib as _importlib
|
|
31
32
|
|
|
32
|
-
_evo_mod = _importlib.import_module(
|
|
33
|
-
_reg_mod = _importlib.import_module(
|
|
34
|
-
_store_mod = _importlib.import_module(
|
|
33
|
+
_evo_mod = _importlib.import_module(module_for('events', 'schema.evolution'))
|
|
34
|
+
_reg_mod = _importlib.import_module(module_for('events', 'schema.registry'))
|
|
35
|
+
_store_mod = _importlib.import_module(module_for('events', 'schema.store'))
|
|
35
36
|
SchemaEvolution = _evo_mod.SchemaEvolution
|
|
36
37
|
SchemaRegistry = _reg_mod.SchemaRegistry
|
|
37
38
|
InMemorySchemaStore = _store_mod.InMemorySchemaStore
|
|
38
39
|
except ImportError:
|
|
39
40
|
out.error(
|
|
40
|
-
"
|
|
41
|
+
"The optional event provider is not installed. "
|
|
42
|
+
"Install the provider before retrying."
|
|
41
43
|
)
|
|
42
44
|
raise typer.Exit(1) from None
|
|
43
45
|
|
|
@@ -88,8 +90,8 @@ def migrate(
|
|
|
88
90
|
# hard cross-extension import at module level.
|
|
89
91
|
import importlib as _importlib
|
|
90
92
|
|
|
91
|
-
_reg_mod = _importlib.import_module(
|
|
92
|
-
_store_mod = _importlib.import_module(
|
|
93
|
+
_reg_mod = _importlib.import_module(module_for('events', 'schema.registry'))
|
|
94
|
+
_store_mod = _importlib.import_module(module_for('events', 'schema.store'))
|
|
93
95
|
registry = _reg_mod.SchemaRegistry(store=_store_mod.InMemorySchemaStore())
|
|
94
96
|
latest = await registry.get_latest_version(event_type)
|
|
95
97
|
target = latest if latest is not None else from_version
|
|
@@ -192,7 +194,7 @@ def replay(
|
|
|
192
194
|
out.print()
|
|
193
195
|
out.print("Use the programmatic approach instead:")
|
|
194
196
|
out.print()
|
|
195
|
-
out.print(" [cyan]from
|
|
197
|
+
out.print(f" [cyan]from {module_for('events')} import EventBus[/cyan]")
|
|
196
198
|
out.print(" [cyan]bus = container.resolve(EventBus)[/cyan]")
|
|
197
199
|
out.print(
|
|
198
200
|
" [cyan]await bus.replay(event_type='UserCreated', since=start_time)[/cyan]"
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import importlib.metadata
|
|
3
4
|
from typing import Annotated
|
|
4
5
|
|
|
5
6
|
import typer
|
|
6
7
|
|
|
7
8
|
from quadkit.cli.constants import __version__
|
|
9
|
+
from quadkit.cli.package_names import installed_quadkit_distributions
|
|
8
10
|
from quadkit.cli.output import OutputManager
|
|
9
11
|
from quadkit.cli.registry.command import CommandEntry, CommandRegistry
|
|
10
12
|
|
|
@@ -84,30 +86,7 @@ def version(
|
|
|
84
86
|
out = OutputManager()
|
|
85
87
|
out.print(f"quadkit {__version__}")
|
|
86
88
|
if all_packages:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
packages = [
|
|
90
|
-
"quadkit",
|
|
91
|
-
"quadkit-cli",
|
|
92
|
-
"quadkit-web",
|
|
93
|
-
"quadkit-sql",
|
|
94
|
-
"quadkit-auth",
|
|
95
|
-
"quadkit-cache",
|
|
96
|
-
"quadkit-events",
|
|
97
|
-
"quadkit-notification",
|
|
98
|
-
"quadkit-queue",
|
|
99
|
-
"quadkit-monitor",
|
|
100
|
-
"quadkit-tasks",
|
|
101
|
-
"quadkit-graphql",
|
|
102
|
-
"quadkit-ai",
|
|
103
|
-
"quadkit-resilience",
|
|
104
|
-
"quadkit-http",
|
|
105
|
-
"quadkit-features",
|
|
106
|
-
"quadkit-search",
|
|
107
|
-
"quadkit-storage",
|
|
108
|
-
"quadkit-admin",
|
|
109
|
-
"quadkit-testing",
|
|
110
|
-
]
|
|
89
|
+
packages = installed_quadkit_distributions()
|
|
111
90
|
rows = []
|
|
112
91
|
for pkg in packages:
|
|
113
92
|
try:
|
|
@@ -8,6 +8,7 @@ import typer
|
|
|
8
8
|
import yaml
|
|
9
9
|
|
|
10
10
|
from quadkit.cli.lib.console import console
|
|
11
|
+
from quadkit.cli.package_names import installed_quadkit_distributions
|
|
11
12
|
from quadkit.cli.registry.health import (
|
|
12
13
|
CheckResult,
|
|
13
14
|
CheckStatus,
|
|
@@ -46,7 +47,7 @@ def info() -> None:
|
|
|
46
47
|
console.print("Project Config: [warning]Not found[/warning]")
|
|
47
48
|
|
|
48
49
|
console.print("\n[bold]Core Packages:[/bold]")
|
|
49
|
-
for pkg in
|
|
50
|
+
for pkg in installed_quadkit_distributions():
|
|
50
51
|
console.print(f"- {pkg}")
|
|
51
52
|
|
|
52
53
|
|
|
@@ -15,6 +15,7 @@ from quadkit.contracts.cli.contributions import (
|
|
|
15
15
|
)
|
|
16
16
|
from quadkit.contracts.cli.protocols import CliContributorProtocol
|
|
17
17
|
from quadkit.contracts.cli.types import GeneratorDefinition
|
|
18
|
+
from quadkit.cli.package_names import PUBLIC_DISTRIBUTIONS
|
|
18
19
|
|
|
19
20
|
ENTRY_POINT_GROUP = "quadkit.cli.contributors"
|
|
20
21
|
|
|
@@ -23,36 +24,7 @@ _BUILTIN_DIST = "quadkit-cli"
|
|
|
23
24
|
_RESERVED_COMMANDS: dict[str, str] = {
|
|
24
25
|
"search": "search",
|
|
25
26
|
}
|
|
26
|
-
_SCOPE_DISTS
|
|
27
|
-
{
|
|
28
|
-
"quadkit",
|
|
29
|
-
"quadkit-contracts",
|
|
30
|
-
"quadkit-ai",
|
|
31
|
-
"quadkit-ai-mcp",
|
|
32
|
-
"quadkit-vector",
|
|
33
|
-
"quadkit-web",
|
|
34
|
-
"quadkit-sql",
|
|
35
|
-
"quadkit-cache",
|
|
36
|
-
"quadkit-auth",
|
|
37
|
-
"quadkit-events",
|
|
38
|
-
"quadkit-queue",
|
|
39
|
-
"quadkit-tasks",
|
|
40
|
-
"quadkit-http",
|
|
41
|
-
"quadkit-resilience",
|
|
42
|
-
"quadkit-storage",
|
|
43
|
-
"quadkit-search",
|
|
44
|
-
"quadkit-notification",
|
|
45
|
-
"quadkit-monitor",
|
|
46
|
-
"quadkit-webhook",
|
|
47
|
-
"quadkit-tenancy",
|
|
48
|
-
"quadkit-features",
|
|
49
|
-
"quadkit-audit",
|
|
50
|
-
"quadkit-graphql",
|
|
51
|
-
"quadkit-nosql",
|
|
52
|
-
"quadkit-workflow",
|
|
53
|
-
"quadkit-testing",
|
|
54
|
-
}
|
|
55
|
-
)
|
|
27
|
+
_SCOPE_DISTS = PUBLIC_DISTRIBUTIONS
|
|
56
28
|
|
|
57
29
|
|
|
58
30
|
@dataclass(frozen=True)
|
|
@@ -58,7 +58,9 @@ class ProviderNotInstalledError(CliError):
|
|
|
58
58
|
"""
|
|
59
59
|
super().__init__(
|
|
60
60
|
message=f"Provider '{provider}' is not installed",
|
|
61
|
-
suggestions=[
|
|
61
|
+
suggestions=[
|
|
62
|
+
f"Install the provider distribution that supplies '{provider}'"
|
|
63
|
+
],
|
|
62
64
|
)
|
|
63
65
|
|
|
64
66
|
|
|
@@ -15,6 +15,7 @@ import importlib
|
|
|
15
15
|
from pathlib import Path
|
|
16
16
|
from typing import TYPE_CHECKING, Any, ClassVar, get_args, get_origin
|
|
17
17
|
|
|
18
|
+
from quadkit.cli.package_names import module_for, provider_available
|
|
18
19
|
from quadkit.logging import get_logger
|
|
19
20
|
|
|
20
21
|
if TYPE_CHECKING:
|
|
@@ -24,29 +25,34 @@ if TYPE_CHECKING:
|
|
|
24
25
|
|
|
25
26
|
logger = get_logger(__name__)
|
|
26
27
|
|
|
27
|
-
# Registry: maps YAML section key → (
|
|
28
|
-
#
|
|
28
|
+
# Registry: maps YAML section key → (provider feature, config class name).
|
|
29
|
+
# Optional entries are materialized only when their provider is installed.
|
|
30
|
+
_CONFIG_SPECS: dict[str, tuple[str, str]] = {
|
|
31
|
+
"database": ("sql", "DatabaseConfig"),
|
|
32
|
+
"web": ("web", "WebConfig"),
|
|
33
|
+
"auth": ("auth", "AuthConfig"),
|
|
34
|
+
"cache": ("cache", "CacheConfig"),
|
|
35
|
+
"storage": ("storage", "StorageConfig"),
|
|
36
|
+
"tasks": ("tasks", "TaskConfig"),
|
|
37
|
+
"events": ("events", "EventsConfig"),
|
|
38
|
+
"search": ("search", "SearchConfig"),
|
|
39
|
+
"ai": ("ai", "AIConfig"),
|
|
40
|
+
"monitor": ("monitor", "MonitorConfig"),
|
|
41
|
+
"messaging": ("messaging", "MessagingConfig"),
|
|
42
|
+
"feature_flags": ("features", "FeatureFlagsConfig"),
|
|
43
|
+
"graphql": ("graphql", "GraphQLConfig"),
|
|
44
|
+
}
|
|
29
45
|
PACKAGE_CONFIGS: dict[str, str] = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
"cache": "quadkit.cache.config:CacheConfig",
|
|
34
|
-
"storage": "quadkit.storage.config:StorageConfig",
|
|
35
|
-
"tasks": "quadkit.tasks.config:TaskConfig",
|
|
36
|
-
"events": "quadkit.events.config:EventsConfig",
|
|
37
|
-
"search": "quadkit.search.config:SearchConfig",
|
|
38
|
-
"ai": "quadkit.ai.config:AIConfig",
|
|
39
|
-
"monitor": "quadkit.monitor.config:MonitorConfig",
|
|
40
|
-
"messaging": "quadkit.messaging.config:MessagingConfig",
|
|
41
|
-
"feature_flags": "quadkit.features.config:FeatureFlagsConfig",
|
|
42
|
-
"graphql": "quadkit.graphql.config:GraphQLConfig",
|
|
46
|
+
key: f"{module_for(feature, 'config')}:{class_name}"
|
|
47
|
+
for key, (feature, class_name) in _CONFIG_SPECS.items()
|
|
48
|
+
if feature == "web" or provider_available(feature)
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
|
|
46
52
|
def _import_config_class(import_path: str) -> type[Any]:
|
|
47
|
-
"""Import a config class from a dotted path like 'quadkit
|
|
53
|
+
"""Import a config class from a dotted path like 'quadkit.<provider>.config:ConfigClass'.
|
|
48
54
|
|
|
49
|
-
Raises ImportError if
|
|
55
|
+
Raises ImportError if the optional domain-model provider is not installed.
|
|
50
56
|
"""
|
|
51
57
|
module_path, class_name = import_path.rsplit(":", 1)
|
|
52
58
|
|
|
@@ -235,7 +241,7 @@ def generate_package_config(
|
|
|
235
241
|
|
|
236
242
|
Args:
|
|
237
243
|
package_key: The YAML section key (e.g. 'database').
|
|
238
|
-
import_path: Import path like 'quadkit
|
|
244
|
+
import_path: Import path like 'quadkit.<provider>.config:ConfigClass'.
|
|
239
245
|
with_comments: Include field descriptions as comments.
|
|
240
246
|
|
|
241
247
|
Returns:
|
|
@@ -244,10 +250,10 @@ def generate_package_config(
|
|
|
244
250
|
try:
|
|
245
251
|
config_cls = _import_config_class(import_path)
|
|
246
252
|
except ImportError as e:
|
|
247
|
-
if "
|
|
253
|
+
if module_for("domain") in str(e) or "DomainModel" in str(e):
|
|
248
254
|
error_msg = (
|
|
249
|
-
"
|
|
250
|
-
"install
|
|
255
|
+
"The optional domain-model provider is required for config "
|
|
256
|
+
"generation; install the provider before retrying."
|
|
251
257
|
)
|
|
252
258
|
return f"# Error: {error_msg}\n# Original error: {e}\n{package_key}: {{}}\n"
|
|
253
259
|
return f"# Failed to import {import_path}: {e}\n{package_key}: {{}}\n"
|