Skip to content

Zero config bootstrap#82

Merged
Kilo59 merged 12 commits intomainfrom
zero-config-bootstrap
Mar 9, 2026
Merged

Zero config bootstrap#82
Kilo59 merged 12 commits intomainfrom
zero-config-bootstrap

Conversation

@Kilo59
Copy link
Copy Markdown
Owner

@Kilo59 Kilo59 commented Mar 9, 2026

🚀 Overview

This PR introduces the --init flag, enabling a "Zero-Config" bootstrapping experience. It also adds first-class support for standalone ruff.toml and .ruff.toml files, making ruff-sync more versatile for projects that don't use pyproject.toml.

✨ Key Changes

🛠️ Bootstrapping with --init

Added a new --init flag to the pull command. In a fresh project with no existing configuration, you can now run:

ruff-sync pull https://github.com/my-org/standards --init

This will scaffold a new pyproject.toml (or ruff.toml) pre-filled with the upstream settings, eliminating the need for manual setup.

📄 Standalone Config Support

  • Added is_ruff_toml_file helper for intelligent file type detection.
  • ruff-sync now correctly identifies and handles ruff.toml and .ruff.toml files as both sources and targets.
  • Improved URL parsing to handle query parameters and fragments (e.g., copied GitHub permalinks with line numbers).

💅 CLI & DX Improvements

  • Relative Path Reporting: The CLI now prints relative paths in success messages (e.g., ✅ Updated pyproject.toml instead of absolute paths) for a cleaner UX.
  • Robustness: Refactored get_config to be more resilient and handle cases where files are missing during initialization.
  • Visual Polish: Added descriptive emojis to the "Key Features" list in the README to improve scanability.

🧪 Testing

  • Added unit tests for is_ruff_toml_file to cover various URL formats (parameters, fragments, local paths).
  • Verified the --init workflow creates valid TOML files from scratch.
  • Confirmed that comments and structure are still preserved during standard merges.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Mar 9, 2026

Reviewer's Guide

Adds zero-config bootstrapping and standalone ruff.toml support to ruff-sync, refactors Ruff config parsing/merging to work for both pyproject and ruff.toml, tightens [tool.ruff-sync] config validation, and updates docs/tests (including new scaffold and config validation test suites).

Sequence diagram for the updated pull command with zero-config init and ruff.toml support

sequenceDiagram
    actor User
    participant CLI as main
    participant Parser as _get_cli_parser
    participant Args as Arguments
    participant FS as Filesystem
    participant TOML as TOMLFile
    participant HTTP as httpx_AsyncClient
    participant CFG as get_ruff_config
    participant MERGE as merge_ruff_toml

    User->>CLI: invoke ruff_sync pull upstream_url --init
    CLI->>Parser: build parser with pull subcommand and init flag
    Parser-->>CLI: parsed argparse Namespace
    CLI->>Args: Arguments.from_cli
    Args-->>CLI: exec_args (includes init, source, upstream)

    CLI->>CLI: _resolve_target_path(exec_args)
    alt source is file
        CLI-->>CLI: use args.source as target path
    else ruff.toml exists
        CLI-->>CLI: use source/ruff.toml
    else .ruff.toml exists
        CLI-->>CLI: use source/.ruff.toml
    else upstream points to ruff.toml
        CLI-->>CLI: use source/ruff.toml
    else
        CLI-->>CLI: use source/pyproject.toml
    end

    CLI->>FS: check if target path exists
    alt file exists
        FS-->>CLI: file found
        CLI->>TOML: read existing document
        TOML-->>CLI: source_doc
    else file missing and init is true
        FS-->>CLI: missing
        CLI->>FS: mkdir parents, touch target file
        CLI->>TOML: create empty tomlkit.document
        TOML-->>CLI: source_doc
    else file missing and init is false
        CLI-->>User: print error and return 1
        CLI-->>User: return
    end

    CLI->>HTTP: create AsyncClient
    CLI->>HTTP: download upstream config
    HTTP-->>CLI: upstream TOML text

    CLI->>CFG: get_ruff_config(upstream_text, is_ruff_toml)
    CFG-->>CLI: upstream_ruff_config (TOMLDocument or Table)

    CLI->>MERGE: merge_ruff_toml(source_doc, upstream_ruff_config, is_ruff_toml)
    MERGE-->>CLI: merged_doc

    CLI->>TOML: write merged_doc to target path
    TOML-->>CLI: write complete
    CLI-->>User: print Updated relative_path
    CLI-->>User: exit code 0
