mcli-framework 7.12.0__py3-none-any.whl → 7.12.2__py3-none-any.whl
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.
Potentially problematic release.
This version of mcli-framework might be problematic. Click here for more details.
- mcli/app/lock_cmd.py +81 -23
- mcli/app/main.py +2 -42
- mcli/self/self_cmd.py +52 -0
- {mcli_framework-7.12.0.dist-info → mcli_framework-7.12.2.dist-info}/METADATA +1 -1
- {mcli_framework-7.12.0.dist-info → mcli_framework-7.12.2.dist-info}/RECORD +9 -9
- {mcli_framework-7.12.0.dist-info → mcli_framework-7.12.2.dist-info}/WHEEL +0 -0
- {mcli_framework-7.12.0.dist-info → mcli_framework-7.12.2.dist-info}/entry_points.txt +0 -0
- {mcli_framework-7.12.0.dist-info → mcli_framework-7.12.2.dist-info}/licenses/LICENSE +0 -0
- {mcli_framework-7.12.0.dist-info → mcli_framework-7.12.2.dist-info}/top_level.txt +0 -0
mcli/app/lock_cmd.py
CHANGED
|
@@ -229,11 +229,15 @@ def write_state(json_file):
|
|
|
229
229
|
@click.option(
|
|
230
230
|
"--global", "-g", "is_global", is_flag=True, help="Verify global commands instead of local"
|
|
231
231
|
)
|
|
232
|
-
|
|
232
|
+
@click.option(
|
|
233
|
+
"--code", "-c", is_flag=True, help="Also validate that workflow code is executable"
|
|
234
|
+
)
|
|
235
|
+
def verify_commands(is_global, code):
|
|
233
236
|
"""
|
|
234
|
-
Verify that custom commands match the lockfile.
|
|
237
|
+
Verify that custom commands match the lockfile and optionally validate code.
|
|
235
238
|
|
|
236
239
|
By default verifies local commands (if in git repo), use --global/-g for global commands.
|
|
240
|
+
Use --code/-c to also validate that workflow code is valid and executable.
|
|
237
241
|
"""
|
|
238
242
|
manager = get_command_manager(global_mode=is_global)
|
|
239
243
|
|
|
@@ -242,28 +246,82 @@ def verify_commands(is_global):
|
|
|
242
246
|
|
|
243
247
|
verification = manager.verify_lockfile()
|
|
244
248
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
249
|
+
has_issues = False
|
|
250
|
+
|
|
251
|
+
if not verification["valid"]:
|
|
252
|
+
has_issues = True
|
|
253
|
+
console.print("[yellow]Commands are out of sync with the lockfile:[/yellow]\n")
|
|
254
|
+
|
|
255
|
+
if verification["missing"]:
|
|
256
|
+
console.print("Missing commands (in lockfile but not found):")
|
|
257
|
+
for name in verification["missing"]:
|
|
258
|
+
console.print(f" - {name}")
|
|
259
|
+
|
|
260
|
+
if verification["extra"]:
|
|
261
|
+
console.print("\nExtra commands (not in lockfile):")
|
|
262
|
+
for name in verification["extra"]:
|
|
263
|
+
console.print(f" - {name}")
|
|
264
|
+
|
|
265
|
+
if verification["modified"]:
|
|
266
|
+
console.print("\nModified commands:")
|
|
267
|
+
for name in verification["modified"]:
|
|
268
|
+
console.print(f" - {name}")
|
|
269
|
+
|
|
270
|
+
console.print("\n[dim]Run 'mcli lock update' to sync the lockfile[/dim]\n")
|
|
271
|
+
|
|
272
|
+
# Validate workflow code if requested
|
|
273
|
+
if code:
|
|
274
|
+
console.print("[cyan]Validating workflow code...[/cyan]\n")
|
|
275
|
+
|
|
276
|
+
commands = manager.load_all_commands()
|
|
277
|
+
invalid_workflows = []
|
|
278
|
+
|
|
279
|
+
for cmd_data in commands:
|
|
280
|
+
if cmd_data.get("group") != "workflow":
|
|
281
|
+
continue
|
|
282
|
+
|
|
283
|
+
cmd_name = cmd_data.get("name")
|
|
284
|
+
temp_group = click.Group()
|
|
285
|
+
language = cmd_data.get("language", "python")
|
|
286
|
+
|
|
287
|
+
try:
|
|
288
|
+
if language == "shell":
|
|
289
|
+
success = manager.register_shell_command_with_click(cmd_data, temp_group)
|
|
290
|
+
else:
|
|
291
|
+
success = manager.register_command_with_click(cmd_data, temp_group)
|
|
292
|
+
|
|
293
|
+
if not success or not temp_group.commands.get(cmd_name):
|
|
294
|
+
invalid_workflows.append({
|
|
295
|
+
"name": cmd_name,
|
|
296
|
+
"reason": "Code does not define a valid Click command"
|
|
297
|
+
})
|
|
298
|
+
except SyntaxError as e:
|
|
299
|
+
invalid_workflows.append({
|
|
300
|
+
"name": cmd_name,
|
|
301
|
+
"reason": f"Syntax error: {e}"
|
|
302
|
+
})
|
|
303
|
+
except Exception as e:
|
|
304
|
+
invalid_workflows.append({
|
|
305
|
+
"name": cmd_name,
|
|
306
|
+
"reason": f"Failed to load: {e}"
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
if invalid_workflows:
|
|
310
|
+
has_issues = True
|
|
311
|
+
console.print("[red]Invalid workflows found:[/red]\n")
|
|
312
|
+
|
|
313
|
+
for item in invalid_workflows:
|
|
314
|
+
console.print(f" [red]✗[/red] {item['name']}")
|
|
315
|
+
console.print(f" [dim]{item['reason']}[/dim]")
|
|
316
|
+
|
|
317
|
+
console.print(f"\n[yellow]Fix with:[/yellow] mcli workflow edit <workflow-name>")
|
|
318
|
+
console.print(f"[dim]Tip: Workflow code must define a Click command decorated with @click.command()[/dim]\n")
|
|
319
|
+
else:
|
|
320
|
+
console.print("[green]✓ All workflow code is valid[/green]\n")
|
|
265
321
|
|
|
266
|
-
|
|
322
|
+
if not has_issues:
|
|
323
|
+
console.print("[green]✓ All custom commands are verified[/green]")
|
|
324
|
+
return 0
|
|
267
325
|
|
|
268
326
|
return 1
|
|
269
327
|
|
mcli/app/main.py
CHANGED
|
@@ -467,54 +467,14 @@ def create_app() -> click.Group:
|
|
|
467
467
|
|
|
468
468
|
app = click.Group(name="mcli")
|
|
469
469
|
|
|
470
|
-
#
|
|
471
|
-
@app.command()
|
|
472
|
-
@click.option("--verbose", "-v", is_flag=True, help="Show additional system information")
|
|
473
|
-
def version(verbose: bool):
|
|
474
|
-
"""Show mcli version and system information"""
|
|
475
|
-
message = get_version_info(verbose)
|
|
476
|
-
logger.info(message)
|
|
477
|
-
info(message)
|
|
478
|
-
|
|
470
|
+
# Version command moved to self group (mcli self version)
|
|
479
471
|
# Add lazy-loaded command groups
|
|
480
472
|
_add_lazy_commands(app)
|
|
481
473
|
|
|
482
474
|
return app
|
|
483
475
|
|
|
484
476
|
|
|
485
|
-
|
|
486
|
-
def get_version_info(verbose: bool = False) -> str:
|
|
487
|
-
"""Get version info, cached to prevent multiple calls."""
|
|
488
|
-
try:
|
|
489
|
-
# Try mcli-framework first (PyPI package name), then mcli (local dev)
|
|
490
|
-
mcli_version = None
|
|
491
|
-
meta = None
|
|
492
|
-
|
|
493
|
-
for pkg_name in ["mcli-framework", "mcli"]:
|
|
494
|
-
try:
|
|
495
|
-
mcli_version = version(pkg_name)
|
|
496
|
-
meta = metadata(pkg_name)
|
|
497
|
-
break
|
|
498
|
-
except Exception:
|
|
499
|
-
continue
|
|
500
|
-
|
|
501
|
-
if mcli_version is None:
|
|
502
|
-
return "Could not determine version: Package metadata not found"
|
|
503
|
-
|
|
504
|
-
info = [f"mcli version {mcli_version}"]
|
|
505
|
-
|
|
506
|
-
if verbose:
|
|
507
|
-
info.extend(
|
|
508
|
-
[
|
|
509
|
-
f"\nPython: {sys.version.split()[0]}",
|
|
510
|
-
f"Platform: {platform.platform()}",
|
|
511
|
-
f"Description: {meta.get('Summary', 'Not available')}",
|
|
512
|
-
f"Author: {meta.get('Author', 'Not available')}",
|
|
513
|
-
]
|
|
514
|
-
)
|
|
515
|
-
return "\n".join(info)
|
|
516
|
-
except Exception as e:
|
|
517
|
-
return f"Could not determine version: {e}"
|
|
477
|
+
# get_version_info moved to self_cmd.py
|
|
518
478
|
|
|
519
479
|
|
|
520
480
|
def main():
|
mcli/self/self_cmd.py
CHANGED
|
@@ -8,9 +8,13 @@ import importlib
|
|
|
8
8
|
import inspect
|
|
9
9
|
import json
|
|
10
10
|
import os
|
|
11
|
+
import platform
|
|
11
12
|
import re
|
|
13
|
+
import sys
|
|
12
14
|
import time
|
|
13
15
|
from datetime import datetime
|
|
16
|
+
from functools import lru_cache
|
|
17
|
+
from importlib.metadata import metadata, version
|
|
14
18
|
from pathlib import Path
|
|
15
19
|
from typing import Any, Dict, List, Optional
|
|
16
20
|
|
|
@@ -48,6 +52,43 @@ console = Console()
|
|
|
48
52
|
|
|
49
53
|
LOCKFILE_PATH = Path.home() / ".local" / "mcli" / "command_lock.json"
|
|
50
54
|
|
|
55
|
+
|
|
56
|
+
# Version info utility
|
|
57
|
+
@lru_cache()
|
|
58
|
+
def get_version_info(verbose: bool = False) -> str:
|
|
59
|
+
"""Get version info, cached to prevent multiple calls."""
|
|
60
|
+
try:
|
|
61
|
+
# Try mcli-framework first (PyPI package name), then mcli (local dev)
|
|
62
|
+
mcli_version = None
|
|
63
|
+
meta = None
|
|
64
|
+
|
|
65
|
+
for pkg_name in ["mcli-framework", "mcli"]:
|
|
66
|
+
try:
|
|
67
|
+
mcli_version = version(pkg_name)
|
|
68
|
+
meta = metadata(pkg_name)
|
|
69
|
+
break
|
|
70
|
+
except Exception:
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
if mcli_version is None:
|
|
74
|
+
return "Could not determine version: Package metadata not found"
|
|
75
|
+
|
|
76
|
+
info = [f"mcli version {mcli_version}"]
|
|
77
|
+
|
|
78
|
+
if verbose:
|
|
79
|
+
info.extend(
|
|
80
|
+
[
|
|
81
|
+
f"\nPython: {sys.version.split()[0]}",
|
|
82
|
+
f"Platform: {platform.platform()}",
|
|
83
|
+
f"Description: {meta.get('Summary', 'Not available')}",
|
|
84
|
+
f"Author: {meta.get('Author', 'Not available')}",
|
|
85
|
+
]
|
|
86
|
+
)
|
|
87
|
+
return "\n".join(info)
|
|
88
|
+
except Exception as e:
|
|
89
|
+
return f"Error getting version info: {e}"
|
|
90
|
+
|
|
91
|
+
|
|
51
92
|
# Utility functions for command state lockfile
|
|
52
93
|
|
|
53
94
|
|
|
@@ -649,6 +690,17 @@ def plugin_update(plugin_name):
|
|
|
649
690
|
return 0
|
|
650
691
|
|
|
651
692
|
|
|
693
|
+
@self_app.command("version")
|
|
694
|
+
@click.option("--verbose", "-v", is_flag=True, help="Show additional system information")
|
|
695
|
+
def version_cmd(verbose: bool):
|
|
696
|
+
"""Show mcli version and system information."""
|
|
697
|
+
from mcli.lib.ui.styling import info
|
|
698
|
+
|
|
699
|
+
message = get_version_info(verbose)
|
|
700
|
+
logger.info(message)
|
|
701
|
+
info(message)
|
|
702
|
+
|
|
703
|
+
|
|
652
704
|
@self_app.command("hello")
|
|
653
705
|
@click.argument("name", default="World")
|
|
654
706
|
def hello(name: str):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcli-framework
|
|
3
|
-
Version: 7.12.
|
|
3
|
+
Version: 7.12.2
|
|
4
4
|
Summary: Portable workflow framework - transform any script into a versioned, schedulable command. Store in ~/.mcli/workflows/, version with lockfile, run as daemon or cron job.
|
|
5
5
|
Author-email: Luis Fernandez de la Vara <luis@lefv.io>
|
|
6
6
|
Maintainer-email: Luis Fernandez de la Vara <luis@lefv.io>
|
|
@@ -6,8 +6,8 @@ mcli/app/__init__.py,sha256=D4RiKk2gOEXwanbe_jXyNSb5zdgNi47kahtskMnEwjY,489
|
|
|
6
6
|
mcli/app/commands_cmd.py,sha256=RAwkNQIy2XFUQxn56M6rIKas7Qb9BhIFWB4iOj4zTFA,50255
|
|
7
7
|
mcli/app/completion_helpers.py,sha256=e62C6w2N-XoD66GYYHgtvKKoD3kYMuIeBBGzVKbuL04,7497
|
|
8
8
|
mcli/app/init_cmd.py,sha256=Pueg96Gi10VJB20xdEwfw_tDj4v5A5f_dEzKj_130UU,12451
|
|
9
|
-
mcli/app/lock_cmd.py,sha256=
|
|
10
|
-
mcli/app/main.py,sha256=
|
|
9
|
+
mcli/app/lock_cmd.py,sha256=dmuX0peOCWt8sQtyakBVVQ6PTkkPnyiuW2x9QRACLXs,12458
|
|
10
|
+
mcli/app/main.py,sha256=QX_NMi3TqsPbH0_1mCpA1we3jyGca0LpZAv4ljFf9lo,19210
|
|
11
11
|
mcli/app/model_cmd.py,sha256=LQQD8FaebFoaJGK3u_kt19wZ3HJyo_ecwSMYyC2xIp8,2497
|
|
12
12
|
mcli/app/store_cmd.py,sha256=Pr2S0G-TEC1UuGSIzyNnJBxPEc1lH42Cs8WCUsZHJ8I,14316
|
|
13
13
|
mcli/app/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -204,7 +204,7 @@ mcli/self/completion_cmd.py,sha256=JXJ70p_yyfC8KlC5QifkQWLNeS2hgUFmNw8xdiix5O8,7
|
|
|
204
204
|
mcli/self/logs_cmd.py,sha256=SCzZ4VZs6p42hksun_w4WN33xIZgmq7RjdWX8P2WcT4,15056
|
|
205
205
|
mcli/self/migrate_cmd.py,sha256=DalSn-pvfez4KdYYaYlYi1hqqtZM6bgS--pNZzfVsE8,14665
|
|
206
206
|
mcli/self/redis_cmd.py,sha256=Cl0LQ3Mqt27gLeb542_xw6bJBbIE-CBmWyMmaUTSk8c,9426
|
|
207
|
-
mcli/self/self_cmd.py,sha256=
|
|
207
|
+
mcli/self/self_cmd.py,sha256=F8_W82ZoMYa3amdsweQA-EbW4f9zOBDK8elvG0JadPo,39606
|
|
208
208
|
mcli/self/store_cmd.py,sha256=O6arjRr4qWQKh1QyVWtzyXq5R7yZEBL87FSI59Db7IY,13320
|
|
209
209
|
mcli/self/test_cmd.py,sha256=WjzgoH1WFa79wc8A7O6UMuJfookLfgciUNcCMbKHAQQ,21
|
|
210
210
|
mcli/self/visual_cmd.py,sha256=jXighahHxeM9HANQ2Brk6nKFgi2ZuQBOBH7PE5xhebk,9428
|
|
@@ -271,9 +271,9 @@ mcli/workflow/sync/test_cmd.py,sha256=neVgs9zEnKSxlvzDpFkuCGucqnzjrShm2OvJtHibsl
|
|
|
271
271
|
mcli/workflow/videos/__init__.py,sha256=aV3DEoO7qdKJY4odWKoQbOKDQq4ludTeCLnZcupOFIM,25
|
|
272
272
|
mcli/workflow/wakatime/__init__.py,sha256=wKG8cVIHVtMPhNRFGFtX43bRnocHqOMMkFMkmW-M6pU,2626
|
|
273
273
|
mcli/workflow/wakatime/wakatime.py,sha256=sEjsUKa3-XyE8Ni6sAb_D3GAY5jDcA30KknW9YTbLTA,142
|
|
274
|
-
mcli_framework-7.12.
|
|
275
|
-
mcli_framework-7.12.
|
|
276
|
-
mcli_framework-7.12.
|
|
277
|
-
mcli_framework-7.12.
|
|
278
|
-
mcli_framework-7.12.
|
|
279
|
-
mcli_framework-7.12.
|
|
274
|
+
mcli_framework-7.12.2.dist-info/licenses/LICENSE,sha256=sahwAMfrJv2-V66HNPTp7A9UmMjxtyejwTZZoWQvEcI,1075
|
|
275
|
+
mcli_framework-7.12.2.dist-info/METADATA,sha256=6KK20iC7JN8RWTAY4V78hvRBVPAYrbs4-kHKEY9mZOg,18635
|
|
276
|
+
mcli_framework-7.12.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
277
|
+
mcli_framework-7.12.2.dist-info/entry_points.txt,sha256=dYrZbDIm-KUPsl1wfv600Kx_8sMy89phMkCihbDRgP8,261
|
|
278
|
+
mcli_framework-7.12.2.dist-info/top_level.txt,sha256=_bnO8J2EUkliWivey_1le0UrnocFKmyVMQjbQ8iVXjc,5
|
|
279
|
+
mcli_framework-7.12.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|