ruff-sync 0.0.2.dev0__tar.gz → 0.0.3__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.
Files changed (50) hide show
  1. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/.agents/TESTING.md +3 -3
  2. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/.agents/workflows/add-test-case.md +4 -4
  3. ruff_sync-0.0.3/.git-blame-ignore-revs +20 -0
  4. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/.github/dependabot.yml +5 -2
  5. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/.github/workflows/ci.yaml +26 -1
  6. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/PKG-INFO +105 -78
  7. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/README.md +104 -77
  8. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/pyproject.toml +2 -2
  9. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/ruff_sync.py +311 -70
  10. ruff_sync-0.0.2.dev0/scripts/dogfood_check.sh → ruff_sync-0.0.3/scripts/check_dogfood.sh +2 -2
  11. ruff_sync-0.0.3/scripts/gitclone_dogfood.sh +46 -0
  12. ruff_sync-0.0.2.dev0/scripts/dogfood.sh → ruff_sync-0.0.3/scripts/pull_dogfood.sh +3 -3
  13. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tasks.py +2 -8
  14. ruff_sync-0.0.3/tests/lifecycle_tomls/readme_excludes_final.toml +39 -0
  15. ruff_sync-0.0.3/tests/lifecycle_tomls/readme_excludes_initial.toml +39 -0
  16. ruff_sync-0.0.3/tests/lifecycle_tomls/readme_excludes_upstream.toml +37 -0
  17. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/test_basic.py +4 -12
  18. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/test_corner_cases.py +1 -3
  19. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/test_e2e.py +78 -21
  20. ruff_sync-0.0.3/tests/test_git_fetch.py +155 -0
  21. ruff_sync-0.0.3/tests/test_url_handling.py +113 -0
  22. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/uv.lock +1 -1
  23. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/.github/workflows/complexity.yaml +0 -0
  24. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/.gitignore +0 -0
  25. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/.pre-commit-config.yaml +0 -0
  26. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/AGENTS.md +0 -0
  27. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/LICENSE.md +0 -0
  28. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/codecov.yml +0 -0
  29. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/ruff_sync_banner.png +0 -0
  30. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/__init__.py +0 -0
  31. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/no_changes_final.toml +0 -0
  32. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/no_changes_initial.toml +0 -0
  33. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/no_changes_upstream.toml +0 -0
  34. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/no_dotted_keys_final.toml +0 -0
  35. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/no_dotted_keys_initial.toml +0 -0
  36. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/no_dotted_keys_upstream.toml +0 -0
  37. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/no_ruff_cfg_final.toml +0 -0
  38. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/no_ruff_cfg_initial.toml +0 -0
  39. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/no_ruff_cfg_upstream.toml +0 -0
  40. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/standard_final.toml +0 -0
  41. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/standard_initial.toml +0 -0
  42. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/lifecycle_tomls/standard_upstream.toml +0 -0
  43. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/ruff.toml +0 -0
  44. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/test_check.py +0 -0
  45. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/test_project.py +0 -0
  46. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/test_toml_operations.py +0 -0
  47. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/test_whitespace.py +0 -0
  48. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/w_ruff_sync_cfg/pyproject.toml +0 -0
  49. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/wo_ruff_cfg/pyproject.toml +0 -0
  50. {ruff_sync-0.0.2.dev0 → ruff_sync-0.0.3}/tests/wo_ruff_sync_cfg/pyproject.toml +0 -0
@@ -13,7 +13,7 @@ This document defines the mandatory testing standards and patterns for the `ruff
13
13
 
14
14
  ## 2. Tooling and Environment
15
15
 
16
- - **Execution**: Always run tests using `poetry run pytest -vv`.
16
+ - **Execution**: Always run tests using `uv run pytest -vv`.
17
17
  - **Async Tests**: We use `pytest-asyncio` in **strict mode**.
18
18
  - Always decorate async tests with `@pytest.mark.asyncio`.
19
19
  - **HTTP Mocking**: Use [respx](https://github.com/lundberg/respx) for all network interactions.
@@ -79,7 +79,7 @@ Each test case consists of three files in `tests/lifecycle_tomls/`:
79
79
  ### Scaffolding New Cases
80
80
  Use the provided Invoke task to create a new case from a template:
81
81
  ```bash
