snowflake-cli-labs 3.0.0rc1__py3-none-any.whl → 3.0.0rc3__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/cli_app.py +10 -1
- snowflake/cli/_app/commands_registration/builtin_plugins.py +2 -0
- snowflake/cli/_app/secret.py +9 -0
- snowflake/cli/_app/snow_connector.py +110 -51
- snowflake/cli/_app/telemetry.py +8 -4
- snowflake/cli/_app/version_check.py +74 -0
- snowflake/cli/_plugins/git/commands.py +55 -14
- snowflake/cli/_plugins/git/manager.py +53 -7
- snowflake/cli/_plugins/helpers/commands.py +57 -0
- snowflake/cli/{api/commands/typer_pre_execute.py → _plugins/helpers/plugin_spec.py} +14 -10
- snowflake/cli/_plugins/nativeapp/application_entity.py +651 -0
- snowflake/cli/{api/project/schemas/entities → _plugins/nativeapp}/application_entity_model.py +2 -2
- snowflake/cli/_plugins/nativeapp/application_package_entity.py +1107 -0
- snowflake/cli/{api/project/schemas/entities → _plugins/nativeapp}/application_package_entity_model.py +3 -3
- snowflake/cli/_plugins/nativeapp/artifacts.py +10 -9
- snowflake/cli/_plugins/nativeapp/bundle_context.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/artifact_processor.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/compiler.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/extension_function_utils.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/models.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +3 -6
- snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +50 -32
- snowflake/cli/_plugins/nativeapp/commands.py +84 -16
- snowflake/cli/_plugins/nativeapp/exceptions.py +0 -9
- snowflake/cli/_plugins/nativeapp/manager.py +56 -92
- snowflake/cli/_plugins/nativeapp/policy.py +3 -0
- snowflake/cli/_plugins/nativeapp/project_model.py +2 -2
- snowflake/cli/_plugins/nativeapp/run_processor.py +65 -272
- snowflake/cli/_plugins/nativeapp/same_account_install_method.py +70 -0
- snowflake/cli/_plugins/nativeapp/teardown_processor.py +11 -154
- snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +150 -40
- snowflake/cli/_plugins/nativeapp/version/commands.py +6 -24
- snowflake/cli/_plugins/nativeapp/version/version_processor.py +35 -235
- snowflake/cli/_plugins/snowpark/commands.py +5 -5
- snowflake/cli/_plugins/snowpark/common.py +4 -4
- snowflake/cli/_plugins/snowpark/models.py +2 -1
- snowflake/cli/{api/entities → _plugins/snowpark}/snowpark_entity.py +2 -2
- snowflake/cli/{api/project/schemas/entities/snowpark_entity.py → _plugins/snowpark/snowpark_entity_model.py} +3 -6
- snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +1 -1
- snowflake/cli/_plugins/stage/manager.py +9 -4
- snowflake/cli/_plugins/streamlit/commands.py +4 -4
- snowflake/cli/_plugins/streamlit/manager.py +17 -4
- snowflake/cli/{api/entities → _plugins/streamlit}/streamlit_entity.py +2 -2
- snowflake/cli/{api/project/schemas/entities → _plugins/streamlit}/streamlit_entity_model.py +5 -12
- snowflake/cli/_plugins/workspace/action_context.py +2 -1
- snowflake/cli/_plugins/workspace/commands.py +127 -48
- snowflake/cli/_plugins/workspace/manager.py +1 -0
- snowflake/cli/_plugins/workspace/plugin_spec.py +1 -1
- snowflake/cli/api/cli_global_context.py +136 -313
- snowflake/cli/api/commands/flags.py +76 -91
- snowflake/cli/api/commands/snow_typer.py +7 -5
- snowflake/cli/api/config.py +1 -1
- snowflake/cli/api/connections.py +214 -0
- snowflake/cli/api/console/abc.py +4 -2
- snowflake/cli/api/entities/common.py +4 -0
- snowflake/cli/api/entities/utils.py +41 -31
- snowflake/cli/api/errno.py +1 -0
- snowflake/cli/api/identifiers.py +7 -3
- snowflake/cli/api/project/definition.py +11 -0
- snowflake/cli/api/project/definition_conversion.py +175 -16
- snowflake/cli/api/project/schemas/entities/common.py +15 -14
- snowflake/cli/api/project/schemas/entities/entities.py +13 -10
- snowflake/cli/api/project/schemas/project_definition.py +107 -45
- snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{identifier_model.py → v1/identifier_model.py} +0 -7
- snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{native_app → v1/native_app}/native_app.py +4 -4
- 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/rendering/project_definition_templates.py +4 -0
- snowflake/cli/api/rendering/sql_templates.py +7 -0
- snowflake/cli/api/sql_execution.py +6 -15
- snowflake/cli/api/utils/definition_rendering.py +3 -1
- {snowflake_cli_labs-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/METADATA +9 -9
- {snowflake_cli_labs-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/RECORD +88 -81
- snowflake/cli/api/entities/application_entity.py +0 -12
- snowflake/cli/api/entities/application_package_entity.py +0 -553
- snowflake/cli/api/project/schemas/snowpark/__init__.py +0 -13
- snowflake/cli/api/project/schemas/streamlit/__init__.py +0 -13
- /snowflake/cli/{api/project/schemas/native_app → _plugins/helpers}/__init__.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/application.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/package.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-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/entry_points.txt +0 -0
- {snowflake_cli_labs-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/licenses/LICENSE +0 -0
|
@@ -19,14 +19,14 @@ from typing import List, Literal, Optional, Union
|
|
|
19
19
|
from pydantic import Field, field_validator
|
|
20
20
|
from snowflake.cli.api.project.schemas.entities.common import (
|
|
21
21
|
EntityModelBase,
|
|
22
|
+
Identifier,
|
|
22
23
|
)
|
|
23
|
-
from snowflake.cli.api.project.schemas.identifier_model import Identifier
|
|
24
|
-
from snowflake.cli.api.project.schemas.native_app.package import DistributionOptions
|
|
25
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import PathMapping
|
|
26
24
|
from snowflake.cli.api.project.schemas.updatable_model import (
|
|
27
25
|
DiscriminatorField,
|
|
28
26
|
IdentifierField,
|
|
29
27
|
)
|
|
28
|
+
from snowflake.cli.api.project.schemas.v1.native_app.package import DistributionOptions
|
|
29
|
+
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import PathMapping
|
|
30
30
|
from snowflake.cli.api.project.util import append_test_resource_suffix
|
|
31
31
|
|
|
32
32
|
|
|
@@ -22,7 +22,8 @@ from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Tupl
|
|
|
22
22
|
|
|
23
23
|
from click.exceptions import ClickException
|
|
24
24
|
from snowflake.cli.api.constants import DEFAULT_SIZE_LIMIT_MB
|
|
25
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import PathMapping
|
|
25
|
+
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import PathMapping
|
|
26
|
+
from snowflake.cli.api.project.util import to_identifier
|
|
26
27
|
from snowflake.cli.api.secure_path import SecurePath
|
|
27
28
|
from yaml import safe_load
|
|
28
29
|
|
|
@@ -734,23 +735,23 @@ def find_setup_script_file(deploy_root: Path) -> Path:
|
|
|
734
735
|
|
|
735
736
|
def find_version_info_in_manifest_file(
|
|
736
737
|
deploy_root: Path,
|
|
737
|
-
) -> Tuple[Optional[str], Optional[
|
|
738
|
+
) -> Tuple[Optional[str], Optional[int]]:
|
|
738
739
|
"""
|
|
739
740
|
Find version and patch, if available, in the manifest.yml file.
|
|
740
741
|
"""
|
|
741
|
-
version_field = "version"
|
|
742
742
|
name_field = "name"
|
|
743
743
|
patch_field = "patch"
|
|
744
744
|
|
|
745
745
|
manifest_content = find_and_read_manifest_file(deploy_root=deploy_root)
|
|
746
746
|
|
|
747
747
|
version_name: Optional[str] = None
|
|
748
|
-
|
|
748
|
+
patch_number: Optional[int] = None
|
|
749
749
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
750
|
+
version_info = manifest_content.get("version", None)
|
|
751
|
+
if version_info:
|
|
752
|
+
if name_field in version_info:
|
|
753
|
+
version_name = to_identifier(str(version_info[name_field]))
|
|
753
754
|
if patch_field in version_info:
|
|
754
|
-
|
|
755
|
+
patch_number = int(version_info[patch_field])
|
|
755
756
|
|
|
756
|
-
return version_name,
|
|
757
|
+
return version_name, patch_number
|
|
@@ -20,7 +20,7 @@ from typing import Optional
|
|
|
20
20
|
|
|
21
21
|
from click import ClickException
|
|
22
22
|
from snowflake.cli._plugins.nativeapp.bundle_context import BundleContext
|
|
23
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import (
|
|
23
|
+
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import (
|
|
24
24
|
PathMapping,
|
|
25
25
|
ProcessorMapping,
|
|
26
26
|
)
|
|
@@ -35,7 +35,7 @@ from snowflake.cli._plugins.nativeapp.codegen.templates.templates_processor impo
|
|
|
35
35
|
)
|
|
36
36
|
from snowflake.cli._plugins.nativeapp.feature_flags import FeatureFlag
|
|
37
37
|
from snowflake.cli.api.console import cli_console as cc
|
|
38
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import (
|
|
38
|
+
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import (
|
|
39
39
|
ProcessorMapping,
|
|
40
40
|
)
|
|
41
41
|
|
|
@@ -38,7 +38,7 @@ from snowflake.cli._plugins.nativeapp.codegen.sandbox import (
|
|
|
38
38
|
)
|
|
39
39
|
from snowflake.cli._plugins.stage.diff import to_stage_path
|
|
40
40
|
from snowflake.cli.api.console import cli_console as cc
|
|
41
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import (
|
|
41
|
+
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import (
|
|
42
42
|
PathMapping,
|
|
43
43
|
ProcessorMapping,
|
|
44
44
|
)
|
|
@@ -27,7 +27,7 @@ from snowflake.cli._plugins.nativeapp.codegen.snowpark.models import (
|
|
|
27
27
|
ExtensionFunctionTypeEnum,
|
|
28
28
|
NativeAppExtensionFunction,
|
|
29
29
|
)
|
|
30
|
-
from snowflake.cli.api.project.schemas.snowpark.argument import Argument
|
|
30
|
+
from snowflake.cli.api.project.schemas.v1.snowpark.argument import Argument
|
|
31
31
|
from snowflake.cli.api.project.util import (
|
|
32
32
|
is_valid_identifier,
|
|
33
33
|
is_valid_string_literal,
|
|
@@ -18,8 +18,8 @@ from enum import Enum
|
|
|
18
18
|
from typing import List, Optional
|
|
19
19
|
|
|
20
20
|
from pydantic import Field
|
|
21
|
-
from snowflake.cli.api.project.schemas.snowpark.callable import _CallableBase
|
|
22
21
|
from snowflake.cli.api.project.schemas.updatable_model import IdentifierField
|
|
22
|
+
from snowflake.cli.api.project.schemas.v1.snowpark.callable import _CallableBase
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class ExtensionFunctionTypeEnum(str, Enum):
|
|
@@ -49,7 +49,7 @@ from snowflake.cli._plugins.nativeapp.codegen.snowpark.models import (
|
|
|
49
49
|
)
|
|
50
50
|
from snowflake.cli._plugins.stage.diff import to_stage_path
|
|
51
51
|
from snowflake.cli.api.console import cli_console as cc
|
|
52
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import (
|
|
52
|
+
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import (
|
|
53
53
|
PathMapping,
|
|
54
54
|
ProcessorMapping,
|
|
55
55
|
)
|
|
@@ -323,11 +323,8 @@ class SnowparkAnnotationProcessor(ArtifactProcessor):
|
|
|
323
323
|
predicate=is_python_file_artifact,
|
|
324
324
|
)
|
|
325
325
|
):
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
dest_file.relative_to(bundle_map.deploy_root())
|
|
329
|
-
)
|
|
330
|
-
)
|
|
326
|
+
src_file_name = src_file.relative_to(self._bundle_ctx.project_root)
|
|
327
|
+
cc.step(f"Processing Snowpark annotations from {src_file_name}")
|
|
331
328
|
collected_extension_function_json = _execute_in_sandbox(
|
|
332
329
|
py_file=str(dest_file.resolve()),
|
|
333
330
|
deploy_root=self._bundle_ctx.deploy_root,
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
+
from pathlib import Path
|
|
17
18
|
from typing import Optional
|
|
18
19
|
|
|
19
20
|
import jinja2
|
|
@@ -24,33 +25,78 @@ from snowflake.cli._plugins.nativeapp.codegen.artifact_processor import (
|
|
|
24
25
|
from snowflake.cli._plugins.nativeapp.exceptions import InvalidTemplateInFileError
|
|
25
26
|
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
26
27
|
from snowflake.cli.api.console import cli_console as cc
|
|
27
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import (
|
|
28
|
+
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import (
|
|
28
29
|
PathMapping,
|
|
29
30
|
ProcessorMapping,
|
|
30
31
|
)
|
|
31
32
|
from snowflake.cli.api.rendering.project_definition_templates import (
|
|
32
33
|
get_client_side_jinja_env,
|
|
34
|
+
has_client_side_templates,
|
|
33
35
|
)
|
|
34
36
|
from snowflake.cli.api.rendering.sql_templates import (
|
|
35
37
|
choose_sql_jinja_env_based_on_template_syntax,
|
|
38
|
+
has_sql_templates,
|
|
36
39
|
)
|
|
37
40
|
|
|
38
41
|
|
|
42
|
+
def _is_sql_file(file: Path) -> bool:
|
|
43
|
+
return file.name.lower().endswith(".sql")
|
|
44
|
+
|
|
45
|
+
|
|
39
46
|
class TemplatesProcessor(ArtifactProcessor):
|
|
40
47
|
"""
|
|
41
48
|
Processor class to perform template expansion on all relevant artifacts (specified in the project definition file).
|
|
42
49
|
"""
|
|
43
50
|
|
|
51
|
+
def expand_templates_in_file(self, src: Path, dest: Path) -> None:
|
|
52
|
+
"""
|
|
53
|
+
Expand templates in the file.
|
|
54
|
+
"""
|
|
55
|
+
if src.is_dir():
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
with self.edit_file(dest) as file:
|
|
59
|
+
if not has_client_side_templates(file.contents) and not (
|
|
60
|
+
_is_sql_file(dest) and has_sql_templates(file.contents)
|
|
61
|
+
):
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
src_file_name = src.relative_to(self._bundle_ctx.project_root)
|
|
65
|
+
cc.step(f"Expanding templates in {src_file_name}")
|
|
66
|
+
with cc.indented():
|
|
67
|
+
try:
|
|
68
|
+
jinja_env = (
|
|
69
|
+
choose_sql_jinja_env_based_on_template_syntax(
|
|
70
|
+
file.contents, reference_name=src_file_name
|
|
71
|
+
)
|
|
72
|
+
if _is_sql_file(dest)
|
|
73
|
+
else get_client_side_jinja_env()
|
|
74
|
+
)
|
|
75
|
+
expanded_template = jinja_env.from_string(file.contents).render(
|
|
76
|
+
get_cli_context().template_context
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# For now, we are printing the source file path in the error message
|
|
80
|
+
# instead of the destination file path to make it easier for the user
|
|
81
|
+
# to identify the file that has the error, and edit the correct file.
|
|
82
|
+
except jinja2.TemplateSyntaxError as e:
|
|
83
|
+
raise InvalidTemplateInFileError(src_file_name, e, e.lineno) from e
|
|
84
|
+
|
|
85
|
+
except jinja2.UndefinedError as e:
|
|
86
|
+
raise InvalidTemplateInFileError(src_file_name, e) from e
|
|
87
|
+
|
|
88
|
+
if expanded_template != file.contents:
|
|
89
|
+
file.edited_contents = expanded_template
|
|
90
|
+
|
|
44
91
|
def process(
|
|
45
92
|
self,
|
|
46
93
|
artifact_to_process: PathMapping,
|
|
47
94
|
processor_mapping: Optional[ProcessorMapping],
|
|
48
95
|
**kwargs,
|
|
49
|
-
):
|
|
96
|
+
) -> None:
|
|
50
97
|
"""
|
|
51
98
|
Process the artifact by executing the template expansion logic on it.
|
|
52
99
|
"""
|
|
53
|
-
cc.step(f"Processing artifact {artifact_to_process} with templates processor")
|
|
54
100
|
|
|
55
101
|
bundle_map = BundleMap(
|
|
56
102
|
project_root=self._bundle_ctx.project_root,
|
|
@@ -62,32 +108,4 @@ class TemplatesProcessor(ArtifactProcessor):
|
|
|
62
108
|
absolute=True,
|
|
63
109
|
expand_directories=True,
|
|
64
110
|
):
|
|
65
|
-
|
|
66
|
-
continue
|
|
67
|
-
with self.edit_file(dest) as f:
|
|
68
|
-
file_name = src.relative_to(self._bundle_ctx.project_root)
|
|
69
|
-
|
|
70
|
-
jinja_env = (
|
|
71
|
-
choose_sql_jinja_env_based_on_template_syntax(
|
|
72
|
-
f.contents, reference_name=file_name
|
|
73
|
-
)
|
|
74
|
-
if dest.name.lower().endswith(".sql")
|
|
75
|
-
else get_client_side_jinja_env()
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
try:
|
|
79
|
-
expanded_template = jinja_env.from_string(f.contents).render(
|
|
80
|
-
get_cli_context().template_context
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
# For now, we are printing the source file path in the error message
|
|
84
|
-
# instead of the destination file path to make it easier for the user
|
|
85
|
-
# to identify the file that has the error, and edit the correct file.
|
|
86
|
-
except jinja2.TemplateSyntaxError as e:
|
|
87
|
-
raise InvalidTemplateInFileError(file_name, e, e.lineno) from e
|
|
88
|
-
|
|
89
|
-
except jinja2.UndefinedError as e:
|
|
90
|
-
raise InvalidTemplateInFileError(file_name, e) from e
|
|
91
|
-
|
|
92
|
-
if expanded_template != f.contents:
|
|
93
|
-
f.edited_contents = expanded_template
|
|
111
|
+
self.expand_templates_in_file(src, dest)
|
|
@@ -22,6 +22,12 @@ from textwrap import dedent
|
|
|
22
22
|
from typing import Generator, Iterable, List, Optional, cast
|
|
23
23
|
|
|
24
24
|
import typer
|
|
25
|
+
from snowflake.cli._plugins.nativeapp.application_entity_model import (
|
|
26
|
+
ApplicationEntityModel,
|
|
27
|
+
)
|
|
28
|
+
from snowflake.cli._plugins.nativeapp.application_package_entity_model import (
|
|
29
|
+
ApplicationPackageEntityModel,
|
|
30
|
+
)
|
|
25
31
|
from snowflake.cli._plugins.nativeapp.common_flags import (
|
|
26
32
|
ForceOption,
|
|
27
33
|
InteractiveOption,
|
|
@@ -46,6 +52,7 @@ from snowflake.cli._plugins.nativeapp.utils import (
|
|
|
46
52
|
shallow_git_clone,
|
|
47
53
|
)
|
|
48
54
|
from snowflake.cli._plugins.nativeapp.v2_conversions.v2_to_v1_decorator import (
|
|
55
|
+
find_entity,
|
|
49
56
|
nativeapp_definition_v2_to_v1,
|
|
50
57
|
)
|
|
51
58
|
from snowflake.cli._plugins.nativeapp.version.commands import app as versions_app
|
|
@@ -54,11 +61,13 @@ from snowflake.cli._plugins.stage.diff import (
|
|
|
54
61
|
compute_stage_diff,
|
|
55
62
|
)
|
|
56
63
|
from snowflake.cli._plugins.stage.utils import print_diff_to_console
|
|
64
|
+
from snowflake.cli._plugins.workspace.manager import WorkspaceManager
|
|
57
65
|
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
58
66
|
from snowflake.cli.api.commands.decorators import (
|
|
59
67
|
with_project_definition,
|
|
60
68
|
)
|
|
61
69
|
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
70
|
+
from snowflake.cli.api.entities.common import EntityActions
|
|
62
71
|
from snowflake.cli.api.exceptions import IncompatibleParametersError
|
|
63
72
|
from snowflake.cli.api.output.formats import OutputFormat
|
|
64
73
|
from snowflake.cli.api.output.types import (
|
|
@@ -69,6 +78,7 @@ from snowflake.cli.api.output.types import (
|
|
|
69
78
|
StreamResult,
|
|
70
79
|
)
|
|
71
80
|
from snowflake.cli.api.project.project_verification import assert_project_type
|
|
81
|
+
from snowflake.cli.api.project.schemas.project_definition import ProjectDefinitionV1
|
|
72
82
|
from snowflake.cli.api.secure_path import SecurePath
|
|
73
83
|
from typing_extensions import Annotated
|
|
74
84
|
|
|
@@ -160,7 +170,7 @@ def app_list_templates(**options) -> CommandResult:
|
|
|
160
170
|
|
|
161
171
|
@app.command("bundle")
|
|
162
172
|
@with_project_definition()
|
|
163
|
-
@nativeapp_definition_v2_to_v1
|
|
173
|
+
@nativeapp_definition_v2_to_v1()
|
|
164
174
|
def app_bundle(
|
|
165
175
|
**options,
|
|
166
176
|
) -> CommandResult:
|
|
@@ -181,7 +191,7 @@ def app_bundle(
|
|
|
181
191
|
|
|
182
192
|
@app.command("diff", requires_connection=True, hidden=True)
|
|
183
193
|
@with_project_definition()
|
|
184
|
-
@nativeapp_definition_v2_to_v1
|
|
194
|
+
@nativeapp_definition_v2_to_v1()
|
|
185
195
|
def app_diff(
|
|
186
196
|
**options,
|
|
187
197
|
) -> CommandResult:
|
|
@@ -208,7 +218,7 @@ def app_diff(
|
|
|
208
218
|
|
|
209
219
|
@app.command("run", requires_connection=True)
|
|
210
220
|
@with_project_definition()
|
|
211
|
-
@nativeapp_definition_v2_to_v1
|
|
221
|
+
@nativeapp_definition_v2_to_v1(app_required=True)
|
|
212
222
|
def app_run(
|
|
213
223
|
version: Optional[str] = typer.Option(
|
|
214
224
|
None,
|
|
@@ -272,7 +282,7 @@ def app_run(
|
|
|
272
282
|
|
|
273
283
|
@app.command("open", requires_connection=True)
|
|
274
284
|
@with_project_definition()
|
|
275
|
-
@nativeapp_definition_v2_to_v1
|
|
285
|
+
@nativeapp_definition_v2_to_v1(app_required=True)
|
|
276
286
|
def app_open(
|
|
277
287
|
**options,
|
|
278
288
|
) -> CommandResult:
|
|
@@ -299,7 +309,9 @@ def app_open(
|
|
|
299
309
|
|
|
300
310
|
@app.command("teardown", requires_connection=True)
|
|
301
311
|
@with_project_definition()
|
|
302
|
-
@nativeapp_definition_v2_to_v1
|
|
312
|
+
# This command doesn't use @nativeapp_definition_v2_to_v1 because it needs to
|
|
313
|
+
# be aware of PDFv2 definitions that have multiple apps created from the same package,
|
|
314
|
+
# which all need to be torn down.
|
|
303
315
|
def app_teardown(
|
|
304
316
|
force: Optional[bool] = ForceOption,
|
|
305
317
|
cascade: Optional[bool] = typer.Option(
|
|
@@ -308,26 +320,70 @@ def app_teardown(
|
|
|
308
320
|
show_default=False,
|
|
309
321
|
),
|
|
310
322
|
interactive: bool = InteractiveOption,
|
|
323
|
+
# Same as the param auto-added by @nativeapp_definition_v2_to_v1
|
|
324
|
+
package_entity_id: Optional[str] = typer.Option(
|
|
325
|
+
default="",
|
|
326
|
+
help="The ID of the package entity on which to operate when definition_version is 2 or higher.",
|
|
327
|
+
),
|
|
311
328
|
**options,
|
|
312
329
|
) -> CommandResult:
|
|
313
330
|
"""
|
|
314
331
|
Attempts to drop both the application object and application package as defined in the project definition file.
|
|
315
332
|
"""
|
|
333
|
+
cli_context = get_cli_context()
|
|
334
|
+
project = cli_context.project_definition
|
|
335
|
+
if isinstance(project, ProjectDefinitionV1):
|
|
336
|
+
# Old behaviour, not multi-app aware so we can use the old processor
|
|
337
|
+
processor = NativeAppTeardownProcessor(
|
|
338
|
+
project_definition=cli_context.project_definition.native_app,
|
|
339
|
+
project_root=cli_context.project_root,
|
|
340
|
+
)
|
|
341
|
+
processor.process(interactive, force, cascade)
|
|
342
|
+
else:
|
|
343
|
+
# New behaviour, multi-app aware so teardown all the apps created from the package
|
|
344
|
+
|
|
345
|
+
# Determine the package entity to drop, there must be one
|
|
346
|
+
app_package_entity = find_entity(
|
|
347
|
+
project,
|
|
348
|
+
ApplicationPackageEntityModel,
|
|
349
|
+
package_entity_id,
|
|
350
|
+
disambiguation_option="--package-entity-id",
|
|
351
|
+
required=True,
|
|
352
|
+
)
|
|
353
|
+
assert app_package_entity is not None # satisfy mypy
|
|
316
354
|
|
|
317
|
-
|
|
355
|
+
# Same implementation as `snow ws drop`
|
|
356
|
+
ws = WorkspaceManager(
|
|
357
|
+
project_definition=cli_context.project_definition,
|
|
358
|
+
project_root=cli_context.project_root,
|
|
359
|
+
)
|
|
360
|
+
for app_entity in project.get_entities_by_type(
|
|
361
|
+
ApplicationEntityModel.get_type()
|
|
362
|
+
).values():
|
|
363
|
+
# Drop each app
|
|
364
|
+
if app_entity.from_.target == app_package_entity.entity_id:
|
|
365
|
+
ws.perform_action(
|
|
366
|
+
app_entity.entity_id,
|
|
367
|
+
EntityActions.DROP,
|
|
368
|
+
force_drop=force,
|
|
369
|
+
interactive=interactive,
|
|
370
|
+
cascade=cascade,
|
|
371
|
+
)
|
|
372
|
+
# Then drop the package
|
|
373
|
+
ws.perform_action(
|
|
374
|
+
app_package_entity.entity_id,
|
|
375
|
+
EntityActions.DROP,
|
|
376
|
+
force_drop=force,
|
|
377
|
+
interactive=interactive,
|
|
378
|
+
cascade=cascade,
|
|
379
|
+
)
|
|
318
380
|
|
|
319
|
-
cli_context = get_cli_context()
|
|
320
|
-
processor = NativeAppTeardownProcessor(
|
|
321
|
-
project_definition=cli_context.project_definition.native_app,
|
|
322
|
-
project_root=cli_context.project_root,
|
|
323
|
-
)
|
|
324
|
-
processor.process(interactive, force, cascade)
|
|
325
381
|
return MessageResult(f"Teardown is now complete.")
|
|
326
382
|
|
|
327
383
|
|
|
328
384
|
@app.command("deploy", requires_connection=True)
|
|
329
385
|
@with_project_definition()
|
|
330
|
-
@nativeapp_definition_v2_to_v1
|
|
386
|
+
@nativeapp_definition_v2_to_v1()
|
|
331
387
|
def app_deploy(
|
|
332
388
|
prune: Optional[bool] = typer.Option(
|
|
333
389
|
default=None,
|
|
@@ -350,6 +406,8 @@ def app_deploy(
|
|
|
350
406
|
unspecified, the command syncs all local changes to the stage."""
|
|
351
407
|
).strip(),
|
|
352
408
|
),
|
|
409
|
+
interactive: bool = InteractiveOption,
|
|
410
|
+
force: Optional[bool] = ForceOption,
|
|
353
411
|
validate: bool = ValidateOption,
|
|
354
412
|
**options,
|
|
355
413
|
) -> CommandResult:
|
|
@@ -360,6 +418,13 @@ def app_deploy(
|
|
|
360
418
|
|
|
361
419
|
assert_project_type("native_app")
|
|
362
420
|
|
|
421
|
+
if force:
|
|
422
|
+
policy = AllowAlwaysPolicy()
|
|
423
|
+
elif interactive:
|
|
424
|
+
policy = AskAlwaysPolicy()
|
|
425
|
+
else:
|
|
426
|
+
policy = DenyAlwaysPolicy()
|
|
427
|
+
|
|
363
428
|
has_paths = paths is not None and len(paths) > 0
|
|
364
429
|
if prune is None and recursive is None and not has_paths:
|
|
365
430
|
prune = True
|
|
@@ -386,6 +451,7 @@ def app_deploy(
|
|
|
386
451
|
recursive=recursive,
|
|
387
452
|
local_paths_to_sync=paths,
|
|
388
453
|
validate=validate,
|
|
454
|
+
policy=policy,
|
|
389
455
|
)
|
|
390
456
|
|
|
391
457
|
return MessageResult(
|
|
@@ -395,8 +461,10 @@ def app_deploy(
|
|
|
395
461
|
|
|
396
462
|
@app.command("validate", requires_connection=True)
|
|
397
463
|
@with_project_definition()
|
|
398
|
-
@nativeapp_definition_v2_to_v1
|
|
399
|
-
def app_validate(
|
|
464
|
+
@nativeapp_definition_v2_to_v1()
|
|
465
|
+
def app_validate(
|
|
466
|
+
**options,
|
|
467
|
+
):
|
|
400
468
|
"""
|
|
401
469
|
Validates a deployed Snowflake Native App's setup script.
|
|
402
470
|
"""
|
|
@@ -428,7 +496,7 @@ DEFAULT_EVENT_FOLLOW_LAST = 20
|
|
|
428
496
|
|
|
429
497
|
@app.command("events", requires_connection=True)
|
|
430
498
|
@with_project_definition()
|
|
431
|
-
@nativeapp_definition_v2_to_v1
|
|
499
|
+
@nativeapp_definition_v2_to_v1(app_required=True)
|
|
432
500
|
def app_events(
|
|
433
501
|
since: str = typer.Option(
|
|
434
502
|
default="",
|
|
@@ -48,15 +48,6 @@ class ApplicationCreatedExternallyError(ClickException):
|
|
|
48
48
|
)
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
class UnexpectedOwnerError(ClickException):
|
|
52
|
-
"""An operation is blocked because an object is owned by an unexpected role."""
|
|
53
|
-
|
|
54
|
-
def __init__(self, item: str, expected_owner: str, actual_owner: str):
|
|
55
|
-
super().__init__(
|
|
56
|
-
f"Cannot operate on {item}: owned by {actual_owner} (expected {expected_owner})"
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
|
|
60
51
|
class MissingScriptError(ClickException):
|
|
61
52
|
"""A referenced script was not found."""
|
|
62
53
|
|