snowflake-cli 3.6.0__py3-none-any.whl → 3.7.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/commands_registration/builtin_plugins.py +2 -0
- snowflake/cli/_app/loggers.py +2 -2
- snowflake/cli/_app/snow_connector.py +2 -2
- snowflake/cli/_plugins/connection/commands.py +2 -1
- snowflake/cli/_plugins/helpers/commands.py +25 -1
- snowflake/cli/_plugins/helpers/snowsl_vars_reader.py +133 -0
- snowflake/cli/_plugins/init/commands.py +9 -6
- snowflake/cli/_plugins/logs/__init__.py +0 -0
- snowflake/cli/_plugins/logs/commands.py +105 -0
- snowflake/cli/_plugins/logs/manager.py +107 -0
- snowflake/cli/_plugins/logs/plugin_spec.py +16 -0
- snowflake/cli/_plugins/logs/utils.py +60 -0
- snowflake/cli/_plugins/notebook/commands.py +3 -0
- snowflake/cli/_plugins/notebook/notebook_entity.py +16 -27
- snowflake/cli/_plugins/project/commands.py +73 -48
- snowflake/cli/_plugins/project/manager.py +57 -23
- snowflake/cli/_plugins/project/project_entity_model.py +22 -3
- snowflake/cli/_plugins/snowpark/commands.py +15 -2
- snowflake/cli/_plugins/sql/manager.py +4 -4
- snowflake/cli/_plugins/stage/manager.py +17 -10
- snowflake/cli/_plugins/streamlit/commands.py +3 -0
- snowflake/cli/_plugins/streamlit/manager.py +19 -15
- snowflake/cli/api/artifacts/upload.py +30 -34
- snowflake/cli/api/artifacts/utils.py +8 -6
- snowflake/cli/api/cli_global_context.py +7 -2
- snowflake/cli/api/commands/decorators.py +11 -2
- snowflake/cli/api/commands/flags.py +23 -2
- snowflake/cli/api/commands/snow_typer.py +20 -2
- snowflake/cli/api/config.py +5 -3
- snowflake/cli/api/entities/utils.py +29 -16
- snowflake/cli/api/exceptions.py +69 -28
- snowflake/cli/api/identifiers.py +2 -0
- snowflake/cli/api/plugins/plugin_config.py +2 -2
- snowflake/cli/api/project/schemas/template.py +3 -3
- snowflake/cli/api/rendering/project_templates.py +3 -3
- snowflake/cli/api/rendering/sql_templates.py +2 -2
- snowflake/cli/api/sql_execution.py +1 -1
- snowflake/cli/api/utils/definition_rendering.py +14 -8
- snowflake/cli/api/utils/templating_functions.py +4 -4
- {snowflake_cli-3.6.0.dist-info → snowflake_cli-3.7.0.dist-info}/METADATA +8 -8
- {snowflake_cli-3.6.0.dist-info → snowflake_cli-3.7.0.dist-info}/RECORD +45 -39
- {snowflake_cli-3.6.0.dist-info → snowflake_cli-3.7.0.dist-info}/WHEEL +0 -0
- {snowflake_cli-3.6.0.dist-info → snowflake_cli-3.7.0.dist-info}/entry_points.txt +0 -0
- {snowflake_cli-3.6.0.dist-info → snowflake_cli-3.7.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -31,7 +31,7 @@ from snowflake.cli._plugins.streamlit.streamlit_entity_model import (
|
|
|
31
31
|
from snowflake.cli._plugins.streamlit.streamlit_project_paths import (
|
|
32
32
|
StreamlitProjectPaths,
|
|
33
33
|
)
|
|
34
|
-
from snowflake.cli.api.artifacts.upload import
|
|
34
|
+
from snowflake.cli.api.artifacts.upload import sync_artifacts_with_stage
|
|
35
35
|
from snowflake.cli.api.commands.experimental_behaviour import (
|
|
36
36
|
experimental_behaviour_enabled,
|
|
37
37
|
)
|
|
@@ -56,18 +56,20 @@ class StreamlitManager(SqlExecutionMixin):
|
|
|
56
56
|
f"grant usage on streamlit {streamlit_name.sql_identifier} to role {to_role}"
|
|
57
57
|
)
|
|
58
58
|
|
|
59
|
-
def
|
|
59
|
+
def _upload_artifacts(
|
|
60
60
|
self,
|
|
61
61
|
streamlit_project_paths: StreamlitProjectPaths,
|
|
62
62
|
stage_root: str,
|
|
63
|
+
prune: bool,
|
|
63
64
|
artifacts: Optional[List[PathMapping]] = None,
|
|
64
65
|
):
|
|
65
|
-
cli_console.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
with cli_console.phase(f"Deploying files to {stage_root}"):
|
|
67
|
+
sync_artifacts_with_stage(
|
|
68
|
+
project_paths=streamlit_project_paths,
|
|
69
|
+
stage_root=stage_root,
|
|
70
|
+
prune=prune,
|
|
71
|
+
artifacts=artifacts,
|
|
72
|
+
)
|
|
71
73
|
|
|
72
74
|
def _create_streamlit(
|
|
73
75
|
self,
|
|
@@ -126,6 +128,7 @@ class StreamlitManager(SqlExecutionMixin):
|
|
|
126
128
|
streamlit: StreamlitEntityModel,
|
|
127
129
|
streamlit_project_paths: StreamlitProjectPaths,
|
|
128
130
|
replace: bool = False,
|
|
131
|
+
prune: bool = False,
|
|
129
132
|
):
|
|
130
133
|
streamlit_id = streamlit.fqn.using_connection(self._conn)
|
|
131
134
|
if (
|
|
@@ -182,10 +185,11 @@ class StreamlitManager(SqlExecutionMixin):
|
|
|
182
185
|
else:
|
|
183
186
|
stage_root = f"{embedded_stage_name}/default_checkout"
|
|
184
187
|
|
|
185
|
-
self.
|
|
188
|
+
self._upload_artifacts(
|
|
186
189
|
streamlit_project_paths,
|
|
187
190
|
stage_root,
|
|
188
|
-
|
|
191
|
+
prune=prune,
|
|
192
|
+
artifacts=streamlit.artifacts,
|
|
189
193
|
)
|
|
190
194
|
else:
|
|
191
195
|
"""
|
|
@@ -198,15 +202,15 @@ class StreamlitManager(SqlExecutionMixin):
|
|
|
198
202
|
stage_name = streamlit.stage or "streamlit"
|
|
199
203
|
stage_name = FQN.from_string(stage_name).using_connection(self._conn)
|
|
200
204
|
|
|
201
|
-
cli_console.step(f"Creating {stage_name} stage")
|
|
202
|
-
stage_manager.create(fqn=stage_name)
|
|
203
|
-
|
|
204
205
|
stage_root = stage_manager.get_standard_stage_prefix(
|
|
205
206
|
f"{stage_name}/{streamlit_name_for_root_location}"
|
|
206
207
|
)
|
|
207
208
|
|
|
208
|
-
self.
|
|
209
|
-
streamlit_project_paths,
|
|
209
|
+
self._upload_artifacts(
|
|
210
|
+
streamlit_project_paths,
|
|
211
|
+
stage_root,
|
|
212
|
+
prune=prune,
|
|
213
|
+
artifacts=streamlit.artifacts,
|
|
210
214
|
)
|
|
211
215
|
|
|
212
216
|
self._create_streamlit(
|
|
@@ -1,51 +1,47 @@
|
|
|
1
|
-
from pathlib import PurePosixPath
|
|
2
1
|
from typing import List, Optional
|
|
3
2
|
|
|
4
3
|
from snowflake.cli._plugins.stage.manager import StageManager
|
|
5
|
-
from snowflake.cli.api.artifacts.
|
|
6
|
-
from snowflake.cli.api.artifacts.utils import symlink_or_copy
|
|
4
|
+
from snowflake.cli.api.artifacts.utils import bundle_artifacts
|
|
7
5
|
from snowflake.cli.api.console import cli_console
|
|
6
|
+
from snowflake.cli.api.entities.utils import sync_deploy_root_with_stage
|
|
8
7
|
from snowflake.cli.api.project.project_paths import ProjectPaths
|
|
9
8
|
from snowflake.cli.api.project.schemas.entities.common import PathMapping
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
def
|
|
11
|
+
def sync_artifacts_with_stage(
|
|
13
12
|
project_paths: ProjectPaths,
|
|
14
13
|
stage_root: str,
|
|
14
|
+
prune: bool = False,
|
|
15
15
|
artifacts: Optional[List[PathMapping]] = None,
|
|
16
16
|
):
|
|
17
|
-
if
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
if artifacts is None:
|
|
18
|
+
artifacts = []
|
|
19
|
+
|
|
20
|
+
bundle_map = bundle_artifacts(project_paths, artifacts)
|
|
21
|
+
stage_path_parts = StageManager().stage_path_parts_from_str(stage_root)
|
|
20
22
|
# We treat the bundle root as deploy root
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
sync_deploy_root_with_stage(
|
|
24
|
+
console=cli_console,
|
|
23
25
|
deploy_root=project_paths.bundle_root,
|
|
26
|
+
bundle_map=bundle_map,
|
|
27
|
+
prune=prune,
|
|
28
|
+
recursive=True,
|
|
29
|
+
stage_path=stage_path_parts,
|
|
30
|
+
print_diff=True,
|
|
24
31
|
)
|
|
25
|
-
for artifact in artifacts:
|
|
26
|
-
bundle_map.add(PathMapping(src=str(artifact.src), dest=artifact.dest))
|
|
27
32
|
|
|
28
|
-
# Clean up bundle root
|
|
29
|
-
project_paths.remove_up_bundle_root()
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
.parent
|
|
46
|
-
)
|
|
47
|
-
full_stage_path = f"{stage_root}/{stage_path}".rstrip("/")
|
|
48
|
-
cli_console.step(f"Uploading {absolute_dest} to {full_stage_path}")
|
|
49
|
-
stage_manager.put(
|
|
50
|
-
local_path=absolute_dest, stage_path=full_stage_path, overwrite=True
|
|
51
|
-
)
|
|
34
|
+
def put_files(
|
|
35
|
+
project_paths: ProjectPaths,
|
|
36
|
+
stage_root: str,
|
|
37
|
+
artifacts: Optional[List[PathMapping]] = None,
|
|
38
|
+
):
|
|
39
|
+
if not artifacts:
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
sync_artifacts_with_stage(
|
|
43
|
+
project_paths=project_paths,
|
|
44
|
+
stage_root=stage_root,
|
|
45
|
+
prune=False,
|
|
46
|
+
artifacts=artifacts,
|
|
47
|
+
)
|
|
@@ -69,14 +69,16 @@ def bundle_artifacts(project_paths: ProjectPaths, artifacts: Artifacts) -> Bundl
|
|
|
69
69
|
bundle_map.add(artifact)
|
|
70
70
|
|
|
71
71
|
project_paths.remove_up_bundle_root()
|
|
72
|
+
SecurePath(project_paths.bundle_root).mkdir(parents=True, exist_ok=True)
|
|
72
73
|
for absolute_src, absolute_dest in bundle_map.all_mappings(
|
|
73
74
|
absolute=True, expand_directories=True
|
|
74
75
|
):
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
if absolute_src.is_file():
|
|
77
|
+
# We treat the bundle root as deploy root
|
|
78
|
+
symlink_or_copy(
|
|
79
|
+
absolute_src,
|
|
80
|
+
absolute_dest,
|
|
81
|
+
deploy_root=project_paths.bundle_root,
|
|
82
|
+
)
|
|
81
83
|
|
|
82
84
|
return bundle_map
|
|
@@ -22,7 +22,7 @@ from pathlib import Path
|
|
|
22
22
|
from typing import TYPE_CHECKING, Iterator, Optional
|
|
23
23
|
|
|
24
24
|
from snowflake.cli.api.connections import ConnectionContext, OpenConnectionCache
|
|
25
|
-
from snowflake.cli.api.exceptions import
|
|
25
|
+
from snowflake.cli.api.exceptions import MissingConfigurationError
|
|
26
26
|
from snowflake.cli.api.metrics import CLIMetrics
|
|
27
27
|
from snowflake.cli.api.output.formats import OutputFormat
|
|
28
28
|
from snowflake.cli.api.rendering.jinja import CONTEXT_KEY
|
|
@@ -61,6 +61,7 @@ class _CliGlobalContextManager:
|
|
|
61
61
|
override_project_definition: ProjectDefinition | None = None
|
|
62
62
|
|
|
63
63
|
_definition_manager: DefinitionManager | None = None
|
|
64
|
+
enhanced_exit_codes: bool = False
|
|
64
65
|
|
|
65
66
|
# which properties invalidate our current DefinitionManager?
|
|
66
67
|
DEFINITION_MANAGER_DEPENDENCIES = [
|
|
@@ -126,7 +127,7 @@ class _CliGlobalContextManager:
|
|
|
126
127
|
{CONTEXT_KEY: {"env": self.project_env_overrides_args}},
|
|
127
128
|
)
|
|
128
129
|
if not dm.has_definition_file and not self.project_is_optional:
|
|
129
|
-
raise
|
|
130
|
+
raise MissingConfigurationError(
|
|
130
131
|
"Cannot find project definition (snowflake.yml). Please provide a path to the project or run this command in a valid project directory."
|
|
131
132
|
)
|
|
132
133
|
self._definition_manager = dm
|
|
@@ -209,6 +210,10 @@ class _CliGlobalContextAccess:
|
|
|
209
210
|
else:
|
|
210
211
|
return None
|
|
211
212
|
|
|
213
|
+
@property
|
|
214
|
+
def enhanced_exit_codes(self) -> bool:
|
|
215
|
+
return self._manager.enhanced_exit_codes
|
|
216
|
+
|
|
212
217
|
|
|
213
218
|
_CLI_CONTEXT_MANAGER: ContextVar[_CliGlobalContextManager | None] = ContextVar(
|
|
214
219
|
"cli_context", default=None
|
|
@@ -29,6 +29,7 @@ from snowflake.cli.api.commands.flags import (
|
|
|
29
29
|
DiagAllowlistPathOption,
|
|
30
30
|
DiagLogPathOption,
|
|
31
31
|
EnableDiagOption,
|
|
32
|
+
EnhancedExitCodesOption,
|
|
32
33
|
HostOption,
|
|
33
34
|
MasterTokenOption,
|
|
34
35
|
MfaPasscodeOption,
|
|
@@ -78,7 +79,6 @@ def global_options_with_connection(func: Callable):
|
|
|
78
79
|
|
|
79
80
|
def with_project_definition(is_optional: bool = False):
|
|
80
81
|
def _decorator(func: Callable):
|
|
81
|
-
|
|
82
82
|
return _options_decorator_factory(
|
|
83
83
|
func,
|
|
84
84
|
additional_options=[
|
|
@@ -159,7 +159,10 @@ def _options_decorator_factory(
|
|
|
159
159
|
execute_before_command_using_new_options(**options)
|
|
160
160
|
return func(**options)
|
|
161
161
|
|
|
162
|
-
wrapper.__signature__ = _extend_signature_with_additional_options(
|
|
162
|
+
wrapper.__signature__ = _extend_signature_with_additional_options( # type: ignore
|
|
163
|
+
func, additional_options
|
|
164
|
+
)
|
|
165
|
+
|
|
163
166
|
return wrapper
|
|
164
167
|
|
|
165
168
|
|
|
@@ -353,6 +356,12 @@ GLOBAL_OPTIONS = [
|
|
|
353
356
|
annotation=Optional[bool],
|
|
354
357
|
default=SilentOption,
|
|
355
358
|
),
|
|
359
|
+
inspect.Parameter(
|
|
360
|
+
"enhanced_exit_codes",
|
|
361
|
+
inspect.Parameter.KEYWORD_ONLY,
|
|
362
|
+
annotation=Optional[bool],
|
|
363
|
+
default=EnhancedExitCodesOption,
|
|
364
|
+
),
|
|
356
365
|
]
|
|
357
366
|
|
|
358
367
|
|
|
@@ -371,6 +371,17 @@ DebugOption = typer.Option(
|
|
|
371
371
|
rich_help_panel=_CLI_BEHAVIOUR,
|
|
372
372
|
)
|
|
373
373
|
|
|
374
|
+
EnhancedExitCodesOption = typer.Option(
|
|
375
|
+
False,
|
|
376
|
+
"--enhanced-exit-codes",
|
|
377
|
+
help="Differentiate exit error codes based on failure type.",
|
|
378
|
+
callback=_context_callback("enhanced_exit_codes"),
|
|
379
|
+
is_flag=True,
|
|
380
|
+
rich_help_panel=_CLI_BEHAVIOUR,
|
|
381
|
+
is_eager=True,
|
|
382
|
+
envvar="SNOWFLAKE_ENHANCED_EXIT_CODES",
|
|
383
|
+
)
|
|
384
|
+
|
|
374
385
|
|
|
375
386
|
# If IfExistsOption, IfNotExistsOption, or ReplaceOption are used with names other than those in CREATE_MODE_OPTION_NAMES,
|
|
376
387
|
# you must also override mutually_exclusive if you want to retain the validation that at most one of these flags is
|
|
@@ -412,9 +423,19 @@ OnErrorOption = typer.Option(
|
|
|
412
423
|
|
|
413
424
|
NoInteractiveOption = typer.Option(False, "--no-interactive", help="Disable prompting.")
|
|
414
425
|
|
|
426
|
+
PruneOption = OverrideableOption(
|
|
427
|
+
False,
|
|
428
|
+
"--prune",
|
|
429
|
+
help=f"Delete files that exist in the stage, but not in the local filesystem.",
|
|
430
|
+
show_default=False,
|
|
431
|
+
)
|
|
432
|
+
|
|
415
433
|
|
|
416
|
-
def entity_argument(entity_type: str) -> typer.Argument:
|
|
417
|
-
|
|
434
|
+
def entity_argument(entity_type: str, required=False) -> typer.Argument:
|
|
435
|
+
_help = f"ID of {entity_type} entity."
|
|
436
|
+
if not required:
|
|
437
|
+
return typer.Argument(None, help=_help)
|
|
438
|
+
return typer.Argument(..., help=_help, show_default=False)
|
|
418
439
|
|
|
419
440
|
|
|
420
441
|
def variables_option(description: str):
|
|
@@ -31,7 +31,13 @@ from snowflake.cli.api.commands.execution_metadata import (
|
|
|
31
31
|
ExecutionStatus,
|
|
32
32
|
)
|
|
33
33
|
from snowflake.cli.api.commands.flags import DEFAULT_CONTEXT_SETTINGS
|
|
34
|
-
from snowflake.cli.api.exceptions import
|
|
34
|
+
from snowflake.cli.api.exceptions import (
|
|
35
|
+
BaseCliError,
|
|
36
|
+
CliArgumentError,
|
|
37
|
+
CliError,
|
|
38
|
+
CliSqlError,
|
|
39
|
+
CommandReturnTypeError,
|
|
40
|
+
)
|
|
35
41
|
from snowflake.cli.api.output.types import CommandResult
|
|
36
42
|
from snowflake.cli.api.sanitizers import sanitize_for_terminal
|
|
37
43
|
from snowflake.cli.api.sql_execution import SqlExecutionMixin
|
|
@@ -168,8 +174,20 @@ class SnowTyper(typer.Typer):
|
|
|
168
174
|
|
|
169
175
|
log.debug("Executing command exception callback")
|
|
170
176
|
log_command_execution_error(exception, execution)
|
|
177
|
+
exception = SnowTyper._cli_base_exception_migration_dispatcher(exception)
|
|
178
|
+
return exception
|
|
179
|
+
|
|
180
|
+
@staticmethod
|
|
181
|
+
def _cli_base_exception_migration_dispatcher(exception):
|
|
182
|
+
"""Handler used for dispatching exception until migration completed."""
|
|
183
|
+
if isinstance(
|
|
184
|
+
exception, (BaseCliError, CliError, CliArgumentError, CliSqlError)
|
|
185
|
+
):
|
|
186
|
+
return exception
|
|
187
|
+
|
|
171
188
|
if isinstance(exception, DatabaseError):
|
|
172
|
-
return
|
|
189
|
+
return CliSqlError(exception.msg)
|
|
190
|
+
|
|
173
191
|
return exception
|
|
174
192
|
|
|
175
193
|
@staticmethod
|
snowflake/cli/api/config.py
CHANGED
|
@@ -26,7 +26,7 @@ import tomlkit
|
|
|
26
26
|
from click import ClickException
|
|
27
27
|
from snowflake.cli.api.exceptions import (
|
|
28
28
|
ConfigFileTooWidePermissionsError,
|
|
29
|
-
|
|
29
|
+
MissingConfigurationError,
|
|
30
30
|
UnsupportedConfigSectionTypeError,
|
|
31
31
|
)
|
|
32
32
|
from snowflake.cli.api.secure_path import SecurePath
|
|
@@ -252,7 +252,9 @@ def get_connection_dict(connection_name: str) -> dict:
|
|
|
252
252
|
try:
|
|
253
253
|
return get_config_section(CONNECTIONS_SECTION, connection_name)
|
|
254
254
|
except KeyError:
|
|
255
|
-
raise
|
|
255
|
+
raise MissingConfigurationError(
|
|
256
|
+
f"Connection {connection_name} is not configured"
|
|
257
|
+
)
|
|
256
258
|
|
|
257
259
|
|
|
258
260
|
def get_default_connection_name() -> str:
|
|
@@ -262,7 +264,7 @@ def get_default_connection_name() -> str:
|
|
|
262
264
|
def get_default_connection_dict() -> dict:
|
|
263
265
|
def_connection_name = get_default_connection_name()
|
|
264
266
|
if not connection_exists(def_connection_name):
|
|
265
|
-
raise
|
|
267
|
+
raise MissingConfigurationError(
|
|
266
268
|
f"Couldn't find connection for default connection `{def_connection_name}`. "
|
|
267
269
|
f"Specify connection name or configure default connection."
|
|
268
270
|
)
|
|
@@ -19,7 +19,10 @@ from snowflake.cli._plugins.stage.diff import (
|
|
|
19
19
|
sync_local_diff_with_stage,
|
|
20
20
|
to_stage_path,
|
|
21
21
|
)
|
|
22
|
-
from snowflake.cli._plugins.stage.manager import
|
|
22
|
+
from snowflake.cli._plugins.stage.manager import (
|
|
23
|
+
StageManager,
|
|
24
|
+
StagePathParts,
|
|
25
|
+
)
|
|
23
26
|
from snowflake.cli._plugins.stage.utils import print_diff_to_console
|
|
24
27
|
from snowflake.cli.api.artifacts.bundle_map import BundleMap
|
|
25
28
|
from snowflake.cli.api.cli_global_context import get_cli_context, span
|
|
@@ -33,6 +36,7 @@ from snowflake.cli.api.exceptions import (
|
|
|
33
36
|
NoWarehouseSelectedInSessionError,
|
|
34
37
|
SnowflakeSQLExecutionError,
|
|
35
38
|
)
|
|
39
|
+
from snowflake.cli.api.identifiers import FQN
|
|
36
40
|
from snowflake.cli.api.metrics import CLICounterField
|
|
37
41
|
from snowflake.cli.api.project.schemas.entities.common import PostDeployHook
|
|
38
42
|
from snowflake.cli.api.rendering.sql_templates import (
|
|
@@ -79,12 +83,12 @@ def _get_stage_paths_to_sync(
|
|
|
79
83
|
def sync_deploy_root_with_stage(
|
|
80
84
|
console: AbstractConsole,
|
|
81
85
|
deploy_root: Path,
|
|
82
|
-
package_name: str,
|
|
83
86
|
bundle_map: BundleMap,
|
|
84
|
-
role: str,
|
|
85
87
|
prune: bool,
|
|
86
88
|
recursive: bool,
|
|
87
|
-
stage_path:
|
|
89
|
+
stage_path: StagePathParts,
|
|
90
|
+
role: str | None = None,
|
|
91
|
+
package_name: str | None = None,
|
|
88
92
|
local_paths_to_sync: List[Path] | None = None,
|
|
89
93
|
print_diff: bool = True,
|
|
90
94
|
) -> DiffResult:
|
|
@@ -99,6 +103,8 @@ def sync_deploy_root_with_stage(
|
|
|
99
103
|
recursive (bool): Whether to traverse directories recursively.
|
|
100
104
|
stage_path (DefaultStagePathParts): stage path object.
|
|
101
105
|
|
|
106
|
+
package_name (str): supported for Native App compatibility. Should be None out of Native App context.
|
|
107
|
+
|
|
102
108
|
local_paths_to_sync (List[Path], optional): List of local paths to sync. Defaults to None to sync all
|
|
103
109
|
local paths. Note that providing an empty list here is equivalent to None.
|
|
104
110
|
print_diff (bool): Whether to print the diff between the local files and the remote stage. Defaults to True
|
|
@@ -106,17 +112,24 @@ def sync_deploy_root_with_stage(
|
|
|
106
112
|
Returns:
|
|
107
113
|
A `DiffResult` instance describing the changes that were performed.
|
|
108
114
|
"""
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
if not package_name:
|
|
116
|
+
# ensure stage exists
|
|
117
|
+
stage_fqn = FQN.from_stage(stage_path.stage)
|
|
118
|
+
console.step(f"Creating stage {stage_fqn} if not exists.")
|
|
119
|
+
StageManager().create(fqn=stage_fqn)
|
|
120
|
+
else:
|
|
121
|
+
# ensure stage exists - nativeapp behavior
|
|
122
|
+
sql_facade = get_snowflake_facade()
|
|
123
|
+
schema = stage_path.schema
|
|
124
|
+
stage_fqn = stage_path.stage
|
|
125
|
+
# Does a stage already exist within the application package, or we need to create one?
|
|
126
|
+
# Using "if not exists" should take care of either case.
|
|
127
|
+
console.step(
|
|
128
|
+
f"Checking if stage {stage_fqn} exists, or creating a new one if none exists."
|
|
129
|
+
)
|
|
130
|
+
if not sql_facade.stage_exists(stage_fqn):
|
|
131
|
+
sql_facade.create_schema(schema, database=package_name)
|
|
132
|
+
sql_facade.create_stage(stage_fqn)
|
|
120
133
|
|
|
121
134
|
# Perform a diff operation and display results to the user for informational purposes
|
|
122
135
|
if print_diff:
|
|
@@ -178,7 +191,7 @@ def sync_deploy_root_with_stage(
|
|
|
178
191
|
if print_diff:
|
|
179
192
|
print_diff_to_console(diff, bundle_map)
|
|
180
193
|
|
|
181
|
-
# Upload diff-ed files to
|
|
194
|
+
# Upload diff-ed files to the stage
|
|
182
195
|
if diff.has_changes():
|
|
183
196
|
console.step(
|
|
184
197
|
"Updating the Snowflake stage from your local %s directory."
|