Skip to content

Commit 3634d4b

Browse files
feat: [SNOW-1890085] add dbt command group; add dbt list command
1 parent 960386b commit 3634d4b

File tree

8 files changed

+158
-1
lines changed

8 files changed

+158
-1
lines changed

src/snowflake/cli/_app/commands_registration/builtin_plugins.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from snowflake.cli._plugins.connection import plugin_spec as connection_plugin_spec
1616
from snowflake.cli._plugins.cortex import plugin_spec as cortex_plugin_spec
17+
from snowflake.cli._plugins.dbt import plugin_spec as dbt_plugin_spec
1718
from snowflake.cli._plugins.git import plugin_spec as git_plugin_spec
1819
from snowflake.cli._plugins.helpers import plugin_spec as migrate_plugin_spec
1920
from snowflake.cli._plugins.init import plugin_spec as init_plugin_spec
@@ -45,6 +46,7 @@ def get_builtin_plugin_name_to_plugin_spec():
4546
"cortex": cortex_plugin_spec,
4647
"init": init_plugin_spec,
4748
"workspace": workspace_plugin_spec,
49+
"dbt": dbt_plugin_spec,
4850
}
4951

5052
return plugin_specs
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (c) 2025 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.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright (c) 2025 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+
19+
from snowflake.cli._plugins.dbt.manager import DBTManager
20+
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
21+
from snowflake.cli.api.output.types import CommandResult, QueryResult
22+
23+
app = SnowTyperFactory(
24+
name="dbt",
25+
help="Manages dbt on Snowflake projects",
26+
is_hidden=lambda: True,
27+
)
28+
log = logging.getLogger(__name__)
29+
30+
31+
@app.command(
32+
"list",
33+
requires_connection=True,
34+
)
35+
def list_dbts(
36+
**options,
37+
) -> CommandResult:
38+
"""
39+
List all dbt projects on Snowflake.
40+
"""
41+
return QueryResult(DBTManager().list())
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) 2025 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 snowflake.cli.api.sql_execution import SqlExecutionMixin
18+
from snowflake.connector.cursor import SnowflakeCursor
19+
20+
21+
class DBTManager(SqlExecutionMixin):
22+
def list(self) -> SnowflakeCursor: # noqa: A003
23+
query = f"show dbt"
24+
return self.execute_query(query)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright (c) 2025 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._plugins.dbt import commands
16+
from snowflake.cli.api.plugins.command import (
17+
SNOWCLI_ROOT_COMMAND_PATH,
18+
CommandSpec,
19+
CommandType,
20+
plugin_hook_impl,
21+
)
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+
)

tests/dbt/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (c) 2025 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.

tests/dbt/test_dbt_commands.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright (c) 2025 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 unittest import mock
16+
17+
import pytest
18+
19+
20+
@pytest.fixture
21+
def mock_connect(mock_ctx):
22+
with mock.patch("snowflake.connector.connect") as _fixture:
23+
ctx = mock_ctx()
24+
_fixture.return_value = ctx
25+
_fixture.mocked_ctx = _fixture.return_value
26+
yield _fixture
27+
28+
29+
def test_list_dbt_objects(mock_connect, runner):
30+
31+
result = runner.invoke(["dbt", "list"])
32+
33+
assert result.exit_code == 0, result.output
34+
assert mock_connect.mocked_ctx.get_query() == "show dbt"

tests/test_help_messages.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def iter_through_all_commands(command_groups_only: bool = False):
3434
Generator iterating through all commands.
3535
Paths are yielded as List[str]
3636
"""
37-
ignore_plugins = ["helpers", "cortex", "workspace"]
37+
ignore_plugins = ["helpers", "cortex", "workspace", "dbt"]
3838

3939
no_command: List[str] = []
4040
yield no_command

0 commit comments

Comments
 (0)