diff --git a/tests_integration/nativeapp/test_bundle.py b/tests_integration/nativeapp/test_bundle.py index 5c5eb933ba..2bcfa1bd6a 100644 --- a/tests_integration/nativeapp/test_bundle.py +++ b/tests_integration/nativeapp/test_bundle.py @@ -23,6 +23,7 @@ from tests_integration.testing_utils import ( assert_that_result_failed_with_message_containing, ) +from tests_integration.testing_utils.project_fixtures import * @pytest.fixture @@ -323,10 +324,13 @@ def test_nativeapp_bundle_deletes_existing_deploy_root(template_setup): @pytest.mark.integration -def test_nativeapp_can_bundle_with_subdirs(runner, nativeapp_project_directory): +def test_nativeapp_can_bundle_with_subdirs( + runner, nativeapp_teardown, setup_v2_project_w_subdir +): command = "app bundle --package-entity-id=pkg_v1" subdir = "v1" - with nativeapp_project_directory("napp_stage_subdirs") as project_root: + project_name, project_root = setup_v2_project_w_subdir() + with nativeapp_teardown(): result = runner.invoke_json(split(command)) assert result.exit_code == 0 @@ -337,9 +341,12 @@ def test_nativeapp_can_bundle_with_subdirs(runner, nativeapp_project_directory): @pytest.mark.integration -def test_nativeapp_bundle_subdirs_dont_overwrite(runner, nativeapp_project_directory): +def test_nativeapp_bundle_subdirs_dont_overwrite( + runner, nativeapp_teardown, setup_v2_project_w_subdir_w_snowpark +): + project_name, project_root = setup_v2_project_w_subdir_w_snowpark() - with nativeapp_project_directory("napp_stage_subdirs_w_snowpark") as project_root: + with nativeapp_teardown(): result_1 = runner.invoke_json(split("app bundle --package-entity-id=pkg_v1")) assert result_1.exit_code == 0 diff --git a/tests_integration/nativeapp/test_deploy.py b/tests_integration/nativeapp/test_deploy.py index be29b3e10e..d0879ee95b 100644 --- a/tests_integration/nativeapp/test_deploy.py +++ b/tests_integration/nativeapp/test_deploy.py @@ -17,12 +17,13 @@ from snowflake.cli.api.project.util import TEST_RESOURCE_SUFFIX_VAR from tests.nativeapp.utils import touch - +from tests_integration.testing_utils.project_fixtures import * from tests.project.fixtures import * from tests_integration.test_utils import ( contains_row_with, not_contains_row_with, row_from_snowflake_session, + row_from_cursor, ) from tests_integration.testing_utils import ( assert_that_result_failed_with_message_containing, @@ -108,7 +109,7 @@ def test_nativeapp_deploy( @pytest.mark.integration def test_nativeapp_deploy_w_stage_subdir( - nativeapp_project_directory, + nativeapp_teardown, runner, snowflake_session, default_username, @@ -116,9 +117,13 @@ def test_nativeapp_deploy_w_stage_subdir( sanitize_deploy_output, snapshot, print_paths_as_posix, + setup_v2_project_w_subdir, ): - project_name = "stage_w_subdirs_pkg" - with nativeapp_project_directory("napp_stage_subdirs"): + ( + project_name, + _, + ) = setup_v2_project_w_subdir() # make this a fixture, don't pass temp_dir + with nativeapp_teardown(): result = runner.invoke_with_connection( split("app deploy --package-entity-id=pkg_v1") ) @@ -127,8 +132,9 @@ def test_nativeapp_deploy_w_stage_subdir( assert sanitize_deploy_output(result.output) == snapshot # package exist - package_name = f"{project_name}_{default_username}{resource_suffix}".upper() - app_name = f"{project_name}_{default_username}{resource_suffix}".upper() + package_name = f"{project_name}_pkg_{default_username}{resource_suffix}".upper() + app_name = f"{project_name}_app_v1_{default_username}{resource_suffix}".upper() + assert contains_row_with( row_from_snowflake_session( snowflake_session.execute_string( @@ -139,7 +145,7 @@ def test_nativeapp_deploy_w_stage_subdir( ) # manifest file exists - stage_name = "app_src.stage/v1" # as defined in native-apps-templates/basic + stage_name = "app_src.stage/v1" stage_files = runner.invoke_with_connection_json( ["stage", "list-files", f"{package_name}.{stage_name}"] ) @@ -274,17 +280,17 @@ def test_nativeapp_deploy_prune_w_stage_subdir( command, contains, not_contains, - nativeapp_project_directory, + nativeapp_teardown, runner, snapshot, print_paths_as_posix, default_username, resource_suffix, sanitize_deploy_output, + setup_v2_project_w_subdir, ): - test_project = "napp_stage_subdirs" - project_name = "stage_w_subdirs_pkg" - with nativeapp_project_directory(test_project): + project_name, _ = setup_v2_project_w_subdir() + with nativeapp_teardown(): result = runner.invoke_with_connection_json( ["app", "deploy", "--package-entity-id=pkg_v1"] ) @@ -299,7 +305,7 @@ def test_nativeapp_deploy_prune_w_stage_subdir( assert sanitize_deploy_output(result.output) == snapshot # verify the file does not exist on the stage - package_name = f"{project_name}_{default_username}{resource_suffix}".upper() + package_name = f"{project_name}_pkg_{default_username}{resource_suffix}".upper() stage_name = "app_src.stage/v1" # as defined in native-apps-templates/basic stage_files = runner.invoke_with_connection_json( ["stage", "list-files", f"{package_name}.{stage_name}"] @@ -355,16 +361,17 @@ def test_nativeapp_deploy_files( @pytest.mark.integration def test_nativeapp_deploy_files_w_stage_subdir( - nativeapp_project_directory, + nativeapp_teardown, runner, snapshot, print_paths_as_posix, default_username, resource_suffix, sanitize_deploy_output, + setup_v2_project_w_subdir, ): - project_name = "stage_w_subdirs_pkg" - with nativeapp_project_directory("napp_stage_subdirs"): + project_name, _ = setup_v2_project_w_subdir() + with nativeapp_teardown(): # sync only two specific files to stage touch("app/v2/file.txt") result = runner.invoke_with_connection( @@ -379,7 +386,7 @@ def test_nativeapp_deploy_files_w_stage_subdir( assert sanitize_deploy_output(result.output) == snapshot # manifest and script files exist, readme doesn't exist - package_name = f"{project_name}_{default_username}{resource_suffix}".upper() + package_name = f"{project_name}_pkg_{default_username}{resource_suffix}".upper() stage_name = "app_src.stage/v2" # as defined in native-apps-templates/basic stage_files = runner.invoke_with_connection_json( ["stage", "list-files", f"{package_name}.{stage_name}"] diff --git a/tests_integration/nativeapp/test_version.py b/tests_integration/nativeapp/test_version.py index 12bf881d40..fc272fb9f2 100644 --- a/tests_integration/nativeapp/test_version.py +++ b/tests_integration/nativeapp/test_version.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from shlex import split +from textwrap import dedent from typing import Any, Union import yaml @@ -102,13 +103,6 @@ def temporary_role(request, snowflake_session, resource_suffix): "ws version drop --entity-id=pkg", "napp_init_v2", ], - [ - "stage_w_subdirs", - "app version create --package-entity-id=pkg_v1", - "app version list --package-entity-id=pkg_v1", - "app version drop --package-entity-id=pkg_v1", - "napp_stage_subdirs", - ], ], ) def test_nativeapp_version_create_and_drop( @@ -155,6 +149,51 @@ def test_nativeapp_version_create_and_drop( assert len(actual.json) == 0 +@pytest.mark.integration +def test_nativeapp_version_create_and_drop_stage_subdir( + runner, + snowflake_session, + default_username, + resource_suffix, + nativeapp_teardown, + setup_v2_project_w_subdir, +): + project_name, _ = setup_v2_project_w_subdir() + drop_command = "app version drop --package-entity-id=pkg_v1" + list_command = "app version list --package-entity-id=pkg_v1" + create_command = "app version create --package-entity-id=pkg_v1" + with nativeapp_teardown(): + result_create = runner.invoke_with_connection_json( + [*split(create_command), "v1", "--force", "--skip-git-check"] + ) + assert result_create.exit_code == 0 + + # package exist + package_name = f"{project_name}_pkg_{default_username}{resource_suffix}".upper() + assert contains_row_with( + row_from_snowflake_session( + snowflake_session.execute_string( + f"show application packages like '{package_name}'", + ) + ), + dict(name=package_name), + ) + + # app package contains version v1 + expect = snowflake_session.execute_string( + f"show versions in application package {package_name}" + ) + actual = runner.invoke_with_connection_json(split(list_command)) + assert actual.json == row_from_snowflake_session(expect) + + result_drop = runner.invoke_with_connection_json( + [*split(drop_command), "v1", "--force"] + ) + assert result_drop.exit_code == 0 + actual = runner.invoke_with_connection_json(split(list_command)) + assert len(actual.json) == 0 + + # Tests upgrading an app from an existing loose files installation to versioned installation. @pytest.mark.integration @pytest.mark.parametrize( @@ -207,15 +246,16 @@ def test_nativeapp_upgrade_w_subdirs( snowflake_session, default_username, resource_suffix, - nativeapp_project_directory, + nativeapp_teardown, + setup_v2_project_w_subdir, ): - project_name = "stage_w_subdirs" + project_name, _ = setup_v2_project_w_subdir() create_command = ( "app version create v1 --package-entity-id=pkg_v1 --force --skip-git-check" ) list_command = "app version list --package-entity-id=pkg_v1" drop_command = "app version drop --package-entity-id=pkg_v1" - with nativeapp_project_directory("napp_stage_subdirs"): + with nativeapp_teardown(): runner.invoke_with_connection_json(["app", "run", "--app-entity-id=app_v1"]) runner.invoke_with_connection_json(split(create_command)) diff --git a/tests_integration/test_data/projects/napp_stage_subdirs/app/v1/README.md b/tests_integration/test_data/projects/napp_stage_subdirs/app/v1/README.md deleted file mode 100644 index 3107d92de2..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs/app/v1/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# README - -This is the <% ctx.pkg_v1.stage_subdirectory %> version of this package! diff --git a/tests_integration/test_data/projects/napp_stage_subdirs/app/v1/manifest.yml b/tests_integration/test_data/projects/napp_stage_subdirs/app/v1/manifest.yml deleted file mode 100644 index 3fa13420db..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs/app/v1/manifest.yml +++ /dev/null @@ -1,11 +0,0 @@ -# This is the v2 version of the napp_init_v1 project - -manifest_version: 1 - -version: - name: v1 - -artifacts: - setup_script: setup_script.sql - readme: README.md - extension_code: true diff --git a/tests_integration/test_data/projects/napp_stage_subdirs/app/v1/setup_script.sql b/tests_integration/test_data/projects/napp_stage_subdirs/app/v1/setup_script.sql deleted file mode 100644 index 18017841cc..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs/app/v1/setup_script.sql +++ /dev/null @@ -1,5 +0,0 @@ - -CREATE APPLICATION ROLE IF NOT EXISTS app_public; - -CREATE OR ALTER VERSIONED SCHEMA core; -GRANT USAGE ON SCHEMA core TO APPLICATION ROLE app_public; diff --git a/tests_integration/test_data/projects/napp_stage_subdirs/app/v2/README.md b/tests_integration/test_data/projects/napp_stage_subdirs/app/v2/README.md deleted file mode 100644 index b6162eae29..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs/app/v2/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# README - -This is the <% ctx.pkg_v2.stage_subdirectory %> version of this package! diff --git a/tests_integration/test_data/projects/napp_stage_subdirs/app/v2/manifest.yml b/tests_integration/test_data/projects/napp_stage_subdirs/app/v2/manifest.yml deleted file mode 100644 index ee1f6c99c5..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs/app/v2/manifest.yml +++ /dev/null @@ -1,11 +0,0 @@ -# This is the v2 version of the napp_init_v1 project - -manifest_version: 1 - -version: - name: v2 - -artifacts: - setup_script: setup_script.sql - readme: README.md - extension_code: true diff --git a/tests_integration/test_data/projects/napp_stage_subdirs/app/v2/setup_script.sql b/tests_integration/test_data/projects/napp_stage_subdirs/app/v2/setup_script.sql deleted file mode 100644 index 18017841cc..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs/app/v2/setup_script.sql +++ /dev/null @@ -1,5 +0,0 @@ - -CREATE APPLICATION ROLE IF NOT EXISTS app_public; - -CREATE OR ALTER VERSIONED SCHEMA core; -GRANT USAGE ON SCHEMA core TO APPLICATION ROLE app_public; diff --git a/tests_integration/test_data/projects/napp_stage_subdirs/snowflake.yml b/tests_integration/test_data/projects/napp_stage_subdirs/snowflake.yml deleted file mode 100644 index c93cab9704..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs/snowflake.yml +++ /dev/null @@ -1,31 +0,0 @@ -definition_version: 2 -entities: - pkg_v1: - type: application package - identifier: <% fn.concat_ids('stage_w_subdirs_pkg_', ctx.env.USER) %> - stage_subdirectory: v1 - manifest: "" - artifacts: - - src: app/v1/* - dest: ./ - - pkg_v2: - type: application package - identifier: <% fn.concat_ids('stage_w_subdirs_pkg_', ctx.env.USER) %> - stage_subdirectory: v2 - manifest: "" - artifacts: - - src: app/v2/* - dest: ./ - - app_v1: - type: application - from: - target: pkg_v1 - identifier: <% fn.concat_ids('stage_w_subdirs_app_v1_', ctx.env.USER) %> - - app_v2: - type: application - from: - target: pkg_v2 - identifier: <% fn.concat_ids('stage_w_subdirs_app_v2_', ctx.env.USER) %> diff --git a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/README.md b/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/README.md deleted file mode 100644 index 3107d92de2..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# README - -This is the <% ctx.pkg_v1.stage_subdirectory %> version of this package! diff --git a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/manifest.yml b/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/manifest.yml deleted file mode 100644 index 3fa13420db..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/manifest.yml +++ /dev/null @@ -1,11 +0,0 @@ -# This is the v2 version of the napp_init_v1 project - -manifest_version: 1 - -version: - name: v1 - -artifacts: - setup_script: setup_script.sql - readme: README.md - extension_code: true diff --git a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/module-echo-v1/echo-v1.py b/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/module-echo-v1/echo-v1.py deleted file mode 100644 index 335b485dd3..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/module-echo-v1/echo-v1.py +++ /dev/null @@ -1,13 +0,0 @@ -# This is where you can create python functions, which can further -# be used to create Snowpark UDFs and Stored Procedures in your setup_script.sql file. - -from snowflake.snowpark.functions import udf - -# UDF example: -# decorated example -@udf( - name="echo_fn", - native_app_params={"schema": "core", "application_roles": ["app_public"]}, -) -def echo_fn(data: str) -> str: - return "echo_fn, v1 implementation: " + data diff --git a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/setup_script.sql b/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/setup_script.sql deleted file mode 100644 index 18017841cc..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v1/setup_script.sql +++ /dev/null @@ -1,5 +0,0 @@ - -CREATE APPLICATION ROLE IF NOT EXISTS app_public; - -CREATE OR ALTER VERSIONED SCHEMA core; -GRANT USAGE ON SCHEMA core TO APPLICATION ROLE app_public; diff --git a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/README.md b/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/README.md deleted file mode 100644 index b6162eae29..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# README - -This is the <% ctx.pkg_v2.stage_subdirectory %> version of this package! diff --git a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/manifest.yml b/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/manifest.yml deleted file mode 100644 index ee1f6c99c5..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/manifest.yml +++ /dev/null @@ -1,11 +0,0 @@ -# This is the v2 version of the napp_init_v1 project - -manifest_version: 1 - -version: - name: v2 - -artifacts: - setup_script: setup_script.sql - readme: README.md - extension_code: true diff --git a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/module-echo-v2/echo-v2.py b/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/module-echo-v2/echo-v2.py deleted file mode 100644 index 6ae32cf48a..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/module-echo-v2/echo-v2.py +++ /dev/null @@ -1,13 +0,0 @@ -# This is where you can create python functions, which can further -# be used to create Snowpark UDFs and Stored Procedures in your setup_script.sql file. - -from snowflake.snowpark.functions import udf - -# UDF example: -# decorated example -@udf( - name="echo_fn", - native_app_params={"schema": "core", "application_roles": ["app_public"]}, -) -def echo_fn(data: str) -> str: - return "echo_fn, v2 implementation: " + data diff --git a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/setup_script.sql b/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/setup_script.sql deleted file mode 100644 index 18017841cc..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/app/v2/setup_script.sql +++ /dev/null @@ -1,5 +0,0 @@ - -CREATE APPLICATION ROLE IF NOT EXISTS app_public; - -CREATE OR ALTER VERSIONED SCHEMA core; -GRANT USAGE ON SCHEMA core TO APPLICATION ROLE app_public; diff --git a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/snowflake.yml b/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/snowflake.yml deleted file mode 100644 index 1f18f52062..0000000000 --- a/tests_integration/test_data/projects/napp_stage_subdirs_w_snowpark/snowflake.yml +++ /dev/null @@ -1,38 +0,0 @@ -definition_version: 2 -entities: - pkg_v1: - type: application package - identifier: <% fn.concat_ids('stage_w_subdirs_pkg', ctx.env.suffix) %> - stage_subdirectory: v1 - manifest: "" - artifacts: - - src: app/v1/* - dest: ./ - processors: - - snowpark - - pkg_v2: - type: application package - identifier: <% fn.concat_ids('stage_w_subdirs_pkg', ctx.env.suffix) %> - stage_subdirectory: v2 - manifest: "" - artifacts: - - src: app/v2/* - dest: ./ - processors: - - snowpark - - app_v1: - type: application - from: - target: pkg_v1 - identifier: <% fn.concat_ids('stage_w_subdirs_app_v1', ctx.env.suffix) %> - - app_v2: - type: application - from: - target: pkg_v2 - identifier: <% fn.concat_ids('stage_w_subdirs_app_v2', ctx.env.suffix) %> - -env: - suffix: <% fn.concat_ids('_', fn.sanitize_id(fn.get_username('unknown_user')) | lower) %> diff --git a/tests_integration/testing_utils/project_fixtures.py b/tests_integration/testing_utils/project_fixtures.py new file mode 100644 index 0000000000..16bf5e0653 --- /dev/null +++ b/tests_integration/testing_utils/project_fixtures.py @@ -0,0 +1,137 @@ +from textwrap import dedent + +import pytest + +from tests.nativeapp.factories import ( + ProjectV2Factory, + ApplicationPackageEntityModelFactory, + ApplicationEntityModelFactory, +) + + +MANIFEST_BASIC = dedent( + """\ + manifest_version: 1 + + version: + name: dev + + artifacts: + setup_script: setup_script.sql + readme: README.md + extension_code: true + """ +) + +PYTHON_W_SNOWPARK = dedent( + """\ + from snowflake.snowpark.functions import udf + @udf( + name="echo_fn", + native_app_params={"schema": "core", "application_roles": ["app_public"]}, + ) + def echo_fn(data: str) -> str: + return "echo_fn: " + data + """ +) + + +@pytest.fixture +def setup_v2_project_w_subdir(temp_dir): + def wrapper(): + readme_v1 = ( + "This is the <% ctx.pkg_v1.stage_subdirectory %> version of this package!" + ) + readme_v2 = ( + "This is the <% ctx.pkg_v2.stage_subdirectory %> version of this package!" + ) + project_name = "stage_w_subdirs" + ProjectV2Factory( + pdf__entities=dict( + pkg_v1=ApplicationPackageEntityModelFactory( + identifier=f"<% fn.concat_ids('{project_name}_pkg_', ctx.env.USER) %>", + manifest="", + artifacts=[{"src": "app/v1/*", "dest": "./"}], + stage_subdirectory="v1", + ), + app_v1=ApplicationEntityModelFactory( + fromm__target="pkg_v1", + identifier=f"<% fn.concat_ids('{project_name}_app_v1_', ctx.env.USER) %>", + ), + pkg_v2=ApplicationPackageEntityModelFactory( + identifier=f"<% fn.concat_ids('{project_name}_pkg_', ctx.env.USER) %>", + manifest="", + artifacts=[{"src": "app/v2/*", "dest": "./"}], + stage_subdirectory="v2", + ), + app_v2=ApplicationEntityModelFactory( + fromm__target="pkg_v2", + identifier=f"<% fn.concat_ids('{project_name}_app_v2_', ctx.env.USER) %>", + ), + ), + files={ + "app/v1/manifest.yml": MANIFEST_BASIC, + "app/v1/README.md": readme_v1, + "app/v1/setup_script.sql": "SELECT 1;", + "app/v2/manifest.yml": MANIFEST_BASIC, + "app/v2/README.md": readme_v2, + "app/v2/setup_script.sql": "SELECT 1;", + }, + ) + return project_name, temp_dir + + return wrapper + + +@pytest.fixture +def setup_v2_project_w_subdir_w_snowpark(temp_dir): + def wrapper(): + setup_script = dedent( + """\ + CREATE APPLICATION ROLE IF NOT EXISTS app_public; + CREATE OR ALTER VERSIONED SCHEMA core; + GRANT USAGE ON SCHEMA core TO APPLICATION ROLE app_public; + """ + ) + project_name = "stage_w_subdirs" + ProjectV2Factory( + pdf__entities=dict( + pkg_v1=ApplicationPackageEntityModelFactory( + identifier=f"<% fn.concat_ids('{project_name}_pkg_', ctx.env.USER) %>", + manifest="", + artifacts=[ + {"src": "app/v1/*", "dest": "./", "processors": ["snowpark"]} + ], + stage_subdirectory="v1", + ), + app_v1=ApplicationEntityModelFactory( + fromm__target="pkg_v1", + identifier=f"<% fn.concat_ids('{project_name}_app_v1_', ctx.env.USER) %>", + ), + pkg_v2=ApplicationPackageEntityModelFactory( + identifier=f"<% fn.concat_ids('{project_name}_pkg_', ctx.env.USER) %>", + manifest="", + artifacts=[ + {"src": "app/v2/*", "dest": "./", "processors": ["snowpark"]} + ], + stage_subdirectory="v2", + ), + app_v2=ApplicationEntityModelFactory( + fromm__target="pkg_v2", + identifier=f"<% fn.concat_ids('{project_name}_app_v2_', ctx.env.USER) %>", + ), + ), + files={ + "app/v1/manifest.yml": MANIFEST_BASIC, + "app/v1/README.md": "\n", + "app/v1/setup_script.sql": setup_script, + "app/v1/module-echo-v1/echo-v1.py": PYTHON_W_SNOWPARK, + "app/v2/manifest.yml": MANIFEST_BASIC, + "app/v2/README.md": "\n", + "app/v2/setup_script.sql": setup_script, + "app/v2/module-echo-v2/echo-v2.py": PYTHON_W_SNOWPARK, + }, + ) + return project_name, temp_dir + + return wrapper