82
- poetry run invoke new-case --name <case_name> --description "Description of the edge case"
82
+ uv run invoke new-case --name <case_name> --description "Description of the edge case"
83
83
  ```
84
84
 
85
85
  ## 5. Standard Assertions for Merges
@@ -109,5 +109,5 @@ def test_my_edge_case():
109
109
  ## 6. Code Coverage
110
110
 
111
111
  We target **high coverage** for `ruff_sync.py`.
112
- - Run coverage locally: `poetry run coverage run -m pytest -vv && poetry run coverage report`
112
+ - Run coverage locally: `uv run coverage run -m pytest -vv && uv run coverage report`
113
113
  - New features MUST include unit tests in `tests/test_basic.py` or specialized files like `tests/test_whitespace.py` if they involve formatting logic.
@@ -12,7 +12,7 @@ Follow these steps to add a new end-to-end (E2E) test case for `ruff-sync` to te
12
12
  // turbo
13
13
  1. Run the `new-case` task to generate the file triple:
14
14
  ```bash
15
- poetry run invoke new-case --name <case_name> --description "Description of the test case"
15
+ uv run invoke new-case --name <case_name> --description "Description of the test case"
16
16
  ```
17
17
  *Replace `<case_name>` with a simple name (e.g., `dotted_keys`). This creates files in `tests/lifecycle_tomls/`.*
18
18
 
@@ -25,7 +25,7 @@ Follow these steps to add a new end-to-end (E2E) test case for `ruff-sync` to te
25
25
  // turbo
26
26
  1. Execute the tests to ensure the new case is picked up:
27
27
  ```bash
28
- poetry run pytest -vv tests/test_e2e.py
28
+ uv run pytest -vv tests/test_e2e.py
29
29
  ```
30
30
  *The E2E suite automatically discovers all file triples in the `lifecycle_tomls/` directory.*
31
31
 
@@ -33,6 +33,6 @@ Follow these steps to add a new end-to-end (E2E) test case for `ruff-sync` to te
33
33
  // turbo
34
34
  1. Ensure the new TOML files don't break any project rules:
35
35
  ```bash
36
- poetry run invoke lint --check
37
- poetry run invoke types
36
+ uv run invoke lint --check
37
+ uv run invoke types
38
38
  ```
@@ -0,0 +1,20 @@
1
+ # .git-blame-ignore-revs
2
+ #
3
+ # This file contains a list of Git commit hashes that should be ignored by
4
+ # `git blame`. It is primarily used for large-scale refactorings, purely
5
+ # stylistic changes, or mass-formatting that would otherwise "pollute" the
6
+ # blame history without changing the actual logic.
7
+ #
8
+ # Use this file VERY SELECTIVELY. Only include commits that are truly
9
+ # non-functional and where seeing the original author in the blame history
10
+ # provides no useful context for the code's behavior.
11
+ #
12
+ # Entries should follow this pattern:
13
+ #
14
+ # # <Brief description of the change>
15
+ # # PR: https://github.com/Kilo59/ruff-sync/pull/<PR_NUMBER>
16
+ # <COMMIT_HASH>
17
+
18
+ # Changing linelength to 100, other changes are tests and readme only
19
+ # PR: https://github.com/Kilo59/ruff-sync/pull/76
20
+ 75f9e34ced8537a32cdc62f85ae0f8e464756cee
@@ -1,9 +1,12 @@
1
1
  # Please see the documentation for all configuration options:
2
2
  # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
3
+ # https://docs.astral.sh/uv/guides/integration/dependency-bots/#dependabot
3
4
 
4
5
  version: 2
5
6
  updates:
6
7
  - package-ecosystem: "uv"
7
- directory: "/" # Location of package manifests
8
+ directory: "/"
8
9
  schedule:
9
- interval: daily
10
+ interval: "weekly"
11
+ cooldown:
12
+ default-days: 7
@@ -64,10 +64,35 @@ jobs:
64
64
  token: ${{ secrets.CODECOV_TOKEN }}
65
65
  slug: Kilo59/ruff-sync
66
66
 
67
+ pre-publish:
68
+ name: Test package installation
69
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
70
+ needs: [static-analysis, tests]
71
+ runs-on: ubuntu-latest
72
+ steps:
73
+ - name: Checkout
74
+ uses: actions/checkout@v4
75
+
76
+ - name: Install uv
77
+ uses: astral-sh/setup-uv@v5
78
+
79
+ - name: Set up Python
80
+ run: uv python install 3.10
81
+
82
+ - name: Build package
83
+ run: uv build
84
+
85
+ - name: Install and test packaged program
86
+ run: |
87
+ uv tool install $(ls dist/*.whl)
88
+ ruff-sync --version
89
+ ruff-sync https://github.com/Kilo59/ruff-sync
90
+ ruff-sync check https://github.com/Kilo59/ruff-sync
91
+
67
92
  publish:
68
93
  name: Build and publish to PyPI
69
94
  if: github.event_name == 'push' && github.ref == 'refs/heads/main'
70
- needs: [static-analysis, tests]
95
+ needs: [pre-publish]
71
96
  runs-on: ubuntu-latest
72
97
  permissions:
73
98
  # This permission is required for trusted publishing
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ruff-sync
3
- Version: 0.0.2.dev0
3
+ Version: 0.0.3
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
@@ -40,7 +40,9 @@ Description-Content-Type: text/markdown
40
40
 
41
41
  # ruff-sync
42
42
 
43
- **Keep your Ruff config consistent across every repo — automatically.**
43
+ **Keep your Ruff config consistent across multiple projects.**
44
+
45
+ `ruff-sync` is a CLI tool that pulls a canonical [Ruff](https://docs.astral.sh/ruff/) configuration from an upstream `pyproject.toml` (hosted anywhere — GitHub, GitLab, or any raw URL) and merges it into your local project, preserving your comments, formatting, and project-specific overrides.
44
46
 
45
47
  ---
46
48
 
@@ -49,16 +51,15 @@ Description-Content-Type: text/markdown
49
51
  - [The Problem](#the-problem)
50
52
  - [How It Works](#how-it-works)
51
53
  - [Quick Start](#quick-start)
52
- - [Install](#install)
53
- - [Usage](#usage)
54
54
  - [Key Features](#key-features)
55
- - [CI Integration](#ci-integration)
56
55
  - [Configuration](#configuration)
56
+ - [CI Integration](#ci-integration)
57
+ - [Example Workflow](#example-workflow)
58
+ - [Detailed Check Logic](#detailed-check-logic)
57
59
  - [Contributing](#contributing)
60
+ - [Dogfooding](#dogfooding)
58
61
  - [License](#license)
59
62
 
60
- `ruff-sync` is a CLI tool that pulls a canonical [Ruff](https://docs.astral.sh/ruff/) configuration from an upstream `pyproject.toml` (hosted anywhere — GitHub, GitLab, a raw URL) and merges it into your local project, preserving your comments, formatting, and project-specific overrides.
61
-
62
63
  ## The Problem
63
64
 
64
65
  If you maintain more than one Python project, you've probably copy-pasted your `[tool.ruff]` config between repos more than once. When you decide to enable a new rule or bump your target Python version, you get to do it again — in _every_ repo. Configs drift, standards diverge, and your "shared" style guide becomes a polite suggestion.
@@ -75,7 +76,7 @@ Ruff's `extend` is perfect inside a monorepo, but if your projects live in **sep
75
76
 
76
77
  **That's what `ruff-sync` does.**
77
78
 
78
- ## How It Works
79
+ ### How It Works
79
80
 
80
81
  ```
