viur-cli 2.3.7__tar.gz → 2.3.9__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.
- {viur_cli-2.3.7 → viur_cli-2.3.9}/LICENSE +1 -1
- {viur_cli-2.3.7/src/viur_cli.egg-info → viur_cli-2.3.9}/PKG-INFO +2 -2
- {viur_cli-2.3.7 → viur_cli-2.3.9}/README.md +1 -1
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/scriptor/cli.py +89 -21
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/scriptor/login.py +1 -1
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/version.py +1 -1
- {viur_cli-2.3.7 → viur_cli-2.3.9/src/viur_cli.egg-info}/PKG-INFO +2 -2
- {viur_cli-2.3.7 → viur_cli-2.3.9}/pyproject.toml +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/setup.cfg +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/__init__.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/build.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/cli.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/cloud.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/conf.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/deprecated.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/local.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/package.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/scriptor/__init__.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/scripts/__init__.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/scripts/get_pyodide.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/setup.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/tool.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/update.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli/utils.py +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli.egg-info/SOURCES.txt +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli.egg-info/dependency_links.txt +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli.egg-info/entry_points.txt +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli.egg-info/requires.txt +0 -0
- {viur_cli-2.3.7 → viur_cli-2.3.9}/src/viur_cli.egg-info/top_level.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright ©
|
|
1
|
+
Copyright © 2026 by Mausbrand Informationssysteme GmbH.
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
4
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: viur-cli
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.9
|
|
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
|
|
@@ -346,7 +346,7 @@ viur-cli depends on
|
|
|
346
346
|
|
|
347
347
|
## License
|
|
348
348
|
|
|
349
|
-
Copyright ©
|
|
349
|
+
Copyright © 2026 by Mausbrand Informationssysteme GmbH.<br>
|
|
350
350
|
Mausbrand and ViUR are registered trademarks of Mausbrand Informationssysteme GmbH.
|
|
351
351
|
|
|
352
352
|
This project is free software under the MIT license.<br>
|
|
@@ -323,7 +323,7 @@ viur-cli depends on
|
|
|
323
323
|
|
|
324
324
|
## License
|
|
325
325
|
|
|
326
|
-
Copyright ©
|
|
326
|
+
Copyright © 2026 by Mausbrand Informationssysteme GmbH.<br>
|
|
327
327
|
Mausbrand and ViUR are registered trademarks of Mausbrand Informationssysteme GmbH.
|
|
328
328
|
|
|
329
329
|
This project is free software under the MIT license.<br>
|
|
@@ -4,6 +4,7 @@ import json
|
|
|
4
4
|
import requests
|
|
5
5
|
import os
|
|
6
6
|
import hashlib
|
|
7
|
+
import difflib
|
|
7
8
|
import asyncio
|
|
8
9
|
import sys
|
|
9
10
|
import glob
|
|
@@ -23,7 +24,7 @@ def get_modules():
|
|
|
23
24
|
global _modules
|
|
24
25
|
if _modules is None:
|
|
25
26
|
_modules = Modules(scriptor_config["base_url"], cookies=scriptor_config["cookies"])
|
|
26
|
-
asyncio.
|
|
27
|
+
asyncio.run(_modules.init())
|
|
27
28
|
|
|
28
29
|
return _modules
|
|
29
30
|
|
|
@@ -36,22 +37,39 @@ def script():
|
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
@script.command()
|
|
39
|
-
@click.option('--url', default=None, help='Set the url')
|
|
40
|
+
@click.option('--url', default=None, help='Set the server url')
|
|
40
41
|
@click.option('--username', default=None, help='Set the username')
|
|
41
42
|
@click.option('--working_dir', default=None, help='Set the working directory where scripts are stored to')
|
|
42
43
|
def configure(url: str, username: str, working_dir: str):
|
|
43
44
|
"""
|
|
44
45
|
Manage configuration settings.
|
|
45
46
|
"""
|
|
47
|
+
if not any([url, username, working_dir]):
|
|
48
|
+
click.echo("No parameters provided. Use one or more of the following options:")
|
|
49
|
+
click.echo(" --url Set the server URL")
|
|
50
|
+
click.echo(" --username Set the username")
|
|
51
|
+
click.echo(" --working_dir Set the working directory where scripts are stored to")
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
changed = []
|
|
46
55
|
|
|
47
56
|
if url:
|
|
48
57
|
scriptor_config["base_url"] = url
|
|
58
|
+
changed.append(f"url = {url}")
|
|
49
59
|
|
|
50
60
|
if username:
|
|
51
61
|
scriptor_config["username"] = username
|
|
62
|
+
changed.append(f"username = {username}")
|
|
52
63
|
|
|
53
64
|
if working_dir:
|
|
54
65
|
scriptor_config["working_dir"] = working_dir.replace("\\", "/")
|
|
66
|
+
changed.append(f"working_dir = {working_dir}")
|
|
67
|
+
|
|
68
|
+
click.echo("Configuration updated:")
|
|
69
|
+
for entry in changed:
|
|
70
|
+
click.echo(f" {entry}")
|
|
71
|
+
|
|
72
|
+
scriptor_config.save()
|
|
55
73
|
|
|
56
74
|
|
|
57
75
|
@script.command()
|
|
@@ -111,7 +129,8 @@ def check_session(ctx: click.Context):
|
|
|
111
129
|
get_modules()
|
|
112
130
|
|
|
113
131
|
@script.command()
|
|
114
|
-
@click.option('--force', default=False,
|
|
132
|
+
@click.option('--force', default=False, is_flag=True,
|
|
133
|
+
help='Overwrite local files without asking for confirmation')
|
|
115
134
|
@click.pass_context
|
|
116
135
|
def pull(ctx: click.Context, force: bool):
|
|
117
136
|
"""
|
|
@@ -125,33 +144,74 @@ def pull(ctx: click.Context, force: bool):
|
|
|
125
144
|
tree = await modules.get_module("script")
|
|
126
145
|
working_dir = scriptor_config.get("working_dir")
|
|
127
146
|
|
|
147
|
+
stats = {"new": 0, "updated": 0, "skipped": 0, "unchanged": 0, "dirs": 0}
|
|
148
|
+
|
|
128
149
|
async def process_entry(entry: dict, is_node: bool):
|
|
129
|
-
_path = os.path.join(working_dir, entry["path"])
|
|
150
|
+
_path = os.path.join(working_dir, entry["path"].lstrip("/"))
|
|
130
151
|
|
|
131
152
|
if is_node:
|
|
132
153
|
if not os.path.exists(_path):
|
|
154
|
+
click.echo(click.style(f" mkdir {entry['path']}", fg="blue"))
|
|
133
155
|
os.makedirs(_path)
|
|
156
|
+
stats["dirs"] += 1
|
|
134
157
|
else:
|
|
158
|
+
click.echo(f" check {entry['path']}", nl=False)
|
|
159
|
+
|
|
135
160
|
def create_file():
|
|
136
161
|
with open(_path, "a+") as f:
|
|
137
|
-
f.write(entry["script"])
|
|
138
|
-
|
|
139
|
-
click.echo(f"Pull {_path}")
|
|
162
|
+
f.write(entry["script"] or "")
|
|
140
163
|
|
|
141
164
|
if os.path.exists(_path):
|
|
142
165
|
if force:
|
|
166
|
+
with open(_path, "r") as f:
|
|
167
|
+
changed = f.read().splitlines() != (entry["script"] or "").splitlines()
|
|
143
168
|
os.remove(_path)
|
|
144
169
|
create_file()
|
|
170
|
+
if changed:
|
|
171
|
+
click.echo(click.style(" [updated]", fg="yellow"))
|
|
172
|
+
stats["updated"] += 1
|
|
173
|
+
else:
|
|
174
|
+
click.echo(click.style(" [ok]", fg="green"))
|
|
175
|
+
stats["unchanged"] += 1
|
|
145
176
|
else:
|
|
146
177
|
with open(_path, "r") as f:
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
178
|
+
local_content = f.read()
|
|
179
|
+
remote_content = entry["script"] or ""
|
|
180
|
+
diff = list(difflib.unified_diff(
|
|
181
|
+
remote_content.splitlines(),
|
|
182
|
+
local_content.splitlines(),
|
|
183
|
+
fromfile=f"server/{entry['path'].lstrip('/')}",
|
|
184
|
+
tofile=f"local/{entry['path'].lstrip('/')}",
|
|
185
|
+
lineterm="",
|
|
186
|
+
))
|
|
187
|
+
if diff:
|
|
188
|
+
click.echo(click.style(" [diff]", fg="yellow"))
|
|
189
|
+
for line in diff:
|
|
190
|
+
if line.startswith("+++") or line.startswith("---"):
|
|
191
|
+
click.echo(click.style(line, bold=True))
|
|
192
|
+
elif line.startswith("@@"):
|
|
193
|
+
click.echo(click.style(line, fg="cyan"))
|
|
194
|
+
elif line.startswith("+"):
|
|
195
|
+
click.echo(click.style(line, fg="green"))
|
|
196
|
+
elif line.startswith("-"):
|
|
197
|
+
click.echo(click.style(line, fg="red"))
|
|
198
|
+
else:
|
|
199
|
+
click.echo(line)
|
|
200
|
+
if click.confirm(f"Overwrite local {entry['path']} with remote version?"):
|
|
201
|
+
os.remove(_path)
|
|
202
|
+
create_file()
|
|
203
|
+
stats["updated"] += 1
|
|
204
|
+
else:
|
|
205
|
+
stats["skipped"] += 1
|
|
206
|
+
else:
|
|
207
|
+
click.echo(click.style(" [ok]", fg="green"))
|
|
208
|
+
stats["unchanged"] += 1
|
|
153
209
|
else:
|
|
210
|
+
click.echo(click.style(" [new]", fg="green"))
|
|
154
211
|
create_file()
|
|
212
|
+
stats["new"] += 1
|
|
213
|
+
|
|
214
|
+
click.echo("Fetching scripts from server...")
|
|
155
215
|
|
|
156
216
|
# Process nodes first
|
|
157
217
|
async for node in tree.list(skel_type="node"):
|
|
@@ -161,7 +221,14 @@ def pull(ctx: click.Context, force: bool):
|
|
|
161
221
|
async for leaf in tree.list(skel_type="leaf"):
|
|
162
222
|
await process_entry(leaf, False)
|
|
163
223
|
|
|
164
|
-
|
|
224
|
+
click.echo("")
|
|
225
|
+
click.echo(click.style("Summary:", bold=True))
|
|
226
|
+
click.echo(f" new: {stats['new']}")
|
|
227
|
+
click.echo(f" updated: {stats['updated']}")
|
|
228
|
+
click.echo(f" skipped: {stats['skipped']}")
|
|
229
|
+
click.echo(f" unchanged: {stats['unchanged']}")
|
|
230
|
+
|
|
231
|
+
asyncio.run(main())
|
|
165
232
|
|
|
166
233
|
|
|
167
234
|
@script.command()
|
|
@@ -220,7 +287,7 @@ def push(ctx: click.Context, force: bool, watch: bool):
|
|
|
220
287
|
with open(_real_file, "r") as f:
|
|
221
288
|
file_content = f.read()
|
|
222
289
|
|
|
223
|
-
if hashlib.sha256(entry["script"].encode("utf-8")).digest() \
|
|
290
|
+
if hashlib.sha256((entry["script"] or "").encode("utf-8")).digest() \
|
|
224
291
|
!= hashlib.sha256(file_content.encode("utf-8")).digest():
|
|
225
292
|
can_push = force
|
|
226
293
|
if not can_push:
|
|
@@ -305,21 +372,22 @@ def push(ctx: click.Context, force: bool, watch: bool):
|
|
|
305
372
|
|
|
306
373
|
def on_modified(event):
|
|
307
374
|
try:
|
|
308
|
-
# check for tmp file
|
|
309
375
|
if event.src_path.endswith("~"):
|
|
310
376
|
return
|
|
377
|
+
if not os.path.exists(event.src_path):
|
|
378
|
+
return
|
|
311
379
|
if event.src_path not in modified_files:
|
|
312
380
|
modified_files[event.src_path] = os.path.getmtime(event.src_path)
|
|
313
381
|
elif os.path.getmtime(event.src_path) == modified_files[event.src_path]:
|
|
314
382
|
return
|
|
315
383
|
modified_files[event.src_path] = os.path.getmtime(event.src_path)
|
|
316
|
-
asyncio.
|
|
384
|
+
asyncio.run(main(event.src_path))
|
|
317
385
|
except Exception as e:
|
|
318
386
|
import traceback
|
|
319
387
|
print(f"Error: on file {event.src_path} {e}")
|
|
320
388
|
traceback.print_exc()
|
|
321
389
|
|
|
322
|
-
regexes = [r".*\.py"]
|
|
390
|
+
regexes = [r".*\.py$"]
|
|
323
391
|
ignore_regexes = []
|
|
324
392
|
ignore_directories = True
|
|
325
393
|
case_sensitive = False
|
|
@@ -341,9 +409,9 @@ def push(ctx: click.Context, force: bool, watch: bool):
|
|
|
341
409
|
observer.stop()
|
|
342
410
|
observer.join()
|
|
343
411
|
|
|
344
|
-
|
|
412
|
+
watch_loop()
|
|
345
413
|
return
|
|
346
|
-
asyncio.
|
|
414
|
+
asyncio.run(main())
|
|
347
415
|
|
|
348
416
|
|
|
349
417
|
@script.command()
|
|
@@ -376,4 +444,4 @@ def run(ctx: click.Context, path: str, args=None):
|
|
|
376
444
|
|
|
377
445
|
await module.main()
|
|
378
446
|
|
|
379
|
-
asyncio.
|
|
447
|
+
asyncio.run(main())
|
|
@@ -49,7 +49,7 @@ def ensure_login(
|
|
|
49
49
|
|
|
50
50
|
cookie_str: str = callback_app.cookie.get()
|
|
51
51
|
key, value = cookie_str.split(";", 1)[0].split("=")
|
|
52
|
-
scriptor_config.
|
|
52
|
+
scriptor_config.setdefault("cookies", {})[key] = value
|
|
53
53
|
scriptor_config.save()
|
|
54
54
|
|
|
55
55
|
return True
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "2.3.
|
|
1
|
+
__version__ = "2.3.9"
|
|
2
2
|
MINIMAL_PIPENV = "2023.11.15"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: viur-cli
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.9
|
|
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
|
|
@@ -346,7 +346,7 @@ viur-cli depends on
|
|
|
346
346
|
|
|
347
347
|
## License
|
|
348
348
|
|
|
349
|
-
Copyright ©
|
|
349
|
+
Copyright © 2026 by Mausbrand Informationssysteme GmbH.<br>
|
|
350
350
|
Mausbrand and ViUR are registered trademarks of Mausbrand Informationssysteme GmbH.
|
|
351
351
|
|
|
352
352
|
This project is free software under the MIT license.<br>
|
|
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
|