ruff-sync 0.1.0.dev1__tar.gz → 0.1.1.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.1.1.dev1/.agents/skills/release-notes-generation/SKILL.md +82 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.pre-commit-config.yaml +2 -1
- ruff_sync-0.1.1.dev1/.pre-commit-hooks.yaml +15 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/AGENTS.md +1 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/PKG-INFO +66 -21
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/README.md +65 -20
- ruff_sync-0.1.1.dev1/docs/assets/favicon.png +0 -0
- ruff_sync-0.1.1.dev1/docs/assets/logo.png +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/docs/ci-integration.md +7 -18
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/docs/configuration.md +16 -1
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/docs/index.md +20 -7
- ruff_sync-0.1.1.dev1/docs/pre-commit.md +69 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/docs/troubleshooting.md +39 -0
- ruff_sync-0.1.1.dev1/docs/usage.md +145 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/mkdocs.yml +7 -3
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/pyproject.toml +2 -2
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/src/ruff_sync/cli.py +63 -24
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/src/ruff_sync/core.py +146 -43
- ruff_sync-0.1.1.dev1/tests/lifecycle_tomls/multi_upstream_final.toml +8 -0
- ruff_sync-0.1.1.dev1/tests/lifecycle_tomls/multi_upstream_initial.toml +7 -0
- ruff_sync-0.1.1.dev1/tests/lifecycle_tomls/multi_upstream_up1.toml +5 -0
- ruff_sync-0.1.1.dev1/tests/lifecycle_tomls/multi_upstream_up2.toml +5 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_basic.py +322 -100
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_check.py +65 -6
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_deprecation.py +1 -1
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_e2e.py +51 -6
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_scaffold.py +6 -6
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/uv.lock +141 -125
- ruff_sync-0.1.0.dev1/docs/usage.md +0 -98
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.agents/TESTING.md +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.agents/skills/mkdocs-generation/SKILL.md +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.agents/skills/mkdocs-generation/examples.md +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.agents/skills/mkdocs-generation/templates/api-reference.md +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.agents/skills/mkdocs-generation/templates/getting-started.md +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.agents/skills/mkdocs-generation/templates/index.md +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.agents/skills/mkdocs-generation/templates/mkdocs.yml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.agents/workflows/add-test-case.md +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.git-blame-ignore-revs +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.github/dependabot.yml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.github/workflows/ci.yaml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.github/workflows/complexity.yaml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.github/workflows/docs.yaml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/.gitignore +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/LICENSE.md +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/codecov.yml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/configs/fastapi/ruff.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/configs/kitchen-sink/ruff.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/docs/assets/ruff_sync_banner.png +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/docs/gen_ref_pages.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/docs/installation.md +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/scripts/check_dogfood.sh +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/scripts/gitclone_dogfood.sh +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/scripts/pull_dogfood.sh +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/skills-lock.json +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/src/ruff_sync/__init__.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/src/ruff_sync/__main__.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tasks.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/__init__.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/conftest.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/no_changes_final.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/no_changes_initial.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/no_changes_upstream.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/no_dotted_keys_final.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/no_dotted_keys_initial.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/no_dotted_keys_upstream.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/no_ruff_cfg_final.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/no_ruff_cfg_initial.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/no_ruff_cfg_upstream.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/readme_excludes_final.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/readme_excludes_initial.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/readme_excludes_upstream.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/standard_final.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/standard_initial.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/lifecycle_tomls/standard_upstream.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/ruff.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_config_validation.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_corner_cases.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_git_fetch.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_project.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_toml_operations.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_url_handling.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/test_whitespace.py +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/w_ruff_sync_cfg/pyproject.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/wo_ruff_cfg/pyproject.toml +0 -0
- {ruff_sync-0.1.0.dev1 → ruff_sync-0.1.1.dev1}/tests/wo_ruff_sync_cfg/pyproject.toml +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-notes-generation
|
|
3
|
+
description: Draft professional and categorized release notes for ruff-sync using GitHub CLI, git history, and the `invoke release` task.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Release Notes Generation
|
|
7
|
+
|
|
8
|
+
This skill guides you through drafting high-quality release notes for `ruff-sync`. It leverages the `invoke release` task and GitHub CLI for context.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
|
|
12
|
+
- **GitHub CLI (`gh`)**: Must be authenticated.
|
|
13
|
+
- **Invoke**: Dev tasks are defined in `tasks.py`.
|
|
14
|
+
- **Git**: Recent history and tags must be available.
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
### 1. Gather Context
|
|
19
|
+
|
|
20
|
+
Before drafting, understand what has changed since the last release.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Get the latest release tag and notes
|
|
24
|
+
gh release list --limit 1
|
|
25
|
+
gh release view <tag>
|
|
26
|
+
|
|
27
|
+
# List merged PRs since the last tag
|
|
28
|
+
# Replace <tag> with the tag found above
|
|
29
|
+
gh pr list --state merged --search "merged:><tag-date>"
|
|
30
|
+
|
|
31
|
+
# Or simple git log
|
|
32
|
+
git log <tag>..HEAD --oneline
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Create Draft Release
|
|
36
|
+
|
|
37
|
+
Use the project's built-in release task to scaffold the release. This task automatically tags the release based on the version in `pyproject.toml` and uses GitHub's `--generate-notes` feature to create a starting point.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Create a draft release (default behavior of invoke release)
|
|
41
|
+
uv run invoke release --draft --skip-tests
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> [!NOTE]
|
|
45
|
+
> `invoke release` will:
|
|
46
|
+
> 1. Check if you are on `main`.
|
|
47
|
+
> 2. Check for clean git state.
|
|
48
|
+
> 3. Create a GitHub Release with `--generate-notes`.
|
|
49
|
+
|
|
50
|
+
### 3. Refine Release Notes
|
|
51
|
+
|
|
52
|
+
GitHub's automatically generated notes are a good start but often lack professional categorization and narrative. Use the following structure for final refinement:
|
|
53
|
+
|
|
54
|
+
#### Categorization
|
|
55
|
+
- **🚀 Features**: New capabilities added to `ruff_sync`.
|
|
56
|
+
- **🐞 Bug Fixes**: Issues resolved in CLI, merging logic, or HTTP handling.
|
|
57
|
+
- **✨ Improvements**: Enhancements to existing features, performance, or logging.
|
|
58
|
+
- **📖 Documentation**: Updates to `README.md`, `docs/`, or docstrings.
|
|
59
|
+
- **🛠️ Maintenance**: Dependency updates, CI changes, or test refactoring.
|
|
60
|
+
|
|
61
|
+
#### Writing Style
|
|
62
|
+
- Use clear, action-oriented language (e.g., "Add support...", "Fix issue where...", "Refactor...").
|
|
63
|
+
- Link to PRs and contributors using their GitHub handles.
|
|
64
|
+
- Include a "Breaking Changes" section if applicable (use `[!WARNING]` alerts).
|
|
65
|
+
|
|
66
|
+
### 4. Finalize
|
|
67
|
+
|
|
68
|
+
Once the notes are drafted and refined, you can view the draft on GitHub or update it via CLI.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# View the draft notes
|
|
72
|
+
gh release view v<version>
|
|
73
|
+
|
|
74
|
+
# Edit the draft (opens your editor)
|
|
75
|
+
gh release edit v<version> --notes "your new notes"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Tips
|
|
79
|
+
|
|
80
|
+
- **Consistency**: Refer to the `AGENTS.md` for project-specific terminology (e.g., "Upstream Layers").
|
|
81
|
+
- **Screenshots**: If the release includes significantly visible changes (e.g., new logging or CLI output formats), consider embedding a screenshot or recording in the notes.
|
|
82
|
+
- **Automated Summary**: You can ask the AI assistant to "Draft release notes based on the git log since <tag>" to get a structured summary before applying it to the release.
|
|
@@ -7,12 +7,13 @@ repos:
|
|
|
7
7
|
- id: check-yaml
|
|
8
8
|
args: ["--unsafe"]
|
|
9
9
|
exclude: .agents/skills/mkdocs-generation/templates/mkdocs.yml
|
|
10
|
+
- id: check-toml
|
|
10
11
|
- id: end-of-file-fixer
|
|
11
12
|
- id: trailing-whitespace
|
|
12
13
|
- id: no-commit-to-branch
|
|
13
14
|
args: [--branch, develop, --branch, main]
|
|
14
15
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
15
|
-
rev: "v0.15.
|
|
16
|
+
rev: "v0.15.6"
|
|
16
17
|
hooks:
|
|
17
18
|
- id: ruff-check
|
|
18
19
|
args: ["--fix"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
- id: ruff-sync-pull
|
|
2
|
+
name: ruff-sync-pull
|
|
3
|
+
description: Pull and apply upstream ruff configuration.
|
|
4
|
+
entry: ruff-sync pull
|
|
5
|
+
language: python
|
|
6
|
+
files: ^(\.ruff\.toml|ruff\.toml|pyproject\.toml)$
|
|
7
|
+
pass_filenames: false
|
|
8
|
+
|
|
9
|
+
- id: ruff-sync-check
|
|
10
|
+
name: ruff-sync-check
|
|
11
|
+
description: Check if ruff configuration is in sync with upstream.
|
|
12
|
+
entry: ruff-sync check --semantic
|
|
13
|
+
language: python
|
|
14
|
+
files: ^(\.ruff\.toml|ruff\.toml|pyproject\.toml)$
|
|
15
|
+
pass_filenames: false
|
|
@@ -150,6 +150,7 @@ uv run coverage run -m pytest -vv
|
|
|
150
150
|
- Use `pathlib` over `os.path` (enforced by `PTH` rules).
|
|
151
151
|
- Prefer f-strings for logging (we ignore `G004`).
|
|
152
152
|
- Do not create custom exception classes for simple errors (`TRY003` is ignored).
|
|
153
|
+
- **Prefer `NamedTuple` for return types** over plain tuples to improve readability and type safety.
|
|
153
154
|
|
|
154
155
|
### TOML Handling
|
|
155
156
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ruff-sync
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1.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://kilo59.github.io/ruff-sync/
|
|
@@ -54,6 +54,7 @@ Description-Content-Type: text/markdown
|
|
|
54
54
|
- [Quick Start](#quick-start)
|
|
55
55
|
- [Key Features](#key-features)
|
|
56
56
|
- [Configuration](#configuration)
|
|
57
|
+
- [Pre-commit Integration](#pre-commit-integration)
|
|
57
58
|
- [CI Integration](#ci-integration)
|
|
58
59
|
- [Example Workflow](#example-workflow)
|
|
59
60
|
- [Detailed Check Logic](#detailed-check-logic)
|
|
@@ -132,37 +133,64 @@ pip install ruff-sync
|
|
|
132
133
|
|
|
133
134
|
### Usage
|
|
134
135
|
|
|
136
|
+
**The Basic Sync**
|
|
137
|
+
|
|
138
|
+
```console
|
|
139
|
+
# Pull rules from a central repository into your current project
|
|
140
|
+
ruff-sync pull https://github.com/my-org/standards
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Persistent Configuration**
|
|
144
|
+
|
|
145
|
+
```console
|
|
146
|
+
# If configured in pyproject.toml (see Configuration), simply run:
|
|
147
|
+
ruff-sync pull
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Initializing a New Project**
|
|
151
|
+
|
|
152
|
+
```console
|
|
153
|
+
# Scaffold a new pyproject.toml if your directory is empty
|
|
154
|
+
ruff-sync pull https://github.com/my-org/standards --init
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Syncing Subdirectories or Specific Files**
|
|
158
|
+
|
|
135
159
|
```console
|
|
136
|
-
|
|
137
|
-
ruff-sync https://github.com/my-org/standards
|
|
138
|
-
|
|
160
|
+
ruff-sync pull https://github.com/my-org/standards/tree/main/configs/shared
|
|
161
|
+
ruff-sync pull https://github.com/my-org/standards/blob/main/pyproject.toml
|
|
162
|
+
```
|
|
139
163
|
|
|
140
|
-
|
|
141
|
-
ruff-sync https://github.com/my-org/standards/blob/main/pyproject.toml
|
|
164
|
+
**Using Git (SSH/HTTP)**
|
|
142
165
|
|
|
143
|
-
|
|
144
|
-
#
|
|
145
|
-
ruff-sync git@github.com:my-org/standards.git
|
|
146
|
-
|
|
166
|
+
```console
|
|
167
|
+
# Clones efficiently (depth 1, blob:none) to extract the config
|
|
168
|
+
ruff-sync pull git@github.com:my-org/standards.git
|
|
169
|
+
```
|
|
147
170
|
|
|
148
|
-
|
|
149
|
-
ruff-sync
|
|
171
|
+
**Excluding Specific Rules**
|
|
150
172
|
|
|
173
|
+
```console
|
|
151
174
|
# Exclude specific sections from being overwritten using dotted paths
|
|
152
|
-
ruff-sync --exclude lint.
|
|
175
|
+
ruff-sync pull --exclude lint.ignore
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Checking for Drift (CI)**
|
|
153
179
|
|
|
154
|
-
|
|
180
|
+
```console
|
|
181
|
+
# Verify local config matches upstream. Exits 1 if out of sync.
|
|
155
182
|
ruff-sync check https://github.com/my-org/standards
|
|
156
183
|
|
|
157
|
-
# Semantic check —
|
|
184
|
+
# Semantic check — ignores cosmetic differences like comments and whitespace
|
|
158
185
|
ruff-sync check --semantic
|
|
159
186
|
```
|
|
160
187
|
|
|
161
|
-
|
|
188
|
+
See the [Usage documentation](https://kilo59.github.io/ruff-sync/usage/) for more detailed examples and advanced workflows.
|
|
162
189
|
|
|
163
190
|
## Key Features
|
|
164
191
|
|
|
165
192
|
- 🏗️ **Format-preserving merges** — Uses [tomlkit](https://github.com/sdispater/tomlkit) under the hood, so your comments, whitespace, and TOML structure are preserved. No reformatting surprises.
|
|
193
|
+
- 📂 **Upstream Layers** — Merge configurations from several sources sequentially (e.g., base company config + team-specific overrides).
|
|
166
194
|
- 🌐 **GitHub & GitLab URL support** — Automatically converts GitHub/GitLab repository URLs, tree (directory) URLs, or blob (file) URLs to raw content URLs.
|
|
167
195
|
- 🔍 **Smart configuration discovery** — Point at a directory and `ruff-sync` will automatically find your config. It checks `pyproject.toml`, `ruff.toml`, and `.ruff.toml` (in that order).
|
|
168
196
|
- 📥 **Git clone support** — If the URL starts with `git@` or uses the `ssh://`, `git://`, or `git+ssh://` schemes, `ruff-sync` will perform an efficient shallow clone (using `--filter=blob:none` and `--no-checkout`) to safely extract the configuration with minimal network traffic.
|
|
@@ -200,8 +228,9 @@ Here are all the possible values that can be provided in `[tool.ruff-sync]` alon
|
|
|
200
228
|
|
|
201
229
|
```toml
|
|
202
230
|
[tool.ruff-sync]
|
|
203
|
-
# The source of truth URL for your Ruff configuration. (Required, unless passed via CLI)
|
|
204
|
-
|
|
231
|
+
# The source of truth URL(s) for your Ruff configuration. (Required, unless passed via CLI)
|
|
232
|
+
# Accepts a single string URL or a list of URLs.
|
|
233
|
+
upstream = ["https://github.com/my-org/standards", "https://github.com/my-org/team-tweaks"]
|
|
205
234
|
|
|
206
235
|
# A list of config keys to exclude from being synced. (Default: ["lint.per-file-ignores"])
|
|
207
236
|
# Use simple names for top-level keys, and dotted paths for nested keys.
|
|
@@ -221,6 +250,19 @@ path = "config/ruff"
|
|
|
221
250
|
to = "."
|
|
222
251
|
```
|
|
223
252
|
|
|
253
|
+
## Pre-commit Integration
|
|
254
|
+
|
|
255
|
+
Ensure your configuration is always in sync before every commit. Add this to your `.pre-commit-config.yaml`:
|
|
256
|
+
|
|
257
|
+
```yaml
|
|
258
|
+
- repo: https://github.com/Kilo59/ruff-sync
|
|
259
|
+
rev: v0.1.0 # Use the latest version
|
|
260
|
+
hooks:
|
|
261
|
+
- id: ruff-sync-check
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
See the [Pre-commit Guide](https://kilo59.github.io/ruff-sync/pre-commit/) for more details.
|
|
265
|
+
|
|
224
266
|
## CI Integration
|
|
225
267
|
|
|
226
268
|
The `check` command is designed for use in CI pipelines. Add it as a step to catch config drift before it merges:
|
|
@@ -329,10 +371,13 @@ When you run `ruff-sync check`, it follows this process to determine if your pro
|
|
|
329
371
|
```mermaid
|
|
330
372
|
flowchart TD
|
|
331
373
|
Start([Start]) --> Local[Read Local Configuration]
|
|
332
|
-
Local -->
|
|
333
|
-
|
|
374
|
+
Local --> Upstreams{For each Upstream}
|
|
375
|
+
Upstreams --> Download[Download/Clone Configuration]
|
|
376
|
+
Download --> Extract[Extract section if needed]
|
|
334
377
|
Extract --> Exclude[Apply Exclusions]
|
|
335
|
-
Exclude --> Merge[
|
|
378
|
+
Exclude --> Merge[Merge into in-memory Doc]
|
|
379
|
+
Merge --> Upstreams
|
|
380
|
+
Upstreams -- Done --> Comparison
|
|
336
381
|
|
|
337
382
|
subgraph Comparison [Comparison Logic]
|
|
338
383
|
direction TB
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
- [Quick Start](#quick-start)
|
|
24
24
|
- [Key Features](#key-features)
|
|
25
25
|
- [Configuration](#configuration)
|
|
26
|
+
- [Pre-commit Integration](#pre-commit-integration)
|
|
26
27
|
- [CI Integration](#ci-integration)
|
|
27
28
|
- [Example Workflow](#example-workflow)
|
|
28
29
|
- [Detailed Check Logic](#detailed-check-logic)
|
|
@@ -101,37 +102,64 @@ pip install ruff-sync
|
|
|
101
102
|
|
|
102
103
|
### Usage
|
|
103
104
|
|
|
105
|
+
**The Basic Sync**
|
|
106
|
+
|
|
107
|
+
```console
|
|
108
|
+
# Pull rules from a central repository into your current project
|
|
109
|
+
ruff-sync pull https://github.com/my-org/standards
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Persistent Configuration**
|
|
113
|
+
|
|
114
|
+
```console
|
|
115
|
+
# If configured in pyproject.toml (see Configuration), simply run:
|
|
116
|
+
ruff-sync pull
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Initializing a New Project**
|
|
120
|
+
|
|
121
|
+
```console
|
|
122
|
+
# Scaffold a new pyproject.toml if your directory is empty
|
|
123
|
+
ruff-sync pull https://github.com/my-org/standards --init
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Syncing Subdirectories or Specific Files**
|
|
127
|
+
|
|
104
128
|
```console
|
|
105
|
-
|
|
106
|
-
ruff-sync https://github.com/my-org/standards
|
|
107
|
-
|
|
129
|
+
ruff-sync pull https://github.com/my-org/standards/tree/main/configs/shared
|
|
130
|
+
ruff-sync pull https://github.com/my-org/standards/blob/main/pyproject.toml
|
|
131
|
+
```
|
|
108
132
|
|
|
109
|
-
|
|
110
|
-
ruff-sync https://github.com/my-org/standards/blob/main/pyproject.toml
|
|
133
|
+
**Using Git (SSH/HTTP)**
|
|
111
134
|
|
|
112
|
-
|
|
113
|
-
#
|
|
114
|
-
ruff-sync git@github.com:my-org/standards.git
|
|
115
|
-
|
|
135
|
+
```console
|
|
136
|
+
# Clones efficiently (depth 1, blob:none) to extract the config
|
|
137
|
+
ruff-sync pull git@github.com:my-org/standards.git
|
|
138
|
+
```
|
|
116
139
|
|
|
117
|
-
|
|
118
|
-
ruff-sync
|
|
140
|
+
**Excluding Specific Rules**
|
|
119
141
|
|
|
142
|
+
```console
|
|
120
143
|
# Exclude specific sections from being overwritten using dotted paths
|
|
121
|
-
ruff-sync --exclude lint.
|
|
144
|
+
ruff-sync pull --exclude lint.ignore
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Checking for Drift (CI)**
|
|
122
148
|
|
|
123
|
-
|
|
149
|
+
```console
|
|
150
|
+
# Verify local config matches upstream. Exits 1 if out of sync.
|
|
124
151
|
ruff-sync check https://github.com/my-org/standards
|
|
125
152
|
|
|
126
|
-
# Semantic check —
|
|
153
|
+
# Semantic check — ignores cosmetic differences like comments and whitespace
|
|
127
154
|
ruff-sync check --semantic
|
|
128
155
|
```
|
|
129
156
|
|
|
130
|
-
|
|
157
|
+
See the [Usage documentation](https://kilo59.github.io/ruff-sync/usage/) for more detailed examples and advanced workflows.
|
|
131
158
|
|
|
132
159
|
## Key Features
|
|
133
160
|
|
|
134
161
|
- 🏗️ **Format-preserving merges** — Uses [tomlkit](https://github.com/sdispater/tomlkit) under the hood, so your comments, whitespace, and TOML structure are preserved. No reformatting surprises.
|
|
162
|
+
- 📂 **Upstream Layers** — Merge configurations from several sources sequentially (e.g., base company config + team-specific overrides).
|
|
135
163
|
- 🌐 **GitHub & GitLab URL support** — Automatically converts GitHub/GitLab repository URLs, tree (directory) URLs, or blob (file) URLs to raw content URLs.
|
|
136
164
|
- 🔍 **Smart configuration discovery** — Point at a directory and `ruff-sync` will automatically find your config. It checks `pyproject.toml`, `ruff.toml`, and `.ruff.toml` (in that order).
|
|
137
165
|
- 📥 **Git clone support** — If the URL starts with `git@` or uses the `ssh://`, `git://`, or `git+ssh://` schemes, `ruff-sync` will perform an efficient shallow clone (using `--filter=blob:none` and `--no-checkout`) to safely extract the configuration with minimal network traffic.
|
|
@@ -169,8 +197,9 @@ Here are all the possible values that can be provided in `[tool.ruff-sync]` alon
|
|
|
169
197
|
|
|
170
198
|
```toml
|
|
171
199
|
[tool.ruff-sync]
|
|
172
|
-
# The source of truth URL for your Ruff configuration. (Required, unless passed via CLI)
|
|
173
|
-
|
|
200
|
+
# The source of truth URL(s) for your Ruff configuration. (Required, unless passed via CLI)
|
|
201
|
+
# Accepts a single string URL or a list of URLs.
|
|
202
|
+
upstream = ["https://github.com/my-org/standards", "https://github.com/my-org/team-tweaks"]
|
|
174
203
|
|
|
175
204
|
# A list of config keys to exclude from being synced. (Default: ["lint.per-file-ignores"])
|
|
176
205
|
# Use simple names for top-level keys, and dotted paths for nested keys.
|
|
@@ -190,6 +219,19 @@ path = "config/ruff"
|
|
|
190
219
|
to = "."
|
|
191
220
|
```
|
|
192
221
|
|
|
222
|
+
## Pre-commit Integration
|
|
223
|
+
|
|
224
|
+
Ensure your configuration is always in sync before every commit. Add this to your `.pre-commit-config.yaml`:
|
|
225
|
+
|
|
226
|
+
```yaml
|
|
227
|
+
- repo: https://github.com/Kilo59/ruff-sync
|
|
228
|
+
rev: v0.1.0 # Use the latest version
|
|
229
|
+
hooks:
|
|
230
|
+
- id: ruff-sync-check
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
See the [Pre-commit Guide](https://kilo59.github.io/ruff-sync/pre-commit/) for more details.
|
|
234
|
+
|
|
193
235
|
## CI Integration
|
|
194
236
|
|
|
195
237
|
The `check` command is designed for use in CI pipelines. Add it as a step to catch config drift before it merges:
|
|
@@ -298,10 +340,13 @@ When you run `ruff-sync check`, it follows this process to determine if your pro
|
|
|
298
340
|
```mermaid
|
|
299
341
|
flowchart TD
|
|
300
342
|
Start([Start]) --> Local[Read Local Configuration]
|
|
301
|
-
Local -->
|
|
302
|
-
|
|
343
|
+
Local --> Upstreams{For each Upstream}
|
|
344
|
+
Upstreams --> Download[Download/Clone Configuration]
|
|
345
|
+
Download --> Extract[Extract section if needed]
|
|
303
346
|
Extract --> Exclude[Apply Exclusions]
|
|
304
|
-
Exclude --> Merge[
|
|
347
|
+
Exclude --> Merge[Merge into in-memory Doc]
|
|
348
|
+
Merge --> Upstreams
|
|
349
|
+
Upstreams -- Done --> Comparison
|
|
305
350
|
|
|
306
351
|
subgraph Comparison [Comparison Logic]
|
|
307
352
|
direction TB
|
|
Binary file
|
|
Binary file
|
|
@@ -72,26 +72,9 @@ ruff-sync-check:
|
|
|
72
72
|
|
|
73
73
|
---
|
|
74
74
|
|
|
75
|
-
## 🛠️ Pre-commit Integration
|
|
76
|
-
|
|
77
75
|
You can use `ruff-sync` with `pre-commit` to ensure your configuration is always in sync before pushing.
|
|
78
76
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```yaml
|
|
82
|
-
repos:
|
|
83
|
-
- repo: local
|
|
84
|
-
hooks:
|
|
85
|
-
- id: ruff-sync-check
|
|
86
|
-
name: ruff-sync-check
|
|
87
|
-
entry: uvx ruff-sync check --semantic
|
|
88
|
-
language: system
|
|
89
|
-
files: ^pyproject\.toml$
|
|
90
|
-
pass_filenames: false
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
!!! note
|
|
94
|
-
Running `ruff-sync check` in pre-commit is fast because it only performs a network request if the local `pyproject.toml` is older than the upstream or if no cache exists.
|
|
77
|
+
See the [Pre-commit Guide](pre-commit.md) for details on using the official hooks.
|
|
95
78
|
|
|
96
79
|
---
|
|
97
80
|
|
|
@@ -101,6 +84,12 @@ repos:
|
|
|
101
84
|
|
|
102
85
|
In CI, you usually only care about the functional configuration. Using `--semantic` ensures that minor formatting changes don't break your builds, while still guaranteeing that the actual rules are identical.
|
|
103
86
|
|
|
87
|
+
### Handle Exclusions Properly
|
|
88
|
+
|
|
89
|
+
If your project intentionally diverges from the upstream (e.g., using different `per-file-ignores` or ignoring a specific rule), ensure those overrides are listed in the `[tool.ruff-sync]` `exclude` list in your `pyproject.toml`.
|
|
90
|
+
|
|
91
|
+
The `check` command respects your local `exclude` list. If you exclude a setting, `ruff-sync check` will completely ignore it when comparing against the upstream, ensuring that intended deviations never cause CI to fail!
|
|
92
|
+
|
|
104
93
|
### Use a Dedicated Workflow
|
|
105
94
|
|
|
106
95
|
Running `ruff-sync` as a separate job in your linting workflow makes it easy to identify when a failure is due to configuration drift rather than a code quality issue.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
| Key | Type | Default | Description |
|
|
8
8
|
| :--- | :--- | :--- | :--- |
|
|
9
|
-
| `upstream` | `str` | *Required* | The URL of the upstream `pyproject.toml` or `ruff.toml`. |
|
|
9
|
+
| `upstream` | `str \| list[str]` | *Required* | The URL(s) of the upstream `pyproject.toml` or `ruff.toml`. |
|
|
10
10
|
| `to` | `str` | `"."` | The local directory or file where configuration should be merged. |
|
|
11
11
|
| `exclude` | `list[str]` | `["lint.per-file-ignores"]` | A list of configuration keys to preserve locally. |
|
|
12
12
|
| `branch` | `str` | `"main"` | The default branch to use when resolving repository URLs. |
|
|
@@ -58,6 +58,21 @@ If your projects are on different Python versions but share linting rules:
|
|
|
58
58
|
exclude = ["target-version"]
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
#### Sequential merging of multiple sources
|
|
62
|
+
|
|
63
|
+
You can specify multiple upstream sources as a list. They will be merged in order—from top to bottom—with later sources overriding or extending earlier ones.
|
|
64
|
+
|
|
65
|
+
```toml
|
|
66
|
+
[tool.ruff-sync]
|
|
67
|
+
upstream = [
|
|
68
|
+
"https://github.com/my-org/shared-config", # 1. Base rules
|
|
69
|
+
"https://github.com/my-org/team-overrides", # 2. Team-specific tweaks (wins)
|
|
70
|
+
]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
!!! tip "Last One Wins"
|
|
74
|
+
The merge logic follows a "last one wins" approach for simple keys (like `line-length`), while performing a deep merge for configuration tables like `lint.per-file-ignores`.
|
|
75
|
+
|
|
61
76
|
## Deprecation Notes
|
|
62
77
|
|
|
63
78
|
- The key `source` in `[tool.ruff-sync]` is deprecated and will be removed in a future version. Use `to` instead.
|
|
@@ -13,10 +13,13 @@
|
|
|
13
13
|
## 🚀 Key Features
|
|
14
14
|
|
|
15
15
|
* **⚡ Fast & Lightweight**: Zero-config needed for most projects.
|
|
16
|
-
* **✨ Formatting Preserved**:
|
|
17
|
-
* **🛡️ Smart Merging**: Safely merges nested tables
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* **✨ Formatting Preserved**: Keeps all comments and whitespace via `tomlkit`.
|
|
17
|
+
* **🛡️ Smart Merging**: Safely merges nested tables without overwriting local overrides.
|
|
18
|
+
* **📂 Upstream Layers**: Combine and merge configurations from several sources sequentially.
|
|
19
|
+
* **🌐 Flexible Sources**: Sync from GitHub, GitLab, raw URLs, or local files.
|
|
20
|
+
* **📥 Efficient Git Support**: Shallow clones and sparse checkouts for fast extraction.
|
|
21
|
+
* **🚀 Zero-Config Bootstrapping**: Use `--init` to scaffold a new project in one command.
|
|
22
|
+
* **✅ CI Ready**: Built-in `check` command with semantic comparison logic.
|
|
20
23
|
|
|
21
24
|
---
|
|
22
25
|
|
|
@@ -37,16 +40,26 @@ Internal "base" configurations or shared presets often fall out of sync, or requ
|
|
|
37
40
|
|
|
38
41
|
## 🏁 Quick Start
|
|
39
42
|
|
|
40
|
-
### 1.
|
|
43
|
+
### 1. Initialize a new project (Optional)
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
If your local directory doesn't have a configuration file yet, you can fetch the standard and create one instantly:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uv run ruff-sync pull https://github.com/my-org/standards --init
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. Configure an existing project
|
|
52
|
+
|
|
53
|
+
Add the upstream URL to your `pyproject.toml` to make it the default:
|
|
43
54
|
|
|
44
55
|
```toml
|
|
45
56
|
[tool.ruff-sync]
|
|
46
57
|
upstream = "https://github.com/my-org/standards/blob/main/pyproject.toml"
|
|
47
58
|
```
|
|
48
59
|
|
|
49
|
-
###
|
|
60
|
+
### 3. Pull the configuration
|
|
61
|
+
|
|
62
|
+
Once configured, simply run:
|
|
50
63
|
|
|
51
64
|
```bash
|
|
52
65
|
uv run ruff-sync pull
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Pre-commit Integration
|
|
2
|
+
|
|
3
|
+
Using `ruff-sync` with [pre-commit](https://pre-commit.com/) ensures that your Ruff configuration stays in sync with your organization's standards automatically.
|
|
4
|
+
|
|
5
|
+
## Official Hooks
|
|
6
|
+
|
|
7
|
+
`ruff-sync` provides two official hooks:
|
|
8
|
+
|
|
9
|
+
### `ruff-sync-check`
|
|
10
|
+
|
|
11
|
+
Verifies that your local `pyproject.toml` or `ruff.toml` matches the upstream configuration. It is recommended to use this hook to prevent accidental drift.
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
- repo: https://github.com/Kilo59/ruff-sync
|
|
15
|
+
rev: v0.1.0 # Use the latest version
|
|
16
|
+
hooks:
|
|
17
|
+
- id: ruff-sync-check
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### `ruff-sync-pull`
|
|
21
|
+
|
|
22
|
+
Automatically pulls and applies the upstream configuration if a drift is detected.
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
- repo: https://github.com/Kilo59/ruff-sync
|
|
26
|
+
rev: v0.1.0 # Use the latest version
|
|
27
|
+
hooks:
|
|
28
|
+
- id: ruff-sync-pull
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Configuration
|
|
32
|
+
|
|
33
|
+
The hooks will automatically respect the configuration defined in your `pyproject.toml` under `[tool.ruff-sync]`. Any arguments passed via `args` in `.pre-commit-config.yaml` will override these settings.
|
|
34
|
+
|
|
35
|
+
> [!NOTE]
|
|
36
|
+
> For a full list of configuration options, see the [Configuration Guide](configuration.md).
|
|
37
|
+
|
|
38
|
+
### Example `.pre-commit-config.yaml`
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
repos:
|
|
42
|
+
- repo: https://github.com/Kilo59/ruff-sync
|
|
43
|
+
rev: v0.1.0
|
|
44
|
+
hooks:
|
|
45
|
+
- id: ruff-sync-check
|
|
46
|
+
# Common arguments:
|
|
47
|
+
# --semantic: ignore cosmetic changes (default in check hook)
|
|
48
|
+
# --no-diff: hide the unified diff
|
|
49
|
+
# --to PATH: sync to a specific file or directory
|
|
50
|
+
args: ["--semantic", "--no-diff"]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Why use `ruff-sync-check`?
|
|
54
|
+
|
|
55
|
+
Running `ruff-sync check` in pre-commit is fast because:
|
|
56
|
+
|
|
57
|
+
1. It only checks the `[tool.ruff]` section of the configuration.
|
|
58
|
+
2. It minimizes network overhead by only fetching exactly what it needs (e.g., using direct HTTP requests for single files or partial git cloning for repositories).
|
|
59
|
+
3. By default, it uses `--semantic` to ignore formatting-only differences, reducing false positives.
|
|
60
|
+
|
|
61
|
+
For more complex scenarios, such as syncing from multiple upstreams or using directory prefixes, see [Advanced Usage](usage.md#advanced-usage).
|
|
62
|
+
|
|
63
|
+
## Manual Execution
|
|
64
|
+
|
|
65
|
+
You can always run the hooks manually using:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pre-commit run ruff-sync-check --all-files
|
|
69
|
+
```
|
|
@@ -4,6 +4,21 @@ Common issues and questions when using `ruff-sync`.
|
|
|
4
4
|
|
|
5
5
|
## Common Issues
|
|
6
6
|
|
|
7
|
+
### Debug Logging
|
|
8
|
+
|
|
9
|
+
If `ruff-sync` is not behaving as expected, you can increase the verbosity of the logs to see what's happening under the hood.
|
|
10
|
+
|
|
11
|
+
**Usage**:
|
|
12
|
+
|
|
13
|
+
- `-v`: Shows `INFO` level logs (e.g., which configuration file is being used, where upstreams are being sourced from).
|
|
14
|
+
- `-vv`: Shows `DEBUG` level logs (e.g., detailed TOML merging operations and raw HTTP/Git requests).
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
ruff-sync pull -vv
|
|
20
|
+
```
|
|
21
|
+
|
|
7
22
|
### Upstream URL not found
|
|
8
23
|
|
|
9
24
|
**Error**: `Error: Upstream Required. No upstream URL found in pyproject.toml or provided as argument.`
|
|
@@ -31,6 +46,30 @@ Use the `--exclude` flag to keep your local settings:
|
|
|
31
46
|
ruff-sync pull --exclude lint.line-length
|
|
32
47
|
```
|
|
33
48
|
|
|
49
|
+
### Multi-upstream Fetch Failures
|
|
50
|
+
|
|
51
|
+
**Error**: `❌ <N> upstream fetches failed`
|
|
52
|
+
|
|
53
|
+
This happens when one or more of the specified upstream URLs cannot be reached, do not exist, or return an error (e.g., 404 or 403). `ruff-sync` fetches all upstreams concurrently for speed, but requires ALL of them to succeed before it will attempt to merge.
|
|
54
|
+
|
|
55
|
+
**Solution**:
|
|
56
|
+
1. Check each URL in the terminal output to see which specific one failed.
|
|
57
|
+
2. Verify you have network access and the correct permissions for each source.
|
|
58
|
+
3. If an HTTP source is blocked or private, consider using a Git SSH URL instead.
|
|
59
|
+
|
|
60
|
+
### Git SSH Workaround for Fetch Errors
|
|
61
|
+
|
|
62
|
+
If you see an HTTP `403 Forbidden` or `404 Not Found` when trying to fetch from GitHub or GitLab, it might be due to authentication requirements.
|
|
63
|
+
|
|
64
|
+
**Solution**:
|
|
65
|
+
Use the git-clone alternative suggested in the error message:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
ruff-sync pull git@github.com:org/repo.git
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This uses your local SSH keys and is often more reliable for internal or private repositories.
|
|
72
|
+
|
|
34
73
|
## FAQ
|
|
35
74
|
|
|
36
75
|
### Does it support `ruff.toml`?
|