81
82
  ┌─────────────────────────────┐
@@ -140,74 +141,79 @@ uv tool install git+https://github.com/Kilo59/ruff-sync
140
141
  ### Usage
141
142
 
142
143
  ```console
143
- # Sync from a GitHub URL (blob URLs are auto-converted to raw)
144
+ # Sync from a GitHub/GitLab repository (defaults to main/pyproject.toml)
145
+ ruff-sync https://github.com/my-org/standards
146
+
147
+ # Or a direct blob/file URL (auto-converts to raw)
144
148
  ruff-sync https://github.com/my-org/standards/blob/main/pyproject.toml
145
149
 
146
- # Once configured in pyproject.toml (see below), simply run:
147
- ruff-sync
150
+ # Clone from any git repository (using SSH or HTTP, defaults to --depth 1)
151
+ # You can use the --branch flag to specify a branch (default: main)
152
+ ruff-sync git@github.com:my-org/standards.git
153
+ ruff-sync ssh://git@gitlab.com/my-org/standards.git
148
154
 
149
- # Sync into a specific project directory
150
- ruff-sync --source ./my-project
155
+ # Or if configured in pyproject.toml (see Configuration), simply run:
156
+ ruff-sync
151
157
 
152
158
  # Exclude specific sections from being overwritten using dotted paths
153
159
  ruff-sync --exclude lint.per-file-ignores lint.ignore
154
160
 
155
161
  # Check if your local config is in sync (useful in CI)
156
- ruff-sync check https://github.com/my-org/standards/blob/main/pyproject.toml
162
+ ruff-sync check https://github.com/my-org/standards
157
163
 
158
164
  # Semantic check — ignore cosmetic differences like comments and whitespace
159
165
  ruff-sync check --semantic
160
166
  ```
161
167
 
162
- ### CLI Reference
168
+ Run `ruff-sync --help` for full details on all available options.
163
169
 
164
- #### `ruff-sync`
170
+ ## Key Features
165
171
 
