code_ownership 2.1.2 → 2.1.3

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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/.cargo/config +2 -2
  3. data/Cargo.lock +9 -2
  4. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.cargo-checksum.json +1 -1
  5. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/Cargo.lock +8 -1
  6. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/Cargo.toml +2 -1
  7. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/file_generator.rs +119 -9
  8. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/validator.rs +77 -15
  9. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/executable_name_config_test.rs +25 -4
  10. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/.github/CODEOWNERS +1 -1
  11. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/default_executable_name/.github/CODEOWNERS +1 -1
  12. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/invalid_project_test.rs +30 -0
  13. data/ext/cargo-vendor/similar-2.7.0/.cargo/config.toml +2 -0
  14. data/ext/cargo-vendor/similar-2.7.0/.cargo-checksum.json +1 -0
  15. data/ext/cargo-vendor/similar-2.7.0/.cargo_vcs_info.json +6 -0
  16. data/ext/cargo-vendor/similar-2.7.0/.github/FUNDING.yml +1 -0
  17. data/ext/cargo-vendor/similar-2.7.0/.github/workflows/clippy.yml +16 -0
  18. data/ext/cargo-vendor/similar-2.7.0/.github/workflows/rustfmt.yml +16 -0
  19. data/ext/cargo-vendor/similar-2.7.0/.github/workflows/tests.yml +49 -0
  20. data/ext/cargo-vendor/similar-2.7.0/.vscode/settings.json +5 -0
  21. data/ext/cargo-vendor/similar-2.7.0/CHANGELOG.md +132 -0
  22. data/ext/cargo-vendor/similar-2.7.0/Cargo.lock +373 -0
  23. data/ext/cargo-vendor/similar-2.7.0/Cargo.lock.msrv +266 -0
  24. data/ext/cargo-vendor/similar-2.7.0/Cargo.toml +149 -0
  25. data/ext/cargo-vendor/similar-2.7.0/Cargo.toml.orig +73 -0
  26. data/ext/cargo-vendor/similar-2.7.0/LICENSE +201 -0
  27. data/ext/cargo-vendor/similar-2.7.0/Makefile +31 -0
  28. data/ext/cargo-vendor/similar-2.7.0/README.md +59 -0
  29. data/ext/cargo-vendor/similar-2.7.0/clippy.toml +1 -0
  30. data/ext/cargo-vendor/similar-2.7.0/examples/close-matches.rs +15 -0
  31. data/ext/cargo-vendor/similar-2.7.0/examples/large.rs +8 -0
  32. data/ext/cargo-vendor/similar-2.7.0/examples/nonstring.rs +13 -0
  33. data/ext/cargo-vendor/similar-2.7.0/examples/original-slices.rs +11 -0
  34. data/ext/cargo-vendor/similar-2.7.0/examples/patience.rs +48 -0
  35. data/ext/cargo-vendor/similar-2.7.0/examples/serde.rs +15 -0
  36. data/ext/cargo-vendor/similar-2.7.0/examples/terminal-inline.rs +60 -0
  37. data/ext/cargo-vendor/similar-2.7.0/examples/terminal.rs +20 -0
  38. data/ext/cargo-vendor/similar-2.7.0/examples/udiff.rs +24 -0
  39. data/ext/cargo-vendor/similar-2.7.0/scripts/wasmtime-wrapper.sh +4 -0
  40. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/capture.rs +117 -0
  41. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/compact.rs +351 -0
  42. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/hook.rs +178 -0
  43. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/lcs.rs +294 -0
  44. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/mod.rs +134 -0
  45. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/myers.rs +442 -0
  46. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/patience.rs +198 -0
  47. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/replace.rs +221 -0
  48. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__capture__capture_hook_grouping-2.snap +60 -0
  49. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__capture__capture_hook_grouping.snap +64 -0
  50. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__contiguous.snap +28 -0
  51. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__diff.snap +22 -0
  52. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__pat.snap +31 -0
  53. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__same.snap +12 -0
  54. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__contiguous.snap +28 -0
  55. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__deadline_reached.snap +22 -0
  56. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__diff.snap +22 -0
  57. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__pat.snap +31 -0
  58. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__patience__patience.snap +45 -0
  59. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__patience__patience_out_of_bounds_bug.snap +16 -0
  60. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/utils.rs +379 -0
  61. data/ext/cargo-vendor/similar-2.7.0/src/common.rs +185 -0
  62. data/ext/cargo-vendor/similar-2.7.0/src/deadline_support.rs +37 -0
  63. data/ext/cargo-vendor/similar-2.7.0/src/iter.rs +195 -0
  64. data/ext/cargo-vendor/similar-2.7.0/src/lib.rs +176 -0
  65. data/ext/cargo-vendor/similar-2.7.0/src/snapshots/similar__udiff__unified_diff.snap +25 -0
  66. data/ext/cargo-vendor/similar-2.7.0/src/snapshots/similar__udiff__unified_diff_newline_hint-2.snap +10 -0
  67. data/ext/cargo-vendor/similar-2.7.0/src/snapshots/similar__udiff__unified_diff_newline_hint.snap +11 -0
  68. data/ext/cargo-vendor/similar-2.7.0/src/text/abstraction.rs +446 -0
  69. data/ext/cargo-vendor/similar-2.7.0/src/text/inline.rs +342 -0
  70. data/ext/cargo-vendor/similar-2.7.0/src/text/mod.rs +792 -0
  71. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__captured_ops.snap +22 -0
  72. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__captured_word_ops.snap +202 -0
  73. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__char_diff.snap +39 -0
  74. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__inline__line_ops_inline.snap +126 -0
  75. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__inline__serde.snap +107 -0
  76. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__lifetimes_on_iter.snap +42 -0
  77. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__line_ops.snap +42 -0
  78. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__serde.snap +55 -0
  79. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__serde_ops.snap +38 -0
  80. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__unified_diff.snap +12 -0
  81. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__virtual_newlines.snap +32 -0
  82. data/ext/cargo-vendor/similar-2.7.0/src/text/utils.rs +55 -0
  83. data/ext/cargo-vendor/similar-2.7.0/src/types.rs +502 -0
  84. data/ext/cargo-vendor/similar-2.7.0/src/udiff.rs +359 -0
  85. data/ext/cargo-vendor/similar-2.7.0/src/utils.rs +412 -0
  86. data/ext/code_ownership/Cargo.toml +1 -1
  87. data/lib/code_ownership/version.rb +1 -1
  88. metadata +252 -178
  89. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.github/CODEOWNERS +0 -0
  90. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.github/workflows/audit.yml +0 -0
  91. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.github/workflows/ci.yml +0 -0
  92. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.github/workflows/dotslash-config.json +0 -0
  93. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.rustfmt.toml +0 -0
  94. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.rusty-hook.toml +0 -0
  95. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/AGENTS.md +0 -0
  96. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/CLAUDE.md +0 -0
  97. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/README.md +0 -0
  98. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/dev/run_benchmarks_for_file.sh +0 -0
  99. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/dev/run_benchmarks_for_gv.sh +0 -0
  100. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/rust-toolchain.toml +0 -0
  101. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/cache/file.rs +0 -0
  102. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/cache/mod.rs +0 -0
  103. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/cache/noop.rs +0 -0
  104. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/cli.rs +0 -0
  105. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/common_test.rs +0 -0
  106. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/config.rs +0 -0
  107. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/crosscheck.rs +0 -0
  108. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/lib.rs +0 -0
  109. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/main.rs +0 -0
  110. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/codeowners_file_parser.rs +0 -0
  111. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/codeowners_query.rs +0 -0
  112. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/file_owner_finder.rs +0 -0
  113. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/file_owner_resolver.rs +0 -0
  114. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/annotated_file_mapper.rs +0 -0
  115. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/directory_mapper.rs +0 -0
  116. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/escaper.rs +0 -0
  117. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/package_mapper.rs +0 -0
  118. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/team_gem_mapper.rs +0 -0
  119. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/team_glob_mapper.rs +0 -0
  120. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/team_yml_mapper.rs +0 -0
  121. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper.rs +0 -0
  122. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership.rs +0 -0
  123. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/path_utils.rs +0 -0
  124. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/project.rs +0 -0
  125. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/project_builder.rs +0 -0
  126. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/project_file_builder.rs +0 -0
  127. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/runner/api.rs +0 -0
  128. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/runner/types.rs +0 -0
  129. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/runner.rs +0 -0
  130. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/tracked_files.rs +0 -0
  131. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/cache_test.rs +0 -0
  132. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/codeowners_path_test.rs +0 -0
  133. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/common/mod.rs +0 -0
  134. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/crosscheck_owners_test.rs +0 -0
  135. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/config/code_ownership.yml +0 -0
  136. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/config/teams/test_team.yml +0 -0
  137. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/docs/CODEOWNERS +0 -0
  138. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/expected/CODEOWNERS +0 -0
  139. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/ruby/app/models/test.rb +0 -0
  140. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/app/foo.rb +0 -0
  141. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/config/code_ownership.yml +0 -0
  142. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/config/teams/foo.yml +0 -0
  143. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/config/teams/payments.yml +0 -0
  144. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/ruby/app/payments/foo.rb +0 -0
  145. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/default_executable_name/app/bar.rb +0 -0
  146. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/default_executable_name/config/code_ownership.yml +0 -0
  147. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/default_executable_name/config/teams/bar.yml +0 -0
  148. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/.github/CODEOWNERS +0 -0
  149. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/config/code_ownership.yml +0 -0
  150. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/config/teams/payments.yml +0 -0
  151. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/config/teams/payroll.yml +0 -0
  152. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/gems/payroll_calculator/calculator.rb +0 -0
  153. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/models/bank_account.rb +0 -0
  154. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/models/blockchain.rb +0 -0
  155. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/models/payroll.rb +0 -0
  156. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/payments/nacha.rb +0 -0
  157. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/services/.codeowner +0 -0
  158. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/services/multi_owned.rb +0 -0
  159. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/unowned.rb +0 -0
  160. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/packages/payroll_flow/package.yml +0 -0
  161. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/.github/CODEOWNERS +0 -0
  162. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/.keep +0 -0
  163. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/config/code_ownership.yml +0 -0
  164. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/config/teams/design.yml +0 -0
  165. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/config/teams/frontend.yml +0 -0
  166. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/apps/public/index.tsx +0 -0
  167. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/dashboard/package.json +0 -0
  168. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/dashboard/src/index.tsx +0 -0
  169. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/ui-kit/.codeowner +0 -0
  170. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/ui-kit/src/button.tsx +0 -0
  171. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/.github/CODEOWNERS +0 -0
  172. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/config/code_ownership.yml +0 -0
  173. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/config/teams/bad_team.yml +0 -0
  174. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/config/teams/good.yml +0 -0
  175. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/gems/pets/dog.rb +0 -0
  176. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/.github/CODEOWNERS +0 -0
  177. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/consumers/.codeowner +0 -0
  178. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/consumers/deep/nesting/nestdir/deep_file.rb +0 -0
  179. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/consumers/one_owner.rb +0 -0
  180. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/services/.codeowner +0 -0
  181. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/services/exciting/.codeowner +0 -0
  182. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/services/exciting/some_other_file.rb +0 -0
  183. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/config/code_ownership.yml +0 -0
  184. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/config/teams/bar.yml +0 -0
  185. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/config/teams/foo.yml +0 -0
  186. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/.github/CODEOWNERS +0 -0
  187. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/.ignore +0 -0
  188. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/config/code_ownership.yml +0 -0
  189. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/config/teams/payments.yml +0 -0
  190. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/config/teams/payroll.yml +0 -0
  191. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/config/teams/ux.yml +0 -0
  192. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/gems/payroll_calculator/calculator.rb +0 -0
  193. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/gems/pets/dog.rb +0 -0
  194. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/PayrollFlow/index.tsx +0 -0
  195. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/PayrollFlow/package.json +0 -0
  196. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/(special)/.codeowner +0 -0
  197. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/(special)/pay.ts +0 -0
  198. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/.codeowner +0 -0
  199. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/item.ts +0 -0
  200. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/list/page-admin.tsx +0 -0
  201. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/models/bank_account.rb +0 -0
  202. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/models/payroll.rb +0 -0
  203. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payments/foo/.codeowner +0 -0
  204. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payments/foo/ownedby_payroll.rb +0 -0
  205. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payments/nacha.rb +0 -0
  206. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payroll/.codeowner +0 -0
  207. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payroll/payroll.rb +0 -0
  208. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/views/foos/edit.erb +0 -0
  209. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/views/foos/index.html.erb +0 -0
  210. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/views/foos/new.html.erb +0 -0
  211. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/ignored_files/git_ignored.rb +0 -0
  212. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/packages/payroll_flow/package.yml +0 -0
  213. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/should_be_ignored/an_ignored_file.rb +0 -0
  214. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/.github/CODEOWNERS +0 -0
  215. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/code_ownership.yml +0 -0
  216. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/brewers.yml +0 -0
  217. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/cubs.yml +0 -0
  218. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/giants.yml +0 -0
  219. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/rockies.yml +0 -0
  220. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/datepicker/package.json +0 -0
  221. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/datepicker/src/picks/dp.tsx +0 -0
  222. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/list/package.json +0 -0
  223. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/list/src/item.tsx +0 -0
  224. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/textfield/package.json +0 -0
  225. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/textfield/src/field.tsx +0 -0
  226. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/textfield/src/fields/small.tsx +0 -0
  227. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/apollo/lib/apollo.rb +0 -0
  228. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/ivy/lib/ivy.rb +0 -0
  229. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/lager/lib/lager.rb +0 -0
  230. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/summit/lib/summit.rb +0 -0
  231. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/games/app/services/stats.rb +0 -0
  232. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/games/package.yml +0 -0
  233. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/locations/app/services/capacity.rb +0 -0
  234. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/locations/package.yml +0 -0
  235. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/schedule/app/services/date.rb +0 -0
  236. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/schedule/package.yml +0 -0
  237. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/brewers/lib/util.rb +0 -0
  238. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/brewers/services/play.rb +0 -0
  239. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/.codeowner +0 -0
  240. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/models/.codeowner +0 -0
  241. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/models/db/price.rb +0 -0
  242. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/models/entertainment.rb +0 -0
  243. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/play.rb +0 -0
  244. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/giants/services/play.rb +0 -0
  245. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/rockies/services/play.rb +0 -0
  246. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/git_stage_test.rs +0 -0
  247. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/invalid_project_structure_test.rs +0 -0
  248. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/missing_github_team_test.rs +0 -0
  249. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/multiple_directory_owners_test.rs +0 -0
  250. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/run_config_executable_override_test.rs +0 -0
  251. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/runner_api.rs +0 -0
  252. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/untracked_files_test.rs +0 -0
  253. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/valid_project_test.rs +0 -0
  254. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/valid_project_with_overrides_test.rs +0 -0
  255. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/validate_files_test.rs +0 -0
  256. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tmp/.gitkeep +0 -0
