Skip to content

Commit

Permalink
refactoring fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-gbloom committed Mar 20, 2024
1 parent 5fdd54c commit f3ee944
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/snowflake/cli/plugins/nativeapp/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,6 @@ def app_deploy(
)

manager.build_bundle()
manager.process()
manager.deploy()

return MessageResult(f"Deployed successfully.")
90 changes: 90 additions & 0 deletions src/snowflake/cli/plugins/nativeapp/run_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
from snowflake.cli.api.exceptions import SnowflakeSQLExecutionError
from snowflake.cli.api.project.schemas.native_app.native_app import NativeApp
from snowflake.cli.plugins.nativeapp.constants import (
ALLOWED_SPECIAL_COMMENTS,
COMMENT_COL,
LOOSE_FILES_MAGIC_VERSION,
SPECIAL_COMMENT,
VERSION_COL,
)
from snowflake.cli.plugins.nativeapp.exceptions import (
ApplicationAlreadyExistsError,
ApplicationPackageDoesNotExistError,
)
from snowflake.cli.plugins.nativeapp.manager import (
Expand All @@ -21,6 +25,8 @@
generic_sql_error_handler,
)
from snowflake.cli.plugins.nativeapp.policy import PolicyBase
from snowflake.cli.plugins.object.stage.diff import DiffResult
from snowflake.cli.plugins.object.stage.manager import StageManager
from snowflake.connector import ProgrammingError
from snowflake.connector.cursor import SnowflakeCursor

Expand All @@ -31,6 +37,90 @@ class NativeAppRunProcessor(NativeAppManager, NativeAppCommandProcessor):
def __init__(self, project_definition: NativeApp, project_root: Path):
super().__init__(project_definition, project_root)

def _create_dev_app(self, diff: DiffResult) -> None:
"""
(Re-)creates the application object with our up-to-date stage.
"""
with self.use_role(self.app_role):

# 1. Need to use a warehouse to create an application object
try:
if self.application_warehouse:
self._execute_query(f"use warehouse {self.application_warehouse}")
except ProgrammingError as err:
generic_sql_error_handler(
err=err, role=self.app_role, warehouse=self.application_warehouse
)

# 2. Check for an existing application object by the same name
show_app_row = self.get_existing_app_info()

# 3. If existing application object is found, perform a few validations and upgrade the application object.
if show_app_row:

# Check if not created by Snowflake CLI or not created using "files on a named stage" / stage dev mode.
if show_app_row[COMMENT_COL] not in ALLOWED_SPECIAL_COMMENTS or (
show_app_row[VERSION_COL] != LOOSE_FILES_MAGIC_VERSION
):
raise ApplicationAlreadyExistsError(self.app_name)

# Check for the right owner
ensure_correct_owner(
row=show_app_row, role=self.app_role, obj_name=self.app_name
)

# If all the above checks are in order, proceed to upgrade
try:
if diff.has_changes():
cc.step(
f"Upgrading existing application object {self.app_name}."
)
self._execute_query(
f"alter application {self.app_name} upgrade using @{self.stage_fqn}"
)

# ensure debug_mode is up-to-date
self._execute_query(
f"alter application {self.app_name} set debug_mode = {self.debug_mode}"
)

return

except ProgrammingError as err:
generic_sql_error_handler(err)

# 4. If no existing application object is found, create an application object using "files on a named stage" / stage dev mode.
cc.step(f"Creating new application {self.app_name} in account.")

if self.app_role != self.package_role:
with self.use_role(new_role=self.package_role):
self._execute_queries(
dedent(
f"""\
grant install, develop on application package {self.package_name} to role {self.app_role};
grant usage on schema {self.package_name}.{self.stage_schema} to role {self.app_role};
grant read on stage {self.stage_fqn} to role {self.app_role};
"""
)
)

stage_name = StageManager.quote_stage_name(self.stage_fqn)

try:
self._execute_query(
dedent(
f"""\
create application {self.app_name}
from application package {self.package_name}
using {stage_name}
debug_mode = {self.debug_mode}
comment = {SPECIAL_COMMENT}
"""
)
)
except ProgrammingError as err:
generic_sql_error_handler(err)

def get_all_existing_versions(self) -> SnowflakeCursor:
"""
Get all existing versions, if defined, for an application package.
Expand Down
7 changes: 3 additions & 4 deletions tests/nativeapp/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
mock_get_app_pkg_distribution_in_sf,
)
from tests.nativeapp.utils import (
NATIVEAPP_MANAGER,
NATIVEAPP_MANAGER_EXECUTE,
NATIVEAPP_MANAGER_GET_EXISTING_APP_PKG_INFO,
NATIVEAPP_MANAGER_IS_APP_PKG_DISTRIBUTION_SAME,
Expand Down Expand Up @@ -592,7 +591,7 @@ def test_create_app_pkg_incorrect_owner(mock_get_existing_app_pkg_info, temp_dir
@mock.patch(NATIVEAPP_MANAGER_GET_EXISTING_APP_PKG_INFO)
@mock_get_app_pkg_distribution_in_sf()
@mock.patch(NATIVEAPP_MANAGER_IS_APP_PKG_DISTRIBUTION_SAME)
@mock.patch(f"{NATIVEAPP_MANAGER}.cc.warning")
@mock.patch(f"{NATIVEAPP_MODULE}.cc.warning")
@pytest.mark.parametrize(
"is_pkg_distribution_same",
[False, True],
Expand Down Expand Up @@ -633,7 +632,7 @@ def test_create_app_pkg_external_distribution(
@mock.patch(NATIVEAPP_MANAGER_GET_EXISTING_APP_PKG_INFO)
@mock_get_app_pkg_distribution_in_sf()
@mock.patch(NATIVEAPP_MANAGER_IS_APP_PKG_DISTRIBUTION_SAME)
@mock.patch(f"{NATIVEAPP_MANAGER}.cc.warning")
@mock.patch(f"{NATIVEAPP_MODULE}.cc.warning")
@pytest.mark.parametrize(
"is_pkg_distribution_same, special_comment",
[
Expand Down Expand Up @@ -680,7 +679,7 @@ def test_create_app_pkg_internal_distribution_special_comment(
@mock.patch(NATIVEAPP_MANAGER_GET_EXISTING_APP_PKG_INFO)
@mock_get_app_pkg_distribution_in_sf()
@mock.patch(NATIVEAPP_MANAGER_IS_APP_PKG_DISTRIBUTION_SAME)
@mock.patch(f"{NATIVEAPP_MANAGER}.cc.warning")
@mock.patch(f"{NATIVEAPP_MODULE}.cc.warning")
@pytest.mark.parametrize(
"is_pkg_distribution_same",
[False, True],
Expand Down

0 comments on commit f3ee944

Please sign in to comment.