snowflake-cli-labs 3.0.0rc3__py3-none-any.whl → 3.0.0rc5__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/telemetry.py +28 -0
- snowflake/cli/_plugins/connection/commands.py +9 -4
- snowflake/cli/_plugins/helpers/commands.py +34 -1
- snowflake/cli/_plugins/nativeapp/codegen/compiler.py +5 -0
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +4 -0
- snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +3 -0
- snowflake/cli/_plugins/nativeapp/commands.py +9 -86
- snowflake/cli/_plugins/nativeapp/entities/__init__.py +0 -0
- snowflake/cli/_plugins/nativeapp/{application_entity.py → entities/application.py} +266 -39
- snowflake/cli/_plugins/nativeapp/{application_package_entity.py → entities/application_package.py} +357 -72
- snowflake/cli/_plugins/nativeapp/manager.py +62 -183
- snowflake/cli/_plugins/nativeapp/run_processor.py +6 -6
- snowflake/cli/_plugins/nativeapp/teardown_processor.py +2 -4
- snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +2 -4
- snowflake/cli/_plugins/nativeapp/version/commands.py +1 -15
- snowflake/cli/_plugins/nativeapp/version/version_processor.py +16 -82
- snowflake/cli/_plugins/object/manager.py +36 -15
- snowflake/cli/_plugins/streamlit/commands.py +12 -0
- snowflake/cli/_plugins/streamlit/manager.py +4 -0
- snowflake/cli/_plugins/workspace/commands.py +33 -0
- snowflake/cli/api/cli_global_context.py +7 -0
- snowflake/cli/api/commands/decorators.py +14 -0
- snowflake/cli/api/commands/flags.py +18 -0
- snowflake/cli/api/config.py +25 -6
- snowflake/cli/api/connections.py +3 -1
- snowflake/cli/api/entities/common.py +1 -0
- snowflake/cli/api/entities/utils.py +3 -0
- snowflake/cli/api/metrics.py +92 -0
- snowflake/cli/api/project/definition_conversion.py +69 -22
- snowflake/cli/api/project/definition_manager.py +5 -5
- snowflake/cli/api/project/schemas/entities/entities.py +3 -5
- snowflake/cli/api/project/schemas/project_definition.py +1 -3
- snowflake/cli/api/rendering/sql_templates.py +6 -0
- snowflake/cli/api/rest_api.py +11 -5
- snowflake/cli/api/utils/definition_rendering.py +24 -4
- {snowflake_cli_labs-3.0.0rc3.dist-info → snowflake_cli_labs-3.0.0rc5.dist-info}/METADATA +4 -2
- {snowflake_cli_labs-3.0.0rc3.dist-info → snowflake_cli_labs-3.0.0rc5.dist-info}/RECORD +41 -42
- snowflake/cli/_plugins/nativeapp/application_entity_model.py +0 -56
- snowflake/cli/_plugins/nativeapp/application_package_entity_model.py +0 -94
- snowflake/cli/_plugins/nativeapp/init.py +0 -345
- {snowflake_cli_labs-3.0.0rc3.dist-info → snowflake_cli_labs-3.0.0rc5.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-3.0.0rc3.dist-info → snowflake_cli_labs-3.0.0rc5.dist-info}/entry_points.txt +0 -0
- {snowflake_cli_labs-3.0.0rc3.dist-info → snowflake_cli_labs-3.0.0rc5.dist-info}/licenses/LICENSE +0 -0
snowflake/cli/_plugins/nativeapp/{application_package_entity.py → entities/application_package.py}
RENAMED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import json
|
|
2
4
|
from contextlib import contextmanager
|
|
3
5
|
from pathlib import Path
|
|
4
6
|
from textwrap import dedent
|
|
5
|
-
from typing import
|
|
7
|
+
from typing import List, Literal, Optional, Union
|
|
6
8
|
|
|
7
9
|
import typer
|
|
8
10
|
from click import BadOptionUsage, ClickException
|
|
9
|
-
from
|
|
10
|
-
ApplicationPackageEntityModel,
|
|
11
|
-
)
|
|
11
|
+
from pydantic import Field, field_validator
|
|
12
12
|
from snowflake.cli._plugins.nativeapp.artifacts import (
|
|
13
13
|
BundleMap,
|
|
14
14
|
build_bundle,
|
|
@@ -39,13 +39,11 @@ from snowflake.cli._plugins.nativeapp.policy import (
|
|
|
39
39
|
DenyAlwaysPolicy,
|
|
40
40
|
PolicyBase,
|
|
41
41
|
)
|
|
42
|
-
from snowflake.cli._plugins.nativeapp.utils import
|
|
43
|
-
needs_confirmation,
|
|
44
|
-
)
|
|
42
|
+
from snowflake.cli._plugins.nativeapp.utils import needs_confirmation
|
|
45
43
|
from snowflake.cli._plugins.stage.diff import DiffResult
|
|
46
44
|
from snowflake.cli._plugins.stage.manager import StageManager
|
|
47
45
|
from snowflake.cli._plugins.workspace.action_context import ActionContext
|
|
48
|
-
from snowflake.cli.api.
|
|
46
|
+
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
49
47
|
from snowflake.cli.api.console.abc import AbstractConsole
|
|
50
48
|
from snowflake.cli.api.entities.common import EntityBase, get_sql_executor
|
|
51
49
|
from snowflake.cli.api.entities.utils import (
|
|
@@ -56,24 +54,95 @@ from snowflake.cli.api.entities.utils import (
|
|
|
56
54
|
sync_deploy_root_with_stage,
|
|
57
55
|
validation_item_to_str,
|
|
58
56
|
)
|
|
59
|
-
from snowflake.cli.api.errno import
|
|
60
|
-
DOES_NOT_EXIST_OR_NOT_AUTHORIZED,
|
|
61
|
-
)
|
|
57
|
+
from snowflake.cli.api.errno import DOES_NOT_EXIST_OR_NOT_AUTHORIZED
|
|
62
58
|
from snowflake.cli.api.exceptions import SnowflakeSQLExecutionError
|
|
63
|
-
from snowflake.cli.api.
|
|
59
|
+
from snowflake.cli.api.metrics import CLICounterField
|
|
60
|
+
from snowflake.cli.api.project.schemas.entities.common import (
|
|
61
|
+
EntityModelBase,
|
|
62
|
+
Identifier,
|
|
63
|
+
PostDeployHook,
|
|
64
|
+
)
|
|
65
|
+
from snowflake.cli.api.project.schemas.updatable_model import (
|
|
66
|
+
DiscriminatorField,
|
|
67
|
+
IdentifierField,
|
|
68
|
+
)
|
|
69
|
+
from snowflake.cli.api.project.schemas.v1.native_app.package import DistributionOptions
|
|
64
70
|
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import PathMapping
|
|
65
71
|
from snowflake.cli.api.project.util import (
|
|
72
|
+
append_test_resource_suffix,
|
|
66
73
|
extract_schema,
|
|
67
74
|
identifier_to_show_like_pattern,
|
|
68
75
|
to_identifier,
|
|
69
76
|
unquote_identifier,
|
|
70
77
|
)
|
|
71
|
-
from snowflake.cli.api.rendering.jinja import
|
|
72
|
-
get_basic_jinja_env,
|
|
73
|
-
)
|
|
78
|
+
from snowflake.cli.api.rendering.jinja import get_basic_jinja_env
|
|
74
79
|
from snowflake.cli.api.utils.cursor import find_all_rows
|
|
75
|
-
from snowflake.connector import ProgrammingError
|
|
76
|
-
from snowflake.connector.cursor import
|
|
80
|
+
from snowflake.connector import DictCursor, ProgrammingError
|
|
81
|
+
from snowflake.connector.cursor import SnowflakeCursor
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ApplicationPackageEntityModel(EntityModelBase):
|
|
85
|
+
type: Literal["application package"] = DiscriminatorField() # noqa: A003
|
|
86
|
+
artifacts: List[Union[PathMapping, str]] = Field(
|
|
87
|
+
title="List of paths or file source/destination pairs to add to the deploy root",
|
|
88
|
+
)
|
|
89
|
+
bundle_root: Optional[str] = Field(
|
|
90
|
+
title="Folder at the root of your project where artifacts necessary to perform the bundle step are stored.",
|
|
91
|
+
default="output/bundle/",
|
|
92
|
+
)
|
|
93
|
+
deploy_root: Optional[str] = Field(
|
|
94
|
+
title="Folder at the root of your project where the build step copies the artifacts",
|
|
95
|
+
default="output/deploy/",
|
|
96
|
+
)
|
|
97
|
+
generated_root: Optional[str] = Field(
|
|
98
|
+
title="Subdirectory of the deploy root where files generated by the Snowflake CLI will be written.",
|
|
99
|
+
default="__generated/",
|
|
100
|
+
)
|
|
101
|
+
stage: Optional[str] = IdentifierField(
|
|
102
|
+
title="Identifier of the stage that stores the application artifacts.",
|
|
103
|
+
default="app_src.stage",
|
|
104
|
+
)
|
|
105
|
+
scratch_stage: Optional[str] = IdentifierField(
|
|
106
|
+
title="Identifier of the stage that stores temporary scratch data used by the Snowflake CLI.",
|
|
107
|
+
default="app_src.stage_snowflake_cli_scratch",
|
|
108
|
+
)
|
|
109
|
+
distribution: Optional[DistributionOptions] = Field(
|
|
110
|
+
title="Distribution of the application package created by the Snowflake CLI",
|
|
111
|
+
default="internal",
|
|
112
|
+
)
|
|
113
|
+
manifest: str = Field(
|
|
114
|
+
title="Path to manifest.yml",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
@field_validator("identifier")
|
|
118
|
+
@classmethod
|
|
119
|
+
def append_test_resource_suffix_to_identifier(
|
|
120
|
+
cls, input_value: Identifier | str
|
|
121
|
+
) -> Identifier | str:
|
|
122
|
+
identifier = (
|
|
123
|
+
input_value.name if isinstance(input_value, Identifier) else input_value
|
|
124
|
+
)
|
|
125
|
+
with_suffix = append_test_resource_suffix(identifier)
|
|
126
|
+
if isinstance(input_value, Identifier):
|
|
127
|
+
return input_value.model_copy(update=dict(name=with_suffix))
|
|
128
|
+
return with_suffix
|
|
129
|
+
|
|
130
|
+
@field_validator("artifacts")
|
|
131
|
+
@classmethod
|
|
132
|
+
def transform_artifacts(
|
|
133
|
+
cls, orig_artifacts: List[Union[PathMapping, str]]
|
|
134
|
+
) -> List[PathMapping]:
|
|
135
|
+
transformed_artifacts = []
|
|
136
|
+
if orig_artifacts is None:
|
|
137
|
+
return transformed_artifacts
|
|
138
|
+
|
|
139
|
+
for artifact in orig_artifacts:
|
|
140
|
+
if isinstance(artifact, PathMapping):
|
|
141
|
+
transformed_artifacts.append(artifact)
|
|
142
|
+
else:
|
|
143
|
+
transformed_artifacts.append(PathMapping(src=artifact))
|
|
144
|
+
|
|
145
|
+
return transformed_artifacts
|
|
77
146
|
|
|
78
147
|
|
|
79
148
|
class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
@@ -160,32 +229,35 @@ class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
|
160
229
|
):
|
|
161
230
|
model = self._entity_model
|
|
162
231
|
package_name = model.fqn.identifier
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
232
|
+
if force:
|
|
233
|
+
policy = AllowAlwaysPolicy()
|
|
234
|
+
elif interactive:
|
|
235
|
+
policy = AskAlwaysPolicy()
|
|
166
236
|
else:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def deploy_to_scratch_stage_fn():
|
|
170
|
-
self.action_deploy(
|
|
171
|
-
ctx=ctx,
|
|
172
|
-
prune=True,
|
|
173
|
-
recursive=True,
|
|
174
|
-
paths=[],
|
|
175
|
-
validate=False,
|
|
176
|
-
stage_fqn=f"{package_name}.{model.scratch_stage}",
|
|
177
|
-
interactive=interactive,
|
|
178
|
-
force=force,
|
|
179
|
-
)
|
|
237
|
+
policy = DenyAlwaysPolicy()
|
|
180
238
|
|
|
181
239
|
self.validate_setup_script(
|
|
182
240
|
console=ctx.console,
|
|
241
|
+
project_root=ctx.project_root,
|
|
242
|
+
deploy_root=Path(model.deploy_root),
|
|
243
|
+
bundle_root=Path(model.bundle_root),
|
|
244
|
+
generated_root=Path(model.generated_root),
|
|
245
|
+
artifacts=model.artifacts,
|
|
183
246
|
package_name=package_name,
|
|
184
|
-
package_role=
|
|
185
|
-
|
|
247
|
+
package_role=(model.meta and model.meta.role) or ctx.default_role,
|
|
248
|
+
package_distribution=model.distribution,
|
|
249
|
+
prune=True,
|
|
250
|
+
recursive=True,
|
|
251
|
+
paths=[],
|
|
252
|
+
stage_fqn=f"{package_name}.{model.stage}",
|
|
253
|
+
package_warehouse=(
|
|
254
|
+
(model.meta and model.meta.warehouse) or ctx.default_warehouse
|
|
255
|
+
),
|
|
256
|
+
post_deploy_hooks=model.meta and model.meta.post_deploy,
|
|
257
|
+
package_scripts=[], # Package scripts are not supported in PDFv2
|
|
258
|
+
policy=policy,
|
|
186
259
|
use_scratch_stage=True,
|
|
187
260
|
scratch_stage_fqn=f"{package_name}.{model.scratch_stage}",
|
|
188
|
-
deploy_to_scratch_stage_fn=deploy_to_scratch_stage_fn,
|
|
189
261
|
)
|
|
190
262
|
ctx.console.message("Setup script is valid")
|
|
191
263
|
|
|
@@ -239,6 +311,32 @@ class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
|
239
311
|
interactive=interactive,
|
|
240
312
|
)
|
|
241
313
|
|
|
314
|
+
def action_version_drop(
|
|
315
|
+
self,
|
|
316
|
+
ctx: ActionContext,
|
|
317
|
+
version: Optional[str],
|
|
318
|
+
interactive: bool,
|
|
319
|
+
force: bool,
|
|
320
|
+
*args,
|
|
321
|
+
**kwargs,
|
|
322
|
+
):
|
|
323
|
+
model = self._entity_model
|
|
324
|
+
package_name = model.fqn.identifier
|
|
325
|
+
return self.version_drop(
|
|
326
|
+
console=ctx.console,
|
|
327
|
+
project_root=ctx.project_root,
|
|
328
|
+
deploy_root=Path(model.deploy_root),
|
|
329
|
+
bundle_root=Path(model.bundle_root),
|
|
330
|
+
generated_root=Path(model.generated_root),
|
|
331
|
+
artifacts=model.artifacts,
|
|
332
|
+
package_name=package_name,
|
|
333
|
+
package_role=(model.meta and model.meta.role) or ctx.default_role,
|
|
334
|
+
package_distribution=model.distribution,
|
|
335
|
+
version=version,
|
|
336
|
+
force=force,
|
|
337
|
+
interactive=interactive,
|
|
338
|
+
)
|
|
339
|
+
|
|
242
340
|
@staticmethod
|
|
243
341
|
def bundle(
|
|
244
342
|
project_root: Path,
|
|
@@ -304,19 +402,18 @@ class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
|
304
402
|
package_distribution=package_distribution,
|
|
305
403
|
)
|
|
306
404
|
except ApplicationPackageAlreadyExistsError as e:
|
|
307
|
-
|
|
405
|
+
console.warning(e.message)
|
|
308
406
|
if not policy.should_proceed("Proceed with using this package?"):
|
|
309
407
|
raise typer.Abort() from e
|
|
310
408
|
with get_sql_executor().use_role(package_role):
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
)
|
|
409
|
+
cls.apply_package_scripts(
|
|
410
|
+
console=console,
|
|
411
|
+
package_scripts=package_scripts,
|
|
412
|
+
package_warehouse=package_warehouse,
|
|
413
|
+
project_root=project_root,
|
|
414
|
+
package_role=package_role,
|
|
415
|
+
package_name=package_name,
|
|
416
|
+
)
|
|
320
417
|
|
|
321
418
|
# 3. Upload files from deploy root local folder to the above stage
|
|
322
419
|
stage_schema = extract_schema(stage_fqn)
|
|
@@ -334,24 +431,35 @@ class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
|
334
431
|
print_diff=print_diff,
|
|
335
432
|
)
|
|
336
433
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
)
|
|
434
|
+
cls.execute_post_deploy_hooks(
|
|
435
|
+
console=console,
|
|
436
|
+
project_root=project_root,
|
|
437
|
+
post_deploy_hooks=post_deploy_hooks,
|
|
438
|
+
package_name=package_name,
|
|
439
|
+
package_warehouse=package_warehouse,
|
|
440
|
+
)
|
|
345
441
|
|
|
346
442
|
if validate:
|
|
347
443
|
cls.validate_setup_script(
|
|
348
444
|
console=console,
|
|
445
|
+
project_root=project_root,
|
|
446
|
+
deploy_root=deploy_root,
|
|
447
|
+
bundle_root=bundle_root,
|
|
448
|
+
generated_root=generated_root,
|
|
449
|
+
artifacts=artifacts,
|
|
349
450
|
package_name=package_name,
|
|
350
451
|
package_role=package_role,
|
|
452
|
+
package_distribution=package_distribution,
|
|
453
|
+
prune=prune,
|
|
454
|
+
recursive=recursive,
|
|
455
|
+
paths=paths,
|
|
351
456
|
stage_fqn=stage_fqn,
|
|
457
|
+
package_warehouse=package_warehouse,
|
|
458
|
+
post_deploy_hooks=post_deploy_hooks,
|
|
459
|
+
package_scripts=package_scripts,
|
|
460
|
+
policy=policy,
|
|
352
461
|
use_scratch_stage=False,
|
|
353
462
|
scratch_stage_fqn="",
|
|
354
|
-
deploy_to_scratch_stage_fn=lambda *args: None,
|
|
355
463
|
)
|
|
356
464
|
|
|
357
465
|
return diff
|
|
@@ -723,6 +831,113 @@ class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
|
723
831
|
except InvalidGitRepositoryError:
|
|
724
832
|
pass # not a git repository, which is acceptable
|
|
725
833
|
|
|
834
|
+
@classmethod
|
|
835
|
+
def version_drop(
|
|
836
|
+
cls,
|
|
837
|
+
console: AbstractConsole,
|
|
838
|
+
project_root: Path,
|
|
839
|
+
deploy_root: Path,
|
|
840
|
+
bundle_root: Path,
|
|
841
|
+
generated_root: Path,
|
|
842
|
+
artifacts: list[PathMapping],
|
|
843
|
+
package_name: str,
|
|
844
|
+
package_role: str,
|
|
845
|
+
package_distribution: str,
|
|
846
|
+
version: Optional[str],
|
|
847
|
+
force: bool,
|
|
848
|
+
interactive: bool,
|
|
849
|
+
):
|
|
850
|
+
"""
|
|
851
|
+
Drops a version defined in an application package. If --force is provided, then no user prompts will be executed.
|
|
852
|
+
"""
|
|
853
|
+
if force:
|
|
854
|
+
interactive = False
|
|
855
|
+
policy = AllowAlwaysPolicy()
|
|
856
|
+
else:
|
|
857
|
+
policy = AskAlwaysPolicy() if interactive else DenyAlwaysPolicy()
|
|
858
|
+
|
|
859
|
+
# 1. Check for existing an existing application package
|
|
860
|
+
show_obj_row = cls.get_existing_app_pkg_info(package_name, package_role)
|
|
861
|
+
if not show_obj_row:
|
|
862
|
+
raise ApplicationPackageDoesNotExistError(package_name)
|
|
863
|
+
|
|
864
|
+
# 2. Check distribution of the existing application package
|
|
865
|
+
actual_distribution = cls.get_app_pkg_distribution_in_snowflake(
|
|
866
|
+
package_name, package_role
|
|
867
|
+
)
|
|
868
|
+
if not cls.verify_project_distribution(
|
|
869
|
+
console=console,
|
|
870
|
+
package_name=package_name,
|
|
871
|
+
package_role=package_role,
|
|
872
|
+
package_distribution=package_distribution,
|
|
873
|
+
expected_distribution=actual_distribution,
|
|
874
|
+
):
|
|
875
|
+
console.warning(
|
|
876
|
+
f"Continuing to execute version drop on application package "
|
|
877
|
+
f"{package_name} with distribution '{actual_distribution}'."
|
|
878
|
+
)
|
|
879
|
+
|
|
880
|
+
# 3. If the user did not pass in a version string, determine from manifest.yml
|
|
881
|
+
if not version:
|
|
882
|
+
console.message(
|
|
883
|
+
dedent(
|
|
884
|
+
f"""\
|
|
885
|
+
Version was not provided through the Snowflake CLI. Checking version in the manifest.yml instead.
|
|
886
|
+
This step will bundle your app artifacts to determine the location of the manifest.yml file.
|
|
887
|
+
"""
|
|
888
|
+
)
|
|
889
|
+
)
|
|
890
|
+
cls.bundle(
|
|
891
|
+
project_root=project_root,
|
|
892
|
+
deploy_root=deploy_root,
|
|
893
|
+
bundle_root=bundle_root,
|
|
894
|
+
generated_root=generated_root,
|
|
895
|
+
artifacts=artifacts,
|
|
896
|
+
package_name=package_name,
|
|
897
|
+
)
|
|
898
|
+
version, _ = find_version_info_in_manifest_file(deploy_root)
|
|
899
|
+
if not version:
|
|
900
|
+
raise ClickException(
|
|
901
|
+
"Manifest.yml file does not contain a value for the version field."
|
|
902
|
+
)
|
|
903
|
+
|
|
904
|
+
# Make the version a valid identifier, adding quotes if necessary
|
|
905
|
+
version = to_identifier(version)
|
|
906
|
+
|
|
907
|
+
console.step(
|
|
908
|
+
f"About to drop version {version} in application package {package_name}."
|
|
909
|
+
)
|
|
910
|
+
|
|
911
|
+
# If user did not provide --force, ask for confirmation
|
|
912
|
+
user_prompt = (
|
|
913
|
+
f"Are you sure you want to drop version {version} "
|
|
914
|
+
f"in application package {package_name}? "
|
|
915
|
+
f"Once dropped, this operation cannot be undone."
|
|
916
|
+
)
|
|
917
|
+
if not policy.should_proceed(user_prompt):
|
|
918
|
+
if interactive:
|
|
919
|
+
console.message("Not dropping version.")
|
|
920
|
+
raise typer.Exit(0)
|
|
921
|
+
else:
|
|
922
|
+
console.message(
|
|
923
|
+
"Cannot drop version non-interactively without --force."
|
|
924
|
+
)
|
|
925
|
+
raise typer.Exit(1)
|
|
926
|
+
|
|
927
|
+
# Drop the version
|
|
928
|
+
sql_executor = get_sql_executor()
|
|
929
|
+
with sql_executor.use_role(package_role):
|
|
930
|
+
try:
|
|
931
|
+
sql_executor.execute_query(
|
|
932
|
+
f"alter application package {package_name} drop version {version}"
|
|
933
|
+
)
|
|
934
|
+
except ProgrammingError as err:
|
|
935
|
+
raise err # e.g. version is referenced in a release directive(s)
|
|
936
|
+
|
|
937
|
+
console.message(
|
|
938
|
+
f"Version {version} in application package {package_name} dropped successfully."
|
|
939
|
+
)
|
|
940
|
+
|
|
726
941
|
@staticmethod
|
|
727
942
|
def get_existing_app_pkg_info(
|
|
728
943
|
package_name: str,
|
|
@@ -837,10 +1052,17 @@ class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
|
837
1052
|
applies all package scripts in-order to the application package.
|
|
838
1053
|
"""
|
|
839
1054
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1055
|
+
metrics = get_cli_context().metrics
|
|
1056
|
+
metrics.set_counter_default(CLICounterField.PACKAGE_SCRIPTS, 0)
|
|
1057
|
+
|
|
1058
|
+
if not package_scripts:
|
|
1059
|
+
return
|
|
1060
|
+
|
|
1061
|
+
metrics.set_counter(CLICounterField.PACKAGE_SCRIPTS, 1)
|
|
1062
|
+
|
|
1063
|
+
console.warning(
|
|
1064
|
+
"WARNING: native_app.package.scripts is deprecated. Please migrate to using native_app.package.post_deploy."
|
|
1065
|
+
)
|
|
844
1066
|
|
|
845
1067
|
queued_queries = render_script_templates(
|
|
846
1068
|
project_root,
|
|
@@ -929,36 +1151,65 @@ class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
|
929
1151
|
package_name: str,
|
|
930
1152
|
package_warehouse: Optional[str],
|
|
931
1153
|
):
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
1154
|
+
get_cli_context().metrics.set_counter_default(
|
|
1155
|
+
CLICounterField.POST_DEPLOY_SCRIPTS, 0
|
|
1156
|
+
)
|
|
1157
|
+
|
|
1158
|
+
if post_deploy_hooks:
|
|
1159
|
+
with cls.use_package_warehouse(package_warehouse):
|
|
1160
|
+
execute_post_deploy_hooks(
|
|
1161
|
+
console=console,
|
|
1162
|
+
project_root=project_root,
|
|
1163
|
+
post_deploy_hooks=post_deploy_hooks,
|
|
1164
|
+
deployed_object_type="application package",
|
|
1165
|
+
database_name=package_name,
|
|
1166
|
+
)
|
|
940
1167
|
|
|
941
1168
|
@classmethod
|
|
942
1169
|
def validate_setup_script(
|
|
943
1170
|
cls,
|
|
944
1171
|
console: AbstractConsole,
|
|
1172
|
+
project_root: Path,
|
|
1173
|
+
deploy_root: Path,
|
|
1174
|
+
bundle_root: Path,
|
|
1175
|
+
generated_root: Path,
|
|
1176
|
+
artifacts: list[PathMapping],
|
|
945
1177
|
package_name: str,
|
|
946
1178
|
package_role: str,
|
|
1179
|
+
package_distribution: str,
|
|
1180
|
+
package_warehouse: str | None,
|
|
1181
|
+
prune: bool,
|
|
1182
|
+
recursive: bool,
|
|
1183
|
+
paths: List[Path] | None,
|
|
947
1184
|
stage_fqn: str,
|
|
1185
|
+
post_deploy_hooks: list[PostDeployHook] | None,
|
|
1186
|
+
package_scripts: List[str],
|
|
1187
|
+
policy: PolicyBase,
|
|
948
1188
|
use_scratch_stage: bool,
|
|
949
1189
|
scratch_stage_fqn: str,
|
|
950
|
-
deploy_to_scratch_stage_fn: Callable,
|
|
951
1190
|
):
|
|
952
1191
|
"""Validates Native App setup script SQL."""
|
|
953
1192
|
with console.phase(f"Validating Snowflake Native App setup script."):
|
|
954
1193
|
validation_result = cls.get_validation_result(
|
|
955
1194
|
console=console,
|
|
1195
|
+
project_root=project_root,
|
|
1196
|
+
deploy_root=deploy_root,
|
|
1197
|
+
bundle_root=bundle_root,
|
|
1198
|
+
generated_root=generated_root,
|
|
1199
|
+
artifacts=artifacts,
|
|
956
1200
|
package_name=package_name,
|
|
957
1201
|
package_role=package_role,
|
|
1202
|
+
package_distribution=package_distribution,
|
|
1203
|
+
prune=prune,
|
|
1204
|
+
recursive=recursive,
|
|
1205
|
+
paths=paths,
|
|
958
1206
|
stage_fqn=stage_fqn,
|
|
1207
|
+
package_warehouse=package_warehouse,
|
|
1208
|
+
post_deploy_hooks=post_deploy_hooks,
|
|
1209
|
+
package_scripts=package_scripts,
|
|
1210
|
+
policy=policy,
|
|
959
1211
|
use_scratch_stage=use_scratch_stage,
|
|
960
1212
|
scratch_stage_fqn=scratch_stage_fqn,
|
|
961
|
-
deploy_to_scratch_stage_fn=deploy_to_scratch_stage_fn,
|
|
962
1213
|
)
|
|
963
1214
|
|
|
964
1215
|
# First print warnings, regardless of the outcome of validation
|
|
@@ -975,20 +1226,54 @@ class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
|
975
1226
|
if validation_result["status"] == "FAIL":
|
|
976
1227
|
raise SetupScriptFailedValidation()
|
|
977
1228
|
|
|
978
|
-
@
|
|
1229
|
+
@classmethod
|
|
979
1230
|
def get_validation_result(
|
|
1231
|
+
cls,
|
|
980
1232
|
console: AbstractConsole,
|
|
1233
|
+
project_root: Path,
|
|
1234
|
+
deploy_root: Path,
|
|
1235
|
+
bundle_root: Path,
|
|
1236
|
+
generated_root: Path,
|
|
1237
|
+
artifacts: list[PathMapping],
|
|
981
1238
|
package_name: str,
|
|
982
1239
|
package_role: str,
|
|
1240
|
+
package_distribution: str,
|
|
1241
|
+
package_warehouse: str | None,
|
|
1242
|
+
prune: bool,
|
|
1243
|
+
recursive: bool,
|
|
1244
|
+
paths: List[Path] | None,
|
|
983
1245
|
stage_fqn: str,
|
|
1246
|
+
post_deploy_hooks: list[PostDeployHook] | None,
|
|
1247
|
+
package_scripts: List[str],
|
|
1248
|
+
policy: PolicyBase,
|
|
984
1249
|
use_scratch_stage: bool,
|
|
985
1250
|
scratch_stage_fqn: str,
|
|
986
|
-
deploy_to_scratch_stage_fn: Callable,
|
|
987
1251
|
):
|
|
988
1252
|
"""Call system$validate_native_app_setup() to validate deployed Native App setup script."""
|
|
989
1253
|
if use_scratch_stage:
|
|
990
1254
|
stage_fqn = scratch_stage_fqn
|
|
991
|
-
|
|
1255
|
+
cls.deploy(
|
|
1256
|
+
console=console,
|
|
1257
|
+
project_root=project_root,
|
|
1258
|
+
deploy_root=deploy_root,
|
|
1259
|
+
bundle_root=bundle_root,
|
|
1260
|
+
generated_root=generated_root,
|
|
1261
|
+
artifacts=artifacts,
|
|
1262
|
+
bundle_map=None,
|
|
1263
|
+
package_name=package_name,
|
|
1264
|
+
package_role=package_role,
|
|
1265
|
+
package_distribution=package_distribution,
|
|
1266
|
+
prune=prune,
|
|
1267
|
+
recursive=recursive,
|
|
1268
|
+
paths=paths,
|
|
1269
|
+
print_diff=False,
|
|
1270
|
+
validate=False,
|
|
1271
|
+
stage_fqn=stage_fqn,
|
|
1272
|
+
package_warehouse=package_warehouse,
|
|
1273
|
+
post_deploy_hooks=post_deploy_hooks,
|
|
1274
|
+
package_scripts=package_scripts,
|
|
1275
|
+
policy=policy,
|
|
1276
|
+
)
|
|
992
1277
|
prefixed_stage_fqn = StageManager.get_standard_stage_prefix(stage_fqn)
|
|
993
1278
|
sql_executor = get_sql_executor()
|
|
994
1279
|
try:
|