ruff-sync 0.1.6.dev2__tar.gz → 0.1.6.dev3__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 (190) hide show
  1. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/plans/issue-116-config-validation.md +2 -2
  2. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/PKG-INFO +1 -1
  3. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/pyproject.toml +1 -1
  4. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/validation.py +102 -2
  5. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_config_validation.py +74 -0
  6. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/uv.lock +1 -1
  7. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/DEPENDENCIES.md +0 -0
  8. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/TESTING.md +0 -0
  9. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/decisions/0001-type-refactoring-strategy.md +0 -0
  10. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/decisions/0002-tui-node-ast.md +0 -0
  11. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/decisions/README.md +0 -0
  12. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/doc-fix.md +0 -0
  13. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/formatters-architecture.md +0 -0
  14. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/gitlab-reports.md +0 -0
  15. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/issue-102-context.md +0 -0
  16. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/plans/issue-100-roadmap-plan.md +0 -0
  17. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/ruff.toml +0 -0
  18. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/adr/SKILL.md +0 -0
  19. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/dirty-equals/SKILL.md +0 -0
  20. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/dirty-equals/references/common-matchers.md +0 -0
  21. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/dirty-equals/references/toml-matching.md +0 -0
  22. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/dirty-equals/trigger_eval.json +0 -0
  23. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/gh-issues/SKILL.md +0 -0
  24. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/mike/SKILL.md +0 -0
  25. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/mike/references/commands.md +0 -0
  26. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/mkdocs-generation/SKILL.md +0 -0
  27. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/mkdocs-generation/examples.md +0 -0
  28. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/mkdocs-generation/templates/api-reference.md +0 -0
  29. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/mkdocs-generation/templates/getting-started.md +0 -0
  30. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/mkdocs-generation/templates/index.md +0 -0
  31. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/mkdocs-generation/templates/mkdocs.yml +0 -0
  32. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/release-notes-generation/SKILL.md +0 -0
  33. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/ruff-sync-usage/SKILL.md +0 -0
  34. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/ruff-sync-usage/references/ci-integration.md +0 -0
  35. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/ruff-sync-usage/references/configuration.md +0 -0
  36. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/ruff-sync-usage/references/troubleshooting.md +0 -0
  37. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/skill-creator/SKILL.md +0 -0
  38. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/skill-creator/references/best-practices.md +0 -0
  39. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/skill-creator/references/evaluating-skills.md +0 -0
  40. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/skill-creator/references/optimizing-descriptions.md +0 -0
  41. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/skill-creator/references/quickstart.md +0 -0
  42. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/skill-creator/references/sources.md +0 -0
  43. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/skill-creator/references/using-scripts.md +0 -0
  44. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/skill-creator/scripts/scaffold_skill.py +0 -0
  45. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/textual/SKILL.md +0 -0
  46. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/textual/examples/basic_app.py +0 -0
  47. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/textual/examples/reactive_example.py +0 -0
  48. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/textual/references/events.md +0 -0
  49. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/textual/references/styling.md +0 -0
  50. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/textual/references/testing.md +0 -0
  51. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/textual/references/widgets.md +0 -0
  52. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/SKILL.md +0 -0
  53. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/evals.json +0 -0
  54. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/references/advanced-narrowing.md +0 -0
  55. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/references/error-code-lookup.md +0 -0
  56. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/references/generics.md +0 -0
  57. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/references/naming.md +0 -0
  58. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/references/protocol-patterns.md +0 -0
  59. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/references/quickstart.md +0 -0
  60. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/references/refactoring-patterns.md +0 -0
  61. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/type-checking/scripts/audit_types.py +0 -0
  62. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/skills/warnings-control/SKILL.md +0 -0
  63. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/tui_design.md +0 -0
  64. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/tui_requirements.md +0 -0
  65. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/tui_rule_browsing.md +0 -0
  66. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/tui_rule_browsing_design.md +0 -0
  67. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/workflows/add-test-case.md +0 -0
  68. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.agents/workflows/update-screenshots.md +0 -0
  69. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.git-blame-ignore-revs +0 -0
  70. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.github/dependabot.yml +0 -0
  71. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.github/workflows/ci.yaml +0 -0
  72. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.github/workflows/complexity.yaml +0 -0
  73. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.gitignore +0 -0
  74. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.pre-commit-config.yaml +0 -0
  75. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/.pre-commit-hooks.yaml +0 -0
  76. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/AGENTS.md +0 -0
  77. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/CONTRIBUTING.md +0 -0
  78. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/LICENSE.md +0 -0
  79. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/README.md +0 -0
  80. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/codecov.yml +0 -0
  81. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/configs/data-science-engineering/ruff.toml +0 -0
  82. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/configs/fastapi/ruff.toml +0 -0
  83. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/configs/kitchen-sink/ruff.toml +0 -0
  84. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/agent-skill.md +0 -0
  85. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/favicon.png +0 -0
  86. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/github-job-summary.png +0 -0
  87. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/github-pr-annotation.png +0 -0
  88. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/inspect-main.png +0 -0
  89. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/inspect-search.png +0 -0
  90. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/logo.png +0 -0
  91. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/ruff_sync_banner.png +0 -0
  92. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/screenshots/dashboard.svg +0 -0
  93. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/screenshots/legend_help.svg +0 -0
  94. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/screenshots/rule_details.svg +0 -0
  95. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/screenshots/screenshot_sample.toml +0 -0
  96. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/assets/screenshots/search_omnibox.svg +0 -0
  97. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/best-practices.md +0 -0
  98. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/ci-integration.md +0 -0
  99. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/configuration.md +0 -0
  100. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/contributing.md +0 -0
  101. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/examples/advanced-config.toml +0 -0
  102. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/examples/basic-config.toml +0 -0
  103. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/gen_ref_pages.py +0 -0
  104. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/index.md +0 -0
  105. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/inspect.md +0 -0
  106. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/installation.md +0 -0
  107. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/overrides/main.html +0 -0
  108. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/overrides/partials/version_warning.html +0 -0
  109. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/pre-commit.md +0 -0
  110. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/pre-defined-configs.md +0 -0
  111. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/troubleshooting.md +0 -0
  112. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/url-resolution.md +0 -0
  113. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/docs/usage.md +0 -0
  114. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/mkdocs.yml +0 -0
  115. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/scripts/check_dogfood.sh +0 -0
  116. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/scripts/generate_tui_screenshots.py +0 -0
  117. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/scripts/gitclone_dogfood.sh +0 -0
  118. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/scripts/pull_dogfood.sh +0 -0
  119. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/skills-lock.json +0 -0
  120. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/__init__.py +0 -0
  121. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/__main__.py +0 -0
  122. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/cli.py +0 -0
  123. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/config_io.py +0 -0
  124. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/constants.py +0 -0
  125. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/core.py +0 -0
  126. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/dependencies.py +0 -0
  127. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/formatters.py +0 -0
  128. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/pre_commit.py +0 -0
  129. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/system.py +0 -0
  130. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/tui/__init__.py +0 -0
  131. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/tui/app.py +0 -0
  132. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/tui/constants.py +0 -0
  133. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/tui/screens.py +0 -0
  134. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/tui/themes.py +0 -0
  135. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/tui/types_.py +0 -0
  136. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/tui/widgets.py +0 -0
  137. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/src/ruff_sync/types_.py +0 -0
  138. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tasks.py +0 -0
  139. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/__init__.py +0 -0
  140. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/conftest.py +0 -0
  141. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/multi_upstream_final.toml +0 -0
  142. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/multi_upstream_initial.toml +0 -0
  143. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/multi_upstream_up1.toml +0 -0
  144. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/multi_upstream_up2.toml +0 -0
  145. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/no_changes_final.toml +0 -0
  146. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/no_changes_initial.toml +0 -0
  147. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/no_changes_upstream.toml +0 -0
  148. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/no_dotted_keys_final.toml +0 -0
  149. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/no_dotted_keys_initial.toml +0 -0
  150. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/no_dotted_keys_upstream.toml +0 -0
  151. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/no_ruff_cfg_final.toml +0 -0
  152. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/no_ruff_cfg_initial.toml +0 -0
  153. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/no_ruff_cfg_upstream.toml +0 -0
  154. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/readme_excludes_final.toml +0 -0
  155. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/readme_excludes_initial.toml +0 -0
  156. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/readme_excludes_upstream.toml +0 -0
  157. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/standard_final.toml +0 -0
  158. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/standard_initial.toml +0 -0
  159. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/lifecycle_tomls/standard_upstream.toml +0 -0
  160. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/ruff.toml +0 -0
  161. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_basic.py +0 -0
  162. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_check.py +0 -0
  163. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_ci_integration.py +0 -0
  164. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_ci_validation.py +0 -0
  165. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_config_io.py +0 -0
  166. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_constants.py +0 -0
  167. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_corner_cases.py +0 -0
  168. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_dependencies.py +0 -0
  169. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_deprecation.py +0 -0
  170. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_e2e.py +0 -0
  171. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_formatters.py +0 -0
  172. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_git_fetch.py +0 -0
  173. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_minimal_imports.sh +0 -0
  174. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_pre_commit.py +0 -0
  175. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_project.py +0 -0
  176. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_rule_logic.py +0 -0
  177. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_scaffold.py +0 -0
  178. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_serialization.py +0 -0
  179. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_system.py +0 -0
  180. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_toml_operations.py +0 -0
  181. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_url_handling.py +0 -0
  182. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/test_whitespace.py +0 -0
  183. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/tui/__init__.py +0 -0
  184. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/tui/conftest.py +0 -0
  185. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/tui/test_themes.py +0 -0
  186. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/tui/test_tui.py +0 -0
  187. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/tui/test_tui_types.py +0 -0
  188. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/w_ruff_sync_cfg/pyproject.toml +0 -0
  189. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/wo_ruff_cfg/pyproject.toml +0 -0
  190. {ruff_sync-0.1.6.dev2 → ruff_sync-0.1.6.dev3}/tests/wo_ruff_sync_cfg/pyproject.toml +0 -0
