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/__about__.py
CHANGED
snowflake/cli/_app/telemetry.py
CHANGED
|
@@ -37,6 +37,12 @@ from snowflake.connector.telemetry import (
|
|
|
37
37
|
from snowflake.connector.time_util import get_time_millis
|
|
38
38
|
|
|
39
39
|
|
|
40
|
+
@unique
|
|
41
|
+
class CLIInstallationSource(Enum):
|
|
42
|
+
BINARY = "binary"
|
|
43
|
+
PYPI = "pypi"
|
|
44
|
+
|
|
45
|
+
|
|
40
46
|
@unique
|
|
41
47
|
class CLITelemetryField(Enum):
|
|
42
48
|
# Basic information
|
|
@@ -44,6 +50,7 @@ class CLITelemetryField(Enum):
|
|
|
44
50
|
VERSION_CLI = "version_cli"
|
|
45
51
|
VERSION_PYTHON = "version_python"
|
|
46
52
|
VERSION_OS = "version_os"
|
|
53
|
+
INSTALLATION_SOURCE = "installation_source"
|
|
47
54
|
# Command execution context
|
|
48
55
|
COMMAND = "command"
|
|
49
56
|
COMMAND_GROUP = "command_group"
|
|
@@ -54,6 +61,8 @@ class CLITelemetryField(Enum):
|
|
|
54
61
|
COMMAND_EXECUTION_TIME = "command_execution_time"
|
|
55
62
|
# Configuration
|
|
56
63
|
CONFIG_FEATURE_FLAGS = "config_feature_flags"
|
|
64
|
+
# Metrics
|
|
65
|
+
COUNTERS = "counters"
|
|
57
66
|
# Information
|
|
58
67
|
EVENT = "event"
|
|
59
68
|
ERROR_MSG = "error_msg"
|
|
@@ -72,6 +81,16 @@ class TelemetryEvent(Enum):
|
|
|
72
81
|
TelemetryDict = Dict[Union[CLITelemetryField, TelemetryField], Any]
|
|
73
82
|
|
|
74
83
|
|
|
84
|
+
def _get_command_metrics() -> TelemetryDict:
|
|
85
|
+
cli_context = get_cli_context()
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
CLITelemetryField.COUNTERS: {
|
|
89
|
+
**cli_context.metrics.counters,
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
75
94
|
def _find_command_info() -> TelemetryDict:
|
|
76
95
|
ctx = click.get_current_context()
|
|
77
96
|
command_path = ctx.command_path.split(" ")[1:]
|
|
@@ -97,6 +116,12 @@ def _get_definition_version() -> str | None:
|
|
|
97
116
|
return None
|
|
98
117
|
|
|
99
118
|
|
|
119
|
+
def _get_installation_source() -> CLIInstallationSource:
|
|
120
|
+
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
|
|
121
|
+
return CLIInstallationSource.BINARY
|
|
122
|
+
return CLIInstallationSource.PYPI
|
|
123
|
+
|
|
124
|
+
|
|
100
125
|
def command_info() -> str:
|
|
101
126
|
info = _find_command_info()
|
|
102
127
|
command = ".".join(info[CLITelemetryField.COMMAND])
|
|
@@ -119,6 +144,7 @@ class CLITelemetryClient:
|
|
|
119
144
|
) -> Dict[str, Any]:
|
|
120
145
|
data = {
|
|
121
146
|
CLITelemetryField.SOURCE: PARAM_APPLICATION_NAME,
|
|
147
|
+
CLITelemetryField.INSTALLATION_SOURCE: _get_installation_source().value,
|
|
122
148
|
CLITelemetryField.VERSION_CLI: VERSION,
|
|
123
149
|
CLITelemetryField.VERSION_OS: platform.platform(),
|
|
124
150
|
CLITelemetryField.VERSION_PYTHON: python_version(),
|
|
@@ -168,6 +194,7 @@ def log_command_result(execution: ExecutionMetadata):
|
|
|
168
194
|
CLITelemetryField.COMMAND_EXECUTION_ID: execution.execution_id,
|
|
169
195
|
CLITelemetryField.COMMAND_RESULT_STATUS: execution.status.value,
|
|
170
196
|
CLITelemetryField.COMMAND_EXECUTION_TIME: execution.get_duration(),
|
|
197
|
+
**_get_command_metrics(),
|
|
171
198
|
}
|
|
172
199
|
)
|
|
173
200
|
|
|
@@ -183,6 +210,7 @@ def log_command_execution_error(exception: Exception, execution: ExecutionMetada
|
|
|
183
210
|
CLITelemetryField.ERROR_TYPE: exception_type,
|
|
184
211
|
CLITelemetryField.IS_CLI_EXCEPTION: is_cli_exception,
|
|
185
212
|
CLITelemetryField.COMMAND_EXECUTION_TIME: execution.get_duration(),
|
|
213
|
+
**_get_command_metrics(),
|
|
186
214
|
}
|
|
187
215
|
)
|
|
188
216
|
|
|
@@ -33,7 +33,7 @@ from snowflake.cli.api.commands.flags import (
|
|
|
33
33
|
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
34
34
|
from snowflake.cli.api.config import (
|
|
35
35
|
ConnectionConfig,
|
|
36
|
-
|
|
36
|
+
add_connection_to_proper_file,
|
|
37
37
|
connection_exists,
|
|
38
38
|
get_all_connections,
|
|
39
39
|
get_connection_dict,
|
|
@@ -49,7 +49,7 @@ from snowflake.cli.api.output.types import (
|
|
|
49
49
|
ObjectResult,
|
|
50
50
|
)
|
|
51
51
|
from snowflake.connector import ProgrammingError
|
|
52
|
-
from snowflake.connector.
|
|
52
|
+
from snowflake.connector.constants import CONNECTIONS_FILE
|
|
53
53
|
|
|
54
54
|
app = SnowTyperFactory(
|
|
55
55
|
name="connection",
|
|
@@ -91,6 +91,11 @@ def list_connections(**options) -> CommandResult:
|
|
|
91
91
|
}
|
|
92
92
|
for connection_name, connection_config in connections.items()
|
|
93
93
|
)
|
|
94
|
+
|
|
95
|
+
if CONNECTIONS_FILE.exists():
|
|
96
|
+
cli_console.warning(
|
|
97
|
+
f"Reading connections from {CONNECTIONS_FILE}. Entries from config.toml are ignored."
|
|
98
|
+
)
|
|
94
99
|
return CollectionResult(result)
|
|
95
100
|
|
|
96
101
|
|
|
@@ -255,7 +260,7 @@ def add(
|
|
|
255
260
|
if connection_exists(connection_name):
|
|
256
261
|
raise ClickException(f"Connection {connection_name} already exists")
|
|
257
262
|
|
|
258
|
-
|
|
263
|
+
connections_file = add_connection_to_proper_file(
|
|
259
264
|
connection_name,
|
|
260
265
|
ConnectionConfig(
|
|
261
266
|
account=account,
|
|
@@ -279,7 +284,7 @@ def add(
|
|
|
279
284
|
)
|
|
280
285
|
|
|
281
286
|
return MessageResult(
|
|
282
|
-
f"Wrote new connection {connection_name} to {
|
|
287
|
+
f"Wrote new connection {connection_name} to {connections_file}"
|
|
283
288
|
)
|
|
284
289
|
|
|
285
290
|
|
|
@@ -16,6 +16,7 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import typer
|
|
18
18
|
import yaml
|
|
19
|
+
from click import ClickException
|
|
19
20
|
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
20
21
|
from snowflake.cli.api.output.types import MessageResult
|
|
21
22
|
from snowflake.cli.api.project.definition_conversion import (
|
|
@@ -35,23 +36,55 @@ def v1_to_v2(
|
|
|
35
36
|
accept_templates: bool = typer.Option(
|
|
36
37
|
False, "-t", "--accept-templates", help="Allows the migration of templates."
|
|
37
38
|
),
|
|
39
|
+
migrate_local_yml: (bool | None) = typer.Option(
|
|
40
|
+
None,
|
|
41
|
+
"-l",
|
|
42
|
+
"--migrate-local-overrides/--no-migrate-local-overrides",
|
|
43
|
+
help=(
|
|
44
|
+
"Merge values in snowflake.local.yml into the main project definition. "
|
|
45
|
+
"The snowflake.local.yml file will not be migrated, "
|
|
46
|
+
"instead its values will be reflected in the output snowflake.yml file. "
|
|
47
|
+
"If unset and snowflake.local.yml is present, an error will be raised."
|
|
48
|
+
),
|
|
49
|
+
show_default=False,
|
|
50
|
+
),
|
|
38
51
|
**options,
|
|
39
52
|
):
|
|
40
53
|
"""Migrates the Snowpark, Streamlit, and Native App project definition files from V1 to V2."""
|
|
41
54
|
manager = DefinitionManager()
|
|
55
|
+
local_yml_path = manager.project_root / "snowflake.local.yml"
|
|
56
|
+
has_local_yml = local_yml_path in manager.project_config_paths
|
|
57
|
+
if has_local_yml:
|
|
58
|
+
if migrate_local_yml is None:
|
|
59
|
+
raise ClickException(
|
|
60
|
+
"snowflake.local.yml file detected, "
|
|
61
|
+
"please specify --migrate-local-overrides to include "
|
|
62
|
+
"or --no-migrate-local-overrides to exclude its values."
|
|
63
|
+
)
|
|
64
|
+
if not migrate_local_yml:
|
|
65
|
+
# If we don't want the local file,
|
|
66
|
+
# remove it from the list of paths to load
|
|
67
|
+
manager.project_config_paths.remove(local_yml_path)
|
|
68
|
+
|
|
42
69
|
pd = manager.unrendered_project_definition
|
|
43
70
|
|
|
44
71
|
if pd.meets_version_requirement("2"):
|
|
45
72
|
return MessageResult("Project definition is already at version 2.")
|
|
46
73
|
|
|
47
|
-
pd_v2 = convert_project_definition_to_v2(
|
|
74
|
+
pd_v2 = convert_project_definition_to_v2(
|
|
75
|
+
manager.project_root, pd, accept_templates, manager.template_context
|
|
76
|
+
)
|
|
48
77
|
|
|
49
78
|
SecurePath("snowflake.yml").rename("snowflake_V1.yml")
|
|
79
|
+
if has_local_yml:
|
|
80
|
+
SecurePath("snowflake.local.yml").rename("snowflake_V1.local.yml")
|
|
50
81
|
with open("snowflake.yml", "w") as file:
|
|
51
82
|
yaml.dump(
|
|
52
83
|
pd_v2.model_dump(
|
|
53
84
|
exclude_unset=True, exclude_none=True, mode="json", by_alias=True
|
|
54
85
|
),
|
|
55
86
|
file,
|
|
87
|
+
sort_keys=False,
|
|
88
|
+
width=float("inf"), # Don't break lines
|
|
56
89
|
)
|
|
57
90
|
return MessageResult("Project definition migrated to version 2.")
|
|
@@ -34,7 +34,9 @@ from snowflake.cli._plugins.nativeapp.codegen.templates.templates_processor impo
|
|
|
34
34
|
TemplatesProcessor,
|
|
35
35
|
)
|
|
36
36
|
from snowflake.cli._plugins.nativeapp.feature_flags import FeatureFlag
|
|
37
|
+
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
37
38
|
from snowflake.cli.api.console import cli_console as cc
|
|
39
|
+
from snowflake.cli.api.metrics import CLICounterField
|
|
38
40
|
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import (
|
|
39
41
|
ProcessorMapping,
|
|
40
42
|
)
|
|
@@ -72,6 +74,9 @@ class NativeAppCompiler:
|
|
|
72
74
|
Go through every artifact object in the project definition of a native app, and execute processors in order of specification for each of the artifact object.
|
|
73
75
|
May have side-effects on the filesystem by either directly editing source files or the deploy root.
|
|
74
76
|
"""
|
|
77
|
+
metrics = get_cli_context().metrics
|
|
78
|
+
metrics.set_counter_default(CLICounterField.TEMPLATES_PROCESSOR, 0)
|
|
79
|
+
metrics.set_counter_default(CLICounterField.SNOWPARK_PROCESSOR, 0)
|
|
75
80
|
|
|
76
81
|
if not self._should_invoke_processors():
|
|
77
82
|
return
|
|
@@ -48,7 +48,9 @@ from snowflake.cli._plugins.nativeapp.codegen.snowpark.models import (
|
|
|
48
48
|
NativeAppExtensionFunction,
|
|
49
49
|
)
|
|
50
50
|
from snowflake.cli._plugins.stage.diff import to_stage_path
|
|
51
|
+
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
51
52
|
from snowflake.cli.api.console import cli_console as cc
|
|
53
|
+
from snowflake.cli.api.metrics import CLICounterField
|
|
52
54
|
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import (
|
|
53
55
|
PathMapping,
|
|
54
56
|
ProcessorMapping,
|
|
@@ -176,6 +178,8 @@ class SnowparkAnnotationProcessor(ArtifactProcessor):
|
|
|
176
178
|
setup script with generated SQL that registers these functions.
|
|
177
179
|
"""
|
|
178
180
|
|
|
181
|
+
get_cli_context().metrics.set_counter(CLICounterField.SNOWPARK_PROCESSOR, 1)
|
|
182
|
+
|
|
179
183
|
bundle_map = BundleMap(
|
|
180
184
|
project_root=self._bundle_ctx.project_root,
|
|
181
185
|
deploy_root=self._bundle_ctx.deploy_root,
|
|
@@ -25,6 +25,7 @@ from snowflake.cli._plugins.nativeapp.codegen.artifact_processor import (
|
|
|
25
25
|
from snowflake.cli._plugins.nativeapp.exceptions import InvalidTemplateInFileError
|
|
26
26
|
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
27
27
|
from snowflake.cli.api.console import cli_console as cc
|
|
28
|
+
from snowflake.cli.api.metrics import CLICounterField
|
|
28
29
|
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import (
|
|
29
30
|
PathMapping,
|
|
30
31
|
ProcessorMapping,
|
|
@@ -98,6 +99,8 @@ class TemplatesProcessor(ArtifactProcessor):
|
|
|
98
99
|
Process the artifact by executing the template expansion logic on it.
|
|
99
100
|
"""
|
|
100
101
|
|
|
102
|
+
get_cli_context().metrics.set_counter(CLICounterField.TEMPLATES_PROCESSOR, 1)
|
|
103
|
+
|
|
101
104
|
bundle_map = BundleMap(
|
|
102
105
|
project_root=self._bundle_ctx.project_root,
|
|
103
106
|
deploy_root=self._bundle_ctx.deploy_root,
|
|
@@ -22,20 +22,15 @@ from textwrap import dedent
|
|
|
22
22
|
from typing import Generator, Iterable, List, Optional, cast
|
|
23
23
|
|
|
24
24
|
import typer
|
|
25
|
-
from
|
|
26
|
-
ApplicationEntityModel,
|
|
27
|
-
)
|
|
28
|
-
from snowflake.cli._plugins.nativeapp.application_package_entity_model import (
|
|
29
|
-
ApplicationPackageEntityModel,
|
|
30
|
-
)
|
|
25
|
+
from click.exceptions import ClickException
|
|
31
26
|
from snowflake.cli._plugins.nativeapp.common_flags import (
|
|
32
27
|
ForceOption,
|
|
33
28
|
InteractiveOption,
|
|
34
29
|
ValidateOption,
|
|
35
30
|
)
|
|
36
|
-
from snowflake.cli._plugins.nativeapp.
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
from snowflake.cli._plugins.nativeapp.entities.application import ApplicationEntityModel
|
|
32
|
+
from snowflake.cli._plugins.nativeapp.entities.application_package import (
|
|
33
|
+
ApplicationPackageEntityModel,
|
|
39
34
|
)
|
|
40
35
|
from snowflake.cli._plugins.nativeapp.manager import NativeAppManager
|
|
41
36
|
from snowflake.cli._plugins.nativeapp.policy import (
|
|
@@ -47,10 +42,6 @@ from snowflake.cli._plugins.nativeapp.run_processor import NativeAppRunProcessor
|
|
|
47
42
|
from snowflake.cli._plugins.nativeapp.teardown_processor import (
|
|
48
43
|
NativeAppTeardownProcessor,
|
|
49
44
|
)
|
|
50
|
-
from snowflake.cli._plugins.nativeapp.utils import (
|
|
51
|
-
get_first_paragraph_from_markdown_file,
|
|
52
|
-
shallow_git_clone,
|
|
53
|
-
)
|
|
54
45
|
from snowflake.cli._plugins.nativeapp.v2_conversions.v2_to_v1_decorator import (
|
|
55
46
|
find_entity,
|
|
56
47
|
nativeapp_definition_v2_to_v1,
|
|
@@ -71,7 +62,6 @@ from snowflake.cli.api.entities.common import EntityActions
|
|
|
71
62
|
from snowflake.cli.api.exceptions import IncompatibleParametersError
|
|
72
63
|
from snowflake.cli.api.output.formats import OutputFormat
|
|
73
64
|
from snowflake.cli.api.output.types import (
|
|
74
|
-
CollectionResult,
|
|
75
65
|
CommandResult,
|
|
76
66
|
MessageResult,
|
|
77
67
|
ObjectResult,
|
|
@@ -79,7 +69,6 @@ from snowflake.cli.api.output.types import (
|
|
|
79
69
|
)
|
|
80
70
|
from snowflake.cli.api.project.project_verification import assert_project_type
|
|
81
71
|
from snowflake.cli.api.project.schemas.project_definition import ProjectDefinitionV1
|
|
82
|
-
from snowflake.cli.api.secure_path import SecurePath
|
|
83
72
|
from typing_extensions import Annotated
|
|
84
73
|
|
|
85
74
|
app = SnowTyperFactory(
|
|
@@ -91,81 +80,15 @@ app.add_typer(versions_app)
|
|
|
91
80
|
log = logging.getLogger(__name__)
|
|
92
81
|
|
|
93
82
|
|
|
94
|
-
@app.command("init")
|
|
95
|
-
def app_init(
|
|
96
|
-
path: str = typer.Argument(
|
|
97
|
-
...,
|
|
98
|
-
help=f"""Directory to be initialized with the Snowflake Native App project. This directory must not already exist.""",
|
|
99
|
-
show_default=False,
|
|
100
|
-
),
|
|
101
|
-
name: str = typer.Option(
|
|
102
|
-
None,
|
|
103
|
-
help=f"""The name of the Snowflake Native App project to include in snowflake.yml. When not specified, it is
|
|
104
|
-
generated from the name of the directory. Names are assumed to be unquoted identifiers whenever possible, but
|
|
105
|
-
can be forced to be quoted by including the surrounding quote characters in the provided value.""",
|
|
106
|
-
),
|
|
107
|
-
template_repo: str = typer.Option(
|
|
108
|
-
None,
|
|
109
|
-
help=f"""Specifies the git URL to a template repository, which can be a template itself or contain many templates inside it,
|
|
110
|
-
such as https://github.com/snowflakedb/native-apps-templates.git for all official Snowflake Native App with Snowflake CLI templates.
|
|
111
|
-
If using a private Github repo, you might be prompted to enter your Github username and password.
|
|
112
|
-
Please use your personal access token in the password prompt, and refer to
|
|
113
|
-
https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.""",
|
|
114
|
-
),
|
|
115
|
-
template: str = typer.Option(
|
|
116
|
-
None,
|
|
117
|
-
help="A specific template name within the template repo to use as template for the Snowflake Native App project. Example: Default is basic if `--template-repo` is https://github.com/snowflakedb/native-apps-templates.git, and None if any other --template-repo is specified.",
|
|
118
|
-
),
|
|
119
|
-
**options,
|
|
120
|
-
) -> CommandResult:
|
|
121
|
-
"""
|
|
122
|
-
Initializes a Snowflake Native App project.
|
|
83
|
+
@app.command("init", hidden=True)
|
|
84
|
+
def app_init(**options):
|
|
123
85
|
"""
|
|
124
|
-
|
|
125
|
-
path=path, name=name, git_url=template_repo, template=template
|
|
126
|
-
)
|
|
127
|
-
return MessageResult(
|
|
128
|
-
f"Snowflake Native App project {project.name} has been created at: {path}"
|
|
129
|
-
)
|
|
130
|
-
|
|
86
|
+
*** Deprecated. Use snow init instead ***
|
|
131
87
|
|
|
132
|
-
|
|
133
|
-
def app_list_templates(**options) -> CommandResult:
|
|
134
|
-
"""
|
|
135
|
-
Prints information regarding the official templates that can be used with snow app init.
|
|
88
|
+
Initializes a Snowflake Native App project.
|
|
136
89
|
"""
|
|
137
|
-
with SecurePath.temporary_directory() as temp_path:
|
|
138
|
-
from git import rmtree as git_rmtree
|
|
139
|
-
|
|
140
|
-
repo = shallow_git_clone(OFFICIAL_TEMPLATES_GITHUB_URL, temp_path.path)
|
|
141
|
-
|
|
142
|
-
# Mark a directory as a template if a project definition jinja template is inside
|
|
143
|
-
template_directories = [
|
|
144
|
-
entry.name
|
|
145
|
-
for entry in repo.head.commit.tree
|
|
146
|
-
if (temp_path / entry.name / "snowflake.yml.jinja").exists()
|
|
147
|
-
]
|
|
148
|
-
|
|
149
|
-
# get the template descriptions from the README.md in its directory
|
|
150
|
-
template_descriptions = [
|
|
151
|
-
get_first_paragraph_from_markdown_file(
|
|
152
|
-
(temp_path / directory / "README.md").path
|
|
153
|
-
)
|
|
154
|
-
for directory in template_directories
|
|
155
|
-
]
|
|
156
|
-
|
|
157
|
-
result = (
|
|
158
|
-
{"template": directory, "description": description}
|
|
159
|
-
for directory, description in zip(
|
|
160
|
-
template_directories, template_descriptions
|
|
161
|
-
)
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
# proactively clean up here to avoid permission issues on Windows
|
|
165
|
-
repo.close()
|
|
166
|
-
git_rmtree(temp_path.path)
|
|
167
90
|
|
|
168
|
-
|
|
91
|
+
raise ClickException("This command has been removed. Use `snow init` instead.")
|
|
169
92
|
|
|
170
93
|
|
|
171
94
|
@app.command("bundle")
|
|
File without changes
|