viur-cli 2.3.2__tar.gz → 3.0.0__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.
Files changed (32) hide show
  1. {viur_cli-2.3.2/src/viur_cli.egg-info → viur_cli-3.0.0}/PKG-INFO +2 -2
  2. {viur_cli-2.3.2 → viur_cli-3.0.0}/pyproject.toml +6 -11
  3. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/__init__.py +0 -1
  4. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/cli.py +9 -9
  5. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/conf.py +2 -2
  6. viur_cli-3.0.0/src/viur_cli/local.py +419 -0
  7. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/scriptor/cli.py +9 -12
  8. viur_cli-3.0.0/src/viur_cli/update.py +213 -0
  9. viur_cli-3.0.0/src/viur_cli/version.py +2 -0
  10. {viur_cli-2.3.2 → viur_cli-3.0.0/src/viur_cli.egg-info}/PKG-INFO +2 -2
  11. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli.egg-info/SOURCES.txt +0 -2
  12. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli.egg-info/requires.txt +1 -1
  13. viur_cli-2.3.2/src/viur_cli/local.py +0 -227
  14. viur_cli-2.3.2/src/viur_cli/scriptor/login.py +0 -59
  15. viur_cli-2.3.2/src/viur_cli/tool.py +0 -80
  16. viur_cli-2.3.2/src/viur_cli/update.py +0 -133
  17. viur_cli-2.3.2/src/viur_cli/version.py +0 -2
  18. {viur_cli-2.3.2 → viur_cli-3.0.0}/LICENSE +0 -0
  19. {viur_cli-2.3.2 → viur_cli-3.0.0}/README.md +0 -0
  20. {viur_cli-2.3.2 → viur_cli-3.0.0}/setup.cfg +0 -0
  21. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/build.py +0 -0
  22. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/cloud.py +0 -0
  23. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/deprecated.py +0 -0
  24. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/package.py +0 -0
  25. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/scriptor/__init__.py +0 -0
  26. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/scripts/__init__.py +0 -0
  27. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/scripts/get_pyodide.py +0 -0
  28. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/setup.py +0 -0
  29. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli/utils.py +0 -0
  30. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli.egg-info/dependency_links.txt +0 -0
  31. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli.egg-info/entry_points.txt +0 -0
  32. {viur_cli-2.3.2 → viur_cli-3.0.0}/src/viur_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: viur-cli
3
- Version: 2.3.2
3
+ Version: 3.0.0
4
4
  Summary: Command-line interface for ViUR application maintenance.
5
5
  Author-email: "Andreas H. Kelch" <ak@mausbrand.de>
6
6
  License-Expression: MIT
@@ -17,7 +17,7 @@ Requires-Dist: pipfile-requirements~=0.3
17
17
  Requires-Dist: requests~=2.0
18
18
  Requires-Dist: semver~=3.0
19
19
  Requires-Dist: watchdog~=6.0
20
- Requires-Dist: safety~=3.5
20
+ Requires-Dist: pip-audit~=2.7
21
21
  Requires-Dist: viur-scriptor-api~=1.0
22
22
  Dynamic: license-file
23
23
 
@@ -1,16 +1,11 @@
1
1
  [build-system]
2
- requires = [
3
- "setuptools>=65",
4
- "wheel"
5
- ]
2
+ requires = ["setuptools>=65", "wheel"]
6
3
  build-backend = "setuptools.build_meta"
7
4
 
8
5
  [project]
9
6
  name = "viur-cli"
10
7
  dynamic = ["version"]
11
- authors = [
12
- {name = "Andreas H. Kelch", email = "ak@mausbrand.de"}
13
- ]
8
+ authors = [{ name = "Andreas H. Kelch", email = "ak@mausbrand.de" }]
14
9
  description = "Command-line interface for ViUR application maintenance."
15
10
  readme = "README.md"
16
11
  requires-python = ">=3.11"
