-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathextract_ruff.py
More file actions
190 lines (153 loc) · 5.67 KB
/
extract_ruff.py
File metadata and controls
190 lines (153 loc) · 5.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
from pathlib import Path
from re import Pattern
from typing import TYPE_CHECKING, Annotated, Literal
from caseconverter import kebabcase
from pydantic import (
BaseModel,
ConfigDict,
Field,
ImportString,
PlainSerializer,
RootModel,
StringConstraints,
)
from pydantic_settings import (
BaseSettings,
PyprojectTomlConfigSettingsSource,
SettingsConfigDict,
)
if TYPE_CHECKING:
from pydantic_settings import PydanticBaseSettingsSource
import sys
import toml
from rich.theme import Theme
script_theme = Theme(
{
"linkish": "bright_magenta",
}
)
# Define file paths
pyproject_path = Path("pyproject.toml")
ruff_path = Path("ruff.toml")
PathStr = Annotated[
Path,
PlainSerializer(lambda x: str(x.as_posix()), return_type=str, when_used="json"),
]
RuleSelector = Annotated[
str, StringConstraints(min_length=1, pattern=r"^[A-Z][A-Z]*\d*$")
]
RuleList = Annotated[
list[RuleSelector], PlainSerializer(lambda x: sorted(x), return_type=list)
]
class BaseConfig(BaseModel):
model_config = ConfigDict(alias_generator=kebabcase, extra="forbid")
class AnalyzeConfig(BaseConfig):
detect_string_imports: bool | None = None
direction: Literal["dependents", "dependencies"] | None = None
class FormatConfig(BaseConfig):
docstring_code_format: bool | None = None
docstring_code_line_length: int | Literal["dynamic"] | None = None
exclude: list[PathStr] | None = None
indent_style: Literal["space", "tab"] | None = None
line_ending: Literal["auto", "lf", "cr-lf", "native"] | None = None
preview: bool | None = None
quote_style: Literal["single", "double"] | None = None
skip_magic_trailing_comma: bool | None = None
class LintExtendPerFileIgnoresConfig(RootModel[dict[PathStr, list[str]]]):
pass
class LintPerFileIgnoresConfig(RootModel[dict[PathStr, list[str]]]):
pass
class LintIsortConfig(BaseConfig):
model_config = ConfigDict(extra="ignore")
force_single_line: bool | None = None
class LintFlake8PytestStyleConfig(BaseConfig):
fixture_parentheses: bool | None = None
class LintConfig(BaseConfig):
model_config = ConfigDict(extra="ignore")
allowed_confusables: list[str] | None = None
dummy_variable_rgx: Pattern | None = None
exclude: list[PathStr] | None = None
explicit_preview_rules: bool | None = None
extend_fixable: RuleList | None = None
extend_ignore: (
Annotated[RuleList, Field(deprecated="Interchangeable with `ignore`")] | None
) = None
extend_per_file_ignores: LintExtendPerFileIgnoresConfig | None = None
extend_safe_fixes: RuleList | None = None
extend_select: RuleList | None = None
extend_unsafe_fixes: RuleList | None = None
external: RuleList | None = None
fixable: Literal["ALL"] | RuleList | None = None
ignore: RuleList | None = None
ignore_init_module_imports: bool | None = None
logger_objects: list[ImportString] | None = None
per_file_ignores: LintExtendPerFileIgnoresConfig | None = None
preview: bool | None = None
select: RuleList | None = None
task_tags: list[str] | None = None
typing_modules: list[ImportString] | None = None
unfixable: RuleList | None = None
flake8_pytest_style: LintFlake8PytestStyleConfig | None = None
isort: LintIsortConfig | None = None
class RuffConfig(BaseSettings):
model_config = SettingsConfigDict(
pyproject_toml_table_header=("tool", "ruff"),
extra="ignore",
alias_generator=kebabcase,
)
builtins: list[PathStr] | None = None
cache_dir: PathStr | None = None
exclude: list[PathStr] | None = None
extend: PathStr | None = None
extend_exclude: list[PathStr] | None = None
extend_include: list[PathStr] | None = None
fix: bool | None = None
fix_only: bool | None = None
force_exclude: bool | None = None
include: list[PathStr] | None = None
indent_width: int | None = None
line_length: int | None = None
namespace_packages: list[PathStr] | None = None
output_format: str | None = None
preview: bool | None = None
required_version: str | None = None
respect_gitignore: bool | None = None
show_fixes: bool | None = None
src: list[PathStr] | None = None
target_version: str | None = None
unsafe_fixes: bool | None = None
analyze: AnalyzeConfig | None = None
# TODO: Add more fields as needed
format: FormatConfig | None = None
lint: LintConfig | None = None
def model_dump_toml(
self, *, by_alias: bool = True, exclude_none: bool = True, **kwargs
):
as_dict = self.model_dump(
mode="json", by_alias=by_alias, exclude_none=exclude_none, **kwargs
)
return toml.dumps(as_dict)
def write_file(self, file_path: Path = ruff_path):
with file_path.open("w") as file:
toml.dump(
self.model_dump(mode="json", by_alias=True, exclude_none=True), file
)
@classmethod
def settings_customise_sources(
cls,
settings_cls: type[BaseSettings],
init_settings: "PydanticBaseSettingsSource",
env_settings: "PydanticBaseSettingsSource",
dotenv_settings: "PydanticBaseSettingsSource",
file_secret_settings: "PydanticBaseSettingsSource",
) -> tuple["PydanticBaseSettingsSource", ...]:
return (PyprojectTomlConfigSettingsSource(settings_cls),)
if __name__ == "__main__":
from rich.console import Console
console = Console(theme=script_theme)
if not pyproject_path.exists():
console.print(f"[linkish]{pyproject_path.name}[/] not found!")
sys.exit(1)
ruff_config = RuffConfig()
console.print(ruff_config.model_dump_toml())
# ruff_config.write_file() # noqa: ERA001