thailint 0.2.0__py3-none-any.whl → 0.2.1__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.
src/cli.py CHANGED
@@ -363,7 +363,7 @@ def config_reset(ctx, yes: bool):
363
363
 
364
364
 
365
365
  @cli.command("file-placement")
366
- @click.argument("paths", nargs=-1, type=click.Path(exists=True))
366
+ @click.argument("paths", nargs=-1, type=click.Path())
367
367
  @click.option("--config", "-c", "config_file", type=click.Path(), help="Path to config file")
368
368
  @click.option("--rules", "-r", help="Inline JSON rules configuration")
369
369
  @format_option
@@ -432,6 +432,7 @@ def _execute_file_placement_lint( # pylint: disable=too-many-arguments,too-many
432
432
  path_objs, config_file, rules, format, recursive, verbose
433
433
  ):
434
434
  """Execute file placement linting."""
435
+ _validate_paths_exist(path_objs)
435
436
  orchestrator = _setup_orchestrator(path_objs, config_file, rules, verbose)
436
437
  all_violations = _execute_linting_on_paths(orchestrator, path_objs, recursive)
437
438
 
@@ -453,6 +454,28 @@ def _handle_linting_error(error: Exception, verbose: bool) -> None:
453
454
  sys.exit(2)
454
455
 
455
456
 
457
+ def _validate_paths_exist(path_objs: list[Path]) -> None:
458
+ """Validate that all provided paths exist.
459
+
460
+ Args:
461
+ path_objs: List of Path objects to validate
462
+
463
+ Raises:
464
+ SystemExit: If any path doesn't exist (exit code 2)
465
+ """
466
+ for path in path_objs:
467
+ if not path.exists():
468
+ click.echo(f"Error: Path does not exist: {path}", err=True)
469
+ click.echo("", err=True)
470
+ click.echo(
471
+ "Hint: When using Docker, ensure paths are inside the mounted volume:", err=True
472
+ )
473
+ click.echo(
474
+ " docker run -v $(pwd):/data thailint <command> /data/your-file.py", err=True
475
+ )
476
+ sys.exit(2)
477
+
478
+
456
479
  def _find_project_root(start_path: Path) -> Path:
