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 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
- def verify_commands(is_global):
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
- if verification["valid"]:
246
- console.print("[green]All custom commands are in sync with the lockfile.[/green]")
247
- return 0
248
-
249
- console.print("[yellow]Commands are out of sync with the lockfile:[/yellow]\n")
250
-
251
- if verification["missing"]:
252
- console.print("Missing commands (in lockfile but not found):")
253
- for name in verification["missing"]:
254
- console.print(f" - {name}")
255
-
256
- if verification["extra"]:
257
- console.print("\nExtra commands (not in lockfile):")
258
- for name in verification["extra"]:
259
- console.print(f" - {name}")
260
-
261
- if verification["modified"]:
262
- console.print("\nModified commands:")
263
- for name in verification["modified"]:
264
- console.print(f" - {name}")
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
- console.print("\n[dim]Run 'mcli lock update' to sync the lockfile[/dim]")
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
- # Clean top-level commands
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
- @lru_cache()
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.0
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=dlMk94Lw7FtKDZC92H4GSOBKJva2sKWExIafIr1ftcQ,10146
10
- mcli/app/main.py,sha256=wFfvILpaP9JmGvRaLqHoLYIAiUGhvPBzh2L149rn9zo,20561
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=m0GhY8u2o5Xo0ws9QaTO_UbdwloOtNQin0vrQEY0o44,38017
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.0.dist-info/licenses/LICENSE,sha256=sahwAMfrJv2-V66HNPTp7A9UmMjxtyejwTZZoWQvEcI,1075
275
- mcli_framework-7.12.0.dist-info/METADATA,sha256=OohrTi2RR9BjdVJQlLsX7skMsOYiC5Gfd5EGQVCmmcY,18635
276
- mcli_framework-7.12.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
277
- mcli_framework-7.12.0.dist-info/entry_points.txt,sha256=dYrZbDIm-KUPsl1wfv600Kx_8sMy89phMkCihbDRgP8,261
278
- mcli_framework-7.12.0.dist-info/top_level.txt,sha256=_bnO8J2EUkliWivey_1le0UrnocFKmyVMQjbQ8iVXjc,5
279
- mcli_framework-7.12.0.dist-info/RECORD,,
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,,