snowflake-cli-labs 2.8.0rc1__py3-none-any.whl → 2.8.2__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.
Files changed (242) hide show
  1. README.md +21 -0
  2. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-2.8.2.dist-info}/METADATA +7 -95
  3. snowflake_cli_labs-2.8.2.dist-info/RECORD +5 -0
  4. snowflake/cli/__about__.py +0 -17
  5. snowflake/cli/__init__.py +0 -13
  6. snowflake/cli/api/__init__.py +0 -48
  7. snowflake/cli/api/cli_global_context.py +0 -390
  8. snowflake/cli/api/commands/__init__.py +0 -13
  9. snowflake/cli/api/commands/alias.py +0 -23
  10. snowflake/cli/api/commands/decorators.py +0 -354
  11. snowflake/cli/api/commands/execution_metadata.py +0 -40
  12. snowflake/cli/api/commands/experimental_behaviour.py +0 -19
  13. snowflake/cli/api/commands/flags.py +0 -640
  14. snowflake/cli/api/commands/project_initialisation.py +0 -65
  15. snowflake/cli/api/commands/snow_typer.py +0 -237
  16. snowflake/cli/api/commands/typer_pre_execute.py +0 -26
  17. snowflake/cli/api/config.py +0 -348
  18. snowflake/cli/api/console/__init__.py +0 -17
  19. snowflake/cli/api/console/abc.py +0 -89
  20. snowflake/cli/api/console/console.py +0 -134
  21. snowflake/cli/api/console/enum.py +0 -17
  22. snowflake/cli/api/constants.py +0 -79
  23. snowflake/cli/api/errno.py +0 -27
  24. snowflake/cli/api/exceptions.py +0 -164
  25. snowflake/cli/api/feature_flags.py +0 -55
  26. snowflake/cli/api/identifiers.py +0 -154
  27. snowflake/cli/api/output/__init__.py +0 -13
  28. snowflake/cli/api/output/formats.py +0 -20
  29. snowflake/cli/api/output/types.py +0 -118
  30. snowflake/cli/api/plugins/__init__.py +0 -13
  31. snowflake/cli/api/plugins/command/__init__.py +0 -72
  32. snowflake/cli/api/plugins/command/plugin_hook_specs.py +0 -21
  33. snowflake/cli/api/plugins/plugin_config.py +0 -32
  34. snowflake/cli/api/project/__init__.py +0 -13
  35. snowflake/cli/api/project/definition.py +0 -84
  36. snowflake/cli/api/project/definition_manager.py +0 -134
  37. snowflake/cli/api/project/errors.py +0 -56
  38. snowflake/cli/api/project/project_verification.py +0 -23
  39. snowflake/cli/api/project/schemas/__init__.py +0 -13
  40. snowflake/cli/api/project/schemas/entities/application_entity.py +0 -44
  41. snowflake/cli/api/project/schemas/entities/application_package_entity.py +0 -66
  42. snowflake/cli/api/project/schemas/entities/common.py +0 -78
  43. snowflake/cli/api/project/schemas/entities/entities.py +0 -30
  44. snowflake/cli/api/project/schemas/identifier_model.py +0 -49
  45. snowflake/cli/api/project/schemas/native_app/__init__.py +0 -13
  46. snowflake/cli/api/project/schemas/native_app/application.py +0 -62
  47. snowflake/cli/api/project/schemas/native_app/native_app.py +0 -93
  48. snowflake/cli/api/project/schemas/native_app/package.py +0 -78
  49. snowflake/cli/api/project/schemas/native_app/path_mapping.py +0 -65
  50. snowflake/cli/api/project/schemas/project_definition.py +0 -199
  51. snowflake/cli/api/project/schemas/snowpark/__init__.py +0 -13
  52. snowflake/cli/api/project/schemas/snowpark/argument.py +0 -28
  53. snowflake/cli/api/project/schemas/snowpark/callable.py +0 -69
  54. snowflake/cli/api/project/schemas/snowpark/snowpark.py +0 -36
  55. snowflake/cli/api/project/schemas/streamlit/__init__.py +0 -13
  56. snowflake/cli/api/project/schemas/streamlit/streamlit.py +0 -46
  57. snowflake/cli/api/project/schemas/template.py +0 -77
  58. snowflake/cli/api/project/schemas/updatable_model.py +0 -194
  59. snowflake/cli/api/project/util.py +0 -261
  60. snowflake/cli/api/rendering/__init__.py +0 -13
  61. snowflake/cli/api/rendering/jinja.py +0 -112
  62. snowflake/cli/api/rendering/project_definition_templates.py +0 -39
  63. snowflake/cli/api/rendering/project_templates.py +0 -98
  64. snowflake/cli/api/rendering/sql_templates.py +0 -60
  65. snowflake/cli/api/rest_api.py +0 -172
  66. snowflake/cli/api/sanitizers.py +0 -43
  67. snowflake/cli/api/secure_path.py +0 -362
  68. snowflake/cli/api/secure_utils.py +0 -29
  69. snowflake/cli/api/sql_execution.py +0 -260
  70. snowflake/cli/api/utils/__init__.py +0 -13
  71. snowflake/cli/api/utils/cursor.py +0 -34
  72. snowflake/cli/api/utils/definition_rendering.py +0 -383
  73. snowflake/cli/api/utils/dict_utils.py +0 -73
  74. snowflake/cli/api/utils/error_handling.py +0 -23
  75. snowflake/cli/api/utils/graph.py +0 -97
  76. snowflake/cli/api/utils/models.py +0 -63
  77. snowflake/cli/api/utils/naming_utils.py +0 -13
  78. snowflake/cli/api/utils/path_utils.py +0 -36
  79. snowflake/cli/api/utils/templating_functions.py +0 -144
  80. snowflake/cli/api/utils/types.py +0 -35
  81. snowflake/cli/app/__init__.py +0 -22
  82. snowflake/cli/app/__main__.py +0 -31
  83. snowflake/cli/app/api_impl/__init__.py +0 -13
  84. snowflake/cli/app/api_impl/plugin/__init__.py +0 -13
  85. snowflake/cli/app/api_impl/plugin/plugin_config_provider_impl.py +0 -66
  86. snowflake/cli/app/build_and_push.sh +0 -8
  87. snowflake/cli/app/cli_app.py +0 -243
  88. snowflake/cli/app/commands_registration/__init__.py +0 -33
  89. snowflake/cli/app/commands_registration/builtin_plugins.py +0 -54
  90. snowflake/cli/app/commands_registration/command_plugins_loader.py +0 -169
  91. snowflake/cli/app/commands_registration/commands_registration_with_callbacks.py +0 -105
  92. snowflake/cli/app/commands_registration/exception_logging.py +0 -26
  93. snowflake/cli/app/commands_registration/threadsafe.py +0 -48
  94. snowflake/cli/app/commands_registration/typer_registration.py +0 -153
  95. snowflake/cli/app/constants.py +0 -19
  96. snowflake/cli/app/dev/__init__.py +0 -13
  97. snowflake/cli/app/dev/commands_structure.py +0 -48
  98. snowflake/cli/app/dev/docs/__init__.py +0 -13
  99. snowflake/cli/app/dev/docs/commands_docs_generator.py +0 -100
  100. snowflake/cli/app/dev/docs/generator.py +0 -35
  101. snowflake/cli/app/dev/docs/project_definition_docs_generator.py +0 -58
  102. snowflake/cli/app/dev/docs/project_definition_generate_json_schema.py +0 -227
  103. snowflake/cli/app/dev/docs/template_utils.py +0 -23
  104. snowflake/cli/app/dev/docs/templates/definition_description.rst.jinja2 +0 -38
  105. snowflake/cli/app/dev/docs/templates/overview.rst.jinja2 +0 -9
  106. snowflake/cli/app/dev/docs/templates/usage.rst.jinja2 +0 -57
  107. snowflake/cli/app/dev/pycharm_remote_debug.py +0 -46
  108. snowflake/cli/app/loggers.py +0 -199
  109. snowflake/cli/app/main_typer.py +0 -62
  110. snowflake/cli/app/printing.py +0 -181
  111. snowflake/cli/app/snow_connector.py +0 -243
  112. snowflake/cli/app/telemetry.py +0 -189
  113. snowflake/cli/plugins/__init__.py +0 -13
  114. snowflake/cli/plugins/connection/__init__.py +0 -13
  115. snowflake/cli/plugins/connection/commands.py +0 -330
  116. snowflake/cli/plugins/connection/plugin_spec.py +0 -30
  117. snowflake/cli/plugins/connection/util.py +0 -179
  118. snowflake/cli/plugins/cortex/__init__.py +0 -13
  119. snowflake/cli/plugins/cortex/commands.py +0 -327
  120. snowflake/cli/plugins/cortex/constants.py +0 -17
  121. snowflake/cli/plugins/cortex/manager.py +0 -189
  122. snowflake/cli/plugins/cortex/plugin_spec.py +0 -30
  123. snowflake/cli/plugins/cortex/types.py +0 -22
  124. snowflake/cli/plugins/git/__init__.py +0 -13
  125. snowflake/cli/plugins/git/commands.py +0 -305
  126. snowflake/cli/plugins/git/manager.py +0 -96
  127. snowflake/cli/plugins/git/plugin_spec.py +0 -30
  128. snowflake/cli/plugins/init/__init__.py +0 -13
  129. snowflake/cli/plugins/init/commands.py +0 -244
  130. snowflake/cli/plugins/init/plugin_spec.py +0 -30
  131. snowflake/cli/plugins/nativeapp/__init__.py +0 -13
  132. snowflake/cli/plugins/nativeapp/artifacts.py +0 -742
  133. snowflake/cli/plugins/nativeapp/codegen/__init__.py +0 -13
  134. snowflake/cli/plugins/nativeapp/codegen/artifact_processor.py +0 -91
  135. snowflake/cli/plugins/nativeapp/codegen/compiler.py +0 -130
  136. snowflake/cli/plugins/nativeapp/codegen/sandbox.py +0 -306
  137. snowflake/cli/plugins/nativeapp/codegen/setup/native_app_setup_processor.py +0 -172
  138. snowflake/cli/plugins/nativeapp/codegen/setup/setup_driver.py.source +0 -56
  139. snowflake/cli/plugins/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -181
  140. snowflake/cli/plugins/nativeapp/codegen/snowpark/extension_function_utils.py +0 -217
  141. snowflake/cli/plugins/nativeapp/codegen/snowpark/models.py +0 -61
  142. snowflake/cli/plugins/nativeapp/codegen/snowpark/python_processor.py +0 -528
  143. snowflake/cli/plugins/nativeapp/commands.py +0 -439
  144. snowflake/cli/plugins/nativeapp/common_flags.py +0 -44
  145. snowflake/cli/plugins/nativeapp/constants.py +0 -27
  146. snowflake/cli/plugins/nativeapp/exceptions.py +0 -122
  147. snowflake/cli/plugins/nativeapp/feature_flags.py +0 -24
  148. snowflake/cli/plugins/nativeapp/init.py +0 -345
  149. snowflake/cli/plugins/nativeapp/manager.py +0 -823
  150. snowflake/cli/plugins/nativeapp/plugin_spec.py +0 -30
  151. snowflake/cli/plugins/nativeapp/policy.py +0 -50
  152. snowflake/cli/plugins/nativeapp/project_model.py +0 -195
  153. snowflake/cli/plugins/nativeapp/run_processor.py +0 -389
  154. snowflake/cli/plugins/nativeapp/teardown_processor.py +0 -301
  155. snowflake/cli/plugins/nativeapp/utils.py +0 -98
  156. snowflake/cli/plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +0 -135
  157. snowflake/cli/plugins/nativeapp/version/__init__.py +0 -13
  158. snowflake/cli/plugins/nativeapp/version/commands.py +0 -170
  159. snowflake/cli/plugins/nativeapp/version/version_processor.py +0 -362
  160. snowflake/cli/plugins/notebook/__init__.py +0 -13
  161. snowflake/cli/plugins/notebook/commands.py +0 -84
  162. snowflake/cli/plugins/notebook/exceptions.py +0 -20
  163. snowflake/cli/plugins/notebook/manager.py +0 -71
  164. snowflake/cli/plugins/notebook/plugin_spec.py +0 -30
  165. snowflake/cli/plugins/notebook/types.py +0 -16
  166. snowflake/cli/plugins/object/__init__.py +0 -13
  167. snowflake/cli/plugins/object/command_aliases.py +0 -94
  168. snowflake/cli/plugins/object/commands.py +0 -174
  169. snowflake/cli/plugins/object/common.py +0 -85
  170. snowflake/cli/plugins/object/manager.py +0 -96
  171. snowflake/cli/plugins/object/plugin_spec.py +0 -30
  172. snowflake/cli/plugins/object_stage_deprecated/__init__.py +0 -15
  173. snowflake/cli/plugins/object_stage_deprecated/commands.py +0 -122
  174. snowflake/cli/plugins/object_stage_deprecated/plugin_spec.py +0 -32
  175. snowflake/cli/plugins/snowpark/__init__.py +0 -13
  176. snowflake/cli/plugins/snowpark/commands.py +0 -548
  177. snowflake/cli/plugins/snowpark/common.py +0 -307
  178. snowflake/cli/plugins/snowpark/manager.py +0 -109
  179. snowflake/cli/plugins/snowpark/models.py +0 -156
  180. snowflake/cli/plugins/snowpark/package/__init__.py +0 -13
  181. snowflake/cli/plugins/snowpark/package/anaconda_packages.py +0 -233
  182. snowflake/cli/plugins/snowpark/package/commands.py +0 -256
  183. snowflake/cli/plugins/snowpark/package/manager.py +0 -43
  184. snowflake/cli/plugins/snowpark/package/utils.py +0 -26
  185. snowflake/cli/plugins/snowpark/package_utils.py +0 -354
  186. snowflake/cli/plugins/snowpark/plugin_spec.py +0 -30
  187. snowflake/cli/plugins/snowpark/snowpark_package_paths.py +0 -65
  188. snowflake/cli/plugins/snowpark/snowpark_shared.py +0 -95
  189. snowflake/cli/plugins/snowpark/zipper.py +0 -81
  190. snowflake/cli/plugins/spcs/__init__.py +0 -35
  191. snowflake/cli/plugins/spcs/common.py +0 -99
  192. snowflake/cli/plugins/spcs/compute_pool/__init__.py +0 -13
  193. snowflake/cli/plugins/spcs/compute_pool/commands.py +0 -240
  194. snowflake/cli/plugins/spcs/compute_pool/manager.py +0 -121
  195. snowflake/cli/plugins/spcs/image_registry/__init__.py +0 -13
  196. snowflake/cli/plugins/spcs/image_registry/commands.py +0 -65
  197. snowflake/cli/plugins/spcs/image_registry/manager.py +0 -105
  198. snowflake/cli/plugins/spcs/image_repository/__init__.py +0 -13
  199. snowflake/cli/plugins/spcs/image_repository/commands.py +0 -196
  200. snowflake/cli/plugins/spcs/image_repository/manager.py +0 -84
  201. snowflake/cli/plugins/spcs/jobs/__init__.py +0 -13
  202. snowflake/cli/plugins/spcs/jobs/commands.py +0 -78
  203. snowflake/cli/plugins/spcs/jobs/manager.py +0 -53
  204. snowflake/cli/plugins/spcs/plugin_spec.py +0 -30
  205. snowflake/cli/plugins/spcs/services/__init__.py +0 -13
  206. snowflake/cli/plugins/spcs/services/commands.py +0 -311
  207. snowflake/cli/plugins/spcs/services/manager.py +0 -170
  208. snowflake/cli/plugins/sql/__init__.py +0 -13
  209. snowflake/cli/plugins/sql/commands.py +0 -83
  210. snowflake/cli/plugins/sql/manager.py +0 -92
  211. snowflake/cli/plugins/sql/plugin_spec.py +0 -30
  212. snowflake/cli/plugins/sql/snowsql_templating.py +0 -28
  213. snowflake/cli/plugins/stage/__init__.py +0 -13
  214. snowflake/cli/plugins/stage/commands.py +0 -261
  215. snowflake/cli/plugins/stage/diff.py +0 -326
  216. snowflake/cli/plugins/stage/manager.py +0 -544
  217. snowflake/cli/plugins/stage/md5.py +0 -160
  218. snowflake/cli/plugins/stage/plugin_spec.py +0 -30
  219. snowflake/cli/plugins/streamlit/__init__.py +0 -13
  220. snowflake/cli/plugins/streamlit/commands.py +0 -186
  221. snowflake/cli/plugins/streamlit/manager.py +0 -222
  222. snowflake/cli/plugins/streamlit/plugin_spec.py +0 -30
  223. snowflake/cli/plugins/workspace/__init__.py +0 -13
  224. snowflake/cli/plugins/workspace/commands.py +0 -35
  225. snowflake/cli/plugins/workspace/plugin_spec.py +0 -30
  226. snowflake/cli/templates/default_snowpark/.gitignore +0 -4
  227. snowflake/cli/templates/default_snowpark/app/__init__.py +0 -0
  228. snowflake/cli/templates/default_snowpark/app/common.py +0 -2
  229. snowflake/cli/templates/default_snowpark/app/functions.py +0 -15
  230. snowflake/cli/templates/default_snowpark/app/procedures.py +0 -22
  231. snowflake/cli/templates/default_snowpark/requirements.txt +0 -1
  232. snowflake/cli/templates/default_snowpark/snowflake.yml +0 -23
  233. snowflake/cli/templates/default_streamlit/.gitignore +0 -4
  234. snowflake/cli/templates/default_streamlit/common/hello.py +0 -2
  235. snowflake/cli/templates/default_streamlit/environment.yml +0 -6
  236. snowflake/cli/templates/default_streamlit/pages/my_page.py +0 -3
  237. snowflake/cli/templates/default_streamlit/snowflake.yml +0 -10
  238. snowflake/cli/templates/default_streamlit/streamlit_app.py +0 -4
  239. snowflake_cli_labs-2.8.0rc1.dist-info/RECORD +0 -240
  240. snowflake_cli_labs-2.8.0rc1.dist-info/entry_points.txt +0 -2
  241. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-2.8.2.dist-info}/WHEEL +0 -0
  242. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-2.8.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,305 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from __future__ import annotations
