ruff-sync 0.1.7.dev2__tar.gz → 0.1.8__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.7.dev2/.agents/skills/ruff-sync-usage → ruff_sync-0.1.8/.agents/skills/ruff-sync}/SKILL.md +1 -1
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/AGENTS.md +3 -2
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/CONTRIBUTING.md +1 -1
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/PKG-INFO +10 -2
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/README.md +9 -1
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/agent-skill.md +10 -6
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/pyproject.toml +4 -1
- ruff_sync-0.1.8/src/ruff_sync/.agents/skills/ruff-sync/SKILL.md +147 -0
- ruff_sync-0.1.8/src/ruff_sync/.agents/skills/ruff-sync/references/ci-integration.md +233 -0
- ruff_sync-0.1.8/src/ruff_sync/.agents/skills/ruff-sync/references/configuration.md +164 -0
- ruff_sync-0.1.8/src/ruff_sync/.agents/skills/ruff-sync/references/troubleshooting.md +157 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/uv.lock +10 -10
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/DEPENDENCIES.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/TESTING.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/args_refactor_plan.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/cli_animation_plan.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/decisions/0001-type-refactoring-strategy.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/decisions/0002-tui-node-ast.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/decisions/0003-argument-resolution-layers.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/decisions/README.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/doc-fix.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/docs_update_plan.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/formatters-architecture.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/gitlab-reports.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/issue-102-context.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/plans/issue-100-roadmap-plan.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/plans/issue-116-config-validation.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/ruff.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/adr/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/dirty-equals/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/dirty-equals/references/common-matchers.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/dirty-equals/references/toml-matching.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/dirty-equals/trigger_eval.json +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/gh-issues/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/mike/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/mike/references/commands.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/mkdocs-generation/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/mkdocs-generation/examples.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/mkdocs-generation/templates/api-reference.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/mkdocs-generation/templates/getting-started.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/mkdocs-generation/templates/index.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/mkdocs-generation/templates/mkdocs.yml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/release-notes-generation/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2/.agents/skills/ruff-sync-usage → ruff_sync-0.1.8/.agents/skills/ruff-sync}/references/ci-integration.md +0 -0
- {ruff_sync-0.1.7.dev2/.agents/skills/ruff-sync-usage → ruff_sync-0.1.8/.agents/skills/ruff-sync}/references/configuration.md +0 -0
- {ruff_sync-0.1.7.dev2/.agents/skills/ruff-sync-usage → ruff_sync-0.1.8/.agents/skills/ruff-sync}/references/troubleshooting.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/skill-creator/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/skill-creator/references/best-practices.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/skill-creator/references/evaluating-skills.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/skill-creator/references/optimizing-descriptions.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/skill-creator/references/quickstart.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/skill-creator/references/sources.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/skill-creator/references/using-scripts.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/skill-creator/scripts/scaffold_skill.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/textual/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/textual/examples/basic_app.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/textual/examples/reactive_example.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/textual/references/events.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/textual/references/styling.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/textual/references/testing.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/textual/references/widgets.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/evals.json +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/references/advanced-narrowing.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/references/error-code-lookup.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/references/generics.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/references/naming.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/references/protocol-patterns.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/references/quickstart.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/references/refactoring-patterns.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/type-checking/scripts/audit_types.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/skills/warnings-control/SKILL.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/tui_design.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/tui_requirements.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/tui_rule_browsing.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/tui_rule_browsing_design.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/workflows/add-test-case.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/workflows/update-recordings.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.agents/workflows/update-screenshots.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.git-blame-ignore-revs +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.github/dependabot.yml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.github/workflows/ci.yaml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.github/workflows/codspeed.yaml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.github/workflows/complexity.yaml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.gitignore +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.pre-commit-config.yaml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/.pre-commit-hooks.yaml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/LICENSE.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/codecov.yml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/configs/data-science-engineering/ruff.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/configs/fastapi/ruff.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/configs/kitchen-sink/ruff.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/favicon.png +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/github-job-summary.png +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/github-pr-annotation.png +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/inspect-main.png +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/inspect-search.png +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/logo.png +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/recordings/check_drift.gif +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/recordings/check_in_sync.gif +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/recordings/help_overview.gif +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/recordings/init_project.gif +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/recordings/pull_basic.gif +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/recordings/validate_strict.gif +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/ruff_sync_banner.png +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/screenshots/dashboard.svg +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/screenshots/legend_help.svg +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/screenshots/rule_details.svg +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/screenshots/screenshot_sample.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/assets/screenshots/search_omnibox.svg +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/best-practices.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/ci-integration.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/configuration.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/contributing.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/examples/advanced-config.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/examples/basic-config.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/gen_ref_pages.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/index.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/inspect.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/installation.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/overrides/main.html +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/overrides/partials/version_warning.html +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/pre-commit.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/pre-defined-configs.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/troubleshooting.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/url-resolution.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/docs/usage.md +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/mkdocs.yml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/scripts/check_dogfood.sh +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/scripts/generate_tui_screenshots.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/scripts/gitclone_dogfood.sh +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/scripts/pull_dogfood.sh +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/skills-lock.json +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/__init__.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/__main__.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/cli.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/config_io.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/constants.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/core.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/dependencies.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/formatters.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/pre_commit.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/system.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/tui/__init__.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/tui/app.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/tui/constants.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/tui/screens.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/tui/themes.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/tui/types_.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/tui/widgets.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/types_.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/src/ruff_sync/validation.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tapes/_common.tape +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tapes/check_drift.tape +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tapes/check_in_sync.tape +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tapes/help_overview.tape +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tapes/init_project.tape +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tapes/pull_basic.tape +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tapes/validate_strict.tape +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tasks.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/__init__.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/conftest.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/multi_upstream_final.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/multi_upstream_initial.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/multi_upstream_up1.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/multi_upstream_up2.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/no_changes_final.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/no_changes_initial.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/no_changes_upstream.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/no_dotted_keys_final.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/no_dotted_keys_initial.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/no_dotted_keys_upstream.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/no_ruff_cfg_final.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/no_ruff_cfg_initial.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/no_ruff_cfg_upstream.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/readme_excludes_final.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/readme_excludes_initial.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/readme_excludes_upstream.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/standard_final.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/standard_initial.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/lifecycle_tomls/standard_upstream.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/ruff.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_basic.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_benchmarks.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_check.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_ci_integration.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_ci_validation.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_config_io.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_config_validation.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_constants.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_corner_cases.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_dependencies.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_deprecation.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_e2e.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_formatters.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_git_fetch.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_minimal_imports.sh +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_pre_commit.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_project.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_rule_logic.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_scaffold.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_serialization.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_system.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_toml_operations.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_url_handling.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/test_whitespace.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/tui/__init__.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/tui/conftest.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/tui/test_themes.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/tui/test_tui.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/tui/test_tui_types.py +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/w_ruff_sync_cfg/pyproject.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/wo_ruff_cfg/pyproject.toml +0 -0
- {ruff_sync-0.1.7.dev2 → ruff_sync-0.1.8}/tests/wo_ruff_sync_cfg/pyproject.toml +0 -0
|
@@ -38,13 +38,14 @@ Specific workflows, libraries, and tools are documented in `.agents/skills/`. Be
|
|
|
38
38
|
decisions/ # Internal Architectural Decision Records (ADRs)
|
|
39
39
|
README.md # Index of all architectural decisions
|
|
40
40
|
skills/
|
|
41
|
-
ruff-sync
|
|
41
|
+
ruff-sync/ # Symlink to src/ruff_sync/.agents/skills/ruff-sync (for local workspace agent loading)
|
|
42
42
|
SKILL.md
|
|
43
43
|
references/
|
|
44
44
|
configuration.md
|
|
45
45
|
troubleshooting.md
|
|
46
46
|
ci-integration.md
|
|
47
47
|
src/ruff_sync/ # The application source
|
|
48
|
+
.agents/skills/ruff-sync/ # [NEW] Canonical physical skill source directory (packaged into wheels)
|
|
48
49
|
__init__.py # Public API
|
|
49
50
|
__main__.py # CLI entry point (`python -m ruff_sync`)
|
|
50
51
|
cli.py # CLI argparse definition and orchestration
|
|
@@ -218,7 +219,7 @@ CI is defined in `.github/workflows/ci.yaml`:
|
|
|
218
219
|
1. **tomlkit proxy objects**: When adding new keys to a proxy table (from dotted keys), the proxy must be converted to a real table first. The `_recursive_update` function handles this. Don't bypass it.
|
|
219
220
|
2. **`cast(Any, ...)` in tests**: Use `cast(Any, tomlkit.parse(...))["tool"]["ruff"]` pattern in tests to avoid mypy complaints about `tomlkit`'s `Item | Container` return types.
|
|
220
221
|
3. **Pre-commit ruff version**: The ruff version in `.pre-commit-config.yaml` must stay in sync with the version in `pyproject.toml`. The test `test_pre_commit_versions_are_in_sync` enforces this.
|
|
221
|
-
4. **Keep `ruff-sync
|
|
222
|
+
4. **Keep `ruff-sync` current**: Update `.agents/skills/ruff-sync/` (which is a symlink pointing to the physical files at `src/ruff_sync/.agents/skills/ruff-sync/`) after any CLI behavior changes (flags, config keys, exits) to ensure the documentation stays accurate. Keep details inside the skill directory.
|
|
222
223
|
5. **No `autouse=True` fixtures**: NEVER use `autouse=True` for pytest fixtures. All fixtures must be explicitly requested by the test functions that require them. This ensures dependencies are explicit and avoids hidden side effects.
|
|
223
224
|
|
|
224
225
|
## Browser Tool Usage
|
|
@@ -131,7 +131,7 @@ This creates three files in `tests/lifecycle_tomls/`: `<case>_initial.toml`, `<c
|
|
|
131
131
|
1. Push your branch and open a PR against `main`.
|
|
132
132
|
2. Fill in the PR description: what changed, why, and how to test it.
|
|
133
133
|
3. Ensure all CI checks pass.
|
|
134
|
-
4. If your change affects CLI behaviour (new flags, changed exit codes, new config keys, URL handling), **update the agent skill** at [`.agents/skills/ruff-sync
|
|
134
|
+
4. If your change affects CLI behaviour (new flags, changed exit codes, new config keys, URL handling), **update the agent skill** at [`.agents/skills/ruff-sync/`](.agents/skills/ruff-sync/) (which is a symlink pointing to the physical files at `src/ruff_sync/.agents/skills/ruff-sync/`):
|
|
135
135
|
- `SKILL.md` — quick start, workflows, exit codes, gotchas
|
|
136
136
|
- `references/configuration.md` — config key reference
|
|
137
137
|
- `references/troubleshooting.md` — error scenarios
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ruff-sync
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
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/
|
|
@@ -353,7 +353,15 @@ $ ruff-sync check --semantic
|
|
|
353
353
|
|
|
354
354
|
## Agent Skill
|
|
355
355
|
|
|
356
|
-
`ruff-sync`
|
|
356
|
+
`ruff-sync` supports the [Library Skills](https://library-skills.io/) specification. AI coding agents that support the [Agent Skills format](https://agentskills.io/what-are-skills) (GitHub Copilot, Claude Code, Cursor, etc.) can automatically load this skill to guide you through setup, configuration, CI integration, and troubleshooting.
|
|
357
|
+
|
|
358
|
+
You can install it automatically using `uvx` (or `npx` in a Node.js project):
|
|
359
|
+
|
|
360
|
+
```console
|
|
361
|
+
$ uvx library-skills
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
This will link the `ruff-sync` skill (bundled inside the installed package) into your project's `.agents/skills/ruff-sync` folder.
|
|
357
365
|
|
|
358
366
|
See the **[Agent Skill guide](https://kilo59.github.io/ruff-sync/stable/agent-skill/)** for details.
|
|
359
367
|
|
|
@@ -320,7 +320,15 @@ $ ruff-sync check --semantic
|
|
|
320
320
|
|
|
321
321
|
## Agent Skill
|
|
322
322
|
|
|
323
|
-
`ruff-sync`
|
|
323
|
+
`ruff-sync` supports the [Library Skills](https://library-skills.io/) specification. AI coding agents that support the [Agent Skills format](https://agentskills.io/what-are-skills) (GitHub Copilot, Claude Code, Cursor, etc.) can automatically load this skill to guide you through setup, configuration, CI integration, and troubleshooting.
|
|
324
|
+
|
|
325
|
+
You can install it automatically using `uvx` (or `npx` in a Node.js project):
|
|
326
|
+
|
|
327
|
+
```console
|
|
328
|
+
$ uvx library-skills
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
This will link the `ruff-sync` skill (bundled inside the installed package) into your project's `.agents/skills/ruff-sync` folder.
|
|
324
332
|
|
|
325
333
|
See the **[Agent Skill guide](https://kilo59.github.io/ruff-sync/stable/agent-skill/)** for details.
|
|
326
334
|
|
|
@@ -8,7 +8,7 @@ The [Agent Skills specification](https://agentskills.io/specification) is an ope
|
|
|
8
8
|
|
|
9
9
|
## What the ruff-sync Skill Covers
|
|
10
10
|
|
|
11
|
-
The skill lives at [`.agents/skills/ruff-sync
|
|
11
|
+
The skill lives at [`.agents/skills/ruff-sync/`](https://github.com/Kilo59/ruff-sync/tree/main/src/ruff_sync/.agents/skills/ruff-sync/) and teaches agents:
|
|
12
12
|
|
|
13
13
|
| File | Contents |
|
|
14
14
|
|---|---|
|
|
@@ -21,15 +21,19 @@ The skill uses [progressive disclosure](https://agentskills.io/specification#pro
|
|
|
21
21
|
|
|
22
22
|
## Using the Skill in Your Project
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
For agents that scan a configurable skill directory (e.g. `.agents/skills/`), copy the skill folder into your own project:
|
|
24
|
+
`ruff-sync` supports the [Library Skills](https://library-skills.io/) specification. You can automatically install the agent skill using `uvx` (or `npx` if in a Node.js project):
|
|
27
25
|
|
|
28
26
|
```bash
|
|
29
|
-
|
|
27
|
+
uvx library-skills
|
|
30
28
|
```
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
This scans your environment, detects `ruff-sync` from your project's dependencies, and sets up a symlink at `.agents/skills/ruff-sync` pointing to the skill files bundled inside the installed package.
|
|
31
|
+
|
|
32
|
+
For Claude Code (which uses `.claude/skills` instead of `.agents/skills`), you can specify the targets or run:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
uvx library-skills --claude
|
|
36
|
+
```
|
|
33
37
|
|
|
34
38
|
## Activation
|
|
35
39
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "ruff-sync"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.8"
|
|
4
4
|
description = "Synchronize Ruff linter configuration across projects"
|
|
5
5
|
keywords = ["ruff", "linter", "config", "synchronize", "python", "linting", "automation", "tomlkit", "pre-commit"]
|
|
6
6
|
authors = [
|
|
@@ -79,6 +79,9 @@ default-groups = ["dev"]
|
|
|
79
79
|
requires = ["hatchling"]
|
|
80
80
|
build-backend = "hatchling.build"
|
|
81
81
|
|
|
82
|
+
[tool.hatch.build.targets.sdist.force-include]
|
|
83
|
+
"src/ruff_sync/.agents" = "src/ruff_sync/.agents"
|
|
84
|
+
|
|
82
85
|
[tool.hatch.build.targets.wheel]
|
|
83
86
|
packages = ["src/ruff_sync"]
|
|
84
87
|
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ruff-sync
|
|
3
|
+
description: >-
|
|
4
|
+
Configure and operate ruff-sync to synchronize Ruff linter settings across Python projects.
|
|
5
|
+
Use when the user wants to set up ruff-sync, sync Ruff config from an upstream source,
|
|
6
|
+
check for configuration drift, integrate ruff-sync into CI, troubleshoot sync issues,
|
|
7
|
+
or keep Ruff rules consistent across multiple repositories.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# ruff-sync Usage
|
|
11
|
+
|
|
12
|
+
`ruff-sync` pulls a canonical Ruff configuration from an upstream URL and merges it into your local project, preserving comments, whitespace, and per-project overrides.
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# 1. Install
|
|
18
|
+
uv tool install ruff-sync
|
|
19
|
+
|
|
20
|
+
# 2. Sync from an upstream repo (extracts [tool.ruff] / ruff.toml automatically)
|
|
21
|
+
ruff-sync https://github.com/my-org/standards
|
|
22
|
+
|
|
23
|
+
# 3. Review the changes before committing
|
|
24
|
+
git diff pyproject.toml
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Persist Configuration
|
|
28
|
+
|
|
29
|
+
Add to `pyproject.toml` so you don't need to pass CLI args every time:
|
|
30
|
+
|
|
31
|
+
```toml
|
|
32
|
+
[tool.ruff-sync]
|
|
33
|
+
upstream = "https://github.com/my-org/standards"
|
|
34
|
+
exclude = [
|
|
35
|
+
"target-version", # each project uses its own Python version
|
|
36
|
+
"lint.per-file-ignores", # project-specific suppressions
|
|
37
|
+
"lint.ignore",
|
|
38
|
+
"lint.isort.known-first-party",
|
|
39
|
+
]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Then just run `ruff-sync` (no arguments needed).
|
|
43
|
+
|
|
44
|
+
See [references/configuration.md](references/configuration.md) for all config keys and defaults.
|
|
45
|
+
|
|
46
|
+
## Common Workflows
|
|
47
|
+
|
|
48
|
+
### Initial Project Setup
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Setup Progress:
|
|
52
|
+
- [ ] 1. Install ruff-sync (uv tool install ruff-sync)
|
|
53
|
+
- [ ] 2. Check for `.pre-commit-config.yaml` — if present, ensure the `ruff` hook is used
|
|
54
|
+
- [ ] 3. Add `[tool.ruff-sync]` to `pyproject.toml` with upstream URL and exclusions
|
|
55
|
+
- [ ] 4. If `.pre-commit-config.yaml` exists, set `pre-commit-version-sync = true` in `[tool.ruff-sync]`
|
|
56
|
+
- [ ] 5. Run `ruff-sync` to pull the upstream config
|
|
57
|
+
- [ ] 6. Review `git diff`
|
|
58
|
+
- [ ] 7. Fix any new lint errors: `uv run ruff check . --fix`
|
|
59
|
+
- [ ] 8. Commit
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Upstream Layers (multi-source)
|
|
63
|
+
|
|
64
|
+
Stack multiple upstream sources — later entries win on conflict:
|
|
65
|
+
|
|
66
|
+
```toml
|
|
67
|
+
[tool.ruff-sync]
|
|
68
|
+
upstream = [
|
|
69
|
+
"https://github.com/my-org/python-standards", # base company rules
|
|
70
|
+
"https://github.com/my-org/ml-team-tweaks", # team-specific overrides
|
|
71
|
+
]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### CI Drift Check
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
CI Setup Progress:
|
|
78
|
+
- [ ] 1. Add ruff-sync check step to CI workflow (see references/ci-integration.md)
|
|
79
|
+
- [ ] 2. Decide: --semantic for value-only checks, or full string comparison
|
|
80
|
+
- [ ] 3. Set output format: --output-format github for PR annotations
|
|
81
|
+
- [ ] 4. Set exit-code expectations (0 = in sync, 1 = config drift, 2 = pre-commit only)
|
|
82
|
+
- [ ] 5. Verify locally: `ruff-sync check --semantic`
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Keep the `ruff-pre-commit` hook version in `.pre-commit-config.yaml` aligned with the project's Ruff version.
|
|
86
|
+
|
|
87
|
+
**Recommendation:** Always prefer the persistent TOML configuration over the ephemeral `--pre-commit` CLI flag.
|
|
88
|
+
|
|
89
|
+
```toml
|
|
90
|
+
[tool.ruff-sync]
|
|
91
|
+
pre-commit-version-sync = true
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Then run `ruff-sync` — it updates the hook rev automatically. Exit code 2 means only the hook version is out of sync (Ruff config itself is fine).
|
|
95
|
+
|
|
96
|
+
## Exit Codes
|
|
97
|
+
|
|
98
|
+
| Code | Meaning |
|
|
99
|
+
|------|---------|
|
|
100
|
+
| `0` | In sync — no action needed |
|
|
101
|
+
| `1` | Ruff config is out of sync with upstream |
|
|
102
|
+
| `2` | Config is in sync, but pre-commit hook version is stale (only when `--pre-commit` is active) |
|
|
103
|
+
|
|
104
|
+
## URL Formats Supported
|
|
105
|
+
|
|
106
|
+
All of these work as the `upstream` value:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
ruff-sync https://github.com/my-org/standards # repo root
|
|
110
|
+
ruff-sync https://github.com/my-org/standards/tree/main/cfg # subdirectory
|
|
111
|
+
ruff-sync https://github.com/my-org/standards/blob/main/ruff.toml # specific file
|
|
112
|
+
ruff-sync https://raw.githubusercontent.com/my-org/standards/main/pyproject.toml
|
|
113
|
+
ruff-sync git@github.com:my-org/standards.git # SSH (shallow clone)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## CLI Reference (Short)
|
|
117
|
+
|
|
118
|
+
| Flag | Meaning |
|
|
119
|
+
|------|---------|
|
|
120
|
+
| `--validate` | Validate merged config with Ruff before writing; aborts if Ruff rejects it |
|
|
121
|
+
| `--strict` | Like `--validate` but also treats warnings (version mismatch, deprecated rules) as failures. Implies `--validate` |
|
|
122
|
+
| `--output-format` | `text` (default), `json`, `github`, `gitlab`, `sarif` (auto-detected in CI) |
|
|
123
|
+
| `--semantic` | Ignore whitespace/comments in `check` |
|
|
124
|
+
| `--pre-commit` | Sync `.pre-commit-config.yaml` hook version |
|
|
125
|
+
| `--save` | Persist CLI args to `pyproject.toml` |
|
|
126
|
+
|
|
127
|
+
## Gotchas
|
|
128
|
+
|
|
129
|
+
- **`exclude` uses dotted paths, not TOML paths.** `lint.per-file-ignores` refers to the `per-file-ignores` key inside `[tool.ruff.lint]`. Do NOT write `tool.ruff.lint.per-file-ignores`.
|
|
130
|
+
- **`--validate` is opt-in.** Validation is off by default. Pass `--validate` (or `--strict`) to run the merged config through Ruff before writing. The sync is aborted if Ruff rejects the config, leaving the local file untouched. This includes a **Python version consistency check** that compares upstream `target-version` against local `requires-python`.
|
|
131
|
+
- **Excluding `target-version` skips consistency validation.** If `target-version` (or `tool.ruff.target-version`) is in the `exclude` list, `ruff-sync` will skip the version consistency check and log a warning. This is useful for projects that intentionally deviate from upstream Python versions.
|
|
132
|
+
- **`--strict` implies `--validate`.** If you want warnings (like version mismatches or deprecated rules) treated as failures, only `--strict` is needed — don't pass both.
|
|
133
|
+
- **Validation soft-fails if `ruff` is not on PATH.** If the `ruff` binary can't be found, a warning is logged and the sync continues normally.
|
|
134
|
+
- **Use `--init` only for new projects.** `ruff-sync` requires an existing `pyproject.toml` or `ruff.toml`. Pass `--init` to scaffold one if the directory is empty. This will automatically generate a `[tool.ruff-sync]` configuration block for future syncs.
|
|
135
|
+
- **Use `--save` to persist CLI arguments.** If you want to update an existing `pyproject.toml` with a new upstream URL or exclusion, pass `--save` to write the new configuration to the file.
|
|
136
|
+
- **`--semantic` ignores comments and whitespace.** Use it in CI to avoid false positives from cosmetic local edits. Omit it for strict byte-for-byte checks.
|
|
137
|
+
- **SSH URLs trigger a shallow clone.** `git@github.com:...` URLs use `git clone --filter=blob:none --depth=1` — no `git` credential issues as long as SSH auth is configured.
|
|
138
|
+
- **Later upstreams win in `upstream` lists.** In a multi-source list, keys set by entry 2 overwrite keys from entry 1.
|
|
139
|
+
- **Config discovery order matters.** When targeting a directory, `ruff-sync` looks for `ruff.toml` -> `.ruff.toml` -> `pyproject.toml` in that order.
|
|
140
|
+
- **Pre-commit exit code 2 is intentional.** A `2` exit from `ruff-sync check` means the Ruff _config_ is fine, only the pre-commit hook tag is stale. You may want to treat this differently from a full config drift (exit 1) in CI.
|
|
141
|
+
- **Prefer TOML for pre-commit sync.** While `--pre-commit` works on the CLI, setting `pre-commit-version-sync = true` in `pyproject.toml` is the recommended way to ensure hook versioning stays consistent for all contributors.
|
|
142
|
+
|
|
143
|
+
## References
|
|
144
|
+
|
|
145
|
+
- **[Configuration reference](references/configuration.md)** — All `[tool.ruff-sync]` keys, types, and defaults
|
|
146
|
+
- **[Troubleshooting](references/troubleshooting.md)** — Common errors and how to resolve them
|
|
147
|
+
- **[CI integration recipes](references/ci-integration.md)** — GitHub Actions, GitLab CI, pre-commit hook
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# CI Integration Recipes
|
|
2
|
+
|
|
3
|
+
## GitHub Actions
|
|
4
|
+
|
|
5
|
+
### Basic Drift Check
|
|
6
|
+
|
|
7
|
+
Add this step to any existing workflow (e.g., `.github/workflows/ci.yaml`):
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
- name: Check Ruff config is in sync
|
|
11
|
+
run: ruff-sync check --semantic --output-format github
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`--semantic` ignores cosmetic differences (comments, whitespace) — only real value or rule changes cause failure.
|
|
15
|
+
`--output-format github` creates inline PR annotations and a structured Job Summary report.
|
|
16
|
+
|
|
17
|
+
### With Strict Validation
|
|
18
|
+
|
|
19
|
+
To also catch deprecated rules and Python version mismatches in CI:
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
- name: Check Ruff config (with validation)
|
|
23
|
+
run: ruff-sync check --semantic --strict --output-format github
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`--strict` implies `--validate`. Deprecated rules and version mismatches are upgraded to failures.
|
|
27
|
+
|
|
28
|
+
> [!TIP]
|
|
29
|
+
> `ruff-sync` automatically groups multiple drifts in the same file into a single annotation to reduce PR noise.
|
|
30
|
+
|
|
31
|
+
### Full Workflow Example
|
|
32
|
+
|
|
33
|
+
Uses [`astral-sh/setup-uv`](https://github.com/astral-sh/setup-uv) — the official action that installs uv, adds it to PATH, and handles caching. No separate `setup-python` step needed.
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
name: Ruff sync check
|
|
37
|
+
|
|
38
|
+
on:
|
|
39
|
+
push:
|
|
40
|
+
branches: [main]
|
|
41
|
+
pull_request:
|
|
42
|
+
|
|
43
|
+
jobs:
|
|
44
|
+
ruff-sync-check:
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
|
|
49
|
+
- name: Install uv
|
|
50
|
+
uses: astral-sh/setup-uv@v6
|
|
51
|
+
with:
|
|
52
|
+
version: "0.10.x" # pin to a minor range; Dependabot can keep this current
|
|
53
|
+
|
|
54
|
+
- name: Install ruff-sync
|
|
55
|
+
run: uv tool install ruff-sync
|
|
56
|
+
|
|
57
|
+
- name: Check Ruff config is in sync with upstream
|
|
58
|
+
run: ruff-sync check --semantic --output-format github
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### With Pre-commit Sync Check
|
|
62
|
+
|
|
63
|
+
To also verify the pre-commit hook version, add the `--pre-commit` flag:
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
- name: Check Ruff config and pre-commit hook
|
|
67
|
+
run: ruff-sync check --semantic --pre-commit --output-format github
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
(Note: For better consistency, you can instead set `pre-commit-version-sync = true` in your `pyproject.toml` — then `ruff-sync check --semantic` will automatically include this check.)
|
|
71
|
+
|
|
72
|
+
### SARIF Upload (GitHub Advanced Security)
|
|
73
|
+
|
|
74
|
+
For repositories with GitHub Advanced Security enabled, upload SARIF results to track drift findings in the **Security tab** and get per-key inline PR annotations that persist across runs:
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
- name: Check Ruff config (SARIF)
|
|
78
|
+
run: ruff-sync check --output-format sarif > ruff-sync.sarif || true
|
|
79
|
+
|
|
80
|
+
- name: Upload SARIF results
|
|
81
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
82
|
+
with:
|
|
83
|
+
sarif_file: ruff-sync.sarif
|
|
84
|
+
category: ruff-sync
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The `|| true` ensures the upload step always runs even when `ruff-sync` exits 1 (drift detected). Without it, GitHub Actions would skip the upload step on failure.
|
|
88
|
+
|
|
89
|
+
> **Why SARIF over `--output-format github`?**
|
|
90
|
+
>
|
|
91
|
+
> | Feature | `github` | `sarif` |
|
|
92
|
+
> |---------|----------|---------|
|
|
93
|
+
> | **PR Feedback** | Inline annotations (grouped) | Inline annotations (per-key) |
|
|
94
|
+
> | **Job Summary** | ✅ Markdown table | ❌ (requires separate parsing) |
|
|
95
|
+
> | **Persistence** | Ephemeral (until re-run) | Persistent (Security tab) |
|
|
96
|
+
> | **Tracking** | Manual | Automated "introduced/resolved" |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## GitLab CI
|
|
101
|
+
|
|
102
|
+
Use the official [`ghcr.io/astral-sh/uv`](https://docs.astral.sh/uv/guides/integration/gitlab/) image — uv is already on the `PATH`, no install step needed.
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
variables:
|
|
106
|
+
UV_VERSION: "0.10"
|
|
107
|
+
PYTHON_VERSION: "3.12"
|
|
108
|
+
BASE_LAYER: alpine
|
|
109
|
+
UV_LINK_MODE: copy # required: GitLab mounts build dir separately
|
|
110
|
+
|
|
111
|
+
ruff-sync-check:
|
|
112
|
+
stage: lint
|
|
113
|
+
image: ghcr.io/astral-sh/uv:$UV_VERSION-python$PYTHON_VERSION-$BASE_LAYER
|
|
114
|
+
script:
|
|
115
|
+
- uvx ruff-sync check --semantic --output-format gitlab > gl-code-quality-report.json
|
|
116
|
+
artifacts:
|
|
117
|
+
when: always
|
|
118
|
+
reports:
|
|
119
|
+
codequality: gl-code-quality-report.json
|
|
120
|
+
paths:
|
|
121
|
+
- gl-code-quality-report.json
|
|
122
|
+
expire_in: 1 week
|
|
123
|
+
rules:
|
|
124
|
+
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
125
|
+
- if: '$CI_COMMIT_BRANCH == "main"'
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### GitLab SAST Report / SARIF (Ultimate tier)
|
|
129
|
+
|
|
130
|
+
Use `--output-format sarif` to feed the GitLab [Security & Compliance dashboard](https://docs.gitlab.com/user/application_security/) via the `sast` artifact report type:
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
variables:
|
|
134
|
+
UV_VERSION: "0.10"
|
|
135
|
+
PYTHON_VERSION: "3.12"
|
|
136
|
+
BASE_LAYER: alpine
|
|
137
|
+
UV_LINK_MODE: copy # required: GitLab mounts build dir separately
|
|
138
|
+
|
|
139
|
+
ruff-sync-sarif:
|
|
140
|
+
stage: lint
|
|
141
|
+
image: ghcr.io/astral-sh/uv:$UV_VERSION-python$PYTHON_VERSION-$BASE_LAYER
|
|
142
|
+
script:
|
|
143
|
+
- uvx ruff-sync check --output-format sarif > ruff-sync.sarif
|
|
144
|
+
artifacts:
|
|
145
|
+
when: always # Upload even when ruff-sync exits 1 (drift detected)
|
|
146
|
+
reports:
|
|
147
|
+
sast: ruff-sync.sarif
|
|
148
|
+
paths:
|
|
149
|
+
- ruff-sync.sarif
|
|
150
|
+
expire_in: 1 week
|
|
151
|
+
rules:
|
|
152
|
+
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
> **Why SARIF over `--output-format gitlab` (codequality)?**
|
|
156
|
+
>
|
|
157
|
+
> | Concern | `codequality` | `sarif` |
|
|
158
|
+
> |---------|--------------|--------|
|
|
159
|
+
> | GitLab tier | Free (MR widget), Ultimate (inline diff) | Ultimate (Security dashboard) |
|
|
160
|
+
> | GitHub support | ❌ | ✅ via `upload-sarif` |
|
|
161
|
+
> | Per-key findings | ❌ one issue per file | ✅ one finding per drifted TOML key |
|
|
162
|
+
> | Finding persistence | MR widget only | Security tab, tracked across branches |
|
|
163
|
+
> | Portability | GitLab only | GitHub, GitLab, SonarQube, IDE extensions |
|
|
164
|
+
>
|
|
165
|
+
> **Rule of thumb**: use `codequality` for lightweight GitLab-native linting feedback; use `sarif` when you need cross-platform compatibility or want findings tracked in a security/code-scanning dashboard.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Pre-commit Hook
|
|
170
|
+
|
|
171
|
+
Run `ruff-sync check` as a pre-commit hook to catch drift before every commit:
|
|
172
|
+
|
|
173
|
+
```yaml
|
|
174
|
+
# .pre-commit-config.yaml
|
|
175
|
+
- repo: https://github.com/Kilo59/ruff-sync
|
|
176
|
+
rev: v0.1.6 # pin to a release tag
|
|
177
|
+
hooks:
|
|
178
|
+
- id: ruff-sync-check
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The hook runs `ruff-sync check --semantic` automatically. Update `rev` to the latest ruff-sync version.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Makefile
|
|
186
|
+
|
|
187
|
+
```makefile
|
|
188
|
+
.PHONY: sync-check sync
|
|
189
|
+
|
|
190
|
+
sync-check:
|
|
191
|
+
ruff-sync check --semantic
|
|
192
|
+
|
|
193
|
+
sync:
|
|
194
|
+
ruff-sync
|
|
195
|
+
git diff pyproject.toml
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Deciding: `--semantic` vs. Full String Check
|
|
201
|
+
|
|
202
|
+
| Mode | Fails on | Use when |
|
|
203
|
+
|------|---------|---------|
|
|
204
|
+
| `ruff-sync check --semantic` | Value/rule differences only | CI — avoids false positives from local comment edits |
|
|
205
|
+
| `ruff-sync check` | Any string difference (comments, whitespace, values) | Enforcing exact config file consistency |
|
|
206
|
+
|
|
207
|
+
Recommendation: **use `--semantic` in CI** and save the full-string check for auditing purposes.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Dogfooding (Self-Check)
|
|
212
|
+
|
|
213
|
+
If `ruff-sync` is configured in the project's own `pyproject.toml` (the standard case), just run:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
ruff-sync check
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
No URL argument needed — it reads `upstream` from `[tool.ruff-sync]`.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Exit Codes
|
|
224
|
+
|
|
225
|
+
| Code | Meaning |
|
|
226
|
+
|------|----------|
|
|
227
|
+
| **0** | In sync — no drift detected |
|
|
228
|
+
| **1** | Config drift (`check`), validation failure (`pull --validate`), or sync error |
|
|
229
|
+
| **2** | CLI usage error — invalid arguments (reserved by argparse) |
|
|
230
|
+
| **3** | Pre-commit hook drift — use `--pre-commit` flag to enable this check |
|
|
231
|
+
| **4** | Upstream unreachable — HTTP error or network failure |
|
|
232
|
+
|
|
233
|
+
All non-zero codes cause a CI step to fail, which is the desired behaviour. To diagnose which failure occurred, check the exit code with `echo $?` after the `ruff-sync check` call.
|