Loading

Class diagram for Arguments, Config, and Ruff configuration helpers

classDiagram
    class Arguments {
        +str command
        +pathlib_Path source
        +str upstream
        +list~str~ exclude
        +str branch
        +str path
        +bool semantic
        +bool diff
        +bool init
        +classmethod from_cli(raw_args)
        +@staticmethod fields()
    }

    class Config {
        +Optional~str~ upstream
        +Optional~list~ exclude
        +Optional~str~ branch
        +Optional~str~ path
        +Optional~bool~ semantic
        +Optional~bool~ diff
        +Optional~bool~ init
    }

    class get_config {
        +get_config(source)
    }

    class get_ruff_config {
        +get_ruff_config(toml, is_ruff_toml, create_if_missing, exclude)
    }

    class merge_ruff_toml {
        +merge_ruff_toml(source, upstream_ruff_doc, is_ruff_toml)
    }

    class is_ruff_toml_file {
        +is_ruff_toml_file(path_or_url)
    }

    class _resolve_target_path {
        +_resolve_target_path(args)
    }

    class check {
        +check(args)
    }

    class pull {
        +pull(args)
    }

    class _apply_exclusions {
        +_apply_exclusions(tbl, exclude)
    }

    class _recursive_update {
        +_recursive_update(source_table, upstream)
    }

    class main {
        +main()
    }

    get_config --> Config : returns
    main --> get_config : calls
    main --> _resolve_target_path : uses via check, pull
    main --> check : may call
    main --> pull : may call

    pull --> _resolve_target_path : resolve target path
    pull --> is_ruff_toml_file : detect upstream and source type
    pull --> get_ruff_config : read upstream ruff config
    pull --> merge_ruff_toml : merge upstream into source

    check --> _resolve_target_path : resolve target path
    check --> is_ruff_toml_file : detect upstream and source type
    check --> get_ruff_config : read upstream ruff config
    check --> merge_ruff_toml : compute merged_doc

    merge_ruff_toml --> get_ruff_config : obtain tool_ruff section when pyproject
    merge_ruff_toml --> _recursive_update : merge structures
    get_ruff_config --> _apply_exclusions : apply exclude paths

    main --> Arguments : constructs
    get_config --> Arguments : uses fields to validate keys
Loading

Flow diagram for resolving the target configuration path

flowchart TD
    Start[[Start _resolve_target_path]]
    SRC[args.source]
    QFile{Is args.source a file?}
    QRuff{Does source/ruff.toml exist?}
    QDotRuff{Does source/.ruff.toml exist?}
    QUpstream{Is args.upstream a ruff.toml?}
    PyProj[source/pyproject.toml]
    Ruff[source/ruff.toml]
    DotRuff[source/.ruff.toml]
    UseFile[Use args.source]
    UseRuff[Use source/ruff.toml]
    UseDotRuff[Use source/.ruff.toml]
    UsePyProj[Use source/pyproject.toml]
    End[[Return target path]]

    Start --> SRC --> QFile
    QFile -- Yes --> UseFile --> End
    QFile -- No --> QRuff
    QRuff -- Yes --> Ruff --> UseRuff --> End
    QRuff -- No --> QDotRuff
    QDotRuff -- Yes --> DotRuff --> UseDotRuff --> End
    QDotRuff -- No --> QUpstream
    QUpstream -- Yes --> Ruff --> UseRuff --> End
    QUpstream -- No --> PyProj --> UsePyProj --> End
Loading

File-Level Changes

Change Details Files
Add CLI --init support and target config resolution so pull/check can bootstrap or locate pyproject.toml vs ruff.toml/.ruff.toml automatically.
  • Extend Arguments and Config to include an init flag and propagate it from CLI parsing into the execution arguments.
  • Add --init option to the pull subcommand and wire it into main() argument construction.
  • Introduce _resolve_target_path to derive the effective config file based on source path, local ruff.toml/.ruff.toml presence, and upstream type.
  • Update check() to use _resolve_target_path, handle missing config files gracefully, and exit with guidance when no config exists.
  • Update pull() to support bootstrapping: create an empty TOML document and scaffold the file when --init is set, or fail with a clear message when missing and --init is not provided, including robust relative path printing for the updated file.
