datasecops-cli 0.5.5__tar.gz → 0.5.7__tar.gz
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.
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/CHANGELOG.md +12 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/PKG-INFO +1 -1
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/pyproject.toml +1 -1
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/main.py +1 -1
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/menus/configuration.py +1 -1
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/menus/downloads.py +1 -1
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/dbt_runner.py +24 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/download_service.py +8 -3
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/utilities/mcp.py +9 -1
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/.github/workflows/auto-tag.yml +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/.github/workflows/publish-cli.yml +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/.github/workflows/test.yml +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/.gitignore +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/DEVELOPMENT.md +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/LICENSE +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/README.md +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/docs/getting-started.md +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/docs/git-operations.md +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/docs/legacy.md +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/docs/legacy_plan_of_action.md +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/docs/mcp-server.md +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/mcp-servers.json +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/setup.ps1 +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/setup.sh +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/__init__.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/config.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/menus/__init__.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/menus/development.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/menus/git_operations.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/models/__init__.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/models/git_helpers.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/models/project_config.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/__init__.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/bootstrap_service.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/dbt_project_generator.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/directory_scaffolder.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/git_service.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/linting_service.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/skill_service.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/snowflake_service.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/upstream_service.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/utilities/__init__.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/utilities/display.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/utilities/file_utils.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/utilities/yaml_utils.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_mcp/__init__.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_mcp/__main__.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_mcp/connection.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_mcp/server.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/tests/__init__.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/tests/test_config.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/tests/test_file_utils.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/tests/test_main.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/tests/test_models.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/tests/test_version.py +0 -0
- {datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/tests/test_yaml_utils.py +0 -0
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the DataSecOps CLI are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.5.7] - 2026-06-22
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **dbt commands scoped to current project** — `run`, `compile`, `build`, and `test` now automatically pass `--select <project_name>` (read from `dbt_project.yml`) when no explicit selector is provided, ensuring packages are not executed alongside project models.
|
|
10
|
+
|
|
11
|
+
## [0.5.6] - 2026-06-19
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **AzureDevOps pipeline platform filter mismatch** — the platform comparison in `download_pipelines` now normalizes by stripping spaces (e.g. `"Azure DevOps"` → `"azuredevops"`) so pipelines returned by the stored procedure are no longer silently skipped when the caller passes `"azuredevops"`.
|
|
16
|
+
|
|
5
17
|
## [0.5.5] - 2026-06-19
|
|
6
18
|
|
|
7
19
|
### Fixed
|
|
@@ -307,7 +307,7 @@ def _run_setup(project_dir: Path):
|
|
|
307
307
|
|
|
308
308
|
info_line("")
|
|
309
309
|
info_line("Which AI tool are you configuring?")
|
|
310
|
-
tool_options = ["
|
|
310
|
+
tool_options = ["Cortex Code", "Cursor", "Claude Code", "VS Code (Copilot)"]
|
|
311
311
|
tool_options.append("Skip")
|
|
312
312
|
tool_choice = select_from_list(tool_options, "tool", add_back=False)
|
|
313
313
|
|
|
@@ -150,7 +150,7 @@ class ConfigurationMenu:
|
|
|
150
150
|
# Select target tool
|
|
151
151
|
info_line("")
|
|
152
152
|
info_line("Which AI tool are you configuring?")
|
|
153
|
-
tool_options = ["
|
|
153
|
+
tool_options = ["Cortex Code", "Cursor", "Claude Code", "VS Code (Copilot)"]
|
|
154
154
|
tool_choice = select_from_list(tool_options, "tool", add_back=False)
|
|
155
155
|
|
|
156
156
|
if tool_choice == "Cortex Code":
|
|
@@ -134,7 +134,7 @@ class DownloadsMenu:
|
|
|
134
134
|
# Select target tool
|
|
135
135
|
info_line("")
|
|
136
136
|
info_line("Which AI tool are you configuring?")
|
|
137
|
-
tool_options = ["
|
|
137
|
+
tool_options = ["Cortex Code", "Cursor", "Claude Code", "VS Code (Copilot)"]
|
|
138
138
|
tool_choice = select_from_list(tool_options, "tool", add_back=False)
|
|
139
139
|
|
|
140
140
|
if tool_choice == "Cortex Code":
|
|
@@ -7,6 +7,8 @@ import webbrowser
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import Optional
|
|
9
9
|
|
|
10
|
+
import yaml
|
|
11
|
+
|
|
10
12
|
from datasecops_cli.utilities.display import info_line, error_line, success_line, warning_line
|
|
11
13
|
|
|
12
14
|
|
|
@@ -19,6 +21,20 @@ class DbtRunner:
|
|
|
19
21
|
self.profiles_dir = profiles_dir
|
|
20
22
|
self.target = target
|
|
21
23
|
self.engine = engine # "dbtf" or "dbt"
|
|
24
|
+
self._project_name: Optional[str] = None
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def project_name(self) -> Optional[str]:
|
|
28
|
+
"""Read the project name from dbt_project.yml (cached)."""
|
|
29
|
+
if self._project_name is None:
|
|
30
|
+
dbt_project_file = self.project_dir / "dbt_project.yml"
|
|
31
|
+
if dbt_project_file.exists():
|
|
32
|
+
with open(dbt_project_file) as f:
|
|
33
|
+
data = yaml.safe_load(f) or {}
|
|
34
|
+
self._project_name = data.get("name", "")
|
|
35
|
+
else:
|
|
36
|
+
self._project_name = ""
|
|
37
|
+
return self._project_name or None
|
|
22
38
|
|
|
23
39
|
def _default_args(self) -> list[str]:
|
|
24
40
|
return [
|
|
@@ -43,6 +59,8 @@ class DbtRunner:
|
|
|
43
59
|
args += ["--select", "state:modified+", "--state", str(self.project_dir)]
|
|
44
60
|
elif select:
|
|
45
61
|
args += ["--select", select]
|
|
62
|
+
elif self.project_name:
|
|
63
|
+
args += ["--select", self.project_name]
|
|
46
64
|
if exclude:
|
|
47
65
|
args += ["--exclude", exclude]
|
|
48
66
|
if full_refresh:
|
|
@@ -55,6 +73,8 @@ class DbtRunner:
|
|
|
55
73
|
args = [f"--target={self.target}"]
|
|
56
74
|
if select:
|
|
57
75
|
args += ["--select", select]
|
|
76
|
+
elif self.project_name:
|
|
77
|
+
args += ["--select", self.project_name]
|
|
58
78
|
if exclude:
|
|
59
79
|
args += ["--exclude", exclude]
|
|
60
80
|
result = self._run_command("build", args)
|
|
@@ -65,12 +85,16 @@ class DbtRunner:
|
|
|
65
85
|
args = [f"--target={self.target}"]
|
|
66
86
|
if select:
|
|
67
87
|
args += ["--select", select]
|
|
88
|
+
elif self.project_name:
|
|
89
|
+
args += ["--select", self.project_name]
|
|
68
90
|
return self._run_command("test", args)
|
|
69
91
|
|
|
70
92
|
def compile(self, select: str = None) -> subprocess.CompletedProcess:
|
|
71
93
|
args = [f"--target={self.target}"]
|
|
72
94
|
if select:
|
|
73
95
|
args += ["--select", select]
|
|
96
|
+
elif self.project_name:
|
|
97
|
+
args += ["--select", self.project_name]
|
|
74
98
|
return self._run_command("compile", args)
|
|
75
99
|
|
|
76
100
|
def deps(self) -> subprocess.CompletedProcess:
|
{datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/download_service.py
RENAMED
|
@@ -129,17 +129,22 @@ class DownloadService:
|
|
|
129
129
|
error_line("No pipeline configuration found in native app")
|
|
130
130
|
return False
|
|
131
131
|
|
|
132
|
+
def _normalize_platform(p: str) -> str:
|
|
133
|
+
return p.lower().replace(" ", "")
|
|
134
|
+
|
|
135
|
+
normalized = _normalize_platform(platform)
|
|
132
136
|
pipelines = raw.get("pipelines", [])
|
|
133
137
|
count = 0
|
|
134
138
|
for pipe in pipelines:
|
|
135
|
-
|
|
139
|
+
pipe_platform = _normalize_platform(pipe.get("platform", "github"))
|
|
140
|
+
if pipe_platform != normalized or not pipe.get("enabled", True):
|
|
136
141
|
continue
|
|
137
142
|
filename = pipe.get("filename", "")
|
|
138
143
|
yaml_content = pipe.get("yaml_content", "")
|
|
139
144
|
if filename and yaml_content:
|
|
140
|
-
if
|
|
145
|
+
if normalized == "github":
|
|
141
146
|
dest = self.project_dir / ".github" / "workflows" / filename
|
|
142
|
-
elif
|
|
147
|
+
elif normalized == "azuredevops":
|
|
143
148
|
dest = self.project_dir / ".azuredevops" / "workflows" / filename
|
|
144
149
|
else:
|
|
145
150
|
dest = self.project_dir / filename
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""MCP server configuration utilities."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
import shutil
|
|
4
5
|
import sys
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
|
|
@@ -9,7 +10,14 @@ from datasecops_cli.utilities.file_utils import ensure_dir, write_file
|
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def _resolve_mcp_command() -> str:
|
|
12
|
-
"""Resolve the
|
|
13
|
+
"""Resolve the path to the datasecops-mcp executable.
|
|
14
|
+
|
|
15
|
+
Checks shutil.which first (covers global/pipx installs), then falls back
|
|
16
|
+
to the project .venv path.
|
|
17
|
+
"""
|
|
18
|
+
found = shutil.which("datasecops-mcp")
|
|
19
|
+
if found:
|
|
20
|
+
return found
|
|
13
21
|
venv_bin = "Scripts" if sys.platform == "win32" else "bin"
|
|
14
22
|
return f".venv/{venv_bin}/datasecops-mcp"
|
|
15
23
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/bootstrap_service.py
RENAMED
|
File without changes
|
{datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/dbt_project_generator.py
RENAMED
|
File without changes
|
{datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/directory_scaffolder.py
RENAMED
|
File without changes
|
|
File without changes
|
{datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/linting_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/snowflake_service.py
RENAMED
|
File without changes
|
{datasecops_cli-0.5.5 → datasecops_cli-0.5.7}/src/datasecops_cli/services/upstream_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|