166
- ```
167
- usage: ruff-sync [-h] [--source SOURCE] [--exclude EXCLUDE [EXCLUDE ...]] [-v] [upstream]
168
-
169
- positional arguments:
170
- upstream The URL to download the pyproject.toml file from.
171
- Optional if defined in [tool.ruff-sync]
172
-
173
- optional arguments:
174
- -h, --help show this help message and exit
175
- --source SOURCE The directory or file to sync. Default: .
176
- --exclude EXCLUDE [EXCLUDE ...]
177
- Exclude certain ruff config keys. Default: lint.per-file-ignores
178
- -v, --verbose Increase verbosity. -v for INFO, -vv for DEBUG.
179
- ```
172
+ - **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.
173
+ - **GitHub & GitLab URL support** Automatically converts GitHub/GitLab repository URLs or blob URLs to raw content URLs.
174
+ - **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.
175
+ - **Selective exclusions** — Keep project-specific overrides (like `per-file-ignores` or `target-version`) from being clobbered by the upstream config.
176
+ - **Works with any host** — GitHub, GitLab, Bitbucket, private SSH servers, or any raw URL that serves a `pyproject.toml`.
177
+ - **CI-ready `check` command** — Verify that your local config is in sync without modifying anything. Exits 1 if out of sync, making it perfect for pre-merge gates. ([See detailed logic](#detailed-check-logic))
178
+ - **Semantic mode** — Use `--semantic` to ignore cosmetic differences (comments, whitespace) and only fail on real value changes.
180
179
 
181
- #### `ruff-sync check`
180
+ ## Configuration
182
181
 
183
- ```
184
- usage: ruff-sync check [-h] [--source SOURCE] [--exclude EXCLUDE [EXCLUDE ...]] [--semantic] [--no-diff] [-v] [upstream]
185
-
186
- positional arguments:
187
- upstream The URL to download the pyproject.toml file from.
188
- Optional if defined in [tool.ruff-sync]
189
-
190
- optional arguments:
191
- -h, --help show this help message and exit
192
- --source SOURCE The directory or file to check. Default: .
193
- --exclude EXCLUDE [EXCLUDE ...]
194
- Exclude certain ruff config keys.
195
- --semantic Ignore cosmetic differences (whitespace, comments);
196
- only fail on actual value changes.
197
- --no-diff Suppress the diff output.
198
- -v, --verbose Increase verbosity. -v for INFO, -vv for DEBUG.
182
+ You can configure `ruff-sync` itself in your `pyproject.toml`:
183
+
184
+ ```toml
185
+ [tool.ruff-sync]
186
+ # The source of truth for your Ruff configuration
187
+ upstream = "https://github.com/my-org/standards"
188
+
189
+ # Use simple names for top-level keys, and dotted paths for nested keys
190
+ exclude = [
191
+ "target-version", # Top-level [tool.ruff] key projects target different Python versions
192
+ "lint.per-file-ignores", # Project-specific file overrides
193
+ "lint.ignore", # Project-specific rule suppressions
194
+ "lint.isort.known-first-party", # Every project has different first-party packages
195
+ "lint.flake8-tidy-imports.banned-api", # Entire plugin section project-specific banned APIs
196
+ "lint.pydocstyle.convention", # Teams may disagree on google vs numpy vs pep257
197
+ ]
199
198
  ```
200
199
 
201
- Exits **0** if in sync, **1** if out of sync.
200
+ This sets the default upstream and exclusions so you don't need to pass them on the command line every time.
201
+ *Note: Any explicitly provided CLI arguments will override the values in `pyproject.toml`.*
202
202
 
203
- ## Key Features
203
+ ### Advanced Configuration
204
204
 
205
- - **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.
206
- - **GitHub URL support** — Paste a GitHub blob URL and it will automatically convert it to the raw content URL.
207
- - **Selective exclusions** — Keep project-specific overrides (like `target-version`) from being clobbered by the upstream config.
208
- - **Works with any host** — GitHub, GitLab, Bitbucket, or any raw URL that serves a `pyproject.toml`.
209
- - **CI-ready `check` command** — Verify that your local config is in sync without modifying anything. Exits 1 if out of sync, making it perfect for pre-merge gates.
210
- - **Semantic mode** — Use `--semantic` to ignore cosmetic differences (comments, whitespace) and only fail on real value changes.
205
+ For more complex setups, you can also configure the default branch and parent directory used when resolving repository URLs (e.g. `https://github.com/my-org/standards`):
206
+
207
+ ```toml
208
+ [tool.ruff-sync]
209
+ upstream = "https://github.com/my-org/standards"
210
+
211
+ # Use a specific branch or tag (default: "main")
212
+ branch = "develop"
213
+
214
+ # Specify a parent directory if pyproject.toml is not at the repo root
215
+ path = "config/ruff"
216
+ ```
211
217
 
212
218
  ## CI Integration
213
219
 
@@ -238,26 +244,6 @@ $ ruff-sync check --semantic
238
244
  ]
239
245
  ```
240
246
 
241
- ## Configuration
242
-
243
- You can configure `ruff-sync` itself in your `pyproject.toml`:
244
-
245
- ```toml
246
- [tool.ruff-sync]
247
- # The source of truth for your ruff configuration
248
- upstream = "https://github.com/my-org/standards/blob/main/pyproject.toml"
249
-
250
- # Use simple names for top-level keys, and dotted paths for nested keys
251
- exclude = [
252
- "target-version", # A top-level key under [tool.ruff]
253
- "lint.per-file-ignores", # A nested key under [tool.ruff.lint]
254
- "lint.ignore"
255
- ]
256
- ```
257
-
258
- This sets the default exclusions so you don't need to pass `--exclude` on the command line every time.
259
- *Note: Any explicitly provided CLI arguments will override the list in `pyproject.toml`.*
260
-
261
247
  ## Example Workflow
262
248
 
263
249
  A typical setup for an organization:
@@ -268,11 +254,49 @@ A typical setup for an organization:
268
254
 
269
255
  ```console
270
256
  # In each project repo:
271
- ruff-sync https://github.com/my-org/python-standards/blob/main/pyproject.toml
257
+ ruff-sync https://github.com/my-org/python-standards
272
258
  git diff pyproject.toml # review the changes
273
259
  git commit -am "sync ruff config from upstream"
274
260
  ```
275
261
 
262
+ ## Detailed Check Logic
263
+
264
+ When you run `ruff-sync check`, it follows this process to determine if your project has drifted from the upstream source:
265
+
266
+ ```mermaid
267
+ flowchart TD
268
+ Start([Start]) --> Local[Read Local pyproject.toml]
269
+ Local --> Upstream[Download Upstream pyproject.toml]
270
+ Upstream --> Extract[Extract tool.ruff section]
271
+ Extract --> Exclude[Apply Exclusions]
272
+ Exclude --> Merge[Perform in-memory Merge]
273
+
274
+ subgraph Comparison [Comparison Logic]
275
+ direction TB
276
+ SemanticNode{--semantic?}
277
+ SemanticNode -- Yes --> Unwrap[Unwrap TOML objects to Python Dicts]
278
+ Unwrap --> CompareVal[Compare Key/Value Pairs]
279
+ SemanticNode -- No --> CompareFull[Compare Full File Strings]
280
+ end
281
+
282
+ Merge --> Comparison
283
+
284
+ CompareVal --> ResultNode{Match?}
285
+ CompareFull --> ResultNode
286
+
287
+ ResultNode -- Yes --> Success([Exit 0: In Sync])
288
+ ResultNode -- No --> Diff[Generate Diff]
289
+ Diff --> Fail([Exit 1: Out of Sync])
290
+
291
+ %% Styling
292
+ style Start fill:#4a90e2,color:#fff,stroke:#357abd
293
+ style Success fill:#48c774,color:#fff,stroke:#36975a
294
+ style Fail fill:#f14668,color:#fff,stroke:#b2334b
295
+ style ResultNode fill:#ffdd57,color:#4a4a4a,stroke:#d4b106
296
+ style Comparison fill:none,stroke:#9e9e9e,stroke-dasharray: 5 5,stroke-width:2px
297
+ style SemanticNode fill:#f4f4f4,color:#363636,stroke:#dbdbdb
298
+ ```
299
+
276
300
  ## Contributing
277
301
 
278
302
  This project uses:
@@ -300,13 +324,16 @@ To see `ruff-sync` in action, you can "dogfood" it on this project's own config.
300
324
  **Check if this project is in sync with its upstream:**
301
325
 
302
326
  ```console
303
- ./scripts/dogfood_check.sh
327
+ ./scripts/check_dogfood.sh
304
328
  ```
305
329
 
306
330
  **Or sync from a large upstream like Pydantic's config:**
307
331
 
308
332
  ```console
309
- ./scripts/dogfood.sh
333
+ # Using a HTTP URL
334
+ ./scripts/pull_dogfood.sh
335
+ # Using a Git URL
336
+ ./scripts/gitclone_dogfood.sh
310
337
  ```
311
338
 
312
339
  This will download Pydantic's Ruff configuration and merge it into the local `pyproject.toml`. You can then use `git diff` to see how it merged the keys while preserving the existing structure and comments.