From a2a877f560905a2cc32ee2eb66f03806d795d7e5 Mon Sep 17 00:00:00 2001 From: Adam Stus Date: Tue, 12 Nov 2024 13:22:28 +0100 Subject: [PATCH] Added full global support --- .../snowpark/snowpark_entity_model.py | 7 ++-- .../snowpark/snowpark_project_paths.py | 41 +++++++++++++++---- tests/snowpark/test_project_paths.py | 18 +++++--- 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/snowflake/cli/_plugins/snowpark/snowpark_entity_model.py b/src/snowflake/cli/_plugins/snowpark/snowpark_entity_model.py index 33d2042000..f44b42c945 100644 --- a/src/snowflake/cli/_plugins/snowpark/snowpark_entity_model.py +++ b/src/snowflake/cli/_plugins/snowpark/snowpark_entity_model.py @@ -14,6 +14,7 @@ from __future__ import annotations +import glob from typing import List, Literal, Optional, Union from pydantic import Field, field_validator @@ -55,9 +56,9 @@ def _convert_artifacts(cls, artifacts: Union[dict, str]): _artifacts = [] for artifact in artifacts: if ( - "*" in artifact - and FeatureFlag.ENABLE_SNOWPARK_BUNDLE_MAP_BUILD.is_disabled() - ): + (isinstance(artifact, str) and glob.has_magic(artifact)) + or (isinstance(artifact, PathMapping) and glob.has_magic(artifact.src)) + ) and FeatureFlag.ENABLE_SNOWPARK_BUNDLE_MAP_BUILD.is_disabled(): raise ValueError( "If you want to use glob patterns in artifacts, you need to enable the Snowpark new build feature flag (ENABLE_SNOWPARK_BUNDLE_MAP_BUILD=true)" ) diff --git a/src/snowflake/cli/_plugins/snowpark/snowpark_project_paths.py b/src/snowflake/cli/_plugins/snowpark/snowpark_project_paths.py index 6079561d8c..331dafc8e3 100644 --- a/src/snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +++ b/src/snowflake/cli/_plugins/snowpark/snowpark_project_paths.py @@ -13,6 +13,8 @@ # limitations under the License. from __future__ import annotations +import glob +import os.path import re from dataclasses import dataclass from pathlib import Path, PurePosixPath @@ -92,9 +94,20 @@ def __init__( @property def _artefact_name(self) -> str: - if "*" in str(self.path): - before_wildcard = str(self.path).split("*")[0] - last_part = Path(before_wildcard).absolute().parts[-1] + if glob.has_magic(str(self.path)): + last_part = None + for part in self.path.parts: + if glob.has_magic(part): + break + else: + last_part = part + if not last_part: + last_part = os.path.commonpath( + [str(self.path), str(self.path.absolute())] + ) + raise ValueError("Doopa") + # before_wildcard = str(self.path).split("*")[0] + # last_part = Path(before_wildcard).absolute().parts[-1] return last_part + ".zip" if (self.project_root / self.path).is_dir(): return self.path.stem + ".zip" @@ -109,7 +122,9 @@ def post_build_path(self) -> Path: """ deploy_root = self.deploy_root() path = ( - self._path_until_asterisk() if "*" in str(self.path) else self.path.parent + self._path_until_asterisk() + if glob.has_magic(str(self.path)) + else self.path.parent ) if self._is_dest_a_file(): return deploy_root / self.dest # type: ignore @@ -131,7 +146,7 @@ def upload_path(self, stage: FQN | str | None) -> str: else: stage_path /= ( self._path_until_asterisk() - if "*" in str(self.path) + if glob.has_magic(str(self.path)) else PurePosixPath(self.path).parent ) @@ -150,9 +165,19 @@ def _is_dest_a_file(self) -> bool: return re.search(r"\.[a-zA-Z0-9]{2,4}$", self.dest) is not None def _path_until_asterisk(self) -> Path: - before_wildcard = str(self.path).split("*")[0] - parts = Path(before_wildcard).parts[:-1] - return Path(*parts) + # before_wildcard = str(self.path).split("*")[0] + # parts = Path(before_wildcard).parts[:-1] + # return Path(*parts) + + path = [] + for part in self.path.parts: + if glob.has_magic(part): + break + else: + path.append(part) + # before_wildcard = str(self.path).split("*")[0] + # parts = Path(before_wildcard).parts[:-1] + return Path(*path[:-1]) # Can be removed after removing ENABLE_SNOWPARK_BUNDLE_MAP_BUILD feature flag. def build(self) -> None: diff --git a/tests/snowpark/test_project_paths.py b/tests/snowpark/test_project_paths.py index f742e6eb2e..55796e1a98 100644 --- a/tests/snowpark/test_project_paths.py +++ b/tests/snowpark/test_project_paths.py @@ -18,7 +18,8 @@ ("src/*", "source/", False, "@db.public.stage/source/src.zip"), ("src/**/*.py", None, False, "@db.public.stage/src.zip"), ("src/**/*.py", "source/", False, "@db.public.stage/source/src.zip"), - ("src/app*", None, False, "@db.public.stage/src/app.zip"), + ("src/app*", None, False, "@db.public.stage/src.zip"), + ("src/app[1-5].py", None, False, "@db.public.stage/src.zip"), ], ) @mock.patch("snowflake.cli.api.cli_global_context.get_cli_context") @@ -48,7 +49,8 @@ def test_artifact_import_path(mock_ctx_context, path, dest, is_file, expected_pa ("src/*", "source/", False, "@db.public.stage/source/"), ("src/**/*.py", None, False, "@db.public.stage/"), ("src/**/*.py", "source/", False, "@db.public.stage/source/"), - ("src/app*", None, False, "@db.public.stage/src/"), + ("src/app*", None, False, "@db.public.stage/"), + ("src/app[1-5].py", None, False, "@db.public.stage/"), ], ) @mock.patch("snowflake.cli.api.cli_global_context.get_cli_context") @@ -93,7 +95,8 @@ def test_artifact_upload_path(mock_ctx_context, path, dest, is_file, expected_pa ("src/*", "source/", False, Path("output") / "source" / "src.zip"), ("src/**/*.py", None, False, Path("output") / "src.zip"), ("src/**/*.py", "source/", False, Path("output") / "source" / "src.zip"), - ("src/app*", None, False, Path("output") / "src" / "app.zip"), + ("src/app*", None, False, Path("output") / "src.zip"), + ("src/app[1-5].py", None, False, Path("output") / "src.zip"), ], ) def test_artifact_post_build_path(path, dest, is_file, expected_path): @@ -116,7 +119,8 @@ def test_artifact_post_build_path(path, dest, is_file, expected_path): ("src/*", "source/", False, "@db.public.stage/source/src.zip"), ("src/**/*.py", None, False, "@db.public.stage/src.zip"), ("src/**/*.py", "source/", False, "@db.public.stage/source/src.zip"), - ("src/app*", None, False, "@db.public.stage/src/app.zip"), + ("src/app*", None, False, "@db.public.stage/src.zip"), + ("src/app[1-5].py", None, False, "@db.public.stage/src.zip"), ], ) @mock.patch("snowflake.cli.api.cli_global_context.get_cli_context") @@ -148,7 +152,8 @@ def test_artifact_import_path_from_other_directory( ("src/*", "source/", False, "@db.public.stage/source/"), ("src/**/*.py", None, False, "@db.public.stage/"), ("src/**/*.py", "source/", False, "@db.public.stage/source/"), - ("src/app*", None, False, "@db.public.stage/src/"), + ("src/app*", None, False, "@db.public.stage/"), + ("src/app[1-5].py", None, False, "@db.public.stage/"), ], ) @mock.patch("snowflake.cli.api.cli_global_context.get_cli_context") @@ -209,7 +214,8 @@ def test_artifact_upload_path_from_other_directory( False, Path.cwd().absolute() / "output" / "source" / "src.zip", ), - ("src/app*", None, False, Path.cwd().absolute() / "output" / "src" / "app.zip"), + ("src/app*", None, False, Path.cwd().absolute() / "output" / "src.zip"), + ("src/app[1-5].py", None, False, Path.cwd().absolute() / "output" / "src.zip"), ], ) def test_artifact_post_build_path_from_other_directory(