ruff_sync.py
Generalize Ruff configuration handling to support both [tool.ruff] in pyproject.toml and root-level ruff.toml documents, including exclusion handling and merging.
  • Add is_ruff_toml_file helper to detect ruff.toml-like paths/URLs.
  • Rename and generalize get_ruff_tool_table to get_ruff_config with overloads and an is_ruff_toml flag, returning either the root TOML document or the [tool.ruff] table as appropriate while still applying exclusions.
  • Alias get_ruff_tool_table to get_ruff_config for backward compatibility with existing callers.
  • Relax _apply_exclusions to accept either a Table or full TOMLDocument, so exclusions can be applied both to [tool.ruff] tables and top-level ruff.toml documents.
  • Extend merge_ruff_toml to accept an is_ruff_toml flag, merging entire root documents in ruff.toml mode vs. tool.ruff tables in pyproject mode, and update check()/pull() to compute and pass is_upstream_ruff_toml/is_source_ruff_toml and use get_ruff_config accordingly.
  • Adjust semantic comparison in check() to compare either root documents (for ruff.toml) or tool.ruff tables (for pyproject.toml).
ruff_sync.py
tests/test_basic.py
tests/test_scaffold.py
Restrict [tool.ruff-sync] config keys to an allowlist and surface warnings for unknown/unsupported keys, with tests.
  • Document that get_config reads [tool.ruff-sync] from pyproject.toml and derive an allowed_keys set from the Config TypedDict annotations instead of Arguments.fields().
  • Change get_config to only accept keys present in Config and log a warning via LOGGER for unknown keys (including disallowed ones like command).
  • Ensure logging configuration in main() is set up before get_config usage in runtime, and add a test helper fixture to make LOGGER warnings visible to caplog in tests.
  • Add tests for warning on unknown and disallowed keys and verifying they are filtered from the resulting configuration.
ruff_sync.py
tests/test_config_validation.py
Update documentation to describe ruff.toml support, bootstrapping with --init, and clarify [tool.ruff-sync] options and internal testing guidelines.
  • Update README to mention upstream/target ruff.toml support, extend the feature list bullets, and add a dedicated bootstrapping section explaining the --init flow and how ruff.toml vs pyproject.toml are handled.
  • Expand the Advanced Configuration section to explicitly list all [tool.ruff-sync] options with explanations and defaults and remove the general Contributing section from README (likely moved elsewhere).
  • Tighten internal testing guidelines in .agents/TESTING.md by forbidding autouse fixtures and requiring a main entry point in every test file, including rationale.
README.md
.agents/TESTING.md
Add tests around scaffolding behavior and adjust existing tests for typing/behavior changes.
  • Introduce tests/test_scaffold.py to cover pull behavior with and without --init, ensuring failure on missing config without init and correct scaffolding for pyproject.toml and ruff.toml targets using pyfakefs and respx.
  • Update test_basic exclusions tests to drop now-unnecessary mypy-specific ignore comments while validating target-version behavior remains unchanged.
  • Ensure new tests comply with the updated testing guidelines by including a main entry point where required.
tests/test_basic.py
tests/test_scaffold.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 9, 2026

Codecov Report

❌ Patch coverage is 85.91549% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.48%. Comparing base (ed0945f) to head (88f449a).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
ruff_sync.py 85.91% 10 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #82      +/-   ##
==========================================
- Coverage   92.13%   90.48%   -1.65%     
==========================================
  Files           1        1              
  Lines         356      410      +54     
