snowflake-cli-labs 2.8.0rc1__py3-none-any.whl → 3.0.0__py3-none-any.whl
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.
- snowflake/cli/__about__.py +1 -1
- snowflake/cli/{app → _app}/__main__.py +1 -1
- snowflake/cli/{app → _app}/cli_app.py +22 -13
- snowflake/cli/{app → _app}/commands_registration/builtin_plugins.py +15 -19
- snowflake/cli/{app → _app}/commands_registration/command_plugins_loader.py +9 -9
- snowflake/cli/{app → _app}/commands_registration/commands_registration_with_callbacks.py +4 -4
- snowflake/cli/{app → _app}/commands_registration/exception_logging.py +2 -2
- snowflake/cli/{app → _app}/commands_registration/typer_registration.py +2 -2
- snowflake/cli/{app → _app}/dev/docs/commands_docs_generator.py +30 -12
- snowflake/cli/{app → _app}/dev/docs/generator.py +3 -3
- snowflake/cli/{app → _app}/dev/docs/project_definition_docs_generator.py +4 -4
- snowflake/cli/{app → _app}/dev/docs/templates/usage.rst.jinja2 +14 -4
- snowflake/cli/{app → _app}/main_typer.py +2 -2
- snowflake/cli/{app → _app}/printing.py +2 -2
- snowflake/cli/_app/secret.py +9 -0
- snowflake/cli/{app → _app}/snow_connector.py +127 -61
- snowflake/cli/{app → _app}/telemetry.py +38 -7
- snowflake/cli/_app/version_check.py +74 -0
- snowflake/cli/{plugins → _plugins}/connection/commands.py +34 -11
- snowflake/cli/_plugins/connection/plugin_spec.py +30 -0
- snowflake/cli/{plugins → _plugins}/connection/util.py +16 -0
- snowflake/cli/{plugins → _plugins}/cortex/commands.py +54 -49
- snowflake/cli/{plugins → _plugins}/cortex/constants.py +1 -1
- snowflake/cli/{plugins → _plugins}/cortex/manager.py +5 -5
- snowflake/cli/{plugins → _plugins}/cortex/plugin_spec.py +1 -1
- snowflake/cli/{plugins → _plugins}/git/commands.py +79 -26
- snowflake/cli/{plugins → _plugins}/git/manager.py +72 -17
- snowflake/cli/{plugins → _plugins}/git/plugin_spec.py +1 -1
- snowflake/cli/_plugins/helpers/commands.py +90 -0
- snowflake/cli/{plugins/notebook → _plugins/helpers}/plugin_spec.py +1 -1
- snowflake/cli/{plugins → _plugins}/init/commands.py +10 -6
- snowflake/cli/{plugins → _plugins}/init/plugin_spec.py +1 -1
- snowflake/cli/{plugins → _plugins}/nativeapp/artifacts.py +24 -9
- snowflake/cli/_plugins/nativeapp/bundle_context.py +31 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/artifact_processor.py +4 -4
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/compiler.py +37 -18
- snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +249 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/setup/setup_driver.py.source +5 -2
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/extension_function_utils.py +5 -5
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/models.py +1 -1
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/python_processor.py +29 -34
- snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +114 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/commands.py +252 -132
- snowflake/cli/{plugins → _plugins}/nativeapp/common_flags.py +1 -1
- snowflake/cli/_plugins/nativeapp/entities/application.py +878 -0
- snowflake/cli/_plugins/nativeapp/entities/application_package.py +1392 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/exceptions.py +3 -12
- snowflake/cli/_plugins/nativeapp/manager.py +415 -0
- snowflake/cli/{plugins/connection → _plugins/nativeapp}/plugin_spec.py +1 -1
- snowflake/cli/{plugins → _plugins}/nativeapp/policy.py +3 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/project_model.py +36 -20
- snowflake/cli/_plugins/nativeapp/run_processor.py +184 -0
- snowflake/cli/_plugins/nativeapp/same_account_install_method.py +70 -0
- snowflake/cli/_plugins/nativeapp/teardown_processor.py +70 -0
- snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +262 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/version/commands.py +20 -49
- snowflake/cli/_plugins/nativeapp/version/version_processor.py +98 -0
- snowflake/cli/{plugins → _plugins}/notebook/commands.py +8 -6
- snowflake/cli/{plugins → _plugins}/notebook/manager.py +14 -14
- snowflake/cli/{plugins/nativeapp → _plugins/notebook}/plugin_spec.py +1 -1
- snowflake/cli/{plugins → _plugins}/notebook/types.py +0 -1
- snowflake/cli/{plugins → _plugins}/object/command_aliases.py +6 -5
- snowflake/cli/{plugins → _plugins}/object/commands.py +16 -10
- snowflake/cli/{plugins → _plugins}/object/manager.py +43 -21
- snowflake/cli/{plugins → _plugins}/object/plugin_spec.py +1 -1
- snowflake/cli/_plugins/snowpark/commands.py +450 -0
- snowflake/cli/_plugins/snowpark/common.py +268 -0
- snowflake/cli/{plugins → _plugins}/snowpark/models.py +2 -8
- snowflake/cli/{plugins → _plugins}/snowpark/package/anaconda_packages.py +2 -36
- snowflake/cli/{plugins → _plugins}/snowpark/package/commands.py +13 -74
- snowflake/cli/{plugins → _plugins}/snowpark/package/manager.py +4 -3
- snowflake/cli/{plugins → _plugins}/snowpark/package_utils.py +5 -5
- snowflake/cli/_plugins/snowpark/plugin_spec.py +30 -0
- snowflake/cli/_plugins/snowpark/snowpark_entity.py +29 -0
- snowflake/cli/_plugins/snowpark/snowpark_entity_model.py +173 -0
- snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +109 -0
- snowflake/cli/{plugins → _plugins}/snowpark/snowpark_shared.py +0 -36
- snowflake/cli/{plugins → _plugins}/snowpark/zipper.py +16 -8
- snowflake/cli/{plugins → _plugins}/spcs/__init__.py +5 -7
- snowflake/cli/{plugins → _plugins}/spcs/compute_pool/commands.py +29 -28
- snowflake/cli/{plugins → _plugins}/spcs/compute_pool/manager.py +3 -3
- snowflake/cli/{plugins → _plugins}/spcs/image_registry/commands.py +3 -3
- snowflake/cli/{plugins → _plugins}/spcs/image_repository/commands.py +25 -19
- snowflake/cli/{plugins → _plugins}/spcs/image_repository/manager.py +1 -1
- snowflake/cli/{plugins → _plugins}/spcs/plugin_spec.py +1 -1
- snowflake/cli/{plugins → _plugins}/spcs/services/commands.py +66 -32
- snowflake/cli/{plugins → _plugins}/spcs/services/manager.py +43 -5
- snowflake/cli/{plugins → _plugins}/sql/commands.py +20 -17
- snowflake/cli/{plugins → _plugins}/sql/manager.py +1 -1
- snowflake/cli/{plugins → _plugins}/sql/plugin_spec.py +1 -1
- snowflake/cli/{plugins → _plugins}/stage/commands.py +20 -17
- snowflake/cli/{plugins → _plugins}/stage/diff.py +1 -47
- snowflake/cli/{plugins → _plugins}/stage/manager.py +62 -24
- snowflake/cli/{plugins → _plugins}/stage/plugin_spec.py +1 -1
- snowflake/cli/_plugins/stage/utils.py +54 -0
- snowflake/cli/{plugins → _plugins}/streamlit/commands.py +71 -62
- snowflake/cli/{plugins → _plugins}/streamlit/manager.py +68 -70
- snowflake/cli/_plugins/streamlit/plugin_spec.py +30 -0
- snowflake/cli/_plugins/streamlit/streamlit_entity.py +12 -0
- snowflake/cli/_plugins/streamlit/streamlit_entity_model.py +66 -0
- snowflake/cli/_plugins/workspace/action_context.py +18 -0
- snowflake/cli/_plugins/workspace/commands.py +306 -0
- snowflake/cli/_plugins/workspace/manager.py +74 -0
- snowflake/cli/_plugins/workspace/plugin_spec.py +30 -0
- snowflake/cli/api/cli_global_context.py +152 -295
- snowflake/cli/api/commands/common.py +25 -0
- snowflake/cli/api/commands/decorators.py +19 -4
- snowflake/cli/api/commands/experimental_behaviour.py +2 -3
- snowflake/cli/api/commands/flags.py +143 -222
- snowflake/cli/api/commands/overrideable_parameter.py +143 -0
- snowflake/cli/api/commands/snow_typer.py +21 -11
- snowflake/cli/api/commands/utils.py +18 -0
- snowflake/cli/api/config.py +44 -12
- snowflake/cli/api/connections.py +216 -0
- snowflake/cli/api/console/abc.py +8 -3
- snowflake/cli/api/constants.py +11 -0
- snowflake/cli/api/entities/common.py +56 -0
- snowflake/cli/api/entities/utils.py +370 -0
- snowflake/cli/api/errno.py +1 -0
- snowflake/cli/api/exceptions.py +31 -5
- snowflake/cli/api/feature_flags.py +0 -1
- snowflake/cli/api/identifiers.py +45 -9
- snowflake/cli/api/metrics.py +92 -0
- snowflake/cli/api/project/definition.py +48 -6
- snowflake/cli/api/project/definition_conversion.py +400 -0
- snowflake/cli/api/project/definition_manager.py +16 -5
- snowflake/cli/api/project/project_verification.py +3 -3
- snowflake/cli/api/project/schemas/entities/common.py +91 -16
- snowflake/cli/api/project/schemas/entities/entities.py +37 -6
- snowflake/cli/api/project/schemas/project_definition.py +180 -49
- snowflake/cli/api/project/schemas/updatable_model.py +11 -3
- snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{identifier_model.py → v1/identifier_model.py} +3 -1
- snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{native_app → v1/native_app}/application.py +8 -9
- snowflake/cli/api/project/schemas/{native_app → v1/native_app}/native_app.py +4 -4
- snowflake/cli/api/project/schemas/{native_app → v1/native_app}/package.py +7 -1
- snowflake/cli/api/project/schemas/v1/snowpark/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/callable.py +2 -2
- snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/snowpark.py +2 -2
- snowflake/cli/api/project/schemas/v1/streamlit/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{streamlit → v1/streamlit}/streamlit.py +2 -1
- snowflake/cli/api/project/util.py +23 -6
- snowflake/cli/api/rendering/jinja.py +14 -8
- snowflake/cli/api/rendering/project_definition_templates.py +5 -1
- snowflake/cli/api/rendering/sql_templates.py +56 -11
- snowflake/cli/api/rest_api.py +11 -5
- snowflake/cli/api/secure_path.py +16 -18
- snowflake/cli/api/secure_utils.py +90 -1
- snowflake/cli/api/sql_execution.py +47 -27
- snowflake/cli/api/utils/definition_rendering.py +45 -13
- {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/METADATA +20 -18
- snowflake_cli_labs-3.0.0.dist-info/RECORD +242 -0
- snowflake_cli_labs-3.0.0.dist-info/entry_points.txt +2 -0
- snowflake/cli/api/commands/project_initialisation.py +0 -65
- snowflake/cli/api/commands/typer_pre_execute.py +0 -26
- snowflake/cli/api/project/schemas/entities/application_entity.py +0 -44
- snowflake/cli/api/project/schemas/entities/application_package_entity.py +0 -66
- snowflake/cli/app/build_and_push.sh +0 -8
- snowflake/cli/plugins/nativeapp/codegen/setup/native_app_setup_processor.py +0 -172
- snowflake/cli/plugins/nativeapp/init.py +0 -345
- snowflake/cli/plugins/nativeapp/manager.py +0 -823
- snowflake/cli/plugins/nativeapp/run_processor.py +0 -389
- snowflake/cli/plugins/nativeapp/teardown_processor.py +0 -301
- snowflake/cli/plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +0 -135
- snowflake/cli/plugins/nativeapp/version/version_processor.py +0 -362
- snowflake/cli/plugins/object_stage_deprecated/__init__.py +0 -15
- snowflake/cli/plugins/object_stage_deprecated/commands.py +0 -122
- snowflake/cli/plugins/object_stage_deprecated/plugin_spec.py +0 -32
- snowflake/cli/plugins/snowpark/commands.py +0 -548
- snowflake/cli/plugins/snowpark/common.py +0 -307
- snowflake/cli/plugins/snowpark/manager.py +0 -109
- snowflake/cli/plugins/snowpark/plugin_spec.py +0 -30
- snowflake/cli/plugins/snowpark/snowpark_package_paths.py +0 -65
- snowflake/cli/plugins/spcs/jobs/commands.py +0 -78
- snowflake/cli/plugins/spcs/jobs/manager.py +0 -53
- snowflake/cli/plugins/streamlit/__init__.py +0 -13
- snowflake/cli/plugins/streamlit/plugin_spec.py +0 -30
- snowflake/cli/plugins/workspace/__init__.py +0 -13
- snowflake/cli/plugins/workspace/commands.py +0 -35
- snowflake/cli/plugins/workspace/plugin_spec.py +0 -30
- snowflake/cli/templates/default_snowpark/.gitignore +0 -4
- snowflake/cli/templates/default_snowpark/app/common.py +0 -2
- snowflake/cli/templates/default_snowpark/app/functions.py +0 -15
- snowflake/cli/templates/default_snowpark/app/procedures.py +0 -22
- snowflake/cli/templates/default_snowpark/requirements.txt +0 -1
- snowflake/cli/templates/default_snowpark/snowflake.yml +0 -23
- snowflake/cli/templates/default_streamlit/.gitignore +0 -4
- snowflake/cli/templates/default_streamlit/common/hello.py +0 -2
- snowflake/cli/templates/default_streamlit/environment.yml +0 -6
- snowflake/cli/templates/default_streamlit/pages/my_page.py +0 -3
- snowflake/cli/templates/default_streamlit/snowflake.yml +0 -10
- snowflake/cli/templates/default_streamlit/streamlit_app.py +0 -4
- snowflake_cli_labs-2.8.0rc1.dist-info/RECORD +0 -240
- snowflake_cli_labs-2.8.0rc1.dist-info/entry_points.txt +0 -2
- /snowflake/cli/{app → _app}/__init__.py +0 -0
- /snowflake/cli/{api/project/schemas/native_app → _app/api_impl}/__init__.py +0 -0
- /snowflake/cli/{api/project/schemas/snowpark → _app/api_impl/plugin}/__init__.py +0 -0
- /snowflake/cli/{app → _app}/api_impl/plugin/plugin_config_provider_impl.py +0 -0
- /snowflake/cli/{app → _app}/commands_registration/__init__.py +0 -0
- /snowflake/cli/{app → _app}/commands_registration/threadsafe.py +0 -0
- /snowflake/cli/{app → _app}/constants.py +0 -0
- /snowflake/cli/{api/project/schemas/streamlit → _app/dev}/__init__.py +0 -0
- /snowflake/cli/{app → _app}/dev/commands_structure.py +0 -0
- /snowflake/cli/{app/api_impl → _app/dev/docs}/__init__.py +0 -0
- /snowflake/cli/{app → _app}/dev/docs/project_definition_generate_json_schema.py +0 -0
- /snowflake/cli/{app → _app}/dev/docs/template_utils.py +0 -0
- /snowflake/cli/{app → _app}/dev/docs/templates/definition_description.rst.jinja2 +0 -0
- /snowflake/cli/{app → _app}/dev/docs/templates/overview.rst.jinja2 +0 -0
- /snowflake/cli/{app → _app}/dev/pycharm_remote_debug.py +0 -0
- /snowflake/cli/{app → _app}/loggers.py +0 -0
- /snowflake/cli/{app/api_impl/plugin → _plugins}/__init__.py +0 -0
- /snowflake/cli/{app/dev → _plugins/connection}/__init__.py +0 -0
- /snowflake/cli/{app/dev/docs → _plugins/cortex}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/cortex/types.py +0 -0
- /snowflake/cli/{plugins → _plugins/git}/__init__.py +0 -0
- /snowflake/cli/{plugins/connection → _plugins/helpers}/__init__.py +0 -0
- /snowflake/cli/{plugins/cortex → _plugins/init}/__init__.py +0 -0
- /snowflake/cli/{plugins/git → _plugins/nativeapp}/__init__.py +0 -0
- /snowflake/cli/{plugins/init → _plugins/nativeapp/codegen}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/sandbox.py +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/constants.py +0 -0
- /snowflake/cli/{templates/default_snowpark/app → _plugins/nativeapp/entities}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/feature_flags.py +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/utils.py +0 -0
- /snowflake/cli/{plugins/nativeapp → _plugins/nativeapp/version}/__init__.py +0 -0
- /snowflake/cli/{plugins/nativeapp/codegen → _plugins/notebook}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/notebook/exceptions.py +0 -0
- /snowflake/cli/{plugins/nativeapp/version → _plugins/object}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/object/common.py +0 -0
- /snowflake/cli/{plugins/notebook → _plugins/snowpark}/__init__.py +0 -0
- /snowflake/cli/{plugins/object → _plugins/snowpark/package}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/snowpark/package/utils.py +0 -0
- /snowflake/cli/{plugins → _plugins}/spcs/common.py +0 -0
- /snowflake/cli/{plugins/snowpark → _plugins/spcs/compute_pool}/__init__.py +0 -0
- /snowflake/cli/{plugins/snowpark/package → _plugins/spcs/image_registry}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/spcs/image_registry/manager.py +0 -0
- /snowflake/cli/{plugins/spcs/compute_pool → _plugins/spcs/image_repository}/__init__.py +0 -0
- /snowflake/cli/{plugins/spcs/image_registry → _plugins/spcs/services}/__init__.py +0 -0
- /snowflake/cli/{plugins/spcs/image_repository → _plugins/sql}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/sql/snowsql_templating.py +0 -0
- /snowflake/cli/{plugins/spcs/jobs → _plugins/stage}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/stage/md5.py +0 -0
- /snowflake/cli/{plugins/spcs/services → _plugins/streamlit}/__init__.py +0 -0
- /snowflake/cli/{plugins/sql → _plugins/workspace}/__init__.py +0 -0
- /snowflake/cli/{plugins/stage → api/project/schemas/entities}/__init__.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/path_mapping.py +0 -0
- /snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/argument.py +0 -0
- {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Dict
|
|
3
|
+
|
|
4
|
+
from snowflake.cli._plugins.workspace.action_context import ActionContext
|
|
5
|
+
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
6
|
+
from snowflake.cli.api.console import cli_console as cc
|
|
7
|
+
from snowflake.cli.api.entities.common import EntityActions, get_sql_executor
|
|
8
|
+
from snowflake.cli.api.exceptions import InvalidProjectDefinitionVersionError
|
|
9
|
+
from snowflake.cli.api.project.definition import default_role
|
|
10
|
+
from snowflake.cli.api.project.schemas.entities.entities import (
|
|
11
|
+
Entity,
|
|
12
|
+
v2_entity_model_to_entity_map,
|
|
13
|
+
)
|
|
14
|
+
from snowflake.cli.api.project.schemas.project_definition import (
|
|
15
|
+
DefinitionV20,
|
|
16
|
+
ProjectDefinition,
|
|
17
|
+
)
|
|
18
|
+
from snowflake.cli.api.project.util import to_identifier
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class WorkspaceManager:
|
|
22
|
+
"""
|
|
23
|
+
Instantiates entity instances from entity models, providing higher-order functionality on entity compositions.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, project_definition: ProjectDefinition, project_root: Path):
|
|
27
|
+
if not project_definition.meets_version_requirement("2"):
|
|
28
|
+
raise InvalidProjectDefinitionVersionError(
|
|
29
|
+
"2.x", project_definition.definition_version
|
|
30
|
+
)
|
|
31
|
+
self._entities_cache: Dict[str, Entity] = {}
|
|
32
|
+
self._project_definition: DefinitionV20 = project_definition
|
|
33
|
+
self._project_root = project_root
|
|
34
|
+
self._default_role = default_role()
|
|
35
|
+
if self._default_role is None:
|
|
36
|
+
self._default_role = get_sql_executor().current_role()
|
|
37
|
+
self.default_warehouse = None
|
|
38
|
+
cli_context = get_cli_context()
|
|
39
|
+
if cli_context.connection.warehouse:
|
|
40
|
+
self.default_warehouse = to_identifier(cli_context.connection.warehouse)
|
|
41
|
+
|
|
42
|
+
def get_entity(self, entity_id: str):
|
|
43
|
+
"""
|
|
44
|
+
Returns an entity instance with the given ID. If exists, reuses the previously returned instance, or instantiates a new one otherwise.
|
|
45
|
+
"""
|
|
46
|
+
if entity_id in self._entities_cache:
|
|
47
|
+
return self._entities_cache[entity_id]
|
|
48
|
+
entity_model = self._project_definition.entities.get(entity_id, None)
|
|
49
|
+
if entity_model is None:
|
|
50
|
+
raise ValueError(f"No such entity ID: {entity_id}")
|
|
51
|
+
entity_model_cls = entity_model.__class__
|
|
52
|
+
entity_cls = v2_entity_model_to_entity_map[entity_model_cls]
|
|
53
|
+
self._entities_cache[entity_id] = entity_cls(entity_model)
|
|
54
|
+
return self._entities_cache[entity_id]
|
|
55
|
+
|
|
56
|
+
def perform_action(self, entity_id: str, action: EntityActions, *args, **kwargs):
|
|
57
|
+
"""
|
|
58
|
+
Instantiates an entity of the given ID and calls the given action on it.
|
|
59
|
+
"""
|
|
60
|
+
entity = self.get_entity(entity_id)
|
|
61
|
+
if entity.supports(action):
|
|
62
|
+
action_ctx = ActionContext(
|
|
63
|
+
console=cc,
|
|
64
|
+
project_root=self.project_root(),
|
|
65
|
+
default_role=self._default_role,
|
|
66
|
+
default_warehouse=self.default_warehouse,
|
|
67
|
+
get_entity=self.get_entity,
|
|
68
|
+
)
|
|
69
|
+
return entity.perform(action, action_ctx, *args, **kwargs)
|
|
70
|
+
else:
|
|
71
|
+
raise ValueError(f'This entity type does not support "{action.value}"')
|
|
72
|
+
|
|
73
|
+
def project_root(self) -> Path:
|
|
74
|
+
return self._project_root
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Copyright (c) 2024 Snowflake Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from snowflake.cli._plugins.workspace import commands
|
|
16
|
+
from snowflake.cli.api.plugins.command import (
|
|
17
|
+
SNOWCLI_ROOT_COMMAND_PATH,
|
|
18
|
+
CommandSpec,
|
|
19
|
+
CommandType,
|
|
20
|
+
plugin_hook_impl,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@plugin_hook_impl
|
|
25
|
+
def command_spec():
|
|
26
|
+
return CommandSpec(
|
|
27
|
+
parent_command_path=SNOWCLI_ROOT_COMMAND_PATH,
|
|
28
|
+
command_type=CommandType.COMMAND_GROUP,
|
|
29
|
+
typer_instance=commands.ws.create_instance(),
|
|
30
|
+
)
|
|
@@ -14,324 +14,129 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
from contextlib import contextmanager
|
|
18
|
+
from contextvars import ContextVar
|
|
19
|
+
from dataclasses import dataclass, field, replace
|
|
18
20
|
from pathlib import Path
|
|
19
|
-
from typing import
|
|
21
|
+
from typing import TYPE_CHECKING, Iterator
|
|
20
22
|
|
|
21
|
-
from snowflake.cli.api.
|
|
23
|
+
from snowflake.cli.api.connections import ConnectionContext, OpenConnectionCache
|
|
24
|
+
from snowflake.cli.api.exceptions import MissingConfiguration
|
|
25
|
+
from snowflake.cli.api.metrics import CLIMetrics
|
|
22
26
|
from snowflake.cli.api.output.formats import OutputFormat
|
|
23
|
-
from snowflake.cli.api.
|
|
27
|
+
from snowflake.cli.api.rendering.jinja import CONTEXT_KEY
|
|
24
28
|
from snowflake.connector import SnowflakeConnection
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class _ConnectionContext:
|
|
30
|
-
def __init__(self):
|
|
31
|
-
self._cached_connection: Optional[SnowflakeConnection] = None
|
|
32
|
-
|
|
33
|
-
self._connection_name: Optional[str] = None
|
|
34
|
-
self._account: Optional[str] = None
|
|
35
|
-
self._database: Optional[str] = None
|
|
36
|
-
self._role: Optional[str] = None
|
|
37
|
-
self._schema: Optional[str] = None
|
|
38
|
-
self._user: Optional[str] = None
|
|
39
|
-
self._password: Optional[str] = None
|
|
40
|
-
self._authenticator: Optional[str] = None
|
|
41
|
-
self._private_key_path: Optional[str] = None
|
|
42
|
-
self._warehouse: Optional[str] = None
|
|
43
|
-
self._mfa_passcode: Optional[str] = None
|
|
44
|
-
self._enable_diag: Optional[bool] = False
|
|
45
|
-
self._diag_log_path: Optional[Path] = None
|
|
46
|
-
self._diag_allowlist_path: Optional[Path] = None
|
|
47
|
-
self._temporary_connection: bool = False
|
|
48
|
-
self._session_token: Optional[str] = None
|
|
49
|
-
self._master_token: Optional[str] = None
|
|
50
|
-
self._token_file_path: Optional[Path] = None
|
|
51
|
-
|
|
52
|
-
def __setattr__(self, key, value):
|
|
53
|
-
"""
|
|
54
|
-
We invalidate connection cache every time connection attributes change.
|
|
55
|
-
"""
|
|
56
|
-
super().__setattr__(key, value)
|
|
57
|
-
if key != "_cached_connection":
|
|
58
|
-
self._cached_connection = None
|
|
59
|
-
|
|
60
|
-
@property
|
|
61
|
-
def connection_name(self) -> Optional[str]:
|
|
62
|
-
return self._connection_name
|
|
63
|
-
|
|
64
|
-
def set_connection_name(self, value: Optional[str]):
|
|
65
|
-
self._connection_name = value
|
|
66
|
-
|
|
67
|
-
@property
|
|
68
|
-
def account(self) -> Optional[str]:
|
|
69
|
-
return self._account
|
|
70
|
-
|
|
71
|
-
def set_account(self, value: Optional[str]):
|
|
72
|
-
self._account = value
|
|
73
|
-
|
|
74
|
-
@property
|
|
75
|
-
def database(self) -> Optional[str]:
|
|
76
|
-
return self._database
|
|
77
|
-
|
|
78
|
-
def set_database(self, value: Optional[str]):
|
|
79
|
-
self._database = value
|
|
80
|
-
|
|
81
|
-
@property
|
|
82
|
-
def role(self) -> Optional[str]:
|
|
83
|
-
return self._role
|
|
84
|
-
|
|
85
|
-
def set_role(self, value: Optional[str]):
|
|
86
|
-
self._role = value
|
|
30
|
+
if TYPE_CHECKING:
|
|
31
|
+
from snowflake.cli.api.project.definition_manager import DefinitionManager
|
|
32
|
+
from snowflake.cli.api.project.schemas.project_definition import ProjectDefinition
|
|
87
33
|
|
|
88
|
-
|
|
89
|
-
def schema(self) -> Optional[str]:
|
|
90
|
-
return self._schema
|
|
91
|
-
|
|
92
|
-
def set_schema(self, value: Optional[str]):
|
|
93
|
-
if (
|
|
94
|
-
value
|
|
95
|
-
and not (value.startswith('"') and value.endswith('"'))
|
|
96
|
-
# if schema is fully qualified name (db.schema)
|
|
97
|
-
and schema_pattern.match(value)
|
|
98
|
-
):
|
|
99
|
-
raise InvalidSchemaError(value)
|
|
100
|
-
self._schema = value
|
|
101
|
-
|
|
102
|
-
@property
|
|
103
|
-
def user(self) -> Optional[str]:
|
|
104
|
-
return self._user
|
|
105
|
-
|
|
106
|
-
def set_user(self, value: Optional[str]):
|
|
107
|
-
self._user = value
|
|
108
|
-
|
|
109
|
-
@property
|
|
110
|
-
def password(self) -> Optional[str]:
|
|
111
|
-
return self._password
|
|
112
|
-
|
|
113
|
-
def set_password(self, value: Optional[str]):
|
|
114
|
-
self._password = value
|
|
115
|
-
|
|
116
|
-
@property
|
|
117
|
-
def authenticator(self) -> Optional[str]:
|
|
118
|
-
return self._authenticator
|
|
119
|
-
|
|
120
|
-
def set_authenticator(self, value: Optional[str]):
|
|
121
|
-
self._authenticator = value
|
|
122
|
-
|
|
123
|
-
@property
|
|
124
|
-
def private_key_path(self) -> Optional[str]:
|
|
125
|
-
return self._private_key_path
|
|
126
|
-
|
|
127
|
-
def set_private_key_path(self, value: Optional[str]):
|
|
128
|
-
self._private_key_path = value
|
|
129
|
-
|
|
130
|
-
@property
|
|
131
|
-
def warehouse(self) -> Optional[str]:
|
|
132
|
-
return self._warehouse
|
|
133
|
-
|
|
134
|
-
def set_warehouse(self, value: Optional[str]):
|
|
135
|
-
self._warehouse = value
|
|
136
|
-
|
|
137
|
-
@property
|
|
138
|
-
def mfa_passcode(self) -> Optional[str]:
|
|
139
|
-
return self._mfa_passcode
|
|
140
|
-
|
|
141
|
-
def set_mfa_passcode(self, value: Optional[str]):
|
|
142
|
-
self._mfa_passcode = value
|
|
143
|
-
|
|
144
|
-
@property
|
|
145
|
-
def enable_diag(self) -> Optional[bool]:
|
|
146
|
-
return self._enable_diag
|
|
147
|
-
|
|
148
|
-
def set_enable_diag(self, value: Optional[bool]):
|
|
149
|
-
self._enable_diag = value
|
|
150
|
-
|
|
151
|
-
@property
|
|
152
|
-
def diag_log_path(self) -> Optional[Path]:
|
|
153
|
-
return self._diag_log_path
|
|
154
|
-
|
|
155
|
-
def set_diag_log_path(self, value: Optional[Path]):
|
|
156
|
-
self._diag_log_path = value
|
|
157
|
-
|
|
158
|
-
@property
|
|
159
|
-
def diag_allowlist_path(self) -> Optional[Path]:
|
|
160
|
-
return self._diag_allowlist_path
|
|
161
|
-
|
|
162
|
-
def set_diag_allowlist_path(self, value: Optional[Path]):
|
|
163
|
-
self._diag_allowlist_path = value
|
|
164
|
-
|
|
165
|
-
@property
|
|
166
|
-
def temporary_connection(self) -> bool:
|
|
167
|
-
return self._temporary_connection
|
|
168
|
-
|
|
169
|
-
def set_temporary_connection(self, value: bool):
|
|
170
|
-
self._temporary_connection = value
|
|
171
|
-
|
|
172
|
-
@property
|
|
173
|
-
def session_token(self) -> Optional[str]:
|
|
174
|
-
return self._session_token
|
|
175
|
-
|
|
176
|
-
def set_session_token(self, value: Optional[str]):
|
|
177
|
-
self._session_token = value
|
|
178
|
-
|
|
179
|
-
@property
|
|
180
|
-
def master_token(self) -> Optional[str]:
|
|
181
|
-
return self._master_token
|
|
182
|
-
|
|
183
|
-
def set_master_token(self, value: Optional[str]):
|
|
184
|
-
self._master_token = value
|
|
185
|
-
|
|
186
|
-
@property
|
|
187
|
-
def token_file_path(self) -> Optional[Path]:
|
|
188
|
-
return self._token_file_path
|
|
189
|
-
|
|
190
|
-
def set_token_file_path(self, value: Optional[Path]):
|
|
191
|
-
self._token_file_path = value
|
|
192
|
-
|
|
193
|
-
@property
|
|
194
|
-
def connection(self) -> SnowflakeConnection:
|
|
195
|
-
if not self._cached_connection:
|
|
196
|
-
self._cached_connection = self._build_connection()
|
|
197
|
-
return self._cached_connection
|
|
198
|
-
|
|
199
|
-
def _collect_not_empty_connection_attributes(self):
|
|
200
|
-
return {
|
|
201
|
-
"account": self.account,
|
|
202
|
-
"user": self.user,
|
|
203
|
-
"password": self.password,
|
|
204
|
-
"authenticator": self.authenticator,
|
|
205
|
-
"private_key_path": self.private_key_path,
|
|
206
|
-
"database": self.database,
|
|
207
|
-
"schema": self.schema,
|
|
208
|
-
"role": self.role,
|
|
209
|
-
"warehouse": self.warehouse,
|
|
210
|
-
"session_token": self.session_token,
|
|
211
|
-
"master_token": self.master_token,
|
|
212
|
-
"token_file_path": self.token_file_path,
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
def _build_connection(self):
|
|
216
|
-
from snowflake.cli.app.snow_connector import connect_to_snowflake
|
|
217
|
-
|
|
218
|
-
return connect_to_snowflake(
|
|
219
|
-
temporary_connection=self.temporary_connection,
|
|
220
|
-
mfa_passcode=self._mfa_passcode,
|
|
221
|
-
enable_diag=self._enable_diag,
|
|
222
|
-
diag_log_path=self._diag_log_path,
|
|
223
|
-
diag_allowlist_path=self._diag_allowlist_path,
|
|
224
|
-
connection_name=self.connection_name,
|
|
225
|
-
**self._collect_not_empty_connection_attributes(),
|
|
226
|
-
)
|
|
34
|
+
_CONNECTION_CACHE = OpenConnectionCache()
|
|
227
35
|
|
|
228
36
|
|
|
37
|
+
@dataclass
|
|
229
38
|
class _CliGlobalContextManager:
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
39
|
+
connection_context: ConnectionContext = field(default_factory=ConnectionContext)
|
|
40
|
+
connection_cache: OpenConnectionCache = (
|
|
41
|
+
_CONNECTION_CACHE # by default, use global cache
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
output_format: OutputFormat = OutputFormat.TABLE
|
|
45
|
+
silent: bool = False
|
|
46
|
+
verbose: bool = False
|
|
47
|
+
experimental: bool = False
|
|
48
|
+
enable_tracebacks: bool = True
|
|
49
|
+
|
|
50
|
+
metrics: CLIMetrics = field(default_factory=CLIMetrics)
|
|
51
|
+
|
|
52
|
+
project_path_arg: str | None = None
|
|
53
|
+
project_is_optional: bool = True
|
|
54
|
+
project_env_overrides_args: dict[str, str] = field(default_factory=dict)
|
|
55
|
+
|
|
56
|
+
# FIXME: this property only exists to help implement
|
|
57
|
+
# nativeapp_definition_v2_to_v1. Consider changing the way
|
|
58
|
+
# this calculation is provided to commands in order to remove
|
|
59
|
+
# this logic (then make project_definition a non-cloned @property)
|
|
60
|
+
override_project_definition: ProjectDefinition | None = None
|
|
61
|
+
|
|
62
|
+
_definition_manager: DefinitionManager | None = None
|
|
63
|
+
|
|
64
|
+
# which properties invalidate our current DefinitionManager?
|
|
65
|
+
DEFINITION_MANAGER_DEPENDENCIES = [
|
|
66
|
+
"project_path_arg",
|
|
67
|
+
"project_is_optional",
|
|
68
|
+
"project_env_overrides_args",
|
|
69
|
+
]
|
|
243
70
|
|
|
244
71
|
def reset(self):
|
|
245
72
|
self.__init__()
|
|
246
73
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
@property
|
|
255
|
-
def output_format(self) -> OutputFormat:
|
|
256
|
-
return self._output_format
|
|
257
|
-
|
|
258
|
-
def set_output_format(self, value: OutputFormat):
|
|
259
|
-
self._output_format = value
|
|
260
|
-
|
|
261
|
-
@property
|
|
262
|
-
def verbose(self) -> bool:
|
|
263
|
-
return self._verbose
|
|
264
|
-
|
|
265
|
-
def set_verbose(self, value: bool):
|
|
266
|
-
self._verbose = value
|
|
267
|
-
|
|
268
|
-
@property
|
|
269
|
-
def experimental(self) -> bool:
|
|
270
|
-
return self._experimental
|
|
271
|
-
|
|
272
|
-
def set_experimental(self, value: bool):
|
|
273
|
-
self._experimental = value
|
|
274
|
-
|
|
275
|
-
@property
|
|
276
|
-
def project_definition(self) -> Optional[ProjectDefinition]:
|
|
277
|
-
return self._project_definition
|
|
278
|
-
|
|
279
|
-
def set_project_definition(self, value: ProjectDefinition):
|
|
280
|
-
self._project_definition = value
|
|
74
|
+
def clone(self) -> _CliGlobalContextManager:
|
|
75
|
+
return replace(
|
|
76
|
+
self,
|
|
77
|
+
connection_context=self.connection_context.clone(),
|
|
78
|
+
project_env_overrides_args=self.project_env_overrides_args.copy(),
|
|
79
|
+
)
|
|
281
80
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
81
|
+
def __setattr__(self, prop, val):
|
|
82
|
+
if prop in self.DEFINITION_MANAGER_DEPENDENCIES:
|
|
83
|
+
self._clear_definition_manager()
|
|
285
84
|
|
|
286
|
-
|
|
287
|
-
self._project_root = project_root
|
|
85
|
+
super().__setattr__(prop, val)
|
|
288
86
|
|
|
289
87
|
@property
|
|
290
|
-
def
|
|
291
|
-
|
|
88
|
+
def project_definition(self) -> ProjectDefinition | None:
|
|
89
|
+
if self.override_project_definition:
|
|
90
|
+
return self.override_project_definition
|
|
292
91
|
|
|
293
|
-
|
|
294
|
-
self._project_path_arg = project_path_arg
|
|
92
|
+
return self._definition_manager_or_raise().project_definition
|
|
295
93
|
|
|
296
94
|
@property
|
|
297
|
-
def
|
|
298
|
-
return self.
|
|
299
|
-
|
|
300
|
-
def set_project_env_overrides_args(
|
|
301
|
-
self, project_env_overrides_args: dict[str, str]
|
|
302
|
-
):
|
|
303
|
-
self._project_env_overrides_args = project_env_overrides_args
|
|
95
|
+
def project_root(self) -> Path:
|
|
96
|
+
return Path(self._definition_manager_or_raise().project_root)
|
|
304
97
|
|
|
305
98
|
@property
|
|
306
99
|
def template_context(self) -> dict:
|
|
307
|
-
return self.
|
|
308
|
-
|
|
309
|
-
def set_template_context(self, template_context: dict):
|
|
310
|
-
self._template_context = template_context
|
|
311
|
-
|
|
312
|
-
@property
|
|
313
|
-
def typer_pre_execute_commands(self) -> list[Callable[[], None]]:
|
|
314
|
-
return self._typer_pre_execute_commands
|
|
315
|
-
|
|
316
|
-
def add_typer_pre_execute_commands(
|
|
317
|
-
self, typer_pre_execute_command: Callable[[], None]
|
|
318
|
-
):
|
|
319
|
-
self._typer_pre_execute_commands.append(typer_pre_execute_command)
|
|
320
|
-
|
|
321
|
-
@property
|
|
322
|
-
def connection_context(self) -> _ConnectionContext:
|
|
323
|
-
return self._connection_context
|
|
100
|
+
return self._definition_manager_or_raise().template_context
|
|
324
101
|
|
|
325
102
|
@property
|
|
326
103
|
def connection(self) -> SnowflakeConnection:
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
104
|
+
"""
|
|
105
|
+
Returns a connection for our configured context from the configured cache.
|
|
106
|
+
By default, this is the global _CONNECTION_CACHE. If a matching connection
|
|
107
|
+
does not already exist, creates a new connection and caches it.
|
|
108
|
+
"""
|
|
109
|
+
self.connection_context.validate_and_complete()
|
|
110
|
+
return self.connection_cache[self.connection_context]
|
|
332
111
|
|
|
333
|
-
def
|
|
334
|
-
|
|
112
|
+
def _definition_manager_or_raise(self) -> DefinitionManager:
|
|
113
|
+
"""
|
|
114
|
+
(Re-)parses project definition based on project args (project_path_arg and
|
|
115
|
+
project_env_overrides_args). If we cannot provide a project definition
|
|
116
|
+
(i.e. no snowflake.yml) and require one, raises MissingConfiguration.
|
|
117
|
+
"""
|
|
118
|
+
from snowflake.cli.api.project.definition_manager import DefinitionManager
|
|
119
|
+
|
|
120
|
+
# don't need to re-parse definition if we already have one
|
|
121
|
+
if not self._definition_manager:
|
|
122
|
+
dm = DefinitionManager(
|
|
123
|
+
self.project_path_arg,
|
|
124
|
+
{CONTEXT_KEY: {"env": self.project_env_overrides_args}},
|
|
125
|
+
)
|
|
126
|
+
if not dm.has_definition_file and not self.project_is_optional:
|
|
127
|
+
raise MissingConfiguration(
|
|
128
|
+
"Cannot find project definition (snowflake.yml). Please provide a path to the project or run this command in a valid project directory."
|
|
129
|
+
)
|
|
130
|
+
self._definition_manager = dm
|
|
131
|
+
|
|
132
|
+
return self._definition_manager
|
|
133
|
+
|
|
134
|
+
def _clear_definition_manager(self):
|
|
135
|
+
"""
|
|
136
|
+
Force re-calculation of definition_manager and its dependent attributes
|
|
137
|
+
(template_context, project_definition, and project_root).
|
|
138
|
+
"""
|
|
139
|
+
self._definition_manager = None
|
|
335
140
|
|
|
336
141
|
|
|
337
142
|
class _CliGlobalContextAccess:
|
|
@@ -343,13 +148,17 @@ class _CliGlobalContextAccess:
|
|
|
343
148
|
return self._manager.connection
|
|
344
149
|
|
|
345
150
|
@property
|
|
346
|
-
def connection_context(self) ->
|
|
151
|
+
def connection_context(self) -> ConnectionContext:
|
|
347
152
|
return self._manager.connection_context
|
|
348
153
|
|
|
349
154
|
@property
|
|
350
155
|
def enable_tracebacks(self) -> bool:
|
|
351
156
|
return self._manager.enable_tracebacks
|
|
352
157
|
|
|
158
|
+
@property
|
|
159
|
+
def metrics(self):
|
|
160
|
+
return self._manager.metrics
|
|
161
|
+
|
|
353
162
|
@property
|
|
354
163
|
def output_format(self) -> OutputFormat:
|
|
355
164
|
return self._manager.output_format
|
|
@@ -367,7 +176,7 @@ class _CliGlobalContextAccess:
|
|
|
367
176
|
return self._manager.project_definition
|
|
368
177
|
|
|
369
178
|
@property
|
|
370
|
-
def project_root(self):
|
|
179
|
+
def project_root(self) -> Path | None:
|
|
371
180
|
return self._manager.project_root
|
|
372
181
|
|
|
373
182
|
@property
|
|
@@ -386,5 +195,53 @@ class _CliGlobalContextAccess:
|
|
|
386
195
|
return self._manager.output_format == OutputFormat.JSON
|
|
387
196
|
|
|
388
197
|
|
|
389
|
-
|
|
390
|
-
cli_context
|
|
198
|
+
_CLI_CONTEXT_MANAGER: ContextVar[_CliGlobalContextManager | None] = ContextVar(
|
|
199
|
+
"cli_context", default=None
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def get_cli_context_manager() -> _CliGlobalContextManager:
|
|
204
|
+
mgr = _CLI_CONTEXT_MANAGER.get()
|
|
205
|
+
if not mgr:
|
|
206
|
+
mgr = _CliGlobalContextManager()
|
|
207
|
+
_CLI_CONTEXT_MANAGER.set(mgr)
|
|
208
|
+
return mgr
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def get_cli_context() -> _CliGlobalContextAccess:
|
|
212
|
+
return _CliGlobalContextAccess(get_cli_context_manager())
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
@contextmanager
|
|
216
|
+
def fork_cli_context(
|
|
217
|
+
connection_overrides: dict | None = None,
|
|
218
|
+
project_env_overrides: dict[str, str] | None = None,
|
|
219
|
+
project_is_optional: bool | None = None,
|
|
220
|
+
project_path: str | None = None,
|
|
221
|
+
) -> Iterator[_CliGlobalContextAccess]:
|
|
222
|
+
"""
|
|
223
|
+
Forks the global CLI context, making changes that are only visible
|
|
224
|
+
(e.g. via get_cli_context()) while inside this context manager.
|
|
225
|
+
|
|
226
|
+
Please note that environment variable changes are only visible through
|
|
227
|
+
the project definition; os.getenv / os.environ / get_env_value are not
|
|
228
|
+
affected by these new values.
|
|
229
|
+
"""
|
|
230
|
+
old_manager = get_cli_context_manager()
|
|
231
|
+
new_manager = old_manager.clone()
|
|
232
|
+
token = _CLI_CONTEXT_MANAGER.set(new_manager)
|
|
233
|
+
|
|
234
|
+
if connection_overrides:
|
|
235
|
+
new_manager.connection_context.update(**connection_overrides)
|
|
236
|
+
|
|
237
|
+
if project_env_overrides:
|
|
238
|
+
new_manager.project_env_overrides_args.update(project_env_overrides)
|
|
239
|
+
|
|
240
|
+
if project_is_optional is not None:
|
|
241
|
+
new_manager.project_is_optional = project_is_optional
|
|
242
|
+
|
|
243
|
+
if project_path:
|
|
244
|
+
new_manager.project_path_arg = project_path
|
|
245
|
+
|
|
246
|
+
yield _CliGlobalContextAccess(new_manager)
|
|
247
|
+
_CLI_CONTEXT_MANAGER.reset(token)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from enum import Enum
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class OnErrorType(Enum):
|
|
6
|
+
"""
|
|
7
|
+
Command option values for what to do when an error occurs.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
BREAK = "break"
|
|
11
|
+
CONTINUE = "continue"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class Variable:
|
|
16
|
+
"""
|
|
17
|
+
Key-value pair dataclass, returned after parsing "key=value" command options.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
key: str
|
|
21
|
+
value: str
|
|
22
|
+
|
|
23
|
+
def __init__(self, key: str, value: str):
|
|
24
|
+
self.key = key
|
|
25
|
+
self.value = value
|