@@ -26,7 +21,7 @@ dependencies = [
26
21
  "requests~=2.0",
27
22
  "semver~=3.0",
28
23
  "watchdog~=6.0",
29
- "safety~=3.5",
24
+ "pip-audit~=2.7",
30
25
  "viur-scriptor-api~=1.0",
31
26
  ]
32
27
 
@@ -39,8 +34,8 @@ viur = "viur_cli:cli"
39
34
  get-pyodide = "viur_cli.scripts.get_pyodide:main"
40
35
 
41
36
  [tool.setuptools]
42
- package-dir = {"" = "src"}
43
- packages = {find = {where = ["src"]}}
37
+ package-dir = { "" = "src" }
38
+ packages = { find = { where = ["src"] } }
44
39
 
45
40
  [tool.setuptools.dynamic]
46
- version = {attr = "viur_cli.version.__version__"}
41
+ version = { attr = "viur_cli.version.__version__" }
@@ -5,7 +5,6 @@ from .local import *
5
5
  from .build import *
6
6
  from .setup import *
7
7
  from .version import *
8
- from .tool import *
9
8
  from .update import *
10
9
  from .cloud import *
11
10
  from .deprecated import *
@@ -3,7 +3,7 @@ import subprocess
3
3
  import click
4
4
  from .conf import *
5
5
  from .version import __version__
6
- from .version import MINIMAL_PIPENV
6
+ from .version import MINIMAL_UV
7
7
  import semver
8
8
  import pprint
9
9
  import os
