driftcheck-py 0.1.48__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 (222) hide show
  1. driftcheck_py-0.1.48/LICENSE +2 -0
  2. driftcheck_py-0.1.48/PKG-INFO +470 -0
  3. driftcheck_py-0.1.48/README.md +450 -0
  4. driftcheck_py-0.1.48/pyproject.toml +33 -0
  5. driftcheck_py-0.1.48/setup.cfg +4 -0
  6. driftcheck_py-0.1.48/src/driftcheck/__init__.py +162 -0
  7. driftcheck_py-0.1.48/src/driftcheck/__main__.py +5 -0
  8. driftcheck_py-0.1.48/src/driftcheck/baseline.py +314 -0
  9. driftcheck_py-0.1.48/src/driftcheck/cli.py +1057 -0
  10. driftcheck_py-0.1.48/src/driftcheck/config.py +136 -0
  11. driftcheck_py-0.1.48/src/driftcheck/detector.py +904 -0
  12. driftcheck_py-0.1.48/src/driftcheck/detectors/__init__.py +694 -0
  13. driftcheck_py-0.1.48/src/driftcheck/detectors/a2a.py +276 -0
  14. driftcheck_py-0.1.48/src/driftcheck/detectors/actions.py +102 -0
  15. driftcheck_py-0.1.48/src/driftcheck/detectors/actions_version_drift.py +56 -0
  16. driftcheck_py-0.1.48/src/driftcheck/detectors/bazel.py +95 -0
  17. driftcheck_py-0.1.48/src/driftcheck/detectors/bun.py +61 -0
  18. driftcheck_py-0.1.48/src/driftcheck/detectors/cargo_features.py +105 -0
  19. driftcheck_py-0.1.48/src/driftcheck/detectors/changelog.py +150 -0
  20. driftcheck_py-0.1.48/src/driftcheck/detectors/ci_os.py +41 -0
  21. driftcheck_py-0.1.48/src/driftcheck/detectors/circleci.py +56 -0
  22. driftcheck_py-0.1.48/src/driftcheck/detectors/cmake.py +52 -0
  23. driftcheck_py-0.1.48/src/driftcheck/detectors/compose.py +55 -0
  24. driftcheck_py-0.1.48/src/driftcheck/detectors/conda.py +46 -0
  25. driftcheck_py-0.1.48/src/driftcheck/detectors/count.py +46 -0
  26. driftcheck_py-0.1.48/src/driftcheck/detectors/dart.py +73 -0
  27. driftcheck_py-0.1.48/src/driftcheck/detectors/deno.py +79 -0
  28. driftcheck_py-0.1.48/src/driftcheck/detectors/dependabot.py +73 -0
  29. driftcheck_py-0.1.48/src/driftcheck/detectors/devcontainer.py +138 -0
  30. driftcheck_py-0.1.48/src/driftcheck/detectors/docker.py +65 -0
  31. driftcheck_py-0.1.48/src/driftcheck/detectors/docker_bases.py +84 -0
  32. driftcheck_py-0.1.48/src/driftcheck/detectors/docker_multistage.py +88 -0
  33. driftcheck_py-0.1.48/src/driftcheck/detectors/dockerfile_instructions.py +68 -0
  34. driftcheck_py-0.1.48/src/driftcheck/detectors/dotnet.py +44 -0
  35. driftcheck_py-0.1.48/src/driftcheck/detectors/editorconfig.py +128 -0
  36. driftcheck_py-0.1.48/src/driftcheck/detectors/elixir.py +50 -0
  37. driftcheck_py-0.1.48/src/driftcheck/detectors/engines.py +124 -0
  38. driftcheck_py-0.1.48/src/driftcheck/detectors/env_drift.py +246 -0
  39. driftcheck_py-0.1.48/src/driftcheck/detectors/external.py +69 -0
  40. driftcheck_py-0.1.48/src/driftcheck/detectors/fix.py +160 -0
  41. driftcheck_py-0.1.48/src/driftcheck/detectors/frontmatter.py +152 -0
  42. driftcheck_py-0.1.48/src/driftcheck/detectors/git_submodule_drift.py +127 -0
  43. driftcheck_py-0.1.48/src/driftcheck/detectors/git_tag.py +83 -0
  44. driftcheck_py-0.1.48/src/driftcheck/detectors/gitlab.py +56 -0
  45. driftcheck_py-0.1.48/src/driftcheck/detectors/go.py +35 -0
  46. driftcheck_py-0.1.48/src/driftcheck/detectors/go_replace.py +135 -0
  47. driftcheck_py-0.1.48/src/driftcheck/detectors/gradle_catalog.py +77 -0
  48. driftcheck_py-0.1.48/src/driftcheck/detectors/helm.py +56 -0
  49. driftcheck_py-0.1.48/src/driftcheck/detectors/helm_deps.py +135 -0
  50. driftcheck_py-0.1.48/src/driftcheck/detectors/java.py +43 -0
  51. driftcheck_py-0.1.48/src/driftcheck/detectors/jenkins.py +141 -0
  52. driftcheck_py-0.1.48/src/driftcheck/detectors/julia.py +96 -0
  53. driftcheck_py-0.1.48/src/driftcheck/detectors/justfile.py +92 -0
  54. driftcheck_py-0.1.48/src/driftcheck/detectors/k8s.py +56 -0
  55. driftcheck_py-0.1.48/src/driftcheck/detectors/kotlin.py +66 -0
  56. driftcheck_py-0.1.48/src/driftcheck/detectors/kotlin_multiplatform.py +184 -0
  57. driftcheck_py-0.1.48/src/driftcheck/detectors/lineending.py +65 -0
  58. driftcheck_py-0.1.48/src/driftcheck/detectors/lockfile.py +77 -0
  59. driftcheck_py-0.1.48/src/driftcheck/detectors/makefile.py +52 -0
  60. driftcheck_py-0.1.48/src/driftcheck/detectors/maven.py +34 -0
  61. driftcheck_py-0.1.48/src/driftcheck/detectors/mise.py +89 -0
  62. driftcheck_py-0.1.48/src/driftcheck/detectors/nix.py +109 -0
  63. driftcheck_py-0.1.48/src/driftcheck/detectors/node.py +41 -0
  64. driftcheck_py-0.1.48/src/driftcheck/detectors/npm_workspaces.py +123 -0
  65. driftcheck_py-0.1.48/src/driftcheck/detectors/npmrc.py +96 -0
  66. driftcheck_py-0.1.48/src/driftcheck/detectors/nvmrc.py +73 -0
  67. driftcheck_py-0.1.48/src/driftcheck/detectors/package_lock.py +295 -0
  68. driftcheck_py-0.1.48/src/driftcheck/detectors/package_manager.py +87 -0
  69. driftcheck_py-0.1.48/src/driftcheck/detectors/package_version.py +100 -0
  70. driftcheck_py-0.1.48/src/driftcheck/detectors/php.py +58 -0
  71. driftcheck_py-0.1.48/src/driftcheck/detectors/pipfile.py +67 -0
  72. driftcheck_py-0.1.48/src/driftcheck/detectors/pnpm.py +72 -0
  73. driftcheck_py-0.1.48/src/driftcheck/detectors/poetry.py +124 -0
  74. driftcheck_py-0.1.48/src/driftcheck/detectors/pre_commit.py +84 -0
  75. driftcheck_py-0.1.48/src/driftcheck/detectors/pyproject_tools.py +124 -0
  76. driftcheck_py-0.1.48/src/driftcheck/detectors/python.py +58 -0
  77. driftcheck_py-0.1.48/src/driftcheck/detectors/python_freshness.py +222 -0
  78. driftcheck_py-0.1.48/src/driftcheck/detectors/python_req.py +292 -0
  79. driftcheck_py-0.1.48/src/driftcheck/detectors/python_setup.py +170 -0
  80. driftcheck_py-0.1.48/src/driftcheck/detectors/python_version.py +120 -0
  81. driftcheck_py-0.1.48/src/driftcheck/detectors/python_version_drift.py +257 -0
  82. driftcheck_py-0.1.48/src/driftcheck/detectors/r_lang.py +99 -0
  83. driftcheck_py-0.1.48/src/driftcheck/detectors/renovate.py +92 -0
  84. driftcheck_py-0.1.48/src/driftcheck/detectors/requirements.py +120 -0
  85. driftcheck_py-0.1.48/src/driftcheck/detectors/ruby.py +49 -0
  86. driftcheck_py-0.1.48/src/driftcheck/detectors/rust.py +77 -0
  87. driftcheck_py-0.1.48/src/driftcheck/detectors/rust_workspace.py +208 -0
  88. driftcheck_py-0.1.48/src/driftcheck/detectors/scala.py +72 -0
  89. driftcheck_py-0.1.48/src/driftcheck/detectors/swift.py +42 -0
  90. driftcheck_py-0.1.48/src/driftcheck/detectors/taskfile.py +152 -0
  91. driftcheck_py-0.1.48/src/driftcheck/detectors/terraform.py +52 -0
  92. driftcheck_py-0.1.48/src/driftcheck/detectors/terraform_lock.py +133 -0
  93. driftcheck_py-0.1.48/src/driftcheck/detectors/tool_versions.py +70 -0
  94. driftcheck_py-0.1.48/src/driftcheck/detectors/typosquat.py +218 -0
  95. driftcheck_py-0.1.48/src/driftcheck/detectors/uv_lock.py +138 -0
  96. driftcheck_py-0.1.48/src/driftcheck/detectors/version_files.py +127 -0
  97. driftcheck_py-0.1.48/src/driftcheck/detectors/vscode.py +64 -0
  98. driftcheck_py-0.1.48/src/driftcheck/detectors/yarnrc.py +71 -0
  99. driftcheck_py-0.1.48/src/driftcheck/doctor.py +434 -0
  100. driftcheck_py-0.1.48/src/driftcheck/explain.py +261 -0
  101. driftcheck_py-0.1.48/src/driftcheck/git_mode.py +226 -0
  102. driftcheck_py-0.1.48/src/driftcheck/plugins.py +235 -0
  103. driftcheck_py-0.1.48/src/driftcheck/sarif.py +742 -0
  104. driftcheck_py-0.1.48/src/driftcheck_py.egg-info/PKG-INFO +470 -0
  105. driftcheck_py-0.1.48/src/driftcheck_py.egg-info/SOURCES.txt +220 -0
  106. driftcheck_py-0.1.48/src/driftcheck_py.egg-info/dependency_links.txt +1 -0
  107. driftcheck_py-0.1.48/src/driftcheck_py.egg-info/entry_points.txt +2 -0
  108. driftcheck_py-0.1.48/src/driftcheck_py.egg-info/top_level.txt +1 -0
  109. driftcheck_py-0.1.48/tests/test_a2a.py +210 -0
  110. driftcheck_py-0.1.48/tests/test_actions.py +93 -0
  111. driftcheck_py-0.1.48/tests/test_actions_version_drift.py +32 -0
  112. driftcheck_py-0.1.48/tests/test_baseline.py +264 -0
  113. driftcheck_py-0.1.48/tests/test_bazel.py +51 -0
  114. driftcheck_py-0.1.48/tests/test_bun.py +47 -0
  115. driftcheck_py-0.1.48/tests/test_cargo_features.py +61 -0
  116. driftcheck_py-0.1.48/tests/test_changelog.py +200 -0
  117. driftcheck_py-0.1.48/tests/test_ci_os.py +106 -0
  118. driftcheck_py-0.1.48/tests/test_circleci.py +43 -0
  119. driftcheck_py-0.1.48/tests/test_cli_detector_aliases.py +86 -0
  120. driftcheck_py-0.1.48/tests/test_cli_only_exclude.py +106 -0
  121. driftcheck_py-0.1.48/tests/test_cli_report.py +93 -0
  122. driftcheck_py-0.1.48/tests/test_cli_report_summary.py +94 -0
  123. driftcheck_py-0.1.48/tests/test_cmake.py +132 -0
  124. driftcheck_py-0.1.48/tests/test_compose.py +53 -0
  125. driftcheck_py-0.1.48/tests/test_compose_override.py +26 -0
  126. driftcheck_py-0.1.48/tests/test_conda.py +40 -0
  127. driftcheck_py-0.1.48/tests/test_config.py +77 -0
  128. driftcheck_py-0.1.48/tests/test_count.py +128 -0
  129. driftcheck_py-0.1.48/tests/test_csv_output.py +92 -0
  130. driftcheck_py-0.1.48/tests/test_custom_docs.py +51 -0
  131. driftcheck_py-0.1.48/tests/test_dart.py +102 -0
  132. driftcheck_py-0.1.48/tests/test_deno.py +90 -0
  133. driftcheck_py-0.1.48/tests/test_dependabot.py +40 -0
  134. driftcheck_py-0.1.48/tests/test_detector.py +320 -0
  135. driftcheck_py-0.1.48/tests/test_devcontainer.py +65 -0
  136. driftcheck_py-0.1.48/tests/test_docker.py +45 -0
  137. driftcheck_py-0.1.48/tests/test_docker_multistage.py +124 -0
  138. driftcheck_py-0.1.48/tests/test_dockerfile_instructions.py +65 -0
  139. driftcheck_py-0.1.48/tests/test_doctor.py +232 -0
  140. driftcheck_py-0.1.48/tests/test_dotnet.py +89 -0
  141. driftcheck_py-0.1.48/tests/test_editorconfig.py +119 -0
  142. driftcheck_py-0.1.48/tests/test_elixir.py +131 -0
  143. driftcheck_py-0.1.48/tests/test_engines.py +108 -0
  144. driftcheck_py-0.1.48/tests/test_env_drift.py +186 -0
  145. driftcheck_py-0.1.48/tests/test_env_example.py +35 -0
  146. driftcheck_py-0.1.48/tests/test_explain.py +201 -0
  147. driftcheck_py-0.1.48/tests/test_external.py +166 -0
  148. driftcheck_py-0.1.48/tests/test_fix.py +272 -0
  149. driftcheck_py-0.1.48/tests/test_frontmatter.py +53 -0
  150. driftcheck_py-0.1.48/tests/test_git_mode.py +228 -0
  151. driftcheck_py-0.1.48/tests/test_git_tag.py +166 -0
  152. driftcheck_py-0.1.48/tests/test_gitlab.py +37 -0
  153. driftcheck_py-0.1.48/tests/test_go.py +119 -0
  154. driftcheck_py-0.1.48/tests/test_go_replace.py +64 -0
  155. driftcheck_py-0.1.48/tests/test_gradle_catalog.py +79 -0
  156. driftcheck_py-0.1.48/tests/test_helm.py +79 -0
  157. driftcheck_py-0.1.48/tests/test_helm_deps.py +53 -0
  158. driftcheck_py-0.1.48/tests/test_helm_values.py +26 -0
  159. driftcheck_py-0.1.48/tests/test_init_command.py +115 -0
  160. driftcheck_py-0.1.48/tests/test_integration.py +349 -0
  161. driftcheck_py-0.1.48/tests/test_integration_new.py +112 -0
  162. driftcheck_py-0.1.48/tests/test_java.py +99 -0
  163. driftcheck_py-0.1.48/tests/test_jenkins.py +110 -0
  164. driftcheck_py-0.1.48/tests/test_julia.py +53 -0
  165. driftcheck_py-0.1.48/tests/test_justfile.py +41 -0
  166. driftcheck_py-0.1.48/tests/test_k8s.py +73 -0
  167. driftcheck_py-0.1.48/tests/test_kotlin.py +164 -0
  168. driftcheck_py-0.1.48/tests/test_kotlin_multiplatform.py +280 -0
  169. driftcheck_py-0.1.48/tests/test_lineending.py +32 -0
  170. driftcheck_py-0.1.48/tests/test_lockfile.py +152 -0
  171. driftcheck_py-0.1.48/tests/test_makefile.py +188 -0
  172. driftcheck_py-0.1.48/tests/test_maven.py +104 -0
  173. driftcheck_py-0.1.48/tests/test_max_file_size.py +124 -0
  174. driftcheck_py-0.1.48/tests/test_mise.py +75 -0
  175. driftcheck_py-0.1.48/tests/test_new_detectors.py +177 -0
  176. driftcheck_py-0.1.48/tests/test_new_detectors_integration.py +192 -0
  177. driftcheck_py-0.1.48/tests/test_nix.py +196 -0
  178. driftcheck_py-0.1.48/tests/test_node.py +40 -0
  179. driftcheck_py-0.1.48/tests/test_npm_workspaces.py +68 -0
  180. driftcheck_py-0.1.48/tests/test_npmrc.py +90 -0
  181. driftcheck_py-0.1.48/tests/test_nvmrc.py +138 -0
  182. driftcheck_py-0.1.48/tests/test_package_lock.py +166 -0
  183. driftcheck_py-0.1.48/tests/test_package_manager.py +86 -0
  184. driftcheck_py-0.1.48/tests/test_package_version.py +112 -0
  185. driftcheck_py-0.1.48/tests/test_php.py +128 -0
  186. driftcheck_py-0.1.48/tests/test_pipfile.py +147 -0
  187. driftcheck_py-0.1.48/tests/test_plugin_sandbox.py +169 -0
  188. driftcheck_py-0.1.48/tests/test_plugins.py +123 -0
  189. driftcheck_py-0.1.48/tests/test_pnpm.py +67 -0
  190. driftcheck_py-0.1.48/tests/test_poetry.py +222 -0
  191. driftcheck_py-0.1.48/tests/test_pre_commit.py +160 -0
  192. driftcheck_py-0.1.48/tests/test_pre_commit_integration.py +33 -0
  193. driftcheck_py-0.1.48/tests/test_publish_workflow_config.py +103 -0
  194. driftcheck_py-0.1.48/tests/test_pyproject_tools.py +79 -0
  195. driftcheck_py-0.1.48/tests/test_python.py +58 -0
  196. driftcheck_py-0.1.48/tests/test_python_freshness.py +161 -0
  197. driftcheck_py-0.1.48/tests/test_python_req.py +108 -0
  198. driftcheck_py-0.1.48/tests/test_python_setup.py +133 -0
  199. driftcheck_py-0.1.48/tests/test_r_lang.py +57 -0
  200. driftcheck_py-0.1.48/tests/test_renovate.py +93 -0
  201. driftcheck_py-0.1.48/tests/test_requirements.py +193 -0
  202. driftcheck_py-0.1.48/tests/test_ruby.py +118 -0
  203. driftcheck_py-0.1.48/tests/test_rust.py +51 -0
  204. driftcheck_py-0.1.48/tests/test_rust_workspace.py +255 -0
  205. driftcheck_py-0.1.48/tests/test_sarif.py +166 -0
  206. driftcheck_py-0.1.48/tests/test_sarif_new.py +195 -0
  207. driftcheck_py-0.1.48/tests/test_sarif_new_types.py +172 -0
  208. driftcheck_py-0.1.48/tests/test_sarif_privacy.py +106 -0
  209. driftcheck_py-0.1.48/tests/test_scala.py +38 -0
  210. driftcheck_py-0.1.48/tests/test_swift.py +108 -0
  211. driftcheck_py-0.1.48/tests/test_symlinks.py +133 -0
  212. driftcheck_py-0.1.48/tests/test_taskfile.py +237 -0
  213. driftcheck_py-0.1.48/tests/test_terraform.py +60 -0
  214. driftcheck_py-0.1.48/tests/test_terraform_lock.py +82 -0
  215. driftcheck_py-0.1.48/tests/test_tool_versions.py +220 -0
  216. driftcheck_py-0.1.48/tests/test_typosquat.py +107 -0
  217. driftcheck_py-0.1.48/tests/test_uv_lock.py +181 -0
  218. driftcheck_py-0.1.48/tests/test_version_files.py +131 -0
  219. driftcheck_py-0.1.48/tests/test_vscode.py +63 -0
  220. driftcheck_py-0.1.48/tests/test_workflow_deploy_concurrency.py +123 -0
  221. driftcheck_py-0.1.48/tests/test_workflow_input_injection.py +271 -0
  222. driftcheck_py-0.1.48/tests/test_yarnrc.py +71 -0
