ruff-sync 0.0.4.dev1__tar.gz → 0.0.5.dev1__tar.gz
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.
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/.github/workflows/ci.yaml +1 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/PKG-INFO +19 -9
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/README.md +18 -8
- ruff_sync-0.0.5.dev1/configs/kitchen-sink/ruff.toml +262 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/pyproject.toml +1 -1
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/ruff_sync.py +80 -15
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_url_handling.py +107 -2
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/uv.lock +1 -1
- ruff_sync-0.0.4.dev1/tests/test_url_parsing.py +0 -31
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/.agents/TESTING.md +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/.agents/workflows/add-test-case.md +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/.git-blame-ignore-revs +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/.github/dependabot.yml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/.github/workflows/complexity.yaml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/.gitignore +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/.pre-commit-config.yaml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/AGENTS.md +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/LICENSE.md +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/codecov.yml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/ruff_sync_banner.png +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/scripts/check_dogfood.sh +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/scripts/gitclone_dogfood.sh +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/scripts/pull_dogfood.sh +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tasks.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/__init__.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_changes_final.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_changes_initial.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_changes_upstream.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_dotted_keys_final.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_dotted_keys_initial.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_dotted_keys_upstream.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_ruff_cfg_final.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_ruff_cfg_initial.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_ruff_cfg_upstream.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/readme_excludes_final.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/readme_excludes_initial.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/readme_excludes_upstream.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/standard_final.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/standard_initial.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/standard_upstream.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/ruff.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_basic.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_check.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_config_validation.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_corner_cases.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_e2e.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_git_fetch.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_project.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_scaffold.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_toml_operations.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/test_whitespace.py +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/w_ruff_sync_cfg/pyproject.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/wo_ruff_cfg/pyproject.toml +0 -0
- {ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/wo_ruff_sync_cfg/pyproject.toml +0 -0
|
@@ -88,6 +88,7 @@ jobs:
|
|
|
88
88
|
ruff-sync --version
|
|
89
89
|
ruff-sync https://github.com/Kilo59/ruff-sync
|
|
90
90
|
ruff-sync check https://github.com/Kilo59/ruff-sync
|
|
91
|
+
! ruff-sync check --semantic https://github.com/Kilo59/ruff-sync --path configs/kitchen-sink
|
|
91
92
|
|
|
92
93
|
publish:
|
|
93
94
|
name: Build and publish to PyPI
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ruff-sync
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.5.dev1
|
|
4
4
|
Summary: Synchronize Ruff linter configuration across projects
|
|
5
5
|
Project-URL: Homepage, https://github.com/Kilo59/ruff-sync
|
|
6
6
|
Project-URL: Documentation, https://github.com/Kilo59/ruff-sync#readme
|
|
@@ -130,14 +130,6 @@ With [pip](https://pip.pypa.io/en/stable/):
|
|
|
130
130
|
pip install ruff-sync
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
-
#### From Source (Bleeding Edge)
|
|
134
|
-
|
|
135
|
-
If you want the latest development version:
|
|
136
|
-
|
|
137
|
-
```console
|
|
138
|
-
uv tool install git+https://github.com/Kilo59/ruff-sync
|
|
139
|
-
```
|
|
140
|
-
|
|
141
133
|
### Usage
|
|
142
134
|
|
|
143
135
|
```console
|
|
@@ -268,6 +260,24 @@ git diff pyproject.toml # review the changes
|
|
|
268
260
|
git commit -am "sync ruff config from upstream"
|
|
269
261
|
```
|
|
270
262
|
|
|
263
|
+
### Curated Examples
|
|
264
|
+
|
|
265
|
+
While `ruff-sync` is designed to sync from *any* repository or URL of your choosing, this repository also provides a few curated configurations in the [`configs/`](./configs/) directory that you can use directly.
|
|
266
|
+
|
|
267
|
+
For example, to sync an exhaustive "kitchen-sink" configuration that explicitly enables all rules and documents them:
|
|
268
|
+
|
|
269
|
+
```console
|
|
270
|
+
ruff-sync https://github.com/Kilo59/ruff-sync/blob/main/configs/kitchen-sink/ruff.toml
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Or configure it using `pyproject.toml` so it's always the default for your local project:
|
|
274
|
+
|
|
275
|
+
```toml
|
|
276
|
+
[tool.ruff-sync]
|
|
277
|
+
upstream = "https://github.com/Kilo59/ruff-sync"
|
|
278
|
+
path = "configs/kitchen-sink"
|
|
279
|
+
```
|
|
280
|
+
|
|
271
281
|
## Bootstrapping a New Project
|
|
272
282
|
|
|
273
283
|
By default, `ruff-sync` requires an existing configuration file (`pyproject.toml` or `ruff.toml`) to merge into. If you are starting a fresh project and want to initialize it with your organization's Ruff settings, you can use the `--init` flag to scaffold a new file automatically.
|
|
@@ -100,14 +100,6 @@ With [pip](https://pip.pypa.io/en/stable/):
|
|
|
100
100
|
pip install ruff-sync
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
#### From Source (Bleeding Edge)
|
|
104
|
-
|
|
105
|
-
If you want the latest development version:
|
|
106
|
-
|
|
107
|
-
```console
|
|
108
|
-
uv tool install git+https://github.com/Kilo59/ruff-sync
|
|
109
|
-
```
|
|
110
|
-
|
|
111
103
|
### Usage
|
|
112
104
|
|
|
113
105
|
```console
|
|
@@ -238,6 +230,24 @@ git diff pyproject.toml # review the changes
|
|
|
238
230
|
git commit -am "sync ruff config from upstream"
|
|
239
231
|
```
|
|
240
232
|
|
|
233
|
+
### Curated Examples
|
|
234
|
+
|
|
235
|
+
While `ruff-sync` is designed to sync from *any* repository or URL of your choosing, this repository also provides a few curated configurations in the [`configs/`](./configs/) directory that you can use directly.
|
|
236
|
+
|
|
237
|
+
For example, to sync an exhaustive "kitchen-sink" configuration that explicitly enables all rules and documents them:
|
|
238
|
+
|
|
239
|
+
```console
|
|
240
|
+
ruff-sync https://github.com/Kilo59/ruff-sync/blob/main/configs/kitchen-sink/ruff.toml
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Or configure it using `pyproject.toml` so it's always the default for your local project:
|
|
244
|
+
|
|
245
|
+
```toml
|
|
246
|
+
[tool.ruff-sync]
|
|
247
|
+
upstream = "https://github.com/Kilo59/ruff-sync"
|
|
248
|
+
path = "configs/kitchen-sink"
|
|
249
|
+
```
|
|
250
|
+
|
|
241
251
|
## Bootstrapping a New Project
|
|
242
252
|
|
|
243
253
|
By default, `ruff-sync` requires an existing configuration file (`pyproject.toml` or `ruff.toml`) to merge into. If you are starting a fresh project and want to initialize it with your organization's Ruff settings, you can use the `--init` flag to scaffold a new file automatically.
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# ruff-sync Kitchen Sink Configuration
|
|
2
|
+
# https://github.com/Kilo59/ruff-sync
|
|
3
|
+
#
|
|
4
|
+
# This file enables ALL possible Ruff rules as of Ruff v0.15.5
|
|
5
|
+
# It explicitly lists all rule categories and provides links to their documentation.
|
|
6
|
+
# This serves as a comprehensive reference for what is possible with Ruff.
|
|
7
|
+
|
|
8
|
+
# Same as Black.
|
|
9
|
+
line-length = 88
|
|
10
|
+
indent-width = 4
|
|
11
|
+
|
|
12
|
+
# Assume Python 3.10. Consumers should override this to match
|
|
13
|
+
# their project's supported Python version.
|
|
14
|
+
target-version = "py310"
|
|
15
|
+
|
|
16
|
+
[lint]
|
|
17
|
+
# Enable all rule categories explicitly.
|
|
18
|
+
select = [
|
|
19
|
+
# https://docs.astral.sh/ruff/rules/#pyflakes-f
|
|
20
|
+
"F", # Pyflakes: Essential checks for python bugs
|
|
21
|
+
# https://docs.astral.sh/ruff/rules/#error-e
|
|
22
|
+
"E", # pycodestyle errors: PEP8 styling
|
|
23
|
+
# https://docs.astral.sh/ruff/rules/#warning-w
|
|
24
|
+
"W", # pycodestyle warnings: PEP8 styling
|
|
25
|
+
# https://docs.astral.sh/ruff/rules/#mccabe-c90
|
|
26
|
+
"C90", # mccabe: Code complexity (cyclomatic complexity)
|
|
27
|
+
# https://docs.astral.sh/ruff/rules/#isort-i
|
|
28
|
+
"I", # isort: Import sorting
|
|
29
|
+
# https://docs.astral.sh/ruff/rules/#pep8-naming-n
|
|
30
|
+
"N", # pep8-naming: Naming conventions
|
|
31
|
+
# https://docs.astral.sh/ruff/rules/#pydocstyle-d
|
|
32
|
+
"D", # pydocstyle: Docstring conventions
|
|
33
|
+
# https://docs.astral.sh/ruff/rules/#pyupgrade-up
|
|
34
|
+
"UP", # pyupgrade: Upgrade syntax for newer Python versions
|
|
35
|
+
# https://docs.astral.sh/ruff/rules/#flake8-2020-ytt
|
|
36
|
+
"YTT", # flake8-2020: Checks for sys.version and sys.version_info usage
|
|
37
|
+
# https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
|
|
38
|
+
"ANN", # flake8-annotations: Type annotation checks
|
|
39
|
+
# https://docs.astral.sh/ruff/rules/#flake8-async-async
|
|
40
|
+
"ASYNC", # flake8-async: Asynchronous code checks
|
|
41
|
+
# https://docs.astral.sh/ruff/rules/#flake8-bandit-s
|
|
42
|
+
"S", # flake8-bandit: Security testing
|
|
43
|
+
# https://docs.astral.sh/ruff/rules/#flake8-blind-except-ble
|
|
44
|
+
"BLE", # flake8-blind-except: Checks for blind except: statements
|
|
45
|
+
# https://docs.astral.sh/ruff/rules/#flake8-boolean-trap-fbt
|
|
46
|
+
"FBT", # flake8-boolean-trap: Boolean trap checks
|
|
47
|
+
# https://docs.astral.sh/ruff/rules/#flake8-bugbear-b
|
|
48
|
+
"B", # flake8-bugbear: Finding likely bugs and design problems
|
|
49
|
+
# https://docs.astral.sh/ruff/rules/#flake8-builtins-a
|
|
50
|
+
"A", # flake8-builtins: Check for python builtins being used as variables or parameters
|
|
51
|
+
# https://docs.astral.sh/ruff/rules/#flake8-commas-com
|
|
52
|
+
"COM", # flake8-commas: Trailing commas checks
|
|
53
|
+
# https://docs.astral.sh/ruff/rules/#flake8-copyright-cpy
|
|
54
|
+
# "CPY", # flake8-copyright: Copyright notice checks (Note: requires `preview = true`)
|
|
55
|
+
# https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4
|
|
56
|
+
"C4", # flake8-comprehensions: Write better list/set/dict comprehensions
|
|
57
|
+
# https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz
|
|
58
|
+
"DTZ", # flake8-datetimez: Usage of unsafe naive datetime class
|
|
59
|
+
# https://docs.astral.sh/ruff/rules/#flake8-debugger-t10
|
|
60
|
+
"T10", # flake8-debugger: Check for pdb/ipdb imports and set_traces
|
|
61
|
+
# https://docs.astral.sh/ruff/rules/#flake8-django-dj
|
|
62
|
+
"DJ", # flake8-django: Django specific code quality checks
|
|
63
|
+
# https://docs.astral.sh/ruff/rules/#flake8-errmsg-em
|
|
64
|
+
"EM", # flake8-errmsg: Nicer error messages
|
|
65
|
+
# https://docs.astral.sh/ruff/rules/#flake8-executable-exe
|
|
66
|
+
"EXE", # flake8-executable: Executable permissions and shebangs
|
|
67
|
+
# https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa
|
|
68
|
+
"FA", # flake8-future-annotations: Verify python 3.7+ from __future__ import annotations
|
|
69
|
+
# https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc
|
|
70
|
+
"ISC", # flake8-implicit-str-concat: Implicit string concatenation checks
|
|
71
|
+
# https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn
|
|
72
|
+
"ICN", # flake8-import-conventions: Enforce standard naming for standard libraries
|
|
73
|
+
# https://docs.astral.sh/ruff/rules/#flake8-logging-format-g
|
|
74
|
+
"G", # flake8-logging-format: Validate logging format strings
|
|
75
|
+
# https://docs.astral.sh/ruff/rules/#flake8-no-pep420-inp
|
|
76
|
+
"INP", # flake8-no-pep420: Ban PEP-420 implicit namespace packages
|
|
77
|
+
# https://docs.astral.sh/ruff/rules/#flake8-pie-pie
|
|
78
|
+
"PIE", # flake8-pie: Misc. lints
|
|
79
|
+
# https://docs.astral.sh/ruff/rules/#flake8-print-t20
|
|
80
|
+
"T20", # flake8-print: Check for Print statements in python files
|
|
81
|
+
# https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi
|
|
82
|
+
"PYI", # flake8-pyi: Linting for .pyi files
|
|
83
|
+
# https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt
|
|
84
|
+
"PT", # flake8-pytest-style: Checking common style issues or inconsistencies with pytest
|
|
85
|
+
# https://docs.astral.sh/ruff/rules/#flake8-quotes-q
|
|
86
|
+
"Q", # flake8-quotes: Lint for quotes
|
|
87
|
+
# https://docs.astral.sh/ruff/rules/#flake8-raise-rse
|
|
88
|
+
"RSE", # flake8-raise: Find and correct raise statements
|
|
89
|
+
# https://docs.astral.sh/ruff/rules/#flake8-return-ret
|
|
90
|
+
"RET", # flake8-return: Check return values
|
|
91
|
+
# https://docs.astral.sh/ruff/rules/#flake8-self-slf
|
|
92
|
+
"SLF", # flake8-self: Private member access checks
|
|
93
|
+
# https://docs.astral.sh/ruff/rules/#flake8-slots-slot
|
|
94
|
+
"SLOT", # flake8-slots: Require __slots__ for subclasses of immutable types
|
|
95
|
+
# https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
|
|
96
|
+
"SIM", # flake8-simplify: Code simplification
|
|
97
|
+
# https://docs.astral.sh/ruff/rules/#flake8-tidy-imports-tid
|
|
98
|
+
"TID", # flake8-tidy-imports: Tidy imports
|
|
99
|
+
# https://docs.astral.sh/ruff/rules/#flake8-type-checking-tc
|
|
100
|
+
"TC", # flake8-type-checking: Move imports into type-checking blocks
|
|
101
|
+
# https://docs.astral.sh/ruff/rules/#flake8-gettext-int
|
|
102
|
+
"ARG", # flake8-unused-arguments: Unused argument checks
|
|
103
|
+
# https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
|
|
104
|
+
"PTH", # flake8-use-pathlib: Use pathlib instead of os.path
|
|
105
|
+
# https://docs.astral.sh/ruff/rules/#flake8-todos-td
|
|
106
|
+
"TD", # flake8-todos: TODO comments formatting
|
|
107
|
+
# https://docs.astral.sh/ruff/rules/#flake8-fixme-fix
|
|
108
|
+
"FIX", # flake8-fixme: Check for FIXME, XXX and other developer notes
|
|
109
|
+
# https://docs.astral.sh/ruff/rules/#eradicate-era
|
|
110
|
+
"ERA", # eradicate: Found commented out code
|
|
111
|
+
# https://docs.astral.sh/ruff/rules/#pandas-vet-pd
|
|
112
|
+
"PD", # pandas-vet: Pandas code checks
|
|
113
|
+
# https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh
|
|
114
|
+
"PGH", # pygrep-hooks: Pygrep hooks
|
|
115
|
+
# https://docs.astral.sh/ruff/rules/#pylint-pl
|
|
116
|
+
"PL", # Pylint: Pylint rules
|
|
117
|
+
# https://docs.astral.sh/ruff/rules/#tryceratops-try
|
|
118
|
+
"TRY", # tryceratops: Prevent Exception Handling AntiPatterns
|
|
119
|
+
# https://docs.astral.sh/ruff/rules/#flynt-fly
|
|
120
|
+
"FLY", # flynt: Convert string formatting to f-strings
|
|
121
|
+
# https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy
|
|
122
|
+
"NPY", # NumPy-specific rules: NumPy conventions
|
|
123
|
+
# https://docs.astral.sh/ruff/rules/#airflow-air
|
|
124
|
+
"AIR", # Airflow: Airflow best practices
|
|
125
|
+
# https://docs.astral.sh/ruff/rules/#perflint-perf
|
|
126
|
+
"PERF", # Perflint: Performance anti-patterns
|
|
127
|
+
# https://docs.astral.sh/ruff/rules/#refurb-furb
|
|
128
|
+
"FURB", # refurb: Modernize Python code
|
|
129
|
+
# https://docs.astral.sh/ruff/rules/#flake8-logging-log
|
|
130
|
+
"LOG", # flake8-logging: Better logging practices
|
|
131
|
+
# https://docs.astral.sh/ruff/rules/#pydoclint-doc
|
|
132
|
+
# "DOC", # pydoclint: Validate docstrings against function signatures (Note: requires `preview = true`)
|
|
133
|
+
# https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
|
|
134
|
+
"RUF" # Ruff-specific rules: Rules unique to Ruff
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
# We don't ignore any rules in this config, as it aims to be exhaustive.
|
|
138
|
+
# WARNING: Some of the rules enabled above may be mutually exclusive or
|
|
139
|
+
# conflict with each other (e.g., D212 and D213). You will likely need to
|
|
140
|
+
# remove some rules from the `select` list or add them to the `ignore`
|
|
141
|
+
# list below based on your preferences and project conventions.
|
|
142
|
+
#
|
|
143
|
+
# Below is a list of lint rules that conflict with the Ruff formatter.
|
|
144
|
+
# We ignore these by default so `ruff format` will run without warnings.
|
|
145
|
+
# See: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
|
|
146
|
+
ignore = [
|
|
147
|
+
"W191", # tab-indentation
|
|
148
|
+
"E111", # indentation-with-invalid-multiple
|
|
149
|
+
"E114", # indentation-with-invalid-multiple-comment
|
|
150
|
+
"E117", # over-indented
|
|
151
|
+
"D206", # docstring-tab-indentation
|
|
152
|
+
"D300", # triple-single-quotes
|
|
153
|
+
"Q000", # bad-quotes-inline-string
|
|
154
|
+
"Q001", # bad-quotes-multiline-string
|
|
155
|
+
"Q002", # bad-quotes-docstring
|
|
156
|
+
"Q003", # avoidable-escaped-quote
|
|
157
|
+
"Q004", # unnecessary-escaped-quote
|
|
158
|
+
"COM812", # missing-trailing-comma
|
|
159
|
+
"COM819", # prohibited-trailing-comma
|
|
160
|
+
"ISC001", # single-line-implicit-string-concatenation
|
|
161
|
+
"ISC002", # multi-line-implicit-string-concatenation
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
# Allow autofix for all enabled rules (when `--fix`) is provided.
|
|
165
|
+
fixable = ["ALL"]
|
|
166
|
+
unfixable = []
|
|
167
|
+
|
|
168
|
+
# Allow unused variables when underscore-prefixed.
|
|
169
|
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
170
|
+
|
|
171
|
+
[lint.mccabe]
|
|
172
|
+
# Flag errors (`C901`) whenever the complexity level exceeds 10.
|
|
173
|
+
# Default: 10
|
|
174
|
+
max-complexity = 10
|
|
175
|
+
|
|
176
|
+
[lint.pydocstyle]
|
|
177
|
+
# Which style to use for docstrings. Can be "google", "numpy", or "pep257".
|
|
178
|
+
# Default: "pep257"
|
|
179
|
+
convention = "pep257"
|
|
180
|
+
|
|
181
|
+
[lint.flake8-quotes]
|
|
182
|
+
# The style to use for inline strings: "single" or "double"
|
|
183
|
+
# Default: "double"
|
|
184
|
+
inline-quotes = "double"
|
|
185
|
+
# The style to use for multiline strings
|
|
186
|
+
# Default: "double"
|
|
187
|
+
multiline-quotes = "double"
|
|
188
|
+
# The style to use for docstrings
|
|
189
|
+
# Default: "double"
|
|
190
|
+
docstring-quotes = "double"
|
|
191
|
+
# Whether to avoid escaping quotes if the other quote type would save an escape
|
|
192
|
+
# Default: true
|
|
193
|
+
avoid-escape = true
|
|
194
|
+
|
|
195
|
+
[lint.flake8-tidy-imports]
|
|
196
|
+
# Ban absolute imports from specific modules
|
|
197
|
+
# ban-relative-imports = "all" # Default: "parents"
|
|
198
|
+
|
|
199
|
+
[lint.isort]
|
|
200
|
+
# How to group imports: "std", "third-party", "first-party", "local-folder".
|
|
201
|
+
# Default: ["future", "standard-library", "third-party", "first-party", "local-folder"]
|
|
202
|
+
# section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
|
|
203
|
+
|
|
204
|
+
[format]
|
|
205
|
+
# Like Black, use double quotes for strings.
|
|
206
|
+
quote-style = "double"
|
|
207
|
+
|
|
208
|
+
# Like Black, indent with spaces, rather than tabs.
|
|
209
|
+
indent-style = "space"
|
|
210
|
+
|
|
211
|
+
# Like Black, respect magic trailing commas.
|
|
212
|
+
skip-magic-trailing-comma = false
|
|
213
|
+
|
|
214
|
+
# Like Black, automatically detect the appropriate line ending.
|
|
215
|
+
line-ending = "auto"
|
|
216
|
+
|
|
217
|
+
# Enable auto-formatting of code examples in docstrings. Markdown,
|
|
218
|
+
# reStructuredText code/literal blocks and doctests are all supported.
|
|
219
|
+
#
|
|
220
|
+
# This is currently disabled by default, but it is planned for this
|
|
221
|
+
# to be opt-out in the future.
|
|
222
|
+
docstring-code-format = true
|
|
223
|
+
|
|
224
|
+
# Set the line length limit used when formatting code snippets in
|
|
225
|
+
# docstrings.
|
|
226
|
+
#
|
|
227
|
+
# This only has an effect when the `docstring-code-format` setting is
|
|
228
|
+
# enabled.
|
|
229
|
+
docstring-code-line-length = "dynamic"
|
|
230
|
+
|
|
231
|
+
[lint.flake8-pytest-style]
|
|
232
|
+
# Whether to require parentheses for pytest fixtures.
|
|
233
|
+
# Default: true
|
|
234
|
+
fixture-parentheses = true
|
|
235
|
+
# The type of pytest.mark.parametrize names to use: "tuple", "list", or "csv"
|
|
236
|
+
# Default: "tuple"
|
|
237
|
+
parametrize-names-type = "tuple"
|
|
238
|
+
|
|
239
|
+
[lint.pylint]
|
|
240
|
+
# The maximum number of arguments allowed for a function.
|
|
241
|
+
# Default: 5
|
|
242
|
+
max-args = 5
|
|
243
|
+
# The maximum return statements allowed for a function.
|
|
244
|
+
# Default: 6
|
|
245
|
+
max-returns = 6
|
|
246
|
+
# The maximum number of branches allowed for a function.
|
|
247
|
+
# Default: 12
|
|
248
|
+
max-branches = 12
|
|
249
|
+
# The maximum number of local variables allowed for a function.
|
|
250
|
+
# Default: 15
|
|
251
|
+
max-locals = 15
|
|
252
|
+
|
|
253
|
+
[lint.pep8-naming]
|
|
254
|
+
# Additional functions or methods that should be exempt from the lower_case_with_underscores rule.
|
|
255
|
+
# Default: []
|
|
256
|
+
ignore-names = []
|
|
257
|
+
# Additional decorators that should be treated as classmethod.
|
|
258
|
+
# Default: []
|
|
259
|
+
classmethod-decorators = [
|
|
260
|
+
"pydantic.validator",
|
|
261
|
+
"pydantic.root_validator",
|
|
262
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "ruff-sync"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.5.dev1"
|
|
4
4
|
description = "Synchronize Ruff linter configuration across projects"
|
|
5
5
|
keywords = ["ruff", "linter", "config", "synchronize", "python", "linting", "automation", "tomlkit"]
|
|
6
6
|
authors = [
|
|
@@ -23,7 +23,7 @@ from tomlkit import TOMLDocument, table
|
|
|
23
23
|
from tomlkit.items import Table
|
|
24
24
|
from tomlkit.toml_file import TOMLFile
|
|
25
25
|
|
|
26
|
-
__version__ = "0.0.
|
|
26
|
+
__version__ = "0.0.5.dev1"
|
|
27
27
|
|
|
28
28
|
_DEFAULT_EXCLUDE: Final[set[str]] = {"lint.per-file-ignores"}
|
|
29
29
|
_GITHUB_REPO_PATH_PARTS_COUNT: Final[int] = 2
|
|
@@ -216,17 +216,35 @@ def _get_cli_parser() -> ArgumentParser:
|
|
|
216
216
|
return parser
|
|
217
217
|
|
|
218
218
|
|
|
219
|
+
def _get_target_path(path: str | None) -> str:
|
|
220
|
+
"""Resolve the target path for configuration files.
|
|
221
|
+
|
|
222
|
+
If the path indicates a .toml file, it's treated as a direct file path.
|
|
223
|
+
Otherwise, it appends 'pyproject.toml' to the path.
|
|
224
|
+
"""
|
|
225
|
+
if not path:
|
|
226
|
+
return "pyproject.toml"
|
|
227
|
+
|
|
228
|
+
# Use PurePosixPath to handle URL-style paths consistently
|
|
229
|
+
posix_path = pathlib.PurePosixPath(path.strip("/"))
|
|
230
|
+
if posix_path.suffix == ".toml":
|
|
231
|
+
return str(posix_path)
|
|
232
|
+
|
|
233
|
+
return str(posix_path / "pyproject.toml")
|
|
234
|
+
|
|
235
|
+
|
|
219
236
|
def _convert_github_url(url: URL, branch: str = "main", path: str = "") -> URL:
|
|
220
237
|
"""Convert a GitHub URL to its corresponding raw content URL.
|
|
221
238
|
|
|
222
239
|
Supports:
|
|
223
240
|
- Blob URLs: https://github.com/org/repo/blob/branch/path/to/file
|
|
224
|
-
- Repo URLs: https://github.com/org/repo (defaults to {branch}/{path}/pyproject.toml
|
|
241
|
+
- Repo URLs: https://github.com/org/repo (defaults to {branch}/{path}/pyproject.toml if path
|
|
242
|
+
doesn't end in .toml)
|
|
225
243
|
|
|
226
244
|
Args:
|
|
227
245
|
url (URL): The GitHub URL to be converted.
|
|
228
246
|
branch (str): The default branch to use for repo URLs.
|
|
229
|
-
path (str): The directory prefix for pyproject.toml.
|
|
247
|
+
path (str): The directory prefix for pyproject.toml, or a direct path to a .toml file.
|
|
230
248
|
|
|
231
249
|
Returns:
|
|
232
250
|
URL: The corresponding raw content URL.
|
|
@@ -243,10 +261,10 @@ def _convert_github_url(url: URL, branch: str = "main", path: str = "") -> URL:
|
|
|
243
261
|
path_parts = [p for p in url.path.split("/") if p]
|
|
244
262
|
if len(path_parts) == _GITHUB_REPO_PATH_PARTS_COUNT:
|
|
245
263
|
org, repo = path_parts
|
|
246
|
-
target_path =
|
|
264
|
+
target_path = _get_target_path(path)
|
|
247
265
|
raw_url = url.copy_with(
|
|
248
266
|
host=_GITHUB_RAW_HOST,
|
|
249
|
-
path=
|
|
267
|
+
path=str(pathlib.PurePosixPath("/", org, repo, branch, target_path)),
|
|
250
268
|
)
|
|
251
269
|
LOGGER.info(f"Converting GitHub repo URL to raw content URL: {raw_url}")
|
|
252
270
|
return raw_url
|
|
@@ -260,12 +278,13 @@ def _convert_gitlab_url(url: URL, branch: str = "main", path: str = "") -> URL:
|
|
|
260
278
|
|
|
261
279
|
Supports:
|
|
262
280
|
- Blob URLs: https://gitlab.com/org/repo/-/blob/branch/path/to/file
|
|
263
|
-
- Repo URLs: https://gitlab.com/org/repo (defaults to {branch}/{path}/pyproject.toml
|
|
281
|
+
- Repo URLs: https://gitlab.com/org/repo (defaults to {branch}/{path}/pyproject.toml if path
|
|
282
|
+
doesn't end in .toml)
|
|
264
283
|
|
|
265
284
|
Args:
|
|
266
285
|
url (URL): The GitLab URL to be converted.
|
|
267
286
|
branch (str): The default branch to use for repo URLs.
|
|
268
|
-
path (str): The directory prefix for pyproject.toml.
|
|
287
|
+
path (str): The directory prefix for pyproject.toml, or a direct path to a .toml file.
|
|
269
288
|
|
|
270
289
|
Returns:
|
|
271
290
|
URL: The corresponding raw content URL.
|
|
@@ -283,8 +302,10 @@ def _convert_gitlab_url(url: URL, branch: str = "main", path: str = "") -> URL:
|
|
|
283
302
|
# Avoid empty paths or just a slash
|
|
284
303
|
path_prefix = url.path.rstrip("/")
|
|
285
304
|
if path_prefix:
|
|
286
|
-
target_path =
|
|
287
|
-
raw_url = url.copy_with(
|
|
305
|
+
target_path = _get_target_path(path)
|
|
306
|
+
raw_url = url.copy_with(
|
|
307
|
+
path=str(pathlib.PurePosixPath(path_prefix, "-", "raw", branch, target_path))
|
|
308
|
+
)
|
|
288
309
|
LOGGER.info(f"Converting GitLab repo URL to raw content URL: {raw_url}")
|
|
289
310
|
return raw_url
|
|
290
311
|
|
|
@@ -297,6 +318,32 @@ def is_git_url(url: URL) -> bool:
|
|
|
297
318
|
return str(url).startswith("git@") or url.scheme in ("ssh", "git", "git+ssh")
|
|
298
319
|
|
|
299
320
|
|
|
321
|
+
def to_git_url(url: URL) -> URL | None:
|
|
322
|
+
"""
|
|
323
|
+
Attempt to convert a browser or raw URL to a git (SSH) URL.
|
|
324
|
+
|
|
325
|
+
Supports GitHub and GitLab.
|
|
326
|
+
"""
|
|
327
|
+
if is_git_url(url):
|
|
328
|
+
return url
|
|
329
|
+
|
|
330
|
+
if url.host in _GITHUB_HOSTS or url.host == _GITHUB_RAW_HOST:
|
|
331
|
+
path_parts = [p for p in url.path.split("/") if p]
|
|
332
|
+
if len(path_parts) >= _GITHUB_REPO_PATH_PARTS_COUNT:
|
|
333
|
+
org, repo = path_parts[:_GITHUB_REPO_PATH_PARTS_COUNT]
|
|
334
|
+
repo = repo.removesuffix(".git")
|
|
335
|
+
return URL(f"git@github.com:{org}/{repo}.git")
|
|
336
|
+
|
|
337
|
+
if url.host in _GITLAB_HOSTS:
|
|
338
|
+
path = url.path.strip("/")
|
|
339
|
+
project_path = path.split("/-/")[0] if "/-/" in path else path
|
|
340
|
+
if project_path:
|
|
341
|
+
project_path = project_path.removesuffix(".git")
|
|
342
|
+
return URL(f"git@{url.host}:{project_path}.git")
|
|
343
|
+
|
|
344
|
+
return None
|
|
345
|
+
|
|
346
|
+
|
|
300
347
|
def resolve_raw_url(url: URL, branch: str = "main", path: str | None = None) -> URL:
|
|
301
348
|
"""Convert a GitHub or GitLab repository/blob URL to a raw content URL.
|
|
302
349
|
|
|
@@ -367,11 +414,7 @@ async def fetch_upstream_config(
|
|
|
367
414
|
capture_output=True,
|
|
368
415
|
text=True,
|
|
369
416
|
)
|
|
370
|
-
target_path = (
|
|
371
|
-
pathlib.Path(path.strip("/")) / "pyproject.toml"
|
|
372
|
-
if path
|
|
373
|
-
else pathlib.Path("pyproject.toml")
|
|
374
|
-
)
|
|
417
|
+
target_path = pathlib.Path(_get_target_path(path))
|
|
375
418
|
|
|
376
419
|
# Restore just the pyproject_toml file
|
|
377
420
|
restore_cmd = [
|
|
@@ -424,7 +467,29 @@ async def fetch_upstream_config(
|
|
|
424
467
|
content = await asyncio.to_thread(_git_clone_and_read)
|
|
425
468
|
return StringIO(content)
|
|
426
469
|
|
|
427
|
-
|
|
470
|
+
try:
|
|
471
|
+
return await download(url, client)
|
|
472
|
+
except httpx.HTTPStatusError as e:
|
|
473
|
+
msg = f"HTTP error {e.response.status_code} when downloading from {url}"
|
|
474
|
+
git_url = to_git_url(url)
|
|
475
|
+
if git_url:
|
|
476
|
+
# sys.argv[1] might be -v or something else when running via pytest
|
|
477
|
+
try:
|
|
478
|
+
cmd = sys.argv[1]
|
|
479
|
+
if cmd not in ("pull", "check"):
|
|
480
|
+
cmd = "pull"
|
|
481
|
+
except IndexError:
|
|
482
|
+
cmd = "pull"
|
|
483
|
+
msg += (
|
|
484
|
+
f"\n\n💡 Check the URL and your permissions. "
|
|
485
|
+
"You might want to try cloning via git instead:\n\n"
|
|
486
|
+
f" ruff-sync {cmd} {git_url}"
|
|
487
|
+
)
|
|
488
|
+
else:
|
|
489
|
+
msg += "\n\n💡 Check the URL and your permissions."
|
|
490
|
+
|
|
491
|
+
# Re-raise with a more helpful message while preserving the original exception context
|
|
492
|
+
raise httpx.HTTPStatusError(msg, request=e.request, response=e.response) from None
|
|
428
493
|
|
|
429
494
|
|
|
430
495
|
def is_ruff_toml_file(path_or_url: str) -> bool:
|
|
@@ -1,9 +1,32 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import httpx
|
|
3
4
|
import pytest
|
|
4
|
-
from httpx import URL
|
|
5
|
+
from httpx import URL, AsyncClient
|
|
5
6
|
|
|
6
|
-
from ruff_sync import resolve_raw_url
|
|
7
|
+
from ruff_sync import fetch_upstream_config, is_ruff_toml_file, resolve_raw_url, to_git_url
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.mark.parametrize(
|
|
11
|
+
"path_or_url,expected",
|
|
12
|
+
[
|
|
13
|
+
("ruff.toml", True),
|
|
14
|
+
(".ruff.toml", True),
|
|
15
|
+
("configs/ruff.toml", True),
|
|
16
|
+
("pyproject.toml", False),
|
|
17
|
+
("https://example.com/ruff.toml", True),
|
|
18
|
+
("https://example.com/ruff.toml?ref=main", True),
|
|
19
|
+
("https://example.com/ruff.toml#L10", True),
|
|
20
|
+
("https://example.com/path/to/ruff.toml?query=1#frag", True),
|
|
21
|
+
("https://example.com/pyproject.toml?file=ruff.toml", False),
|
|
22
|
+
("https://example.com/ruff.toml/other", False),
|
|
23
|
+
# Case where it's not a URL but has query/fragment characters
|
|
24
|
+
("ruff.toml?raw=1", True),
|
|
25
|
+
("ruff.toml#section", True),
|
|
26
|
+
],
|
|
27
|
+
)
|
|
28
|
+
def test_is_ruff_toml_file(path_or_url: str, expected: bool):
|
|
29
|
+
assert is_ruff_toml_file(path_or_url) is expected
|
|
7
30
|
|
|
8
31
|
|
|
9
32
|
@pytest.mark.parametrize(
|
|
@@ -111,3 +134,85 @@ def test_raw_url_with_branch_and_path(input_url: str, branch: str, path: str, ex
|
|
|
111
134
|
url = URL(input_url)
|
|
112
135
|
result = resolve_raw_url(url, branch=branch, path=path)
|
|
113
136
|
assert str(result) == expected_url
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@pytest.mark.parametrize(
|
|
140
|
+
"input_url, expected_git_url",
|
|
141
|
+
[
|
|
142
|
+
# GitHub Browser URLs
|
|
143
|
+
(
|
|
144
|
+
"https://github.com/pydantic/pydantic/blob/main/pyproject.toml",
|
|
145
|
+
"git@github.com:pydantic/pydantic.git",
|
|
146
|
+
),
|
|
147
|
+
(
|
|
148
|
+
"https://github.com/org/repo/blob/develop/config/ruff.toml",
|
|
149
|
+
"git@github.com:org/repo.git",
|
|
150
|
+
),
|
|
151
|
+
# GitHub Repo URLs
|
|
152
|
+
(
|
|
153
|
+
"https://github.com/pydantic/pydantic",
|
|
154
|
+
"git@github.com:pydantic/pydantic.git",
|
|
155
|
+
),
|
|
156
|
+
# GitHub Raw URLs
|
|
157
|
+
(
|
|
158
|
+
"https://raw.githubusercontent.com/pydantic/pydantic/main/pyproject.toml",
|
|
159
|
+
"git@github.com:pydantic/pydantic.git",
|
|
160
|
+
),
|
|
161
|
+
# GitLab Repo URLs
|
|
162
|
+
(
|
|
163
|
+
"https://gitlab.com/gitlab-org/gitlab",
|
|
164
|
+
"git@gitlab.com:gitlab-org/gitlab.git",
|
|
165
|
+
),
|
|
166
|
+
(
|
|
167
|
+
"https://gitlab.com/gitlab-org/nested/group/sub-a/sub-b/project",
|
|
168
|
+
"git@gitlab.com:gitlab-org/nested/group/sub-a/sub-b/project.git",
|
|
169
|
+
),
|
|
170
|
+
# GitLab Blob URLs
|
|
171
|
+
(
|
|
172
|
+
"https://gitlab.com/gitlab-org/gitlab/-/blob/master/pyproject.toml",
|
|
173
|
+
"git@gitlab.com:gitlab-org/gitlab.git",
|
|
174
|
+
),
|
|
175
|
+
# Already git URLs
|
|
176
|
+
(
|
|
177
|
+
"git@github.com:org/repo.git",
|
|
178
|
+
"git@github.com:org/repo.git",
|
|
179
|
+
),
|
|
180
|
+
# Non-matching URLs
|
|
181
|
+
(
|
|
182
|
+
"https://example.com/pyproject.toml",
|
|
183
|
+
None,
|
|
184
|
+
),
|
|
185
|
+
],
|
|
186
|
+
)
|
|
187
|
+
def test_to_git_url(input_url: str, expected_git_url: str | None):
|
|
188
|
+
url = URL(input_url)
|
|
189
|
+
result = to_git_url(url)
|
|
190
|
+
if expected_git_url is None:
|
|
191
|
+
assert result is None
|
|
192
|
+
else:
|
|
193
|
+
assert str(result) == expected_git_url
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@pytest.mark.asyncio
|
|
197
|
+
async def test_fetch_upstream_config_http_error_with_git_suggestion(monkeypatch):
|
|
198
|
+
url = URL("https://github.com/org/repo/blob/main/pyproject.toml")
|
|
199
|
+
|
|
200
|
+
async def mock_get(*args, **kwargs):
|
|
201
|
+
# Create a mock response with 404 status
|
|
202
|
+
request = httpx.Request("GET", url)
|
|
203
|
+
response = httpx.Response(404, request=request)
|
|
204
|
+
response.raise_for_status()
|
|
205
|
+
|
|
206
|
+
# We need to mock the client's get method
|
|
207
|
+
# Since fetch_upstream_config uses the client passed to it
|
|
208
|
+
|
|
209
|
+
async with AsyncClient() as client:
|
|
210
|
+
monkeypatch.setattr(client, "get", mock_get)
|
|
211
|
+
|
|
212
|
+
with pytest.raises(httpx.HTTPStatusError) as excinfo:
|
|
213
|
+
await fetch_upstream_config(url, client, branch="main", path="")
|
|
214
|
+
|
|
215
|
+
error_msg = str(excinfo.value)
|
|
216
|
+
assert "HTTP error 404" in error_msg
|
|
217
|
+
assert "git@github.com:org/repo.git" in error_msg
|
|
218
|
+
assert "ruff-sync pull" in error_msg
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
from ruff_sync import is_ruff_toml_file
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@pytest.mark.parametrize(
|
|
9
|
-
"path_or_url,expected",
|
|
10
|
-
[
|
|
11
|
-
("ruff.toml", True),
|
|
12
|
-
(".ruff.toml", True),
|
|
13
|
-
("configs/ruff.toml", True),
|
|
14
|
-
("pyproject.toml", False),
|
|
15
|
-
("https://example.com/ruff.toml", True),
|
|
16
|
-
("https://example.com/ruff.toml?ref=main", True),
|
|
17
|
-
("https://example.com/ruff.toml#L10", True),
|
|
18
|
-
("https://example.com/path/to/ruff.toml?query=1#frag", True),
|
|
19
|
-
("https://example.com/pyproject.toml?file=ruff.toml", False),
|
|
20
|
-
("https://example.com/ruff.toml/other", False),
|
|
21
|
-
# Case where it's not a URL but has query/fragment characters
|
|
22
|
-
("ruff.toml?raw=1", True),
|
|
23
|
-
("ruff.toml#section", True),
|
|
24
|
-
],
|
|
25
|
-
)
|
|
26
|
-
def test_is_ruff_toml_file(path_or_url: str, expected: bool):
|
|
27
|
-
assert is_ruff_toml_file(path_or_url) is expected
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if __name__ == "__main__":
|
|
31
|
-
pytest.main([__file__, "-vv"])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_changes_upstream.toml
RENAMED
|
File without changes
|
{ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_dotted_keys_final.toml
RENAMED
|
File without changes
|
{ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_dotted_keys_initial.toml
RENAMED
|
File without changes
|
{ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_dotted_keys_upstream.toml
RENAMED
|
File without changes
|
|
File without changes
|
{ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_ruff_cfg_initial.toml
RENAMED
|
File without changes
|
{ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/no_ruff_cfg_upstream.toml
RENAMED
|
File without changes
|
{ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/readme_excludes_final.toml
RENAMED
|
File without changes
|
{ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/readme_excludes_initial.toml
RENAMED
|
File without changes
|
{ruff_sync-0.0.4.dev1 → ruff_sync-0.0.5.dev1}/tests/lifecycle_tomls/readme_excludes_upstream.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|