thailint 0.1.0__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/.ai/layout.yaml +48 -0
- src/__init__.py +49 -0
- src/api.py +118 -0
- src/cli.py +698 -0
- src/config.py +386 -0
- src/core/__init__.py +17 -0
- src/core/base.py +122 -0
- src/core/registry.py +170 -0
- src/core/types.py +83 -0
- src/linter_config/__init__.py +13 -0
- src/linter_config/ignore.py +403 -0
- src/linter_config/loader.py +77 -0
- src/linters/__init__.py +4 -0
- src/linters/file_placement/__init__.py +31 -0
- src/linters/file_placement/linter.py +621 -0
- src/linters/nesting/__init__.py +87 -0
- src/linters/nesting/config.py +50 -0
- src/linters/nesting/linter.py +257 -0
- src/linters/nesting/python_analyzer.py +89 -0
- src/linters/nesting/typescript_analyzer.py +180 -0
- src/orchestrator/__init__.py +9 -0
- src/orchestrator/core.py +188 -0
- src/orchestrator/language_detector.py +81 -0
- thailint-0.1.0.dist-info/LICENSE +21 -0
- thailint-0.1.0.dist-info/METADATA +601 -0
- thailint-0.1.0.dist-info/RECORD +28 -0
- thailint-0.1.0.dist-info/WHEEL +4 -0
- thailint-0.1.0.dist-info/entry_points.txt +4 -0
src/.ai/layout.yaml
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
file-placement:
|
|
2
|
+
directories:
|
|
3
|
+
.ai:
|
|
4
|
+
allow:
|
|
5
|
+
- .*\\.(md|yaml|yml)$
|
|
6
|
+
.roadmap:
|
|
7
|
+
allow:
|
|
8
|
+
- .*\\.md$
|
|
9
|
+
docs:
|
|
10
|
+
allow:
|
|
11
|
+
- .*\\.(md|rst|txt|py)$
|
|
12
|
+
deny:
|
|
13
|
+
- ^(?!.*\\.(md|rst|txt|py)$).*
|
|
14
|
+
src:
|
|
15
|
+
allow:
|
|
16
|
+
- .*\\.py$
|
|
17
|
+
deny:
|
|
18
|
+
- test_.*\\.py$
|
|
19
|
+
- .*_test\\.py$
|
|
20
|
+
tests:
|
|
21
|
+
allow:
|
|
22
|
+
- test_.*\\.py$
|
|
23
|
+
- .*_test\\.py$
|
|
24
|
+
- conftest\\.py$
|
|
25
|
+
- __init__\\.py$
|
|
26
|
+
deny:
|
|
27
|
+
- ^(?!test_|.*_test\\.py|conftest\\.py|__init__\\.py).*\\.py$
|
|
28
|
+
global_patterns:
|
|
29
|
+
deny:
|
|
30
|
+
- message: Python files should be in src/, tests/, scripts/, docs/, .ai/, or .roadmap/
|
|
31
|
+
directories
|
|
32
|
+
pattern: ^(?!src/|tests/|scripts/|docs/|\\.ai/|\\.roadmap/).*\\.py$
|
|
33
|
+
ignore:
|
|
34
|
+
- __pycache__/
|
|
35
|
+
- '*.pyc'
|
|
36
|
+
- .git/
|
|
37
|
+
- .venv/
|
|
38
|
+
- venv/
|
|
39
|
+
- .pytest_cache/
|
|
40
|
+
- .mypy_cache/
|
|
41
|
+
- .ruff_cache/
|
|
42
|
+
- htmlcov/
|
|
43
|
+
- '*.egg-info/'
|
|
44
|
+
- dist/
|
|
45
|
+
- build/
|
|
46
|
+
nesting:
|
|
47
|
+
enabled: true
|
|
48
|
+
max_nesting_depth: 3
|
src/__init__.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Purpose: Package initialization and version definition for CLI application
|
|
3
|
+
|
|
4
|
+
Scope: Package-level exports and metadata
|
|
5
|
+
|
|
6
|
+
Overview: Initializes the CLI application package, defines version number using semantic versioning,
|
|
7
|
+
and exports the public API. Provides single source of truth for version information used by
|
|
8
|
+
setup tools, CLI help text, and documentation. Exports main CLI entry point, high-level Linter
|
|
9
|
+
class for library usage, configuration utilities, and direct linter imports for advanced usage.
|
|
10
|
+
Includes nesting depth linter exports for convenient access to nesting analysis functionality.
|
|
11
|
+
|
|
12
|
+
Dependencies: None (minimal imports for package initialization)
|
|
13
|
+
|
|
14
|
+
Exports: __version__, Linter (high-level API), cli (CLI entry point), load_config, save_config,
|
|
15
|
+
ConfigError, Orchestrator (advanced usage), file_placement_lint, nesting_lint, NestingDepthRule
|
|
16
|
+
|
|
17
|
+
Interfaces: Package version string, Linter class API, CLI command group, configuration functions
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
__version__ = "0.1.0"
|
|
21
|
+
|
|
22
|
+
# High-level Library API (primary interface)
|
|
23
|
+
from src.api import Linter
|
|
24
|
+
|
|
25
|
+
# CLI interface
|
|
26
|
+
from src.cli import cli
|
|
27
|
+
from src.config import ConfigError, load_config, save_config
|
|
28
|
+
|
|
29
|
+
# Advanced/direct imports (backwards compatibility)
|
|
30
|
+
from src.linters.file_placement import lint as file_placement_lint
|
|
31
|
+
from src.linters.nesting import NestingDepthRule
|
|
32
|
+
from src.linters.nesting import lint as nesting_lint
|
|
33
|
+
from src.orchestrator.core import Orchestrator
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
"__version__",
|
|
37
|
+
# Primary Library API
|
|
38
|
+
"Linter",
|
|
39
|
+
# CLI
|
|
40
|
+
"cli",
|
|
41
|
+
"load_config",
|
|
42
|
+
"save_config",
|
|
43
|
+
"ConfigError",
|
|
44
|
+
# Advanced/direct usage (backwards compatibility)
|
|
45
|
+
"Orchestrator",
|
|
46
|
+
"file_placement_lint",
|
|
47
|
+
"nesting_lint",
|
|
48
|
+
"NestingDepthRule",
|
|
49
|
+
]
|
src/api.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Purpose: High-level Library API providing clean programmatic interface for thailint
|
|
3
|
+
|
|
4
|
+
Scope: Public API for library usage without CLI, supporting configuration and linting operations
|
|
5
|
+
|
|
6
|
+
Overview: Provides high-level Linter class that serves as the primary entry point for using
|
|
7
|
+
thailint as a library in other Python applications. Wraps the Orchestrator with a clean,
|
|
8
|
+
user-friendly API that handles configuration loading, path normalization, rule filtering,
|
|
9
|
+
and violation collection. Supports initialization with config files or project roots,
|
|
10
|
+
autodiscovery of .thailint.yaml/.thailint.json in project directory, and flexible linting
|
|
11
|
+
with optional rule filtering. Designed for embedding in editors, CI/CD pipelines, testing
|
|
12
|
+
frameworks, and automation tools. Maintains backwards compatibility with existing direct
|
|
13
|
+
imports while providing improved ergonomics for library users.
|
|
14
|
+
|
|
15
|
+
Dependencies: pathlib for path handling, Orchestrator from orchestrator.core for linting engine,
|
|
16
|
+
LinterConfigLoader from linter_config.loader for configuration, Violation from core.types
|
|
17
|
+
|
|
18
|
+
Exports: Linter class as primary library API
|
|
19
|
+
|
|
20
|
+
Interfaces: Linter(config_file=None, project_root=None) initialization,
|
|
21
|
+
lint(path, rules=None) -> list[Violation] method
|
|
22
|
+
|
|
23
|
+
Implementation: Thin wrapper around Orchestrator with enhanced configuration handling,
|
|
24
|
+
path normalization (str/Path support), rule filtering by name, and graceful error handling
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
|
|
29
|
+
from src.core.types import Violation
|
|
30
|
+
from src.linter_config.loader import LinterConfigLoader
|
|
31
|
+
from src.orchestrator.core import Orchestrator
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Linter:
|
|
35
|
+
"""High-level linter API for programmatic usage.
|
|
36
|
+
|
|
37
|
+
Provides clean interface for using thailint as a library without CLI.
|
|
38
|
+
Supports configuration files, project root detection, and rule filtering.
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
>>> from src import Linter
|
|
42
|
+
>>> linter = Linter(config_file='.thailint.yaml')
|
|
43
|
+
>>> violations = linter.lint('src/', rules=['file-placement'])
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
config_file: str | Path | None = None,
|
|
49
|
+
project_root: str | Path | None = None,
|
|
50
|
+
):
|
|
51
|
+
"""Initialize linter with configuration.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
config_file: Path to config file (.thailint.yaml or .thailint.json).
|
|
55
|
+
If not provided, will autodiscover in project_root.
|
|
56
|
+
project_root: Root directory of project. Defaults to current directory.
|
|
57
|
+
"""
|
|
58
|
+
self.project_root = Path(project_root) if project_root else Path.cwd()
|
|
59
|
+
self.config_loader = LinterConfigLoader()
|
|
60
|
+
|
|
61
|
+
config_path = self._resolve_config_path(config_file)
|
|
62
|
+
self.config = self.config_loader.load(config_path)
|
|
63
|
+
self.orchestrator = Orchestrator(project_root=self.project_root)
|
|
64
|
+
|
|
65
|
+
def _resolve_config_path(self, config_file: str | Path | None) -> Path:
|
|
66
|
+
"""Resolve configuration file path."""
|
|
67
|
+
if config_file:
|
|
68
|
+
return Path(config_file)
|
|
69
|
+
|
|
70
|
+
yaml_path = self.project_root / ".thailint.yaml"
|
|
71
|
+
if yaml_path.exists():
|
|
72
|
+
return yaml_path
|
|
73
|
+
return self.project_root / ".thailint.json"
|
|
74
|
+
|
|
75
|
+
def lint(
|
|
76
|
+
self,
|
|
77
|
+
path: str | Path,
|
|
78
|
+
rules: list[str] | None = None,
|
|
79
|
+
) -> list[Violation]:
|
|
80
|
+
"""Lint a file or directory.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
path: Path to file or directory to lint. Accepts string or Path.
|
|
84
|
+
rules: Optional list of rule names to run. If None, runs all rules.
|
|
85
|
+
Example: ['file-placement']
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
List of violations found.
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
>>> linter = Linter()
|
|
92
|
+
>>> violations = linter.lint('src/', rules=['file-placement'])
|
|
93
|
+
>>> for v in violations:
|
|
94
|
+
... print(f"{v.file_path}: {v.message}")
|
|
95
|
+
"""
|
|
96
|
+
path_obj = Path(path) if isinstance(path, str) else path
|
|
97
|
+
|
|
98
|
+
if not path_obj.exists():
|
|
99
|
+
return []
|
|
100
|
+
|
|
101
|
+
violations = self._lint_path(path_obj)
|
|
102
|
+
return self._filter_violations(violations, rules)
|
|
103
|
+
|
|
104
|
+
def _lint_path(self, path_obj: Path) -> list[Violation]:
|
|
105
|
+
"""Lint a path (file or directory)."""
|
|
106
|
+
if path_obj.is_file():
|
|
107
|
+
return self.orchestrator.lint_file(path_obj)
|
|
108
|
+
if path_obj.is_dir():
|
|
109
|
+
return self.orchestrator.lint_directory(path_obj, recursive=True)
|
|
110
|
+
return []
|
|
111
|
+
|
|
112
|
+
def _filter_violations(
|
|
113
|
+
self, violations: list[Violation], rules: list[str] | None
|
|
114
|
+
) -> list[Violation]:
|
|
115
|
+
"""Filter violations by rule names."""
|
|
116
|
+
if rules:
|
|
117
|
+
return [v for v in violations if v.rule_id in rules]
|
|
118
|
+
return violations
|