@@ -29,18 +29,18 @@ def cli(ctx):
29
29
  """
30
30
 
31
31
  # Get the systems pipenv Version Number
32
- pipenv_version = subprocess.check_output(['pipenv', '--version']).decode("utf-8")
32
+ uv_version = subprocess.check_output(['uv', 'self', 'version']).decode("utf-8")
33
33
  version_pattern = r'\b(\d+\.\d+\.\d+)\b'
34
- match = re.search(version_pattern, pipenv_version)
35
- sys_pipenv = match.group(1)
34
+ match = re.search(version_pattern, uv_version)
35
+ sys_uv = match.group(1)
36
36
 
37
37
  # sys kleiner min
38
- if semver.compare(sys_pipenv, MINIMAL_PIPENV) < 0:
38
+ if semver.compare(sys_uv, MINIMAL_UV) < 0:
39
39
  echo_warning(
40
- f"Your pipenv Version does not match the recommended pipenv version. \n"
41
- f"This mismatch may cause Errors, please consider updating your Systems pipenv version \n"
42
- f"Your Version: {sys_pipenv}\n"
43
- f"Recommended Version: {MINIMAL_PIPENV}"
40
+ f"Your uv Version does not match the recommended uv version. \n"
41
+ f"This mismatch may cause Errors, please consider updating your Systems uv version \n"
42
+ f"Your Version: {sys_uv}\n"
43
+ f"Recommended Version: {MINIMAL_UV}"
44
44
  )
45
45
 
46
46
 
@@ -208,11 +208,11 @@ class ProjectConfig(Config):
208
208
 
209
209
 
210
210
  def print_changelog_from_github(user, repo, last_version):
211
- version_url = f"https://raw.githubusercontent.com/{user}/{repo}/main/CHANGELOG.md"
211
+ version_url = f"https://raw.githubusercontent.com/{user}/{repo}/refs/heads/main/CHANGELOG.md"
212
212
  response = requests.get(version_url)
213
213
 
214
214
  if last_version is not None:
215
- version_url1 = f"https://raw.githubusercontent.com/{user}/{repo}/{last_version}/CHANGELOG.md"
215
+ version_url1 = f"https://raw.githubusercontent.com/{user}/{repo}/refs/tags/v{last_version}/CHANGELOG.md"
216
216
  echo_warning(version_url1)
217
217
  response1 = requests.get(version_url1)
218
218
 
@@ -0,0 +1,419 @@
1
+ import json
2
+
3
+ import click
4
+ import shutil
5
+ import subprocess
6
+ from datetime import datetime
7
+
8
+ from viur_cli import echo_warning
9
+ from .conf import config
10
+ from . import cli, echo_error, utils, echo_fatal
11
+
12
+
13
+ def get_user_info():
14
+ gcloud_auth_process = subprocess.run(
15
+ ["gcloud", "auth", "application-default", "print-access-token"],
16
+ capture_output=True,
17
+ text=True,
18
+ )
19
+
20
+ auth_token = gcloud_auth_process.stdout.strip() # Extract auth token
21
+
22
+ curl_command = f'curl -X GET -H "Authorization: Bearer {auth_token}" "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"'
23
+
24
+ curl_process = subprocess.run(
25
+ curl_command, capture_output=True, shell=True, text=True
26
+ )
27
+ user_info = json.loads(curl_process.stdout)
28
+
29
+ return user_info
30
+
31
+
32
+ @cli.command(context_settings={"ignore_unknown_options": True})
33
+ @click.argument("profile", default="default")
34
+ @click.argument("additional_args", nargs=-1)
35
+ def run(profile, additional_args):
36
+ """
37
+ Start your application locally.
38
+ The 'run' command launches your ViUR application locally specified configuration and optional arguments.
39
+ This Enforces the Usage of gcloud tool
40
+ """
41
+ try:
42
+ echo_warning(
43
+ f"You are using the development Server with your default account: {get_user_info()['email']}"
44
+ )
45
+ except:
46
+ echo_fatal(
47
+ f"It seems you are not Using an appropriate account. "
48
+ f"Please install the 'gcloud' tool or Log in with an appropriate account."
49
+ )
50
+
51
+ conf = config.get_profile(profile)
52
+ additional_args = list(additional_args)
53
+
54
+ if appyaml := conf.get("appyaml"):
55
+ additional_args.append(f"--appyaml={appyaml}")
56
+ if conf.get("port"):
57
+ additional_args.append(f"--port={conf['port']}")
58
+ if conf.get("gunicorn_port"):
59
+ additional_args.append(f"--gunicorn_port={conf['gunicorn_port']}")
60
+
61
+ utils.system(
62
+ f"app_server -A={conf['application_name']} {conf['distribution_folder']} {' '.join(additional_args)}"
63
+ )
64
+
65
+
66
+ @cli.command()
67
+ @click.argument("profile", default="default")
68
+ def env(profile):
69
+ """
70
+ Check the local environment for ViUR development.
71
+
72
+ The 'env' command provides information about the versions tools and dependencies, such as ViUR-CLI, app_server,
73
+ git, Python, npm, node, and more. It checks the availability of these tools and reports their versions.
74
+
75
+ """
76
+
77
+ valid_icon = "\U00002714"
78
+ failed_icon = "\U0000274c"
79
+
80
+ conf = config.get_profile(profile)
81
+ click.echo(f"Project Info:\n--------------------------------")
82
+ try:
83
+ click.echo(f"format: {config['format']}")
84
+ for entry in conf["builds"]:
85
+ if entry in conf["builds"]:
86
+ click.echo(f"\n {entry}: {conf['builds'][entry]['version'] } ")
87
+
88
+ except Exception as e:
89
+ echo_error("Error while collecting viur info")
90
+
91
+ echo_error(str(e))
92
+ click.echo(f"\nCurrent Environment:\n--------------------------------")
93
+
94
+ # viur-cli
95
+ if shutil.which("viur"):
96
+ app_server_version = subprocess.check_output(["viur", "--version"]).decode(
97
+ "utf-8"
98
+ )
99
+ click.echo(f"{valid_icon} {app_server_version}")
100
+ else:
101
+ click.echo(f"{failed_icon} ViUR-CLI")
102
+
103
+ # app_server
104
+ if shutil.which("app_server"):
105
+ app_server_version = subprocess.check_output(["app_server", "-V"]).decode(
106
+ "utf-8"
107
+ )
108
+ click.echo(f"{valid_icon} {app_server_version}")
109
+ else:
110
+ click.echo(f"{failed_icon} app_server")
111
+
112
+ # git
113
+ if shutil.which("git"):
114
+ git_version = subprocess.check_output(["git", "--version"]).decode("utf-8")
115
+ click.echo(f"{valid_icon} {git_version}")
116
+ else:
117
+ click.echo(f"{failed_icon}")
118
+
119
+ # python3
120
+ if shutil.which("python3"):
121
+ npm_version = subprocess.check_output(["python3", "-V"]).decode("utf-8")
122
+ click.echo(f"{valid_icon} python3 > {npm_version}")
123
+ else:
124
+ click.echo(f"{failed_icon}")
125
+
126
+ # python
127
+ if shutil.which("python"):
128
+ npm_version = subprocess.check_output(["python", "-V"]).decode("utf-8")
129
+ click.echo(f"{valid_icon} python > {npm_version}")
130
+ else:
131
+ click.echo(f"{failed_icon}")
132
+
133
+ # python3
134
+ if shutil.which("pyenv"):
135
+ pyenv_version = subprocess.check_output(["pyenv", "--version"]).decode("utf-8")
136
+ click.echo(f"{valid_icon} {pyenv_version}")
137
+ else:
138
+ click.echo(f"{failed_icon}")
139
+
140
+ # npm
141
+ if shutil.which("npm"):
142
+ npm_version = subprocess.check_output(["npm", "-v"]).decode("utf-8")
143
+ click.echo(f"{valid_icon} npm {npm_version}")
144
+ else:
145
+ click.echo(f"{failed_icon} npm")
146
+
147
+ # node
148
+ if shutil.which("node"):
149
+ npm_version = subprocess.check_output(["node", "-v"]).decode("utf-8")
150
+ click.echo(f"{valid_icon} node {npm_version}")
151
+ else:
152
+ click.echo(f"{failed_icon} node")
153
+
154
+ # pnpm
155
+ if shutil.which("pnpm"):
156
+ npm_version = subprocess.check_output(["pnpm", "-v"]).decode("utf-8")
157
+ click.echo(f"{valid_icon} pnpm {npm_version}")
158
+ else:
159
+ click.echo(f"{failed_icon} pnpm (optional)")
160
+
161
+ # gcloud
162
+ if shutil.which("gcloud"):
163
+ gcloud_version = (
164
+ subprocess.check_output(["gcloud", "-v"]).decode("utf-8").split("\n\n")[0]
165
+ )
166
+ versionList = []
167
+ for line in gcloud_version.split("\n"):
168
+ if not line:
169
+ continue
170
+ if not line.startswith("Google Cloud SDK"):
171
+ line = " - " + line
172
+ versionList.append(line)
173
+ versionString = "\n".join(versionList)
174
+ click.echo(f"{valid_icon} {versionString}")
175
+ else:
176
+ click.echo(f"{failed_icon} gcloud")
177
+
178
+ click.echo(f"\nYour default gcloud user Info:\n--------------------------------")
179
+ for k, v in get_user_info().items():
180
+ click.echo(f"{k}: {v}")
181
+
182
+
183
+ @cli.command()
184
+ @click.option("--dev", "-d", is_flag=True, default=False)
185
+ def check(dev):
186
+ """
187
+ Perform security checks for vulnerabilities.
188
+ The 'check' command helps you identify and address security vulnerabilities in your project's dependencies.
189
+ """
190
+
191
+ if do_checks(dev):
192
+ utils.echo_info("\U00002714 No vulnerabilities found.")
193
+
194
+
195
+ def do_checks(dev=True):
196
+ """
197
+ Run security checks for Python and npm dependencies.
198
+
199
+ Args:
200
+ dev: Development mode flag (currently unused but kept for API compatibility)
201
+
202
+ Returns:
203
+ bool: True if no vulnerabilities found, False otherwise
204
+ """
205
+ has_vulnerabilities = False
206
+
207
+ # Python vulnerability check
208
+ try:
209
+ # Run uv-secure with JSON output to parse results
210
+ result = subprocess.run(
211
+ [
212
+ "uvx",
213
+ "pysentry-rs",
214
+ "--sources",
215
+ "pypa,pypi,osv",
216
+ "--format",
217
+ "json",
218
+ "--fail-on",
219
+ "high",
220
+ ],
221
+ capture_output=True,
222
+ check=True,
223
+ )
224
+
225
+ # Parse JSON output (strict=False allows control characters)
226
+ data = json.loads(result.stdout, strict=False)
227
+
228
+ # Check if no vulnerabilities found
229
+ if data.get("vulnerable_packages", 0) == 0:
230
+ py_vulns = False
231
+ else:
232
+ py_vulns = True
233
+ has_vulnerabilities = True
234
+
235
+ # Format scan time to human readable format
236
+ scan_time_str = data.get("scan_time", "N/A")
237
+ try:
238
+ scan_time = datetime.fromisoformat(scan_time_str.replace("Z", "+00:00"))
239
+ formatted_time = scan_time.strftime("%H:%M:%S")
240
+ except:
241
+ formatted_time = scan_time_str
242
+
243
+ # Display scan summary for Python
244
+ click.echo("\n" + "=" * 60)
245
+ click.echo("Python Security Scan Results")
246
+ click.echo("=" * 60)
247
+ click.echo(f"Scan Time: {formatted_time}")
248
+ click.echo(f"Total Packages: {data.get('total_packages', 0)}")
249
+ click.echo(f"Vulnerable Packages: {data.get('vulnerable_packages', 0)}")
250
+ click.echo(f"Total Vulnerabilities: {data.get('total_vulnerabilities', 0)}")
251
+ click.echo("=" * 60)
252
+
253
+ # Display individual vulnerabilities
254
+ vulnerabilities = data.get("vulnerabilities", [])
255
+ if vulnerabilities:
256
+ click.echo("\nFound Python Vulnerabilities:\n")
257
+ for i, vuln in enumerate(vulnerabilities, 1):
258
+ click.echo(
259
+ f"{i}. Package: {click.style(vuln.get('package_name', 'Unknown'), fg='red', bold=True)}"
260
+ )
261
+ click.echo(
262
+ f" Installed Version: {vuln.get('installed_version', 'N/A')}"
263
+ )
264
+
265
+ severity = vuln.get("severity", "Unknown")
266
+ severity_color = {
267
+ "Critical": "red",
268
+ "High": "red",
269
+ "Medium": "yellow",
270
+ "Low": "green",
271
+ }.get(severity, "white")
272
+ click.echo(
273
+ f" Severity: {click.style(severity, fg=severity_color, bold=True)}"
274
+ )
275
+
276
+ fixed_versions = vuln.get("fixed_versions", [])
277
+ if fixed_versions:
278
+ click.echo(f" Fixed in: {', '.join(fixed_versions)}")
279
+ else:
280
+ click.echo(" Fixed in: No fix available yet")
281
+ click.echo()
282
+
283
+ except FileNotFoundError:
284
+ echo_warning("uv-secure not found. Install with: uv pip install uv-secure")
285
+ py_vulns = False
286
+ except json.JSONDecodeError as e:
287
+ echo_error(f"Error parsing uv-secure output: {e}")
288
+ echo_error(f"Raw output: {result.stdout[:500]}")
289
+ py_vulns = False
290
+ except Exception as e:
291
+ echo_error(f"Unexpected error during Python security check: {e}")
292
+ py_vulns = False
293
+ # npm vulnerability check
294
+ if shutil.which("npm"):
295
+ conf = config.get_profile("default")
296
+ builds = conf.get("builds", {})
297
+ sources_folder = conf.get("sources_folder", "./sources")
298
+
299
+ # Collect all npm builds
300
+ npm_builds = []
301
+ for build_name, build_config in builds.items():
302
+ if build_config.get("kind") == "npm":
303
+ source_path = build_config.get("source")
304
+ if source_path:
305
+ npm_builds.append(
306
+ {"name": build_name, "path": f"{sources_folder}/{source_path}"}
307
+ )
308
+
309
+ if not npm_builds:
310
+ click.echo("\n" + "=" * 60)
311
+ click.echo("No npm builds found in config - skipping npm audit")
312
+ click.echo("=" * 60)
313
+ else:
314
+ # Run audit for each npm build
315
+ for build in npm_builds:
316
+ try:
317
+ npm_audit_dir = build["path"]
318
+
319
+ npm_result = subprocess.run(
320
+ ["npm", "audit", "--json"],
321
+ capture_output=True,
322
+ text=True,
323
+ cwd=npm_audit_dir,
324
+ )
325
+
326
+ npm_data = json.loads(npm_result.stdout, strict=False)
327
+
328
+ metadata = npm_data.get("metadata", {})
329
+ npm_vulnerabilities = npm_data.get("vulnerabilities", {})
330
+
331
+ vuln_counts = metadata.get("vulnerabilities", {})
332
+ dependencies = metadata.get("dependencies", {})
333
+
334
+ total_npm_vulns = vuln_counts.get("total", 0)
335
+
336
+ if total_npm_vulns > 0:
337
+ has_vulnerabilities = True
338
+
339
+ # Display npm scan summary
340
+ click.echo("\n" + "=" * 60)
341
+ click.echo(f"npm Security Scan Results - {build['name']}")
342
+ click.echo("=" * 60)
343
+ click.echo(f"Build Path: {npm_audit_dir}")
344
+ click.echo(
345
+ f"Total Dependencies: {dependencies.get('total', 0)}"
346
+ )
347
+ click.echo(f"Total Vulnerabilities: {total_npm_vulns}")
348
+ click.echo(
349
+ f" Critical: {vuln_counts.get('critical', 0)}"
350
+ )
351
+ click.echo(f" High: {vuln_counts.get('high', 0)}")
352
+ click.echo(
353
+ f" Moderate: {vuln_counts.get('moderate', 0)}"
354
+ )
355
+ click.echo(f" Low: {vuln_counts.get('low', 0)}")
356
+ click.echo(f" Info: {vuln_counts.get('info', 0)}")
357
+ click.echo("=" * 60)
358
+
359
+ # Display individual npm vulnerabilities
360
+ if npm_vulnerabilities and total_npm_vulns > 0:
361
+ click.echo(f"\nFound npm Vulnerabilities in {build['name']}:\n")
362
+ for i, (pkg_name, vuln_info) in enumerate(
363
+ npm_vulnerabilities.items(), 1
364
+ ):
365
+ severity = vuln_info.get("severity", "unknown")
366
+ severity_color = {
367
+ "critical": "red",
368
+ "high": "red",
369
+ "moderate": "yellow",
370
+ "low": "green",
371
+ "info": "blue",
372
+ }.get(severity.lower(), "white")
373
+
374
+ # Get current version from nodes
375
+ nodes = vuln_info.get("nodes", [])
376
+ current_version = vuln_info.get("range", "N/A")
377
+
378
+ click.echo(
379
+ f"{i}. Package: {click.style(pkg_name, fg='red', bold=True)}"
380
+ )
381
+ click.echo(f" Current Range: {current_version}")
382
+ click.echo(
383
+ f" Severity: {click.style(severity.capitalize(), fg=severity_color, bold=True)}"
384
+ )
385
+
386
+ # Check for breaking changes
387
+ fix_available = vuln_info.get("fixAvailable", {})
388
+ if fix_available:
389
+ fix_package = fix_available.get("name", pkg_name)
390
+ fix_version = fix_available.get("version", "N/A")
391
+ is_breaking = fix_available.get("isSemVerMajor", False)
392
+
393
+ fix_text = f" Fixed in: {fix_package}@{fix_version}"
394
+ if is_breaking:
395
+ fix_text += click.style(
396
+ " (breaking change)", fg="yellow", bold=True
397
+ )
398
+ click.echo(fix_text)
399
+ else:
400
+ click.echo(" Fixed in: No fix available yet")
401
+
402
+ click.echo()
403
+
404
+ except FileNotFoundError:
405
+ echo_warning(f"npm audit directory not found: {build['path']}")
406
+ except json.JSONDecodeError as e:
407
+ echo_error(
408
+ f"Error parsing npm audit output for {build['name']}: {e}"
409
+ )
410
+ except Exception as e:
411
+ echo_error(
412
+ f"Unexpected error during npm security check for {build['name']}: {e}"
413
+ )
414
+ else:
415
+ click.echo("\n" + "=" * 60)
416
+ click.echo("npm not found - skipping npm audit")
417
+ click.echo("=" * 60)
418
+
419
+ return not has_vulnerabilities
@@ -12,7 +12,6 @@ from weakref import proxy
12
12
  from viur.scriptor import Modules
13
13
  from ..cli import cli
14
14
  from ..cli import scriptor_config
15
- from .login import ensure_login
16
15
 
17
16
  # Global modules instance that will be initialized when needed
18
17
  _modules = None
@@ -44,6 +43,7 @@ def configure(url: str, username: str, working_dir: str):
44
43
  Manage configuration settings.
45
44
  """