16
-
17
- import itertools
18
- import logging
19
- from os import path
20
- from pathlib import Path
21
- from typing import List, Optional
22
-
23
- import typer
24
- from click import ClickException
25
- from snowflake.cli.api.commands.flags import (
26
- ExecuteVariablesOption,
27
- OnErrorOption,
28
- PatternOption,
29
- identifier_argument,
30
- like_option,
31
- )
32
- from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
33
- from snowflake.cli.api.console.console import cli_console
34
- from snowflake.cli.api.constants import ObjectType
35
- from snowflake.cli.api.output.types import CollectionResult, CommandResult, QueryResult
36
- from snowflake.cli.api.utils.path_utils import is_stage_path
37
- from snowflake.cli.plugins.git.manager import GitManager
38
- from snowflake.cli.plugins.object.command_aliases import (
39
- add_object_command_aliases,
40
- scope_option,
41
- )
42
- from snowflake.cli.plugins.object.manager import ObjectManager
43
- from snowflake.cli.plugins.stage.manager import OnErrorType
44
-
45
- app = SnowTyperFactory(
46
- name="git",
47
- help="Manages git repositories in Snowflake.",
48
- )
49
- log = logging.getLogger(__name__)
50
-
51
-
52
- def _repo_path_argument_callback(path):
53
- # All repository paths must start with repository scope:
54
- # "@repo_name/tag/example_tag/*"
55
- if not is_stage_path(path) or path.count("/") < 3:
56
- raise ClickException(
57
- "REPOSITORY_PATH should be a path to git repository stage with scope provided."
58
- " Path to the repository root must end with '/'."
59
- " For example: @my_repo/branches/main/"
60
- )
61
-
62
- return path
63
-
64
-
65
- RepoNameArgument = identifier_argument(sf_object="git repository", example="my_repo")
66
- RepoPathArgument = typer.Argument(
67
- metavar="REPOSITORY_PATH",
68
- help=(
69
- "Path to git repository stage with scope provided."
70
- " Path to the repository root must end with '/'."
71
- " For example: @my_repo/branches/main/"
72
- ),
73
- callback=_repo_path_argument_callback,
74
- )
75
- add_object_command_aliases(
76
- app=app,
77
- object_type=ObjectType.GIT_REPOSITORY,
78
- name_argument=RepoNameArgument,
79
- like_option=like_option(
80
- help_example='`list --like "my%"` lists all git repositories with name that begin with “my”',
81
- ),
82
- scope_option=scope_option(help_example="`list --in database my_db`"),
83
- )
84
-
85
-
86
- def _assure_repository_does_not_exist(om: ObjectManager, repository_name: str) -> None:
87
- if om.object_exists(
88
- object_type=ObjectType.GIT_REPOSITORY.value.cli_name, name=repository_name
89
- ):
90
- raise ClickException(f"Repository '{repository_name}' already exists")
91
-
92
-
93
- def _validate_origin_url(url: str) -> None:
94
- if not url.startswith("https://"):
95
- raise ClickException("Url address should start with 'https'")
96
-
97
-
98
- @app.command("setup", requires_connection=True)
99
- def setup(
100
- repository_name: str = RepoNameArgument,
101
- **options,
102
- ) -> CommandResult:
103
- """
104
- Sets up a git repository object.
105
-
106
- You will be prompted for:
107
-
108
- * url - address of repository to be used for git clone operation
109
-
110
- * secret - Snowflake secret containing authentication credentials. Not needed if origin repository does not require
111
- authentication for RO operations (clone, fetch)
112
-
113
- * API integration - object allowing Snowflake to interact with git repository.
114
- """
115
- manager = GitManager()
116
- om = ObjectManager()
117
- _assure_repository_does_not_exist(om, repository_name)
118
-
119
- url = typer.prompt("Origin url")
120
- _validate_origin_url(url)
121
-
122
- secret_needed = typer.confirm("Use secret for authentication?")
123
- should_create_secret = False
124
- secret_name = None
125
- if secret_needed:
126
- secret_name = f"{repository_name}_secret"
127
- secret_name = typer.prompt(
128
- "Secret identifier (will be created if not exists)", default=secret_name
129
- )
130
- if om.object_exists(
131
- object_type=ObjectType.SECRET.value.cli_name, name=secret_name
132
- ):
133
- cli_console.step(f"Using existing secret '{secret_name}'")
134
- else:
135
- should_create_secret = True
136
- cli_console.step(f"Secret '{secret_name}' will be created")
137
- secret_username = typer.prompt("username")
138
- secret_password = typer.prompt("password/token", hide_input=True)
139
-
140
- api_integration = f"{repository_name}_api_integration"
141
- api_integration = typer.prompt(
142
- "API integration identifier (will be created if not exists)",
143
- default=api_integration,
144
- )
145
-
146
- if should_create_secret:
147
- manager.create_password_secret(
148
- name=secret_name, username=secret_username, password=secret_password
149
- )
150
- cli_console.step(f"Secret '{secret_name}' successfully created.")
151
-
152
- if not om.object_exists(
153
- object_type=ObjectType.INTEGRATION.value.cli_name, name=api_integration
154
- ):
155
- manager.create_api_integration(
156
- name=api_integration,
157
- api_provider="git_https_api",
158
- allowed_prefix=url,
159
- secret=secret_name,
160
- )
161
- cli_console.step(f"API integration '{api_integration}' successfully created.")
162
- else:
163
- cli_console.step(f"Using existing API integration '{api_integration}'.")
164
-
165
- return QueryResult(
166
- manager.create(
167
- repo_name=repository_name,
168
- url=url,
169
- api_integration=api_integration,
170
- secret=secret_name,
171
- )
172
- )
173
-
174
-
175
- @app.command(
176
- "list-branches",
177
- requires_connection=True,
178
- )
179
- def list_branches(
180
- repository_name: str = RepoNameArgument,
181
- like=like_option(
182
- help_example='`list-branches --like "%_test"` lists all branches that end with "_test"'
183
- ),
184
- **options,
185
- ) -> CommandResult:
186
- """
187
- List all branches in the repository.
188
- """
189
- return QueryResult(GitManager().show_branches(repo_name=repository_name, like=like))
190
-
191
-
192
- @app.command(
193
- "list-tags",
194
- requires_connection=True,
195
- )
196
- def list_tags(
197
- repository_name: str = RepoNameArgument,
198
- like=like_option(
199
- help_example='`list-tags --like "v2.0%"` lists all tags that start with "v2.0"'
200
- ),
201
- **options,
202
- ) -> CommandResult:
203
- """
204
- List all tags in the repository.
205
- """
206
- return QueryResult(GitManager().show_tags(repo_name=repository_name, like=like))
207
-
208
-
209
- @app.command(
210
- "list-files",
211
- requires_connection=True,
212
- )
213
- def list_files(
214
- repository_path: str = RepoPathArgument,
215
- pattern=PatternOption,
216
- **options,
217
- ) -> CommandResult:
218
- """
219
- List files from given state of git repository.
220
- """
221
- return QueryResult(
222
- GitManager().list_files(stage_name=repository_path, pattern=pattern)
223
- )
224
-
225
-
226
- @app.command(
227
- "fetch",
228
- requires_connection=True,
229
- )
230
- def fetch(
231
- repository_name: str = RepoNameArgument,
232
- **options,
233
- ) -> CommandResult:
234
- """
235
- Fetch changes from origin to Snowflake repository.
236
- """
237
- return QueryResult(GitManager().fetch(repo_name=repository_name))
238
-
239
-
240
- @app.command(
241
- "copy",
242
- requires_connection=True,
243
- )
244
- def copy(
245
- repository_path: str = RepoPathArgument,
246
- destination_path: str = typer.Argument(
247
- help="Target path for copy operation. Should be a path to a directory on remote stage or local file system.",
248
- ),
249
- parallel: int = typer.Option(
250
- 4,
251
- help="Number of parallel threads to use when downloading files.",
252
- ),
253
- **options,
254
- ):
255
- """
256
- Copies all files from given state of repository to local directory or stage.
257
-
258
- If the source path ends with '/', the command copies contents of specified directory.
259
- Otherwise, it creates a new directory or file in the destination directory.
260
- """
261
- is_copy = is_stage_path(destination_path)
262
- if is_copy:
263
- return QueryResult(
264
- GitManager().copy_files(
265
- source_path=repository_path, destination_path=destination_path
266
- )
267
- )
268
- return get(
269
- source_path=repository_path,
270
- destination_path=destination_path,
271
- parallel=parallel,
272
- )
273
-
274
-
275
- @app.command("execute", requires_connection=True)
276
- def execute(
277
- repository_path: str = RepoPathArgument,
278
- on_error: OnErrorType = OnErrorOption,
279
- variables: Optional[List[str]] = ExecuteVariablesOption,
280
- **options,
281
- ):
282
- """
283
- Execute immediate all files from the repository path. Files can be filtered with glob like pattern,
284
- e.g. `@my_repo/branches/main/*.sql`, `@my_repo/branches/main/dev/*`. Only files with `.sql`
285
- extension will be executed.
286
- """
287
- results = GitManager().execute(
288
- stage_path=repository_path, on_error=on_error, variables=variables
289
- )
290
- return CollectionResult(results)
291
-
292
-
293
- def get(source_path: str, destination_path: str, parallel: int):
294
- target = Path(destination_path).resolve()
295
-
296
- cursors = GitManager().get_recursive(
297
- stage_path=source_path, dest_path=target, parallel=parallel
298
- )
299
- results = [list(QueryResult(c).result) for c in cursors]
300
- flattened_results = list(itertools.chain.from_iterable(results))
301
- sorted_results = sorted(
302
- flattened_results,
303
- key=lambda e: (path.dirname(e["file"]), path.basename(e["file"])),
304
- )
305
- return CollectionResult(sorted_results)
@@ -1,96 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from __future__ import annotations
16
-
17
- from pathlib import Path
18
- from textwrap import dedent
19
- from typing import List
20
-
21
- from snowflake.cli.plugins.stage.manager import (
22
- USER_STAGE_PREFIX,
23
- StageManager,
24
- StagePathParts,
25
- UserStagePathParts,
26
- )
27
- from snowflake.connector.cursor import SnowflakeCursor
28
-
29
-
30
- class GitStagePathParts(StagePathParts):
31
- def __init__(self, stage_path: str):
32
- self.stage = GitManager.get_stage_from_path(stage_path)
33
- stage_path_parts = Path(stage_path).parts
34
- git_repo_name = stage_path_parts[0].split(".")[-1]
35
- if git_repo_name.startswith("@"):
36
- git_repo_name = git_repo_name[1:]
37
- self.stage_name = "/".join([git_repo_name, *stage_path_parts[1:3], ""])
38
- self.directory = "/".join(stage_path_parts[3:])
39
- self.is_directory = True if stage_path.endswith("/") else False
40
-
41
- @property
42
- def path(self) -> str:
43
- return (
44
- f"{self.stage_name}{self.directory}"
45
- if self.stage_name.endswith("/")
46
- else f"{self.stage_name}/{self.directory}"
47
- )
48
-
49
- def add_stage_prefix(self, file_path: str) -> str:
50
- stage = Path(self.stage).parts[0]
51
- file_path_without_prefix = Path(file_path).parts[1:]
52
- return f"{stage}/{'/'.join(file_path_without_prefix)}"
53
-
54
- def get_directory_from_file_path(self, file_path: str) -> List[str]:
55
- stage_path_length = len(Path(self.directory).parts)
56
- return list(Path(file_path).parts[3 + stage_path_length : -1])
57
-
58
-
59
- class GitManager(StageManager):
60
- def show_branches(self, repo_name: str, like: str) -> SnowflakeCursor:
61
- return self._execute_query(f"show git branches like '{like}' in {repo_name}")
62
-
63
- def show_tags(self, repo_name: str, like: str) -> SnowflakeCursor:
64
- return self._execute_query(f"show git tags like '{like}' in {repo_name}")
65
-
66
- def fetch(self, repo_name: str) -> SnowflakeCursor:
67
- return self._execute_query(f"alter git repository {repo_name} fetch")
68
-
69
- def create(
70
- self, repo_name: str, api_integration: str, url: str, secret: str
71
- ) -> SnowflakeCursor:
72
- query = dedent(
73
- f"""
74
- create git repository {repo_name}
75
- api_integration = {api_integration}
76
- origin = '{url}'
77
- """
78
- )
79
- if secret is not None:
80
- query += f"git_credentials = {secret}\n"
81
- return self._execute_query(query)
82
-
83
- @staticmethod
84
- def get_stage_from_path(path: str):
85
- """
86
- Returns stage name from potential path on stage. For example
87
- repo/branches/main/foo/bar -> repo/branches/main/
88
- """
89
- return f"{'/'.join(Path(path).parts[0:3])}/"
90
-
91
- @staticmethod
92
- def _stage_path_part_factory(stage_path: str) -> StagePathParts:
93
- stage_path = StageManager.get_standard_stage_prefix(stage_path)
94
- if stage_path.startswith(USER_STAGE_PREFIX):
95
- return UserStagePathParts(stage_path)
96
- return GitStagePathParts(stage_path)
@@ -1,30 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from snowflake.cli.api.plugins.command import (
16
- SNOWCLI_ROOT_COMMAND_PATH,
17
- CommandSpec,
18
- CommandType,
19
- plugin_hook_impl,
20
- )
21
- from snowflake.cli.plugins.git import commands
22
-
23
-
24
- @plugin_hook_impl
25
- def command_spec():
26
- return CommandSpec(
27
- parent_command_path=SNOWCLI_ROOT_COMMAND_PATH,
28
- command_type=CommandType.COMMAND_GROUP,
29
- typer_instance=commands.app.create_instance(),
30
- )
@@ -1,13 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
@@ -1,244 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from __future__ import annotations
16
-
17
- import logging
18
- from typing import Any, Dict, List, Optional
19
-
20
- import typer
21
- import yaml
22
- from click import ClickException
23
- from snowflake.cli.__about__ import VERSION
24
- from snowflake.cli.api.commands.flags import (
25
- NoInteractiveOption,
26
- parse_key_value_variables,
27
- variables_option,
28
- )
29
- from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
30
- from snowflake.cli.api.constants import DEFAULT_SIZE_LIMIT_MB
31
- from snowflake.cli.api.exceptions import InvalidTemplate
32
- from snowflake.cli.api.output.types import (
33
- CommandResult,
34
- MessageResult,
35
- )
36
- from snowflake.cli.api.project.schemas.template import Template, TemplateVariable
37
- from snowflake.cli.api.rendering.project_templates import render_template_files
38
- from snowflake.cli.api.secure_path import SecurePath
39
-
40
- # simple Typer with defaults because it won't become a command group as it contains only one command
41
- app = SnowTyperFactory()
42
-
43
-
44
- DEFAULT_SOURCE = "https://github.com/snowflakedb/snowflake-cli-templates"
45
-
46
- log = logging.getLogger(__name__)
47
-
48
-
49
- def _path_argument_callback(path: str) -> str:
50
- if SecurePath(path).exists():
51
- raise ClickException(
52
- f"The directory {path} already exists. Please specify a different path for the project."
53
- )
54
- return path
55
-
56
-
57
- PathArgument = typer.Argument(
58
- ...,
59
- help="Directory to be initialized with the project. This directory must not already exist",
60
- show_default=False,
61
- callback=_path_argument_callback,
62
- )
63
- TemplateOption = typer.Option(
64
- None,
65
- "--template",
66
- help="which template (subdirectory of --template-source) should be used. If not provided,"
67
- " whole source will be used as the template.",
68
- show_default=False,
69
- )
70
- SourceOption = typer.Option(
71
- default=DEFAULT_SOURCE,
72
- help=f"local path to template directory or URL to git repository with templates.",
73
- )
74
- VariablesOption = variables_option(
75
- "String in `key=value` format. Provided variables will not be prompted for."
76
- )
77
-
78
- TEMPLATE_METADATA_FILE_NAME = "template.yml"
79
-
80
-
81
- def _fetch_local_template(
82
- template_source: SecurePath, path: Optional[str], destination: SecurePath
83
- ) -> SecurePath:
84
- """Copies local template to [dest] and returns path to the template root.
85
- Ends with an error of the template does not exist."""
86
-
87
- template_source.assert_exists()
88
- template_origin = template_source / path if path else template_source
89
- log.info("Copying local template from %s", template_origin.path)
90
- if not template_origin.exists():
91
- raise ClickException(
92
- f"Template '{path}' cannot be found under {template_source}"
93
- )
94
-
95
- template_origin.copy(destination.path)
96
- return destination / template_origin.name
97
-
98
-
99
- def _fetch_remote_template(
100
- url: str, path: Optional[str], destination: SecurePath
101
- ) -> SecurePath:
102
- """Downloads remote repository template to [dest],
103
- and returns path to the template root.
104
- Ends with an error of the template does not exist."""
105
- from git import GitCommandError
106
- from git import rmtree as git_rmtree
107
-
108
- # TODO: during nativeapp refactor get rid of this dependency
109
- from snowflake.cli.plugins.nativeapp.utils import shallow_git_clone
110
-
111
- log.info("Downloading remote template from %s", url)
112
- try:
113
- shallow_git_clone(url, to_path=destination.path)
114
- except GitCommandError as err:
115
- import re
116
-
117
- if re.search("fatal: repository '.*' not found", err.stderr):
118
- raise ClickException(f"Repository '{url}' does not exist")
119
- raise
120
-
121
- if path:
122
- # template is a subdirectoruy of the repository
123
- template_root = destination / path
124
- else:
125
- # template is a whole repository
126
- # removing .git directory not to copy it to the template
127
- template_root = destination
128
- git_rmtree((template_root / ".git").path)
129
- if not template_root.exists():
130
- raise ClickException(f"Template '{path}' cannot be found under {url}")
131
-
132
- return template_root
133
-
134
-
135
- def _read_template_metadata(template_root: SecurePath) -> Template:
136
- """Parse template.yml file."""
137
- template_metadata_path = template_root / TEMPLATE_METADATA_FILE_NAME
138
- log.debug("Reading template metadata from %s", template_metadata_path.path)
139
- if not template_metadata_path.exists():
140
- raise InvalidTemplate(
141
- f"Template does not have {TEMPLATE_METADATA_FILE_NAME} file."
142
- )
143
- with template_metadata_path.open(read_file_limit_mb=DEFAULT_SIZE_LIMIT_MB) as fd:
144
- yaml_contents = yaml.safe_load(fd) or {}
145
- return Template(template_root, **yaml_contents)
146
-
147
-
148
- def _remove_template_metadata_file(template_root: SecurePath) -> None:
149
- (template_root / TEMPLATE_METADATA_FILE_NAME).unlink()
150
-
151
-
152
- def _determine_variable_values(
153
- variables_metadata: List[TemplateVariable],
154
- variables_from_flags: Dict[str, Any],
155
- no_interactive: bool,
156
- ) -> Dict[str, Any]:
157
- """
158
- Prompt user for values not provided in [variables_from_flags].
159
- If [no_interactive] is True, fill not provided variables with their default values.
160
- """
161
- result = {}
162
-
163
- log.debug(
164
- "Resolving values of variables: %s",
165
- ", ".join(v.name for v in variables_metadata),
166
- )
167
- for variable in variables_metadata:
168
- if variable.name in variables_from_flags:
169
- value = variable.python_type(variables_from_flags[variable.name])
170
- else:
171
- value = variable.prompt_user_for_value(no_interactive)
172
-
173
- result[variable.name] = value
174
-
175
- return result
176
-
177
-
178
- def _validate_cli_version(required_version: str) -> None:
179
- from packaging.version import parse
180
-
181
- if parse(required_version) > parse(VERSION):
182
- raise ClickException(
183
- f"Snowflake CLI version ({VERSION}) is too low - minimum version required"
184
- f" by template is {required_version}. Please upgrade before continuing."
185
- )
186
-
187
-
188
- @app.command(no_args_is_help=True)
189
- def init(
190
- path: str = PathArgument,
191
- template: Optional[str] = TemplateOption,
192
- template_source: Optional[str] = SourceOption,
193
- variables: Optional[List[str]] = VariablesOption,
194
- no_interactive: bool = NoInteractiveOption,
195
- **options,
196
- ) -> CommandResult:
197
- """
198
- Creates project directory from template.
199
- """
200
- variables_from_flags = {
201
- v.key: v.value for v in parse_key_value_variables(variables)
202
- }
203
- is_remote = any(
204
- template_source.startswith(prefix) for prefix in ["git@", "http://", "https://"] # type: ignore
205
- )
206
-
207
- # copy/download template into tmpdir, so it is going to be removed in case command ends with an error
208
- with SecurePath.temporary_directory() as tmpdir:
209
- if is_remote:
210
- template_root = _fetch_remote_template(
211
- url=template_source, path=template, destination=tmpdir # type: ignore
212
- )
213
- else:
214
- template_root = _fetch_local_template(
215
- template_source=SecurePath(template_source),
216
- path=template,
217
- destination=tmpdir,
218
- )
219
-
220
- template_metadata = _read_template_metadata(template_root)
221
- if template_metadata.minimum_cli_version:
222
- _validate_cli_version(template_metadata.minimum_cli_version)
223
-
224
- variable_values = _determine_variable_values(
225
- variables_metadata=template_metadata.variables,
226
- variables_from_flags=variables_from_flags,
227
- no_interactive=no_interactive,
228
- ) | {
229
- "project_dir_name": SecurePath(path).name,
230
- "snowflake_cli_version": VERSION,
231
- }
232
- log.debug(
233
- "Rendering template files: %s", ", ".join(template_metadata.files_to_render)
234
- )
235
- render_template_files(
236
- template_root=template_root,
237
- files_to_render=template_metadata.files_to_render,
238
- data=variable_values,
239
- )
240
- _remove_template_metadata_file(template_root)
241
- SecurePath(path).parent.mkdir(exist_ok=True, parents=True)
242
- template_root.copy(path)
243
-
244
- return MessageResult(f"Initialized the new project in {path}")