@@ -0,0 +1,2 @@
1
+ MIT License
2
+ Copyright (c) 2026 Yunare Maia
@@ -0,0 +1,470 @@
1
+ Metadata-Version: 2.4
2
+ Name: driftcheck-py
3
+ Version: 0.1.48
4
+ Summary: Detect version drift between docs and toolchain files (README vs Dockerfile, build.gradle, rust-toolchain.toml, package.json, etc.)
5
+ Author-email: Yunare Maia <yunare@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yunaremaia/driftcheck
8
+ Keywords: drift,docs,version,consistency,cli
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Software Development :: Quality Assurance
15
+ Classifier: Topic :: Software Development :: Testing
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Dynamic: license-file
20
+
21
+ # driftcheck
22
+ [![CI](https://github.com/yunaremaia/driftcheck/actions/workflows/ci.yml/badge.svg)](https://github.com/yunaremaia/driftcheck/actions)
23
+ [![Release](https://img.shields.io/github/v/release/yunaremaia/driftcheck)](https://github.com/yunaremaia/driftcheck/releases/latest)
24
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
25
+ [![License](https://img.shields.io/github/license/yunaremaia/driftcheck) ![Stars](https://img.shields.io/github/stars/yunaremaia/driftcheck)](https://github.com/yunaremaia/driftcheck/blob/main/LICENSE)
26
+
27
+ **Detect version drift between docs and toolchain files.**
28
+
29
+ `README.md` says Rust 1.93.0 but `rust-toolchain.toml` pins 1.96.1? `CONTRIBUTING.md` says Node 18 but `package.json` engines says 24? `go.mod` says 1.23 but docs say 1.21? `driftcheck` catches it before your contributors hit a build failure.
30
+
31
+ ```bash
32
+ pip install git+https://github.com/yunaremaia/driftcheck.git
33
+ driftcheck # scan current repo
34
+ driftcheck --json # machine-readable
35
+ driftcheck --fix # auto-fix drifts in documentation files
36
+ driftcheck --sarif # SARIF 2.1.0 output for GitHub Code Scanning
37
+ driftcheck --csv # CSV output for spreadsheets/data pipelines
38
+ driftcheck --list-detectors # show available detectors
39
+ driftcheck --only tool_versions_drifts # run specific detectors
40
+ driftcheck --exclude nvmrc_drifts,lockfile_drifts # exclude detectors
41
+ driftcheck --quiet # only output drifts, suppress OK
42
+ driftcheck --no-informational # skip informational drifts
43
+ driftcheck --version
44
+ ```
45
+
46
+ ### GitHub Action
47
+
48
+ Add driftcheck to your CI with a single step:
49
+
50
+ ```yaml
51
+ - uses: yunaremaia/driftcheck@main
52
+ with:
53
+ fail-on-drift: true # default
54
+ args: "--no-informational"
55
+ ```
56
+
57
+ Or with SARIF upload for GitHub Code Scanning:
58
+
59
+ ```yaml
60
+ - uses: yunaremaia/driftcheck@main
61
+ with:
62
+ sarif: true
63
+ - uses: github/codeql-action/upload-sarif@v3
64
+ with:
65
+ sarif_file: driftcheck.sarif
66
+ ```
67
+
68
+ SARIF output includes an `originalUriBaseIds.repoRoot` `file://` URI and
69
+ repo-relative artifact paths tagged with `uriBaseId: "repoRoot"`, so code
70
+ scanning can resolve findings correctly when driftcheck runs from a subdirectory.
71
+
72
+ ### Reusable Workflow (Zero-Config CI)
73
+
74
+ For the simplest setup, use driftcheck's reusable workflow — no YAML to write in your repo:
75
+
76
+ ```yaml
77
+ # .github/workflows/driftcheck.yml in YOUR repo
78
+ name: Driftcheck
79
+ on:
80
+ push:
81
+ branches: [main, master]
82
+ pull_request:
83
+ branches: [main, master]
84
+
85
+ jobs:
86
+ driftcheck:
87
+ uses: yunaremaia/driftcheck/.github/workflows/driftcheck.yml@main
88
+ with:
89
+ fail-on-drift: true
90
+ detectors: 'docker,compose,github-actions,node,python,rust'
91
+ ```
92
+
93
+ With SARIF upload for GitHub Code Scanning alerts:
94
+
95
+ ```yaml
96
+ jobs:
97
+ driftcheck:
98
+ uses: yunaremaia/driftcheck/.github/workflows/driftcheck.yml@main
99
+ with:
100
+ fail-on-drift: true
101
+ output-format: sarif
102
+ sarif-upload: true
103
+ permissions:
104
+ contents: read
105
+ security-events: write
106
+ ```
107
+
108
+ ### CSV Export
109
+
110
+ Output drift findings as CSV — useful for spreadsheets, data pipelines, and CI artifact collection:
111
+
112
+ ```bash
113
+ driftcheck --csv # CSV output to stdout
114
+ driftcheck --csv > drifts.csv # save to file for CI artifact
115
+ driftcheck --csv --no-informational # exclude informational drifts
116
+ ```
117
+
118
+ Output columns: `file`, `detector`, `doc_version`, `actual_version`, `severity`, `message`.
119
+
120
+ ### Markdown Report
121
+
122
+ Generate a markdown summary for CI job summaries or PR comments:
123
+
124
+ ```bash
125
+ driftcheck --report # output markdown to stdout
126
+ driftcheck --report >> $GITHUB_STEP_SUMMARY # post to GitHub Actions
127
+ ```
128
+
129
+ The report includes a statistical summary at the top:
130
+
131
+ ```
132
+ ## driftcheck report
133
+
134
+ ### 📊 Summary
135
+
136
+ - **Total drifts:** 3
137
+ - ❌ Blocking: 2
138
+ - ℹ️ Informational: 1
139
+ - **Detectors fired:** 2
140
+ - `node`: 2
141
+ - `lockfile`: 1
142
+ - **Top files:**
143
+ - `README.md`: 2 drift(s)
144
+
145
+ ### ❌ Blocking drifts
146
+
147
+ **Node.js package.json engines vs README** (node_drifts):
148
+ - `README.md`: Node 18 → should be 20
149
+ ```
150
+
151
+ ### Initialize Config
152
+
153
+ Generate a starter `.driftcheck.toml`:
154
+
155
+ ```bash
156
+ driftcheck --init # creates .driftcheck.toml with examples
157
+ ```
158
+
159
+ ### Configuration (`.driftcheck.toml`)
160
+
161
+ Place a `.driftcheck.toml` file in your repo root to customize detection:
162
+
163
+ ```toml
164
+ [driftcheck]
165
+ # Exclude specific detectors (supports short names or drift keys)
166
+ exclude_detectors = ["lockfile", "nvmrc", "ci_os"]
167
+
168
+ # Treat informational drifts as blocking
169
+ fail_on_informational = false
170
+
171
+ # Custom doc paths — additional files to scan for version mentions
172
+ # Supports glob patterns (e.g., "docs/*.md")
173
+ doc_paths = ["docs/setup.md", "CHANGELOG.md"]
174
+ ```
175
+
176
+ By default, informational drifts (such as missing lockfiles or orphaned configurations) are reported as non-blocking warnings and exit with code `0`.
177
+
178
+ - **`--fail-on-informational`**: Promotes informational drifts to blocking errors, causing `driftcheck` to exit with code `1`. Useful in strict CI pipelines where you want to enforce rules like missing lockfiles or missing `.gitattributes` (`* text=auto eol=lf`).
179
+ - **`--no-informational`**: Suppresses informational drifts from the output entirely.
180
+
181
+ You can also use CLI flags `--only` and `--exclude` to filter detectors at runtime.
182
+
183
+ ### Git-Mode (Incremental Scans)
184
+
185
+ For large repositories, scan only the detectors relevant to your latest changes:
186
+
187
+ ```bash
188
+ # Only check files changed since the last commit
189
+ driftcheck --git-mode
190
+
191
+ # Compare against a specific base (e.g., main branch)
192
+ driftcheck --git-mode --git-base origin/main
193
+ ```
194
+
195
+ This maps changed file paths to detector patterns (e.g., a `package.json` change runs only the Node.js and npm-related detectors) and skips the rest. Useful in CI where the full scan is overkill for a targeted PR.
196
+
197
+ ### CI/CD Integration
198
+
199
+ driftcheck is designed to run as a quality gate in CI pipelines. It exits with code 1 when blocking drifts are found, making it easy to fail a build or PR check.
200
+
201
+ **Exit codes:**
202
+ - `0` — no blocking drifts (clean)
203
+ - `1` — blocking drifts detected
204
+
205
+ **GitHub Actions (full scan):**
206
+
207
+ ```yaml
208
+ - name: Run driftcheck
209
+ run: driftcheck --report >> $GITHUB_STEP_SUMMARY
210
+ ```
211
+
212
+ **GitHub Actions (PR comparison against main):**
213
+
214
+ ```yaml
215
+ - uses: actions/checkout@v5
216
+ with:
217
+ fetch-depth: 0 # full history for git-base comparison
218
+
219
+ - name: Driftcheck PR
220
+ run: |
221
+ driftcheck --git-mode --git-base origin/main --report >> $GITHUB_STEP_SUMMARY
222
+ ```
223
+
224
+ **Comparing against a specific tag:**
225
+
226
+ ```bash
227
+ driftcheck --git-mode --git-base v1.0.0
228
+ ```
229
+
230
+ ### Checks (v0.1.47):
231
+
232
+ **Language runtimes:**
233
+ - **Rust**: `rust-toolchain.toml` `channel` **and** `Cargo.toml` `rust-version` vs `README.md` / `docs/README*.md` / `CONTRIBUTING*.md` — minor-aware (patch differences ignored)
234
+ - **Cargo features**: `Cargo.toml` `[features]` vs explicit `features = [...]` lists and `--features` flags in README
235
+ - **npm workspaces**: same dependency declared at different ranges across workspace `package.json` files
236
+ - **Node**: `package.json` `engines.node` vs README
237
+ - **Bun**: `package.json` `engines.bun` vs README — major.minor comparison
238
+ - **Package version**: `package.json` `version` vs explicit npm badge URLs, install commands, and changelog headers in README/docs
239
+ - **Python**: `pyproject.toml` `requires-python` vs README
240
+ - **Python tool targets**: `[tool.ruff]`, `[tool.black]`, `[tool.mypy]`, `[tool.pyright]` vs `requires-python`
241
+ - **Python (legacy setup)**: `setup.py` / `setup.cfg` `python_requires` and explicit `install_requires` pins vs README/CONTRIBUTING
242
+ - **Go**: `go.mod` `go` directive vs README
243
+ - **PHP**: `composer.json` `require.php` vs README — major.minor comparison
244
+ - **Ruby**: `Gemfile` `ruby "x.y.z"` directive vs README — major.minor comparison
245
+ - **.NET/C#**: `*.csproj` `<TargetFramework>` vs README — handles multi-targeting
246
+ - **Elixir**: `mix.exs` `elixir:` version vs README
247
+ - **Kotlin**: `build.gradle.kts` plugin version vs README
248
+ - **Swift**: `Package.swift` `swift-tools-version` and dependency pins vs README
249
+ - **Dart/Flutter**: `pubspec.yaml` `environment.sdk` constraint vs README
250
+ - **Deno**: `deno.json` version pins vs README
251
+ - **Python Version**: `.python-version` vs `pyproject.toml` `requires-python` floor
252
+
253
+ **Package managers & lockfiles:**
254
+ - **Pipfile**: `Pipfile` vs `Pipfile.lock` version mismatches
255
+ - **Conda**: `environment.yml` unpinned packages
256
+ - **Gradle Version Catalog**: `libs.versions.toml` vs README
257
+ - **Kotlin Multiplatform (KMP)**: `gradle/libs.versions.toml` KMP catalog vs README badges (kotlin, coroutines, compose, AGP, KSP)
258
+ - **Lockfile**: missing, stale, or orphaned lockfiles (package-lock.json, yarn.lock, Cargo.lock, go.sum, Gemfile.lock, composer.lock, poetry.lock, uv.lock) (informational)
259
+ - **package-lock integrity**: package.json dependency ranges vs package-lock.json v1/v2/v3 resolved versions; flags missing direct dependencies and semver range violations
260
+ - **Nix**: `flake.lock` nixpkgs pins vs README mentions
261
+ - **Engines**: `package.json` `engines` field consistency across package managers
262
+ - **Requirements**: `requirements.txt` unpinned packages vs known latest
263
+
264
+ **CI/CD:**
265
+ - **GitHub Actions**: outdated `uses: action@version` — compares against known latest versions for 18 popular actions; detects deprecated Node 20 runtime
266
+ - **GitLab CI**: `.gitlab-ci.yml` image tags vs README
267
+ - **CircleCI**: `.circleci/config.yml` docker image tags vs README
268
+ - **Jenkins**: `Jenkinsfile` tool versions (`nodejs`, `python`, `docker.image`) vs README
269
+ - **CI OS**: deprecated GitHub Actions runners (ubuntu-18.04, macos-11, windows-2016)
270
+
271
+ **Infrastructure:**
272
+ - **Docker**: `Dockerfile` `FROM <image>:<tag>` vs README
273
+ - **Docker Bases**: floating/unpinned Dockerfile base images
274
+ - **Docker Multistage**: multi-stage Dockerfile `FROM` consistency across stages
275
+ - **Docker Compose**: `docker-compose.yml`/`compose.yaml` image tags vs README
276
+ - **Kubernetes**: image tags in manifests vs README
277
+ - **Helm**: `Chart.yaml`/`values.yaml` image tags vs README
278
+ - **Terraform**: `versions.tf` `required_providers` block `version` vs README
279
+ - **Environment drift**: `.env.example` vs `.env`, `docker-compose.yml` vs `docker-compose.prod.yml`, `values.yaml` vs `values.prod.yaml`
280
+
281
+ **Build tools:**
282
+ - **Bazel**: `.bazelversion`, `MODULE.bazel` `bazel_dep`, and `WORKSPACE.bazel` `http_archive` pins vs README
283
+ - **Makefile**: tool version variables (`GCC_VERSION`, `CMAKE_VERSION`, `GO_VERSION`, etc.)
284
+ - **CMake**: `CMakeLists.txt` `cmake_minimum_required` version vs README
285
+ - **Maven**: `pom.xml` `java.version`, `maven.compiler.source`, `maven.compiler.target`, `release` vs README
286
+ - **Java/Gradle**: `build.gradle` `sourceCompatibility`, `jvmTarget`, `JavaVersion.VERSION_*` vs README
287
+
288
+ **Configuration:**
289
+ - **Tool versions**: `.tool-versions` (asdf/mise) — detects drift for Node, Python, Go, Rust, Ruby, Java, PHP, .NET
290
+ - **Mise**: `mise.toml` `[tools]` section vs README — supports string and dict specs (e.g., `node = "22"` or `python = {version = "3.12"}`)
291
+ - **Version files**: `.ruby-version`, `.python-version`, `.node-version`, `.java-version`, `.terraform-version` vs README
292
+ - **EditorConfig**: `.editorconfig` `indent_size`/`indent_style` vs project convention
293
+ - **Devcontainer**: `.devcontainer/devcontainer.json` image/tags vs README
294
+ - **Renovate**: `renovate.json` configuration drift vs README
295
+ - **NVMRC**: `.nvmrc` vs `package.json` engines.node (informational)
296
+ - **Dependabot**: ecosystems used but not covered by `.github/dependabot.yml` (informational)
297
+ - **SARIF output**: `driftcheck --sarif` generates SARIF 2.1.0 for GitHub Code Scanning
298
+
299
+ **Security:**
300
+ - **Typosquat**: suspicious package names similar to popular packages
301
+ - **package-lock integrity**: blocking supply-chain check for package-lock resolutions outside declared package.json ranges
302
+
303
+ **Other:**
304
+ - **Line endings**: missing `* text=auto eol=lf` in `.gitattributes` (informational)
305
+ - **External resources**: third-party CDN dependencies that break offline rendering (informational)
306
+ - **Count**: `skills/` directory count vs README mentions of "N skills"
307
+ - **Plugins**: custom drift detection via `.driftcheck_plugins/` directory
308
+ - **NPMRC**: `.npmrc` registry vs README mentions
309
+ - **Yarn RC**: `.yml` Yarn version vs README mentions
310
+ - **PNPM workspace**: `pnpm-workspace.yaml` packages vs `package.json` workspaces
311
+ - **Git Tag**: latest git tag vs README version mentions — detects when README references a stale version
312
+ - **Pre-commit**: `.pre-commit-config.yaml` `rev:` vs README mentions of pre-commit version
313
+
314
+ ### Plugins
315
+
316
+ driftcheck supports plugins for custom drift detection. Create a `.driftcheck_plugins/` directory in your repo root and add Python files that define a `register()` function:
317
+
318
+ ```python
319
+ # .driftcheck_plugins/my_detector.py
320
+ import re
321
+
322
+ def register():
323
+ return {"my_detector": find_my_drift}
324
+
325
+ MY_RE = re.compile(r'my_tool\s+(?P<ver>\d+\.\d+)')
326
+
327
+ def find_my_drift(root, docs):
328
+ drifts = []
329
+ for fname, content in docs.items():
330
+ for m in MY_RE.finditer(content):
331
+ drifts.append({
332
+ "file": fname,
333
+ "doc_version": m.group("ver"),
334
+ "detail": f"my_tool {m.group('ver')} mentioned",
335
+ })
336
+ return drifts
337
+ ```
338
+
339
+ Plugin results appear as `plugin_<name>_drifts` in JSON output and are printed in the CLI. Broken plugins are skipped with a warning — they won't crash driftcheck.
340
+
341
+ ### Pre-commit hook
342
+
343
+ driftcheck ships a pre-commit hook that limits work to detectors relevant to
344
+ the files staged for the next commit:
345
+
346
+ ```yaml
347
+ repos:
348
+ - repo: https://github.com/yunaremaia/driftcheck
349
+ rev: v0.1.47
350
+ hooks:
351
+ - id: driftcheck
352
+ args: ["--no-informational"]
353
+ ```
354
+
355
+ The published hook uses `--changed-only`, which reads the staged git diff and
356
+ runs only relevant detectors. You can use the same mode directly:
357
+
358
+ ```bash
359
+ driftcheck --changed-only
360
+ ```
361
+
362
+ To print the hook manifest entry for tooling or inspection:
363
+
364
+ ```bash
365
+ driftcheck pre-commit
366
+ ```
367
+
368
+ Or install pre-commit locally:
369
+
370
+ ```bash
371
+ pip install pre-commit
372
+ pre-commit install
373
+ ```
374
+
375
+ ### Stats
376
+
377
+ - **85 detector modules** covering 50+ toolchains and file formats
378
+ - **74 registered drift keys** (including split environment detectors, lockfile variants, plugin system, and A2A protocol drift detection)
379
+ - **1511 tests** with >95% code coverage
380
+ - **SARIF 2.1.0** output for GitHub Code Scanning
381
+ - **Plugin system** for custom detectors
382
+ - **Pre-commit hook** support
383
+
384
+ ### Python API
385
+
386
+ See the [API Reference](docs/api.md) for embedding driftcheck in scripts and CI pipelines.
387
+
388
+ ### Detector Comparison Matrix
389
+
390
+ | Ecosystem | Detector | Drift Key | Example Detected |
391
+ |-----------|----------|-----------|------------------|
392
+ | .NET | dotnet | `dotnet_drifts` | .NET csproj TargetFramework |
393
+ | C/C++ | cmake | `cmake_drifts` | CMakeLists.txt cmake_minimum_required |
394
+ | C/C++ | makefile | `makefile_drifts` | Makefile tool version pins (CC, CMAKE, GO) |
395
+ | CI/CD | actions-outdated | `gh_actions_version_drifts` | GitHub Actions outdated versions |
396
+ | CI/CD | ci-os | `ci_os_drifts` | Deprecated CI runner (e.g., ubuntu-20.04) |
397
+ | CI/CD | circleci | `circleci_drifts` | CircleCI config.yml image |
398
+ | CI/CD | gitlab | `gitlab_drifts` | GitLab CI image tag |
399
+ | CI/CD | jenkins | `jenkins_drifts` | Jenkinsfile tool versions (nodejs, python, docker) |
400
+ | Docker | compose | `dc_drifts` | Docker Compose image |
401
+ | Docker | compose-override | `compose_override_drifts` | Docker Compose override file image drift |
402
+ | Docker | docker | `docker_drifts` | Dockerfile FROM tag |
403
+ | Docker | docker-bases | `docker_bases_drifts` | Floating/unpinned base images |
404
+ | Docker | docker-multistage | `docker_multistage_drifts` | Multi-stage Dockerfile conflicting tags |
405
+ | Editor/IDE | editorconfig | `editorconfig_drifts` | .editorconfig vs README/IDE indent |
406
+ | Editor/IDE | vscode-ext | `vscode_ext_drifts` | VSCode extensions.json vs README recommendations |
407
+ | Elixir | elixir | `elixir_drifts` | Elixir mix.exs version |
408
+ | Environment | env | `env_drifts` | .env.example vs .env, compose overrides |
409
+ | Environment | env-example | `env_example_drifts` | .env.example vs .env key drift |
410
+ | General | count | `count_drifts` | Skills directory count vs README |
411
+ | General | dart | `dart_drifts` | Dart pubspec.yaml SDK constraint |
412
+ | General | deno | `deno_drifts` | Deno deno.json version field |
413
+ | General | dependabot | `dependabot_drifts` | Dependabot coverage gaps (informational) |
414
+ | General | external | `external_resource_drifts` | External CDN resources in HTML (informational) |
415
+ | General | lineending | `lineending_drifts` | Missing .gitattributes line ending config |
416
+ | General | lockfile | `lockfile_drifts` | Lockfile missing/stale/orphaned (informational) |
417
+ | General | mise | `mise_drifts` | mise.toml tool versions |
418
+ | General | nvmrc | `nvmrc_drifts` | .nvmrc vs package.json engines (informational) |
419
+ | General | package-manager | `package_manager_drifts` | packageManager field vs lockfile |
420
+ | General | swift | `swift_drifts` | Swift Package.swift version pins |
421
+ | General | taskfile | `taskfile_drifts` | Taskfile.yml tool versions |
422
+ | General | tool-versions | `tool_versions_drifts` | .tool-versions asdf/mise |
423
+ | Git | git-tag | `git_tag_drifts` | Latest git tag vs README version mentions |
424
+ | Go | go | `go_drifts` | Go go.mod directive |
425
+ | Gradle | gradle | `java_drifts` | Gradle build.gradle sourceCompatibility |
426
+ | Gradle | gradle-catalog | `gradle_catalog_drifts` | Gradle Version Catalog (libs.versions.toml) |
427
+ | Helm | helm | `helm_drifts` | Helm Chart.yaml/values.yaml |
428
+ | Helm | helm-values | `helm_values_drifts` | Helm values.yaml vs environment-specific values |
429
+ | Java | java-version | `java_version_drifts` | .java-version vs README |
430
+ | Kotlin | kotlin | `kotlin_drifts` | Kotlin build.gradle.kts plugin version |
431
+ | Kotlin | kotlin-multiplatform | `kmp_drifts` | Kotlin Multiplatform (KMP) version catalog drift |
432
+ | Kubernetes | k8s | `k8s_drifts` | Kubernetes manifest image |
433
+ | Maven | maven | `maven_drifts` | Maven pom.xml java.version |
434
+ | Node | actions-node20 | `actions_drifts` | GitHub Actions Node 20 deprecation |
435
+ | Node | bun | `bun_drifts` | Bun package.json engines.bun |
436
+ | Node | node | `node_drifts` | Node.js package.json engines |
437
+ | Node | node-version | `node_version_drifts` | .node-version vs README |
438
+ | Node | npmrc | `npmrc_drifts` | .npmrc vs package.json settings |
439
+ | Node | pnpm | `pnpm_workspace_drifts` | pnpm-workspace.yaml vs package.json workspaces |
440
+ | Node | yarnrc | `yarnrc_drifts` | .yarnrc.yml Yarn version |
441
+ | PHP | php | `php_drifts` | composer.json require.php |
442
+ | Python | conda | `conda_drifts` | Conda environment.yml pinned versions |
443
+ | Python | pipfile | `pipfile_drifts` | Pipfile vs Pipfile.lock version mismatches |
444
+ | Python | poetry | `poetry_drifts` | Poetry pyproject.toml [tool.poetry] dependencies |
445
+ | Python | python | `python_drifts` | Python pyproject.toml requires-python |
446
+ | Python | python-version | `python_version_drifts` | .python-version vs README |
447
+ | Python | requirements | `requirements_drifts` | requirements.txt package versions |
448
+ | Ruby | ruby | `ruby_drifts` | Gemfile ruby directive |
449
+ | Ruby | ruby-version | `ruby_version_drifts` | .ruby-version vs README |
450
+ | Rust | rust-cargo | `rust_drifts` | Rust Cargo.toml rust-version |
451
+ | Rust | rust-toolchain | `drifts` | Rust toolchain.toml channel |
452
+ | Security | typosquat | `typosquat_drifts` | Typosquat detection in dependencies (informational) |
453
+ | AI Agents | a2a | `a2a_drifts` | A2A agent card spec_version vs docs, capabilities, endpoints (informational) |
454
+ | Documentation | changelog | `changelog_drifts` | CHANGELOG.md presence/content vs CONTRIBUTING.md policy (informational) |
455
+ | Terraform | terraform | `terraform_drifts` | Terraform versions.tf provider |
456
+ | Terraform | terraform-version | `terraform_version_drifts` | .terraform-version vs README |
457
+
458
+ ## Sponsoring / Treasury
459
+
460
+ driftcheck is MIT licensed and maintained in the open. If it saves you time, you can
461
+ support continued development through GitHub Sponsors or the Solana treasury below.
462
+
463
+ Funding details are declared in [`.github/FUNDING.yml`](.github/FUNDING.yml), which is
464
+ what GitHub reads to render the **Sponsor** button on this repository.
465
+
466
+ - **GitHub Sponsors:** [@yunaremaia](https://github.com/sponsors/yunaremaia)
467
+ - **Solana:** `Eeztv1nCYUt1fwGWpzKC948gaWfjejYCAuLtUMgzDWbW`
468
+
469
+ Use the Solana address only for intended donations. Anyone can generate a similar
470
+ address, so verify the address against `.github/FUNDING.yml` before sending funds.