46
45
 
46
+
47
47
  if url:
48
48
  scriptor_config["base_url"] = url
49
49
 
@@ -61,14 +61,6 @@ def setup():
61
61
  """
62
62
 
63
63
  base_url = scriptor_config.get("base_url")
64
-
65
- try:
66
- click.echo("This Feature is only avalible on viur-core 3.8.19 or higher.")
67
- res = ensure_login("", host=base_url)
68
- if res:
69
- return
70
- except KeyboardInterrupt:
71
- pass
72
64
  try:
73
65
  session = requests.session()
74
66
  skey = session.get(base_url + "/json/skey")
@@ -104,11 +96,15 @@ def check_session(ctx: click.Context):
104
96
 
105
97
  response = s.get(base_url + "/vi/user/view/self", cookies=scriptor_config.get("cookies", {}))
106
98
  if not response.ok:
107
- click.echo("Invalid session, please run `viur script setup` again. okay ?")
99
+ click.echo("Invalid session, please run `viur script setup` again.")
108
100
  ctx.invoke(setup)
109
101
  ctx.close()
102
+ #FIXME We need this ?
103
+ # Update modules with cookies
104
+ modules = get_modules()
105
+ # modules.request.cookies = cookiejar_from_dict(scriptor_config.get("cookies", {}))
106
+
110
107
 
111
-
112
108
  @script.command()
113
109
  @click.option('--force', default=False, help='Force replace files from server in local working directory')
114
110
  @click.pass_context
@@ -118,6 +114,7 @@ def pull(ctx: click.Context, force: bool):
118
114
  """
119
115
  check_session(ctx)
120
116
 
117
+
121
118
  async def main():
122
119
  # In the new API, we don't need to call structure
123
120
  modules = get_modules()
@@ -291,7 +288,7 @@ def push(ctx: click.Context, force: bool, watch: bool):
291
288
  f.write(args["script"])
292
289
 
293
290
  click.echo(f"Push {_real_file}")
294
- await tree.add(args, skel_type=_type)
291
+ await tree.add(_type, args)
295
292
 
296
293
  if watch:
297
294
  print("Watching...")