==========================================
+ Hits          328      371      +43     
- Misses         28       39      +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Kilo59 Kilo59 marked this pull request as ready for review March 9, 2026 00:55
@Kilo59 Kilo59 self-assigned this Mar 9, 2026
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • The new is_ruff_toml_file helper relies on a simple .endswith("ruff.toml") check, which will fail for common URL patterns with query strings or fragments (e.g. ruff.toml?raw=1); consider using URL parsing or a more robust suffix check to avoid misclassifying valid upstream configs.
  • The updated testing guidelines require each test file to end with a __main__ block, but tests/test_scaffold.py is missing this, so it would be good to add the standard if __name__ == "__main__": pytest.main([...]) footer there for consistency.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `is_ruff_toml_file` helper relies on a simple `.endswith("ruff.toml")` check, which will fail for common URL patterns with query strings or fragments (e.g. `ruff.toml?raw=1`); consider using URL parsing or a more robust suffix check to avoid misclassifying valid upstream configs.
- The updated testing guidelines require each test file to end with a `__main__` block, but `tests/test_scaffold.py` is missing this, so it would be good to add the standard `if __name__ == "__main__": pytest.main([...])` footer there for consistency.

## Individual Comments

### Comment 1
<location path="ruff_sync.py" line_range="429-431" />
<code_context>
     return await download(url, client)


+def is_ruff_toml_file(path_or_url: str) -> bool:
+    """Return True if the path or URL indicates a ruff.toml file."""
+    return path_or_url.endswith("ruff.toml")
+
+
</code_context>
<issue_to_address>
**suggestion:** Relying on `endswith("ruff.toml")` might misclassify URLs with query strings or fragments.

This correctly handles plain paths and URLs that literally end with `ruff.toml` (including `.ruff.toml`), but will return `False` for cases like `...?file=ruff.toml` or `ruff.toml?ref=main`. If such URLs are expected, consider parsing with `urllib.parse.urlparse` and applying `endswith("ruff.toml")` to the path component, or otherwise checking only the part before any query string or fragment.

Suggested implementation:

```python
def is_ruff_toml_file(path_or_url: str) -> bool:
    """Return True if the path or URL indicates a ruff.toml file.

    This handles:
    - Plain paths (e.g. "ruff.toml", ".ruff.toml", "configs/ruff.toml")
    - URLs with query strings or fragments (e.g. "ruff.toml?ref=main", "ruff.toml#L10")
    by examining only the path component (or the part before any query/fragment).
    """
    parsed = urlparse(path_or_url)

    # If it's a URL with a scheme/netloc, use the parsed path component.
    # Otherwise, fall back to stripping any query/fragment from the raw string.
    if parsed.scheme or parsed.netloc:
        path = parsed.path
    else:
        path = path_or_url.split("?", 1)[0].split("#", 1)[0]

    return path.endswith("ruff.toml")

```

Add the missing import near the other imports at the top of `ruff_sync.py`:

- `from urllib.parse import urlparse`

This ensures `urlparse` is available for `is_ruff_toml_file`. No other changes should be required.
</issue_to_address>