@@ -0,0 +1,442 @@
1
+ //! Myers' diff algorithm.
2
+ //!
3
+ //! * time: `O((N+M)D)`
4
+ //! * space `O(N+M)`
5
+ //!
6
+ //! See [the original article by Eugene W. Myers](http://www.xmailserver.org/diff2.pdf)
7
+ //! describing it.
8
+ //!
9
+ //! The implementation of this algorithm is based on the implementation by
10
+ //! Brandon Williams.
11
+ //!
12
+ //! # Heuristics
13
+ //!
14
+ //! At present this implementation of Myers' does not implement any more advanced
15
+ //! heuristics that would solve some pathological cases. For instance passing two
16
+ //! large and completely distinct sequences to the algorithm will make it spin
17
+ //! without making reasonable progress. Currently the only protection in the
18
+ //! library against this is to pass a deadline to the diffing algorithm.
19
+ //!
20
+ //! For potential improvements here see [similar#15](https://github.com/mitsuhiko/similar/issues/15).
21
+
22
+ use std::ops::{Index, IndexMut, Range};
23
+
24
+ use crate::algorithms::utils::{common_prefix_len, common_suffix_len, is_empty_range};
25
+ use crate::algorithms::DiffHook;
26
+ use crate::deadline_support::{deadline_exceeded, Instant};
27
+
28
+ /// Myers' diff algorithm.
29
+ ///
30
+ /// Diff `old`, between indices `old_range` and `new` between indices `new_range`.
31
+ pub fn diff<Old, New, D>(
32
+ d: &mut D,
33
+ old: &Old,
34
+ old_range: Range<usize>,
35
+ new: &New,
36
+ new_range: Range<usize>,
37
+ ) -> Result<(), D::Error>
38
+ where
39
+ Old: Index<usize> + ?Sized,
40
+ New: Index<usize> + ?Sized,
41
+ D: DiffHook,
42
+ New::Output: PartialEq<Old::Output>,
43
+ {
44
+ diff_deadline(d, old, old_range, new, new_range, None)
45
+ }
46
+
47
+ /// Myers' diff algorithm with deadline.
48
+ ///
49
+ /// Diff `old`, between indices `old_range` and `new` between indices `new_range`.
50
+ ///
51
+ /// This diff is done with an optional deadline that defines the maximal
52
+ /// execution time permitted before it bails and falls back to an approximation.
53
+ pub fn diff_deadline<Old, New, D>(
54
+ d: &mut D,
55
+ old: &Old,
56
+ old_range: Range<usize>,
57
+ new: &New,
58
+ new_range: Range<usize>,
59
+ deadline: Option<Instant>,
60
+ ) -> Result<(), D::Error>
61
+ where
62
+ Old: Index<usize> + ?Sized,
63
+ New: Index<usize> + ?Sized,
64
+ D: DiffHook,
65
+ New::Output: PartialEq<Old::Output>,
66
+ {
67
+ let max_d = max_d(old_range.len(), new_range.len());
68
+ let mut vb = V::new(max_d);
69
+ let mut vf = V::new(max_d);
70
+ conquer(
71
+ d, old, old_range, new, new_range, &mut vf, &mut vb, deadline,
72
+ )?;
73
+ d.finish()
74
+ }
75
+
76
+ // A D-path is a path which starts at (0,0) that has exactly D non-diagonal
77
+ // edges. All D-paths consist of a (D - 1)-path followed by a non-diagonal edge
78
+ // and then a possibly empty sequence of diagonal edges called a snake.
79
+
80
+ /// `V` contains the endpoints of the furthest reaching `D-paths`. For each
81
+ /// recorded endpoint `(x,y)` in diagonal `k`, we only need to retain `x` because
82
+ /// `y` can be computed from `x - k`. In other words, `V` is an array of integers
83
+ /// where `V[k]` contains the row index of the endpoint of the furthest reaching
84
+ /// path in diagonal `k`.
85
+ ///
86
+ /// We can't use a traditional Vec to represent `V` since we use `k` as an index
87
+ /// and it can take on negative values. So instead `V` is represented as a
88
+ /// light-weight wrapper around a Vec plus an `offset` which is the maximum value
89
+ /// `k` can take on in order to map negative `k`'s back to a value >= 0.
90
+ #[derive(Debug)]
91
+ struct V {
92
+ offset: isize,
93
+ v: Vec<usize>, // Look into initializing this to -1 and storing isize
94
+ }
95
+
96
+ impl V {
97
+ fn new(max_d: usize) -> Self {
98
+ Self {
99
+ offset: max_d as isize,
100
+ v: vec![0; 2 * max_d],
101
+ }
102
+ }
103
+
104
+ fn len(&self) -> usize {
105
+ self.v.len()
106
+ }
107
+ }
108
+
109
+ impl Index<isize> for V {
110
+ type Output = usize;
111
+
112
+ fn index(&self, index: isize) -> &Self::Output {
113
+ &self.v[(index + self.offset) as usize]
114
+ }
115
+ }
116
+
117
+ impl IndexMut<isize> for V {
118
+ fn index_mut(&mut self, index: isize) -> &mut Self::Output {
119
+ &mut self.v[(index + self.offset) as usize]
120
+ }
121
+ }
122
+
123
+ fn max_d(len1: usize, len2: usize) -> usize {
124
+ // XXX look into reducing the need to have the additional '+ 1'
125
+ (len1 + len2 + 1) / 2 + 1
126
+ }
127
+
128
+ #[inline(always)]
129
+ fn split_at(range: Range<usize>, at: usize) -> (Range<usize>, Range<usize>) {
130
+ (range.start..at, at..range.end)
131
+ }
132
+
133
+ /// A `Snake` is a sequence of diagonal edges in the edit graph. Normally
134
+ /// a snake has a start end end point (and it is possible for a snake to have
135
+ /// a length of zero, meaning the start and end points are the same) however
136
+ /// we do not need the end point which is why it's not implemented here.
137
+ ///
138
+ /// The divide part of a divide-and-conquer strategy. A D-path has D+1 snakes
139
+ /// some of which may be empty. The divide step requires finding the ceil(D/2) +
140
+ /// 1 or middle snake of an optimal D-path. The idea for doing so is to
141
+ /// simultaneously run the basic algorithm in both the forward and reverse
142
+ /// directions until furthest reaching forward and reverse paths starting at
143
+ /// opposing corners 'overlap'.
144
+ fn find_middle_snake<Old, New>(
145
+ old: &Old,
146
+ old_range: Range<usize>,
147
+ new: &New,
148
+ new_range: Range<usize>,
149
+ vf: &mut V,
150
+ vb: &mut V,
151
+ deadline: Option<Instant>,
152
+ ) -> Option<(usize, usize)>
153
+ where
154
+ Old: Index<usize> + ?Sized,
155
+ New: Index<usize> + ?Sized,
156
+ New::Output: PartialEq<Old::Output>,
157
+ {
158
+ let n = old_range.len();
159
+ let m = new_range.len();
160
+
161
+ // By Lemma 1 in the paper, the optimal edit script length is odd or even as
162
+ // `delta` is odd or even.
163
+ let delta = n as isize - m as isize;
164
+ let odd = delta & 1 == 1;
165
+
166
+ // The initial point at (0, -1)
167
+ vf[1] = 0;
168
+ // The initial point at (N, M+1)
169
+ vb[1] = 0;
170
+
171
+ // We only need to explore ceil(D/2) + 1
172
+ let d_max = max_d(n, m);
173
+ assert!(vf.len() >= d_max);
174
+ assert!(vb.len() >= d_max);
175
+
176
+ for d in 0..d_max as isize {
177
+ // are we running for too long?
178
+ if deadline_exceeded(deadline) {
179
+ break;
180
+ }
181
+
182
+ // Forward path
183
+ for k in (-d..=d).rev().step_by(2) {
184
+ let mut x = if k == -d || (k != d && vf[k - 1] < vf[k + 1]) {
185
+ vf[k + 1]
186
+ } else {
187
+ vf[k - 1] + 1
188
+ };
189
+ let y = (x as isize - k) as usize;
190
+
191
+ // The coordinate of the start of a snake
192
+ let (x0, y0) = (x, y);
193
+ // While these sequences are identical, keep moving through the
194
+ // graph with no cost
195
+ if x < old_range.len() && y < new_range.len() {
196
+ let advance = common_prefix_len(
197
+ old,
198
+ old_range.start + x..old_range.end,
199
+ new,
200
+ new_range.start + y..new_range.end,
201
+ );
202
+ x += advance;
203
+ }
204
+
205
+ // This is the new best x value
206
+ vf[k] = x;
207
+
208
+ // Only check for connections from the forward search when N - M is
209
+ // odd and when there is a reciprocal k line coming from the other
210
+ // direction.
211
+ if odd && (k - delta).abs() <= (d - 1) {
212
+ // TODO optimize this so we don't have to compare against n
213
+ if vf[k] + vb[-(k - delta)] >= n {
214
+ // Return the snake
215
+ return Some((x0 + old_range.start, y0 + new_range.start));
216
+ }
217
+ }
218
+ }
219
+
220
+ // Backward path
221
+ for k in (-d..=d).rev().step_by(2) {
222
+ let mut x = if k == -d || (k != d && vb[k - 1] < vb[k + 1]) {
223
+ vb[k + 1]
224
+ } else {
225
+ vb[k - 1] + 1
226
+ };
227
+ let mut y = (x as isize - k) as usize;
228
+
229
+ // The coordinate of the start of a snake
230
+ if x < n && y < m {
231
+ let advance = common_suffix_len(
232
+ old,
233
+ old_range.start..old_range.start + n - x,
234
+ new,
235
+ new_range.start..new_range.start + m - y,
236
+ );
237
+ x += advance;
238
+ y += advance;
239
+ }
240
+
241
+ // This is the new best x value
242
+ vb[k] = x;
243
+
244
+ if !odd && (k - delta).abs() <= d {
245
+ // TODO optimize this so we don't have to compare against n
246
+ if vb[k] + vf[-(k - delta)] >= n {
247
+ // Return the snake
248
+ return Some((n - x + old_range.start, m - y + new_range.start));
249
+ }
250
+ }
251
+ }
252
+
253
+ // TODO: Maybe there's an opportunity to optimize and bail early?
254
+ }
255
+
256
+ // deadline reached
257
+ None
258
+ }
259
+
260
+ #[allow(clippy::too_many_arguments)]
261
+ fn conquer<Old, New, D>(
262
+ d: &mut D,
263
+ old: &Old,
264
+ mut old_range: Range<usize>,
265
+ new: &New,
266
+ mut new_range: Range<usize>,
267
+ vf: &mut V,
268
+ vb: &mut V,
269
+ deadline: Option<Instant>,
270
+ ) -> Result<(), D::Error>
271
+ where
272
+ Old: Index<usize> + ?Sized,
273
+ New: Index<usize> + ?Sized,
274
+ D: DiffHook,
275
+ New::Output: PartialEq<Old::Output>,
276
+ {
277
+ // Check for common prefix
278
+ let common_prefix_len = common_prefix_len(old, old_range.clone(), new, new_range.clone());
279
+ if common_prefix_len > 0 {
280
+ d.equal(old_range.start, new_range.start, common_prefix_len)?;
281
+ }
282
+ old_range.start += common_prefix_len;
283
+ new_range.start += common_prefix_len;
284
+
285
+ // Check for common suffix
286
+ let common_suffix_len = common_suffix_len(old, old_range.clone(), new, new_range.clone());
287
+ let common_suffix = (
288
+ old_range.end - common_suffix_len,
289
+ new_range.end - common_suffix_len,
290
+ );
291
+ old_range.end -= common_suffix_len;
292
+ new_range.end -= common_suffix_len;
293
+
294
+ if is_empty_range(&old_range) && is_empty_range(&new_range) {
295
+ // Do nothing
296
+ } else if is_empty_range(&new_range) {
297
+ d.delete(old_range.start, old_range.len(), new_range.start)?;
298
+ } else if is_empty_range(&old_range) {
299
+ d.insert(old_range.start, new_range.start, new_range.len())?;
300
+ } else if let Some((x_start, y_start)) = find_middle_snake(
301
+ old,
302
+ old_range.clone(),
303
+ new,
304
+ new_range.clone(),
305
+ vf,
306
+ vb,
307
+ deadline,
308
+ ) {
309
+ let (old_a, old_b) = split_at(old_range, x_start);
310
+ let (new_a, new_b) = split_at(new_range, y_start);
311
+ conquer(d, old, old_a, new, new_a, vf, vb, deadline)?;
312
+ conquer(d, old, old_b, new, new_b, vf, vb, deadline)?;
313
+ } else {
314
+ d.delete(
315
+ old_range.start,
316
+ old_range.end - old_range.start,
317
+ new_range.start,
318
+ )?;
319
+ d.insert(
320
+ old_range.start,
321
+ new_range.start,
322
+ new_range.end - new_range.start,
323
+ )?;
324
+ }
325
+
326
+ if common_suffix_len > 0 {
327
+ d.equal(common_suffix.0, common_suffix.1, common_suffix_len)?;
328
+ }
329
+
330
+ Ok(())
331
+ }
332
+
333
+ #[test]
334
+ fn test_find_middle_snake() {
335
+ let a = &b"ABCABBA"[..];
336
+ let b = &b"CBABAC"[..];
337
+ let max_d = max_d(a.len(), b.len());
338
+ let mut vf = V::new(max_d);
339
+ let mut vb = V::new(max_d);
340
+ let (x_start, y_start) =
341
+ find_middle_snake(a, 0..a.len(), b, 0..b.len(), &mut vf, &mut vb, None).unwrap();
342
+ assert_eq!(x_start, 4);
343
+ assert_eq!(y_start, 1);
344
+ }
345
+
346
+ #[test]
347
+ fn test_diff() {
348
+ let a: &[usize] = &[0, 1, 2, 3, 4];
349
+ let b: &[usize] = &[0, 1, 2, 9, 4];
350
+
351
+ let mut d = crate::algorithms::Replace::new(crate::algorithms::Capture::new());
352
+ diff(&mut d, a, 0..a.len(), b, 0..b.len()).unwrap();
353
+ insta::assert_debug_snapshot!(d.into_inner().ops());
354
+ }
355
+
356
+ #[test]
357
+ fn test_contiguous() {
358
+ let a: &[usize] = &[0, 1, 2, 3, 4, 4, 4, 5];
359
+ let b: &[usize] = &[0, 1, 2, 8, 9, 4, 4, 7];
360
+
361
+ let mut d = crate::algorithms::Replace::new(crate::algorithms::Capture::new());
362
+ diff(&mut d, a, 0..a.len(), b, 0..b.len()).unwrap();
363
+ insta::assert_debug_snapshot!(d.into_inner().ops());
364
+ }
365
+
366
+ #[test]
367
+ fn test_pat() {
368
+ let a: &[usize] = &[0, 1, 3, 4, 5];
369
+ let b: &[usize] = &[0, 1, 4, 5, 8, 9];
370
+
371
+ let mut d = crate::algorithms::Capture::new();
372
+ diff(&mut d, a, 0..a.len(), b, 0..b.len()).unwrap();
373
+ insta::assert_debug_snapshot!(d.ops());
374
+ }
375
+
376
+ #[test]
377
+ fn test_deadline_reached() {
378
+ use std::ops::Index;
379
+ use std::time::Duration;
380
+
381
+ let a = (0..100).collect::<Vec<_>>();
382
+ let mut b = (0..100).collect::<Vec<_>>();
383
+ b[10] = 99;
384
+ b[50] = 99;
385
+ b[25] = 99;
386
+
387
+ struct SlowIndex<'a>(&'a [usize]);
388
+
389
+ impl Index<usize> for SlowIndex<'_> {
390
+ type Output = usize;
391
+
392
+ fn index(&self, index: usize) -> &Self::Output {
393
+ std::thread::sleep(Duration::from_millis(1));
394
+ &self.0[index]
395
+ }
396
+ }
397
+
398
+ let slow_a = SlowIndex(&a);
399
+ let slow_b = SlowIndex(&b);
400
+
401
+ // don't give it enough time to do anything interesting
402
+ let mut d = crate::algorithms::Replace::new(crate::algorithms::Capture::new());
403
+ diff_deadline(
404
+ &mut d,
405
+ &slow_a,
406
+ 0..a.len(),
407
+ &slow_b,
408
+ 0..b.len(),
409
+ Some(Instant::now() + Duration::from_millis(50)),
410
+ )
411
+ .unwrap();
412
+ insta::assert_debug_snapshot!(d.into_inner().ops());
413
+ }
414
+
415
+ #[test]
416
+ fn test_finish_called() {
417
+ struct HasRunFinish(bool);
418
+
419
+ impl DiffHook for HasRunFinish {
420
+ type Error = ();
421
+ fn finish(&mut self) -> Result<(), Self::Error> {
422
+ self.0 = true;
423
+ Ok(())
424
+ }
425
+ }
426
+
427
+ let mut d = HasRunFinish(false);
428
+ let slice = &[1, 2];
429
+ let slice2 = &[1, 2, 3];
430
+ diff(&mut d, slice, 0..slice.len(), slice2, 0..slice2.len()).unwrap();
431
+ assert!(d.0);
432
+
433
+ let mut d = HasRunFinish(false);
434
+ let slice = &[1, 2];
435
+ diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap();
436
+ assert!(d.0);
437
+
438
+ let mut d = HasRunFinish(false);
439
+ let slice: &[u8] = &[];
440
+ diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap();
441
+ assert!(d.0);
442
+ }
@@ -0,0 +1,198 @@
1
+ //! Patience diff algorithm.
2
+ //!
3
+ //! * time: `O(N log N + M log M + (N+M)D)`
4
+ //! * space: `O(N+M)`
5
+ //!
6
+ //! Tends to give more human-readable outputs. See [Bram Cohen's blog
7
+ //! post](https://bramcohen.livejournal.com/73318.html) describing it.
8
+ //!
9
+ //! This is based on the patience implementation of [pijul](https://pijul.org/)
10
+ //! by Pierre-Étienne Meunier.
11
+ use std::hash::Hash;
12
+ use std::ops::{Index, Range};
13
+
14
+ use crate::algorithms::{myers, DiffHook, NoFinishHook, Replace};
15
+ use crate::deadline_support::Instant;
16
+
17
+ use super::utils::{unique, UniqueItem};
18
+
19
+ /// Patience diff algorithm.
20
+ ///
21
+ /// Diff `old`, between indices `old_range` and `new` between indices `new_range`.
22
+ pub fn diff<Old, New, D>(
23
+ d: &mut D,
24
+ old: &Old,
25
+ old_range: Range<usize>,
26
+ new: &New,
27
+ new_range: Range<usize>,
28
+ ) -> Result<(), D::Error>
29
+ where
30
+ Old: Index<usize> + ?Sized,
31
+ New: Index<usize> + ?Sized,
32
+ Old::Output: Hash + Eq,
33
+ New::Output: PartialEq<Old::Output> + Hash + Eq,
34
+ D: DiffHook,
35
+ {
36
+ diff_deadline(d, old, old_range, new, new_range, None)
37
+ }
38
+
39
+ /// Patience diff algorithm with deadline.
40
+ ///
41
+ /// Diff `old`, between indices `old_range` and `new` between indices `new_range`.
42
+ ///
43
+ /// This diff is done with an optional deadline that defines the maximal
44
+ /// execution time permitted before it bails and falls back to an approximation.
45
+ pub fn diff_deadline<Old, New, D>(
46
+ d: &mut D,
47
+ old: &Old,
48
+ old_range: Range<usize>,
49
+ new: &New,
50
+ new_range: Range<usize>,
51
+ deadline: Option<Instant>,
52
+ ) -> Result<(), D::Error>
53
+ where
54
+ Old: Index<usize> + ?Sized,
55
+ New: Index<usize> + ?Sized,
56
+ Old::Output: Hash + Eq,
57
+ New::Output: PartialEq<Old::Output> + Hash + Eq,
58
+ D: DiffHook,
59
+ {
60
+ let old_indexes = unique(old, old_range.clone());
61
+ let new_indexes = unique(new, new_range.clone());
62
+
63
+ let mut d = Replace::new(Patience {
64
+ d,
65
+ old,
66
+ old_current: old_range.start,
67
+ old_end: old_range.end,
68
+ old_indexes: &old_indexes,
69
+ new,
70
+ new_current: new_range.start,
71
+ new_end: new_range.end,
72
+ new_indexes: &new_indexes,
73
+ deadline,
74
+ });
75
+ myers::diff_deadline(
76
+ &mut d,
77
+ &old_indexes,
78
+ 0..old_indexes.len(),
79
+ &new_indexes,
80
+ 0..new_indexes.len(),
81
+ deadline,
82
+ )?;
83
+ Ok(())
84
+ }
85
+
86
+ struct Patience<'old, 'new, 'd, Old: ?Sized, New: ?Sized, D> {
87
+ d: &'d mut D,
88
+ old: &'old Old,
89
+ old_current: usize,
90
+ old_end: usize,
91
+ old_indexes: &'old [UniqueItem<'old, Old>],
92
+ new: &'new New,
93
+ new_current: usize,
94
+ new_end: usize,
95
+ new_indexes: &'new [UniqueItem<'new, New>],
96
+ deadline: Option<Instant>,
97
+ }
98
+
99
+ impl<'old, 'new, 'd, Old, New, D> DiffHook for Patience<'old, 'new, 'd, Old, New, D>
100
+ where
101
+ D: DiffHook + 'd,
102
+ Old: Index<usize> + ?Sized + 'old,
103
+ New: Index<usize> + ?Sized + 'new,
104
+ New::Output: PartialEq<Old::Output>,
105
+ {
106
+ type Error = D::Error;
107
+ fn equal(&mut self, old: usize, new: usize, len: usize) -> Result<(), D::Error> {
108
+ for (old, new) in (old..old + len).zip(new..new + len) {
109
+ let a0 = self.old_current;
110
+ let b0 = self.new_current;
111
+ while self.old_current < self.old_indexes[old].original_index()
112
+ && self.new_current < self.new_indexes[new].original_index()
113
+ && self.new[self.new_current] == self.old[self.old_current]
114
+ {
115
+ self.old_current += 1;
116
+ self.new_current += 1;
117
+ }
118
+ if self.old_current > a0 {
119
+ self.d.equal(a0, b0, self.old_current - a0)?;
120
+ }
121
+ let mut no_finish_d = NoFinishHook::new(&mut self.d);
122
+ myers::diff_deadline(
123
+ &mut no_finish_d,
124
+ self.old,
125
+ self.old_current..self.old_indexes[old].original_index(),
126
+ self.new,
127
+ self.new_current..self.new_indexes[new].original_index(),
128
+ self.deadline,
129
+ )?;
130
+ self.old_current = self.old_indexes[old].original_index();
131
+ self.new_current = self.new_indexes[new].original_index();
132
+ }
133
+ Ok(())
134
+ }
135
+
136
+ fn finish(&mut self) -> Result<(), D::Error> {
137
+ myers::diff_deadline(
138
+ self.d,
139
+ self.old,
140
+ self.old_current..self.old_end,
141
+ self.new,
142
+ self.new_current..self.new_end,
143
+ self.deadline,
144
+ )
145
+ }
146
+ }
147
+
148
+ #[test]
149
+ fn test_patience() {
150
+ let a: &[usize] = &[11, 1, 2, 2, 3, 4, 4, 4, 5, 47, 19];
151
+ let b: &[usize] = &[10, 1, 2, 2, 8, 9, 4, 4, 7, 47, 18];
152
+
153
+ let mut d = Replace::new(crate::algorithms::Capture::new());
154
+ diff(&mut d, a, 0..a.len(), b, 0..b.len()).unwrap();
155
+
156
+ insta::assert_debug_snapshot!(d.into_inner().ops());
157
+ }
158
+
159
+ #[test]
160
+ fn test_patience_out_of_bounds_bug() {
161
+ // this used to be a bug
162
+ let a: &[usize] = &[1, 2, 3, 4];
163
+ let b: &[usize] = &[1, 2, 3];
164
+
165
+ let mut d = Replace::new(crate::algorithms::Capture::new());
166
+ diff(&mut d, a, 0..a.len(), b, 0..b.len()).unwrap();
167
+
168
+ insta::assert_debug_snapshot!(d.into_inner().ops());
169
+ }
170
+
171
+ #[test]
172
+ fn test_finish_called() {
173
+ struct HasRunFinish(bool);
174
+
175
+ impl DiffHook for HasRunFinish {
176
+ type Error = ();
177
+ fn finish(&mut self) -> Result<(), Self::Error> {
178
+ self.0 = true;
179
+ Ok(())
180
+ }
181
+ }
182
+
183
+ let mut d = HasRunFinish(false);
184
+ let slice = &[1, 2];
185
+ let slice2 = &[1, 2, 3];
186
+ diff(&mut d, slice, 0..slice.len(), slice2, 0..slice2.len()).unwrap();
187
+ assert!(d.0);
188
+
189
+ let mut d = HasRunFinish(false);
190
+ let slice = &[1, 2];
191
+ diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap();
192
+ assert!(d.0);
193
+
194
+ let mut d = HasRunFinish(false);
195
+ let slice: &[u8] = &[];
196
+ diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap();
197
+ assert!(d.0);
198
+ }