@@ -28,8 +28,8 @@ passing both.
28
28
  |---|---|---|---|---|---|
29
29
  | 1 (Must Have) | 🔴 | 🟡 Moderate | TOML syntax + Ruff CLI validation | New `validation.py` module; gated by `--validate` in `pull()` | ✅ Completed |
30
30
  | 2 (Should Have) | 🟠 | 🟢 Simple | Python version consistency check | `validation.py` + warn when `--validate` is active | ✅ Completed |
31
- | 3 (Could Have) | 🟡 | 🔴 Complex | Rule deprecation warnings | `validation.py` + subprocess + JSON + DI; gated by `--validate` | Pending |
32
- | 4 (Nice to Have) | 🟢 | 🟢 Simple | `--strict` flag | Upgrades warnings to failures; implies `--validate` | 🚧 In Progress |
31
+ | 3 (Could Have) | 🟡 | 🔴 Complex | Rule deprecation warnings | `validation.py` + subprocess + JSON + DI; gated by `--validate` | Completed |
32
+ | 4 (Nice to Have) | 🟢 | 🟢 Simple | `--strict` flag | Upgrades warnings to failures; implies `--validate` | Completed |
33
33
 
34
34
  ---
35
35
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ruff-sync
3
- Version: 0.1.6.dev2
3
+ Version: 0.1.6.dev3
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/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ruff-sync"
3
- version = "0.1.6.dev2"
3
+ version = "0.1.6.dev3"
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 = [
@@ -2,6 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import functools
6
+ import json
5
7
  import logging
6
8
  import pathlib
7
9
  import re
@@ -109,6 +111,97 @@ def check_python_version_consistency(
109
111
  return True
110
112
 
111
113
 
114
+ _RULE_LIST_KEYS: frozenset[str] = frozenset({"select", "extend-select", "ignore", "extend-ignore"})
115
+
116
+
117
+ @functools.lru_cache(maxsize=1)
118
+ def _get_deprecated_rule_codes() -> frozenset[str]:
119
+ """Return the set of deprecated rule codes reported by the installed Ruff version.
120
+
121
+ Returns an empty frozenset if ruff is not found or output cannot be parsed.
122
+ """
123
+ try:
124
+ result = subprocess.run(
125
+ ["ruff", "rule", "--all", "--output-format", "json"], # noqa: S607
126
+ capture_output=True,
127
+ text=True,
128
+ timeout=30,
129
+ check=False,
130
+ )
131
+ if result.returncode != 0:
132
+ return frozenset()
133
+ rules = json.loads(result.stdout)
134
+ return frozenset(r["code"] for r in rules if r.get("deprecated") is True)
135
+ except (
136
+ FileNotFoundError,
137
+ subprocess.TimeoutExpired,
138
+ json.JSONDecodeError,
139
+ KeyError,
140
+ TypeError,
141
+ ):
142
+ return frozenset()
143
+
144
+
145
+ def check_deprecated_rules(
146
+ doc: TOMLDocument,
147
+ is_ruff_toml: bool = False,
148
+ strict: bool = False,
149
+ _deprecated_codes: frozenset[str] | None = None,
150
+ exclude: Iterable[str] = (),
151
+ ) -> bool:
152
+ """Warn if the merged config references any deprecated Ruff rules.
153
+
154
+ Args:
155
+ doc: The merged TOML document.
156
+ is_ruff_toml: True if the document is a standalone ruff.toml.
157
+ strict: If True, treat deprecated rules as a failure.
158
+ _deprecated_codes: Optional set of deprecated codes to use (for testing).
159
+ exclude: List of keys excluded from the ruff configuration.
160
+
161
+ Returns:
162
+ True if no deprecated rules are found, or if strict=False.
163
+ False if strict=True and deprecated rules are found.
164
+ """
165
+ deprecated_codes = (
166
+ _deprecated_codes if _deprecated_codes is not None else _get_deprecated_rule_codes()
167
+ )
168
+ if not deprecated_codes:
169
+ return True # Nothing to check (ruff not found or returned no deprecated rules)
170
+
171
+ if is_ruff_toml:
172
+ lint_section = doc.get("lint", {})
173
+ else:
174
+ lint_section = doc.get("tool", {}).get("ruff", {}).get("lint", {})
175
+
176
+ if not isinstance(lint_section, dict):
177
+ return True
178
+
179
+ found_deprecated = False
180
+ for key in _RULE_LIST_KEYS:
181
+ full_key = f"lint.{key}" if is_ruff_toml else f"tool.ruff.lint.{key}"
182
+ if key in exclude or full_key in exclude:
183
+ continue
184
+
185
+ rule_list = lint_section.get(key, [])
186
+ if not isinstance(rule_list, list):
187
+ continue
188
+ for rule_code in rule_list:
189
+ rule_str = str(rule_code).strip().upper()
190
+ if rule_str in deprecated_codes:
191
+ found_deprecated = True
192
+ msg = (
193
+ f"Upstream config uses deprecated rule '{rule_str}' "
194
+ f"(found in [{'lint' if is_ruff_toml else 'tool.ruff.lint'}].{key}). "
195
+ "This rule may be removed in a future Ruff version."
196
+ )
197
+ if strict:
198
+ LOGGER.error(f"❌ {msg}")
199
+ else:
200
+ LOGGER.warning(f"⚠️ {msg}")
201
+
202
+ return not (strict and found_deprecated)
203
+
204
+
112
205
  def validate_toml_syntax(doc: TOMLDocument) -> bool:
113
206
  """Return True if the document serializes to valid TOML.
114
207
 
@@ -218,6 +311,13 @@ def validate_merged_config(
218
311
  return False
219
312
  if not validate_ruff_accepts_config(doc, is_ruff_toml=is_ruff_toml, strict=strict):
220
313
  return False
314
+
315
+ version_ok = True
221
316
  if not is_ruff_toml:
222
- return check_python_version_consistency(doc, strict=strict, exclude=exclude)
223
- return True
317
+ version_ok = check_python_version_consistency(doc, strict=strict, exclude=exclude)
318
+
319
+ deprecated_ok = check_deprecated_rules(
320
+ doc, is_ruff_toml=is_ruff_toml, strict=strict, exclude=exclude
321
+ )
322
+
323
+ return version_ok and deprecated_ok
@@ -21,6 +21,7 @@ import ruff_sync
21
21
  from ruff_sync import get_config
22
22
  from ruff_sync.cli import LOGGER
23
23
  from ruff_sync.validation import (
24
+ check_deprecated_rules,
24
25
  check_python_version_consistency,
25
26
  validate_merged_config,
26
27
  validate_ruff_accepts_config,
@@ -653,5 +654,78 @@ def test_strict_mode_fails_on_version_mismatch(caplog: pytest.LogCaptureFixture)
653
654
  assert "Version mismatch" in caplog.text
654
655
 
655
656
 
657
+ # ===========================================================================
658
+ # Priority 3 — Rule Deprecation Warnings
659
+ # ===========================================================================
660
+
661
+
662
+ def test_deprecated_rule_warning_emitted(caplog: pytest.LogCaptureFixture) -> None:
663
+ doc = tomlkit.parse('[tool.ruff.lint]\nselect = ["UP036"]\n')
664
+ with caplog.at_level(logging.WARNING, logger="ruff_sync.validation"):
665
+ result = check_deprecated_rules(doc, _deprecated_codes=frozenset({"UP036"}))
666
+ assert result is True
667
+ assert "deprecated rule 'UP036'" in caplog.text
668
+
669
+
670
+ def test_deprecated_rule_ruff_toml_warning_emitted(caplog: pytest.LogCaptureFixture) -> None:
671
+ doc = tomlkit.parse('[lint]\nselect = ["UP036"]\n')
672
+ with caplog.at_level(logging.WARNING, logger="ruff_sync.validation"):
673
+ result = check_deprecated_rules(
674
+ doc, is_ruff_toml=True, _deprecated_codes=frozenset({"UP036"})
675
+ )
676
+ assert result is True
677
+ assert "deprecated rule 'UP036'" in caplog.text
678
+
679
+
680
+ def test_deprecated_rules_skipped_when_excluded(caplog: pytest.LogCaptureFixture) -> None:
681
+ doc = tomlkit.parse('[tool.ruff.lint]\nselect = ["UP036"]\n')
682
+ with caplog.at_level(logging.WARNING, logger="ruff_sync.validation"):
683
+ result = check_deprecated_rules(
684
+ doc, _deprecated_codes=frozenset({"UP036"}), exclude=("tool.ruff.lint.select",)
685
+ )
686
+ assert result is True
687
+ assert "deprecated rule" not in caplog.text
688
+
689
+ # Also check short name exclusion works
690
+ with caplog.at_level(logging.WARNING, logger="ruff_sync.validation"):
691
+ result = check_deprecated_rules(
692
+ doc, _deprecated_codes=frozenset({"UP036"}), exclude=("select",)
693
+ )
694
+ assert result is True
695
+ assert "deprecated rule" not in caplog.text
696
+
697
+
698
+ def test_no_warning_for_valid_rules(caplog: pytest.LogCaptureFixture) -> None:
699
+ doc = tomlkit.parse('[tool.ruff.lint]\nselect = ["E501"]\n')
700
+ with caplog.at_level(logging.WARNING, logger="ruff_sync.validation"):
701
+ result = check_deprecated_rules(doc, _deprecated_codes=frozenset({"UP036"}))
702
+ assert result is True
703
+ assert "deprecated rule" not in caplog.text
704
+
705
+
706
+ def test_deprecated_rules_skipped_when_ruff_unavailable(caplog: pytest.LogCaptureFixture) -> None:
707
+ doc = tomlkit.parse('[tool.ruff.lint]\nselect = ["UP036"]\n')
708
+ with caplog.at_level(logging.WARNING, logger="ruff_sync.validation"):
709
+ result = check_deprecated_rules(doc, _deprecated_codes=frozenset())
710
+ assert result is True
711
+ assert "deprecated rule" not in caplog.text
712
+
713
+
714
+ def test_strict_mode_fails_on_deprecated_rules(caplog: pytest.LogCaptureFixture) -> None:
715
+ doc = tomlkit.parse('[tool.ruff.lint]\nselect = ["UP036"]\n')
716
+ with caplog.at_level(logging.ERROR, logger="ruff_sync.validation"):
717
+ result = check_deprecated_rules(doc, strict=True, _deprecated_codes=frozenset({"UP036"}))
718
+ assert result is False
719
+ assert "deprecated rule 'UP036'" in caplog.text
720
+
721
+
722
+ def test_non_strict_mode_passes_on_deprecated_rules(caplog: pytest.LogCaptureFixture) -> None:
723
+ doc = tomlkit.parse('[tool.ruff.lint]\nselect = ["UP036"]\n')
724
+ with caplog.at_level(logging.WARNING, logger="ruff_sync.validation"):
725
+ result = check_deprecated_rules(doc, strict=False, _deprecated_codes=frozenset({"UP036"}))
726
+ assert result is True
727
+ assert "deprecated rule 'UP036'" in caplog.text
728
+
729
+
656
730
  if __name__ == "__main__":
657
731
  pytest.main([__file__, "-vv"])
@@ -1610,7 +1610,7 @@ wheels = [
1610
1610
 
1611
1611
  [[package]]
1612
1612
  name = "ruff-sync"
1613
- version = "0.1.6.dev2"
1613
+ version = "0.1.6.dev3"
1614
1614
  source = { editable = "." }
1615
1615
  dependencies = [
1616
1616
  { name = "httpx" },
File without changes
File without changes
File without changes