457
480
  """Find project root by looking for .git or pyproject.toml.
458
481
 
@@ -637,7 +660,7 @@ def _run_nesting_lint(orchestrator, path_objs: list[Path], recursive: bool):
637
660
 
638
661
 
639
662
  @cli.command("nesting")
640
- @click.argument("paths", nargs=-1, type=click.Path(exists=True))
663
+ @click.argument("paths", nargs=-1, type=click.Path())
641
664
  @click.option("--config", "-c", "config_file", type=click.Path(), help="Path to config file")
642
665
  @format_option
643
666
  @click.option("--max-depth", type=int, help="Override max nesting depth (default: 4)")
@@ -710,6 +733,7 @@ def _execute_nesting_lint( # pylint: disable=too-many-arguments,too-many-positi
710
733
  path_objs, config_file, format, max_depth, recursive, verbose
711
734
  ):
712
735
  """Execute nesting lint."""
736
+ _validate_paths_exist(path_objs)
713
737
  orchestrator = _setup_nesting_orchestrator(path_objs, config_file, verbose)
714
738
  _apply_nesting_config_override(orchestrator, max_depth, verbose)
715
739
  nesting_violations = _run_nesting_lint(orchestrator, path_objs, recursive)
@@ -773,7 +797,7 @@ def _run_srp_lint(orchestrator, path_objs: list[Path], recursive: bool):
773
797
 
774
798
 
775
799
  @cli.command("srp")
776
- @click.argument("paths", nargs=-1, type=click.Path(exists=True))
800
+ @click.argument("paths", nargs=-1, type=click.Path())
777
801
  @click.option("--config", "-c", "config_file", type=click.Path(), help="Path to config file")
778
802
  @format_option
779
803
  @click.option("--max-methods", type=int, help="Override max methods per class (default: 7)")
@@ -845,6 +869,7 @@ def _execute_srp_lint( # pylint: disable=too-many-arguments,too-many-positional
845
869
  path_objs, config_file, format, max_methods, max_loc, recursive, verbose
846
870
  ):
847
871
  """Execute SRP lint."""
872
+ _validate_paths_exist(path_objs)
848
873
  orchestrator = _setup_srp_orchestrator(path_objs, config_file, verbose)
849
874
  _apply_srp_config_override(orchestrator, max_methods, max_loc, verbose)
850
875
  srp_violations = _run_srp_lint(orchestrator, path_objs, recursive)
@@ -857,7 +882,7 @@ def _execute_srp_lint( # pylint: disable=too-many-arguments,too-many-positional
857
882
 
858
883
 
859
884
  @cli.command("dry")
860
- @click.argument("paths", nargs=-1, type=click.Path(exists=True))
885
+ @click.argument("paths", nargs=-1, type=click.Path())
861
886
  @click.option("--config", "-c", "config_file", type=click.Path(), help="Path to config file")
862
887
  @format_option
863
888
  @click.option("--min-lines", type=int, help="Override min duplicate lines threshold")
@@ -943,6 +968,7 @@ def _execute_dry_lint( # pylint: disable=too-many-arguments,too-many-positional
943
968
  path_objs, config_file, format, min_lines, no_cache, clear_cache, recursive, verbose
944
969
  ):
945
970
  """Execute DRY linting."""
971
+ _validate_paths_exist(path_objs)
946
972
  orchestrator = _setup_dry_orchestrator(path_objs, config_file, verbose)
947
973
  _apply_dry_config_override(orchestrator, min_lines, no_cache, verbose)
948
974
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: thailint
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: The AI Linter - Enterprise-grade linting and governance for AI-generated code across multiple languages
5
5
  License: MIT
6
6
  Keywords: linter,ai,code-quality,static-analysis,file-placement,governance,multi-language,cli,docker,python
@@ -2,7 +2,7 @@ src/__init__.py,sha256=f601zncODr2twrUHqTLS5wyOdZqZi9tMjAe2INhRKqU,2175
2
2
  src/analyzers/__init__.py,sha256=fFloZtjkBGwYbAhKTxS3Qy3yDr2_3i3WSfKTw1mAioo,972
3
3
  src/analyzers/typescript_base.py,sha256=4I7fAcMOAY9vY1AXh52QpohgFmguBECwOkvBRP4zCS4,5054
4
4
  src/api.py,sha256=pJ5l3qxccKBEY-BkANwzTgLAl1ZFq7OP6hx6LSxbhDw,4664
5
- src/cli.py,sha256=ihsUtuUSBnaxDZx1TqGVATIRa5ccfXZXyyyt615SU0M,31608
5
+ src/cli.py,sha256=TTg7nrMF3tEfcj_rbotfvosTjuIWaQqpBjxxj9Tlipw,32421
6
6
  src/config.py,sha256=VCnsguO4BRTYlzmaD6lYJwgJNPcsquDg7P2Tn6Xa5nk,12333
7
7
  src/core/__init__.py,sha256=5FtsDvhMt4SNRx3pbcGURrxn135XRbeRrjSUxiXwkNc,381
8
8
  src/core/base.py,sha256=cFnFSK0K7JqYiXA31lr0JAKRoxvytdqzmlFpCz1tUJI,4787
@@ -68,8 +68,8 @@ src/orchestrator/core.py,sha256=zb4H4HtDNLmnsRCUXI3oNtfM3T-nTPW9Q2pAbI61VEs,8374
68
68
  src/orchestrator/language_detector.py,sha256=rHyVMApit80NTTNyDH1ObD1usKD8LjGmH3DwqNAWYGc,2736
69
69
  src/utils/__init__.py,sha256=NiBtKeQ09Y3kuUzeN4O1JNfUIYPQDS2AP1l5ODq-Dec,125
70
70
  src/utils/project_root.py,sha256=ldv2-XeMT0IElpSgrHdTaP2CUfwmdZix8vQ2qXO1O5s,2735
71
- thailint-0.2.0.dist-info/LICENSE,sha256=kxh1J0Sb62XvhNJ6MZsVNe8PqNVJ7LHRn_EWa-T3djw,1070
72
- thailint-0.2.0.dist-info/METADATA,sha256=LOyjWZxLKsp2XmpyY4Ix7r4fqXT-SICr6pl9K5_gK_I,27109
73
- thailint-0.2.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
74
- thailint-0.2.0.dist-info/entry_points.txt,sha256=l7DQJgU18sVLDpSaXOXY3lLhnQHQIRrSJZTQjG1cEAk,62
75
- thailint-0.2.0.dist-info/RECORD,,
71
+ thailint-0.2.1.dist-info/LICENSE,sha256=kxh1J0Sb62XvhNJ6MZsVNe8PqNVJ7LHRn_EWa-T3djw,1070
72
+ thailint-0.2.1.dist-info/METADATA,sha256=QlQOYyn3OostFqz8NmMf9OCx_TeaE0VEhJQGo2bvTVo,27109
73
+ thailint-0.2.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
74
+ thailint-0.2.1.dist-info/entry_points.txt,sha256=l7DQJgU18sVLDpSaXOXY3lLhnQHQIRrSJZTQjG1cEAk,62
75
+ thailint-0.2.1.dist-info/RECORD,,