### Comment 2
<location path="tests/test_scaffold.py" line_range="8-10" />
<code_context>
+"""
+
+
+@pytest.mark.asyncio
+async def test_pull_without_init_fails_on_missing_file(
+    mock_http: respx.MockRouter, fs: FakeFilesystem, capsys: pytest.CaptureFixture[str]
+):
+    target_dir = pathlib.Path(fs.create_dir("empty_dir").path)  # type: ignore[arg-type]
+
+    upstream = URL("https://example.com/pyproject.toml")
+    result = await ruff_sync.pull(
+        ruff_sync.Arguments(
+            command="pull",
+            upstream=upstream,
+            source=target_dir,
+            exclude=(),
+            verbose=0,
+            init=False,
+        )
+    )
+
+    assert result == 1
+    captured = capsys.readouterr()
+    assert "Configuration file" in captured.out
+    assert "does not exist" in captured.out
+    assert "Pass the '--init' flag" in captured.out
+    assert not (target_dir / "pyproject.toml").exists()
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add coverage for `_resolve_target_path` when a config file already exists, and for `.ruff.toml` resolution

The current tests only cover the "no config present" case. Please also exercise `_resolve_target_path` when config files already exist, including its precedence of `ruff.toml``.ruff.toml``pyproject.toml`. Concretely, add tests that:

- Start with an existing `pyproject.toml` and verify `pull --init` uses it and does not create `ruff.toml`.
- Start with both `pyproject.toml` and `.ruff.toml` and assert `.ruff.toml` is selected.
- Start with only `.ruff.toml` and verify `pull` updates it.

This will cover the key branches in `_resolve_target_path` and guard against regressions in file selection behavior.

```suggestion
from httpx import URL, Response

import ruff_sync


@pytest.mark.asyncio
async def test_pull_init_uses_existing_pyproject_toml(
    mock_http: respx.MockRouter, fs: "FakeFilesystem", capsys: pytest.CaptureFixture[str]
) -> None:
    # Arrange: existing pyproject.toml, no ruff.toml or .ruff.toml
    directory = fs.create_dir("project_with_pyproject")
    target_dir = pathlib.Path(directory.path)  # type: ignore[arg-type]
    pyproject_path = target_dir / "pyproject.toml"

    fs.create_file(str(pyproject_path), contents="[tool.ruff]\nline-length = 79\n")

    upstream = URL("https://example.com/pyproject.toml")
    mock_http.get(str(upstream), return_value=Response(200, text="[tool.ruff]\nline-length = 88\n"))

    # Act
    result = await ruff_sync.pull(
        ruff_sync.Arguments(
            command="pull",
            upstream=upstream,
            source=target_dir,
            exclude=(),
            verbose=0,
            init=True,
        )
    )

    # Assert: command succeeded, existing pyproject.toml was used as target
    assert result == 0
    captured = capsys.readouterr()
    assert "pyproject.toml" in captured.out

    assert pyproject_path.exists()
    assert (target_dir / "ruff.toml").exists() is False
    assert (target_dir / ".ruff.toml").exists() is False

    contents = pyproject_path.read_text()
    assert "line-length = 88" in contents


@pytest.mark.asyncio
async def test_pull_prefers_dot_ruff_toml_over_pyproject_toml(
    mock_http: respx.MockRouter, fs: "FakeFilesystem", capsys: pytest.CaptureFixture[str]
) -> None:
    # Arrange: both pyproject.toml and .ruff.toml exist
    directory = fs.create_dir("project_with_pyproject_and_dot_ruff")
    target_dir = pathlib.Path(directory.path)  # type: ignore[arg-type]
    pyproject_path = target_dir / "pyproject.toml"
    dot_ruff_path = target_dir / ".ruff.toml"

    fs.create_file(str(pyproject_path), contents="[tool.ruff]\nline-length = 79\n")
    fs.create_file(str(dot_ruff_path), contents="[tool.ruff]\nline-length = 100\n")

    upstream = URL("https://example.com/ruff.toml")
    mock_http.get(str(upstream), return_value=Response(200, text="[tool.ruff]\nline-length = 88\n"))

    # Act: no --init, should update existing config, preferring .ruff.toml
    result = await ruff_sync.pull(
        ruff_sync.Arguments(
            command="pull",
            upstream=upstream,
            source=target_dir,
            exclude=(),
            verbose=0,
            init=False,
        )
    )

    # Assert: command succeeded and .ruff.toml was selected and updated
    assert result == 0
    captured = capsys.readouterr()
    assert ".ruff.toml" in captured.out

    assert pyproject_path.exists()
    assert dot_ruff_path.exists()

    pyproject_contents = pyproject_path.read_text()
    dot_ruff_contents = dot_ruff_path.read_text()

    # pyproject.toml should remain unchanged
    assert "line-length = 79" in pyproject_contents
    # .ruff.toml should be updated with the upstream contents
    assert "line-length = 88" in dot_ruff_contents


@pytest.mark.asyncio
async def test_pull_updates_existing_dot_ruff_toml(
    mock_http: respx.MockRouter, fs: "FakeFilesystem", capsys: pytest.CaptureFixture[str]
) -> None:
    # Arrange: only .ruff.toml exists
    directory = fs.create_dir("project_with_dot_ruff_only")
    target_dir = pathlib.Path(directory.path)  # type: ignore[arg-type]
    dot_ruff_path = target_dir / ".ruff.toml"

    fs.create_file(str(dot_ruff_path), contents="[tool.ruff]\nline-length = 79\n")

    upstream = URL("https://example.com/ruff.toml")
    mock_http.get(str(upstream), return_value=Response(200, text="[tool.ruff]\nline-length = 120\n"))

    # Act
    result = await ruff_sync.pull(
        ruff_sync.Arguments(
            command="pull",
            upstream=upstream,
            source=target_dir,
            exclude=(),
            verbose=0,
            init=False,
        )
    )

    # Assert: command succeeded, .ruff.toml was updated, and no new files created
    assert result == 0
    captured = capsys.readouterr()
    assert ".ruff.toml" in captured.out

    assert dot_ruff_path.exists()
    assert (target_dir / "ruff.toml").exists() is False
    assert (target_dir / "pyproject.toml").exists() is False

    contents = dot_ruff_path.read_text()
    assert "line-length = 120" in contents
```
</issue_to_address>

### Comment 3
<location path="tests/test_config_validation.py" line_range="26-35" />
<code_context>
+    LOGGER.propagate = original_propagate
+
+
+def test_get_config_warns_on_unknown_key(
+    tmp_path: pathlib.Path, caplog: pytest.LogCaptureFixture, clean_config_cache: None
+):
+    pyproject = tmp_path / "pyproject.toml"
+    pyproject.write_text(
+        """
+[tool.ruff-sync]
+upstream = "https://github.com/org/repo"
+unknown_key = "value"
+"""
+    )
+
+    # We need to ensure the logger is set up to capture the warning
+    # In ruff_sync.py, get_config is called before handlers are added in main()
+    # But in tests, caplog should catch it if the level is right.
+
+    with caplog.at_level(logging.WARNING):
+        config = get_config(tmp_path)
+
+    assert "Unknown ruff-sync configuration: unknown_key" in caplog.text
+    assert "upstream" in config
+    assert "unknown_key" not in config
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add a positive test ensuring allowed keys are passed through without warnings

The current tests only cover disallowed keys and their warnings/filtering. Please also add a test where the config contains only allowed keys (e.g. `upstream`, `exclude`, `branch`) and assert that `get_config()` returns them unchanged and no warnings are logged (e.g. `caplog.text` does not contain "Unknown ruff-sync configuration"). This will help catch regressions where valid keys might be excluded in future changes.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread ruff_sync.py Outdated
Comment thread tests/test_scaffold.py
Comment thread tests/test_config_validation.py
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 9, 2026

╒═══════════════╤═════════════════╤══════════════╤═════════════════╤════════════╕
│ File          │ Lines of Code   │ Cyclomatic   │ Maintainabili   │ Unique     │
│               │                 │ Complexity   │ ty Index        │ Operands   │
╞═══════════════╪═════════════════╪══════════════╪═════════════════╪════════════╡
│ ruff_sync.py  │ 777 -> 889      │ 105 -> 120   │ 33.3087 ->      │ 12 -> 12   │
│               │                 │              │ 29.4918         │            │
├───────────────┼─────────────────┼──────────────┼─────────────────┼────────────┤
│ tests/test_sc │ - -> 257        │ - -> 8       │ - -> 47.67405   │ - -> 6     │
│ affold.py     │                 │              │ 034097512       │            │
├───────────────┼─────────────────┼──────────────┼─────────────────┼────────────┤
│ tests/test_ur │ - -> 31         │ - -> 1       │ - -> 83.33342   │ - -> 2     │
│ l_parsing.py  │                 │              │ 688248723       │            │
├───────────────┼─────────────────┼──────────────┼─────────────────┼────────────┤
│ tests/test_co │ - -> 91         │ - -> 4       │ - -> 61.40588   │ - -> 4     │
│ nfig_validati │                 │              │ 005795634       │            │
│ on.py         │                 │              │                 │            │
├───────────────┼─────────────────┼──────────────┼─────────────────┼────────────┤
│ tests/test_ba │ 557 -> 557      │ 30 -> 30     │ 33.8683 ->      │ 8 -> 8     │
│ sic.py        │                 │              │ 33.475          │            │
╘═══════════════╧═════════════════╧══════════════╧═════════════════╧════════════╛

@Kilo59 Kilo59 enabled auto-merge (squash) March 9, 2026 10:47
@Kilo59 Kilo59 merged commit 829c084 into main Mar 9, 2026
12 of 14 checks passed
@Kilo59 Kilo59 deleted the zero-config-bootstrap branch March 9, 2026 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support bootstrapping/scaffolding missing configuration files Work for ruff.toml

1 participant