dependabot-core 0.76.1

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 (321) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +6408 -0
  3. data/LICENSE +37 -0
  4. data/README.md +115 -0
  5. data/helpers/elixir/bin/check_update.exs +92 -0
  6. data/helpers/elixir/bin/do_update.exs +39 -0
  7. data/helpers/elixir/bin/parse_deps.exs +103 -0
  8. data/helpers/elixir/bin/run.exs +76 -0
  9. data/helpers/elixir/mix.exs +21 -0
  10. data/helpers/elixir/mix.lock +3 -0
  11. data/helpers/go/Makefile +9 -0
  12. data/helpers/go/go.mod +9 -0
  13. data/helpers/go/go.sum +5 -0
  14. data/helpers/go/importresolver/main.go +34 -0
  15. data/helpers/go/main.go +77 -0
  16. data/helpers/go/updatechecker/main.go +107 -0
  17. data/helpers/go/updater/go.mod +3 -0
  18. data/helpers/go/updater/go.sum +2 -0
  19. data/helpers/go/updater/helpers.go +57 -0
  20. data/helpers/go/updater/main.go +48 -0
  21. data/helpers/npm/.agignore +1 -0
  22. data/helpers/npm/.envrc +2 -0
  23. data/helpers/npm/.eslintrc +14 -0
  24. data/helpers/npm/.nvimrc +7 -0
  25. data/helpers/npm/bin/run.js +34 -0
  26. data/helpers/npm/lib/helpers.js +25 -0
  27. data/helpers/npm/lib/peer-dependency-checker.js +102 -0
  28. data/helpers/npm/lib/subdependency-updater.js +48 -0
  29. data/helpers/npm/lib/updater.js +95 -0
  30. data/helpers/npm/package.json +17 -0
  31. data/helpers/npm/test/fixtures/npm-left-pad.json +1 -0
  32. data/helpers/npm/test/fixtures/updater/original/package-lock.json +16 -0
  33. data/helpers/npm/test/fixtures/updater/original/package.json +9 -0
  34. data/helpers/npm/test/fixtures/updater/updated/package-lock.json +16 -0
  35. data/helpers/npm/test/helpers.js +7 -0
  36. data/helpers/npm/test/updater.test.js +50 -0
  37. data/helpers/npm/yarn.lock +6120 -0
  38. data/helpers/php/.php_cs +34 -0
  39. data/helpers/php/bin/run.php +57 -0
  40. data/helpers/php/composer.json +14 -0
  41. data/helpers/php/composer.lock +1521 -0
  42. data/helpers/php/composer.phar +0 -0
  43. data/helpers/php/setup.sh +4 -0
  44. data/helpers/php/src/DependabotInstallationManager.php +61 -0
  45. data/helpers/php/src/DependabotPluginManager.php +23 -0
  46. data/helpers/php/src/ExceptionIO.php +25 -0
  47. data/helpers/php/src/Hasher.php +21 -0
  48. data/helpers/php/src/UpdateChecker.php +123 -0
  49. data/helpers/php/src/Updater.php +97 -0
  50. data/helpers/python/lib/__init__.py +0 -0
  51. data/helpers/python/lib/hasher.py +23 -0
  52. data/helpers/python/lib/parser.py +130 -0
  53. data/helpers/python/requirements.txt +9 -0
  54. data/helpers/python/run.py +18 -0
  55. data/helpers/test/run.rb +15 -0
  56. data/helpers/utils/git-credential-store-immutable +10 -0
  57. data/helpers/yarn/.agignore +1 -0
  58. data/helpers/yarn/.envrc +2 -0
  59. data/helpers/yarn/.eslintrc +14 -0
  60. data/helpers/yarn/.nvimrc +7 -0
  61. data/helpers/yarn/bin/run.js +36 -0
  62. data/helpers/yarn/lib/fix-duplicates.js +53 -0
  63. data/helpers/yarn/lib/helpers.js +5 -0
  64. data/helpers/yarn/lib/lockfile-parser.js +21 -0
  65. data/helpers/yarn/lib/peer-dependency-checker.js +130 -0
  66. data/helpers/yarn/lib/replace-lockfile-declaration.js +45 -0
  67. data/helpers/yarn/lib/subdependency-updater.js +69 -0
  68. data/helpers/yarn/lib/updater.js +254 -0
  69. data/helpers/yarn/package.json +17 -0
  70. data/helpers/yarn/test/fixtures/updater/original/package.json +6 -0
  71. data/helpers/yarn/test/fixtures/updater/original/yarn.lock +11 -0
  72. data/helpers/yarn/test/fixtures/updater/updated/yarn.lock +12 -0
  73. data/helpers/yarn/test/fixtures/updater/with-version-comments/package.json +5 -0
  74. data/helpers/yarn/test/fixtures/updater/with-version-comments/yarn.lock +13 -0
  75. data/helpers/yarn/test/fixtures/yarnpkg-is-positive.json +1 -0
  76. data/helpers/yarn/test/fixtures/yarnpkg-left-pad.json +1 -0
  77. data/helpers/yarn/test/helpers.js +7 -0
  78. data/helpers/yarn/test/updater.test.js +93 -0
  79. data/helpers/yarn/yarn.lock +4912 -0
  80. data/lib/bundler_definition_bundler_version_patch.rb +15 -0
  81. data/lib/bundler_definition_ruby_version_patch.rb +14 -0
  82. data/lib/bundler_git_source_patch.rb +27 -0
  83. data/lib/dependabot.rb +4 -0
  84. data/lib/dependabot/clients/bitbucket.rb +101 -0
  85. data/lib/dependabot/clients/github_with_retries.rb +117 -0
  86. data/lib/dependabot/clients/gitlab.rb +72 -0
  87. data/lib/dependabot/dependency.rb +118 -0
  88. data/lib/dependabot/dependency_file.rb +54 -0
  89. data/lib/dependabot/errors.rb +179 -0
  90. data/lib/dependabot/file_fetchers.rb +48 -0
  91. data/lib/dependabot/file_fetchers/README.md +65 -0
  92. data/lib/dependabot/file_fetchers/base.rb +302 -0
  93. data/lib/dependabot/file_fetchers/docker/docker.rb +40 -0
  94. data/lib/dependabot/file_fetchers/dotnet/nuget.rb +215 -0
  95. data/lib/dependabot/file_fetchers/dotnet/nuget/import_paths_finder.rb +51 -0
  96. data/lib/dependabot/file_fetchers/dotnet/nuget/sln_project_paths_finder.rb +55 -0
  97. data/lib/dependabot/file_fetchers/elixir/hex.rb +78 -0
  98. data/lib/dependabot/file_fetchers/elm/elm_package.rb +52 -0
  99. data/lib/dependabot/file_fetchers/git/submodules.rb +73 -0
  100. data/lib/dependabot/file_fetchers/go/dep.rb +69 -0
  101. data/lib/dependabot/file_fetchers/go/modules.rb +64 -0
  102. data/lib/dependabot/file_fetchers/java/gradle.rb +56 -0
  103. data/lib/dependabot/file_fetchers/java/gradle/settings_file_parser.rb +66 -0
  104. data/lib/dependabot/file_fetchers/java/maven.rb +127 -0
  105. data/lib/dependabot/file_fetchers/java_script/npm_and_yarn.rb +330 -0
  106. data/lib/dependabot/file_fetchers/java_script/npm_and_yarn/path_dependency_builder.rb +107 -0
  107. data/lib/dependabot/file_fetchers/php/composer.rb +131 -0
  108. data/lib/dependabot/file_fetchers/python/pip.rb +305 -0
  109. data/lib/dependabot/file_fetchers/ruby/bundler.rb +185 -0
  110. data/lib/dependabot/file_fetchers/ruby/bundler/child_gemfile_finder.rb +70 -0
  111. data/lib/dependabot/file_fetchers/ruby/bundler/path_gemspec_finder.rb +114 -0
  112. data/lib/dependabot/file_fetchers/ruby/bundler/require_relative_finder.rb +67 -0
  113. data/lib/dependabot/file_fetchers/rust/cargo.rb +240 -0
  114. data/lib/dependabot/file_parsers.rb +48 -0
  115. data/lib/dependabot/file_parsers/README.md +45 -0
  116. data/lib/dependabot/file_parsers/base.rb +31 -0
  117. data/lib/dependabot/file_parsers/base/dependency_set.rb +77 -0
  118. data/lib/dependabot/file_parsers/docker/docker.rb +164 -0
  119. data/lib/dependabot/file_parsers/dotnet/nuget.rb +85 -0
  120. data/lib/dependabot/file_parsers/dotnet/nuget/packages_config_parser.rb +65 -0
  121. data/lib/dependabot/file_parsers/dotnet/nuget/project_file_parser.rb +156 -0
  122. data/lib/dependabot/file_parsers/dotnet/nuget/property_value_finder.rb +131 -0
  123. data/lib/dependabot/file_parsers/elixir/hex.rb +134 -0
  124. data/lib/dependabot/file_parsers/elm/elm_package.rb +136 -0
  125. data/lib/dependabot/file_parsers/git/submodules.rb +69 -0
  126. data/lib/dependabot/file_parsers/go/dep.rb +163 -0
  127. data/lib/dependabot/file_parsers/go/modules.rb +34 -0
  128. data/lib/dependabot/file_parsers/go/modules/go_mod_parser.rb +134 -0
  129. data/lib/dependabot/file_parsers/java/gradle.rb +236 -0
  130. data/lib/dependabot/file_parsers/java/gradle/property_value_finder.rb +90 -0
  131. data/lib/dependabot/file_parsers/java/gradle/repositories_finder.rb +145 -0
  132. data/lib/dependabot/file_parsers/java/maven.rb +252 -0
  133. data/lib/dependabot/file_parsers/java/maven/property_value_finder.rb +166 -0
  134. data/lib/dependabot/file_parsers/java/maven/repositories_finder.rb +188 -0
  135. data/lib/dependabot/file_parsers/java_script/npm_and_yarn.rb +394 -0
  136. data/lib/dependabot/file_parsers/php/composer.rb +177 -0
  137. data/lib/dependabot/file_parsers/python/pip.rb +223 -0
  138. data/lib/dependabot/file_parsers/python/pip/pipfile_files_parser.rb +154 -0
  139. data/lib/dependabot/file_parsers/python/pip/poetry_files_parser.rb +141 -0
  140. data/lib/dependabot/file_parsers/python/pip/setup_file_parser.rb +160 -0
  141. data/lib/dependabot/file_parsers/ruby/bundler.rb +295 -0
  142. data/lib/dependabot/file_parsers/ruby/bundler/file_preparer.rb +85 -0
  143. data/lib/dependabot/file_parsers/ruby/bundler/gemfile_checker.rb +48 -0
  144. data/lib/dependabot/file_parsers/rust/cargo.rb +213 -0
  145. data/lib/dependabot/file_updaters.rb +48 -0
  146. data/lib/dependabot/file_updaters/README.md +58 -0
  147. data/lib/dependabot/file_updaters/base.rb +52 -0
  148. data/lib/dependabot/file_updaters/docker/docker.rb +133 -0
  149. data/lib/dependabot/file_updaters/dotnet/nuget.rb +151 -0
  150. data/lib/dependabot/file_updaters/dotnet/nuget/packages_config_declaration_finder.rb +69 -0
  151. data/lib/dependabot/file_updaters/dotnet/nuget/project_file_declaration_finder.rb +78 -0
  152. data/lib/dependabot/file_updaters/dotnet/nuget/property_value_updater.rb +64 -0
  153. data/lib/dependabot/file_updaters/elixir/hex.rb +71 -0
  154. data/lib/dependabot/file_updaters/elixir/hex/lockfile_updater.rb +147 -0
  155. data/lib/dependabot/file_updaters/elixir/hex/mixfile_git_pin_updater.rb +53 -0
  156. data/lib/dependabot/file_updaters/elixir/hex/mixfile_requirement_updater.rb +74 -0
  157. data/lib/dependabot/file_updaters/elixir/hex/mixfile_sanitizer.rb +28 -0
  158. data/lib/dependabot/file_updaters/elixir/hex/mixfile_updater.rb +98 -0
  159. data/lib/dependabot/file_updaters/elm/elm_package.rb +79 -0
  160. data/lib/dependabot/file_updaters/elm/elm_package/elm_json_updater.rb +69 -0
  161. data/lib/dependabot/file_updaters/elm/elm_package/elm_package_updater.rb +69 -0
  162. data/lib/dependabot/file_updaters/git/submodules.rb +38 -0
  163. data/lib/dependabot/file_updaters/go/dep.rb +77 -0
  164. data/lib/dependabot/file_updaters/go/dep/lockfile_updater.rb +219 -0
  165. data/lib/dependabot/file_updaters/go/dep/manifest_updater.rb +155 -0
  166. data/lib/dependabot/file_updaters/go/modules.rb +71 -0
  167. data/lib/dependabot/file_updaters/go/modules/go_mod_updater.rb +81 -0
  168. data/lib/dependabot/file_updaters/java/gradle.rb +176 -0
  169. data/lib/dependabot/file_updaters/java/gradle/dependency_set_updater.rb +66 -0
  170. data/lib/dependabot/file_updaters/java/gradle/property_value_updater.rb +58 -0
  171. data/lib/dependabot/file_updaters/java/maven.rb +155 -0
  172. data/lib/dependabot/file_updaters/java/maven/declaration_finder.rb +132 -0
  173. data/lib/dependabot/file_updaters/java/maven/property_value_updater.rb +61 -0
  174. data/lib/dependabot/file_updaters/java_script/npm_and_yarn.rb +159 -0
  175. data/lib/dependabot/file_updaters/java_script/npm_and_yarn/npm_lockfile_updater.rb +532 -0
  176. data/lib/dependabot/file_updaters/java_script/npm_and_yarn/npmrc_builder.rb +191 -0
  177. data/lib/dependabot/file_updaters/java_script/npm_and_yarn/package_json_preparer.rb +91 -0
  178. data/lib/dependabot/file_updaters/java_script/npm_and_yarn/package_json_updater.rb +220 -0
  179. data/lib/dependabot/file_updaters/java_script/npm_and_yarn/yarn_lockfile_updater.rb +475 -0
  180. data/lib/dependabot/file_updaters/php/composer.rb +78 -0
  181. data/lib/dependabot/file_updaters/php/composer/lockfile_updater.rb +264 -0
  182. data/lib/dependabot/file_updaters/php/composer/manifest_updater.rb +70 -0
  183. data/lib/dependabot/file_updaters/python/pip.rb +147 -0
  184. data/lib/dependabot/file_updaters/python/pip/pip_compile_file_updater.rb +363 -0
  185. data/lib/dependabot/file_updaters/python/pip/pipfile_file_updater.rb +397 -0
  186. data/lib/dependabot/file_updaters/python/pip/pipfile_preparer.rb +125 -0
  187. data/lib/dependabot/file_updaters/python/pip/poetry_file_updater.rb +289 -0
  188. data/lib/dependabot/file_updaters/python/pip/pyproject_preparer.rb +105 -0
  189. data/lib/dependabot/file_updaters/python/pip/requirement_file_updater.rb +166 -0
  190. data/lib/dependabot/file_updaters/python/pip/requirement_replacer.rb +95 -0
  191. data/lib/dependabot/file_updaters/python/pip/setup_file_sanitizer.rb +91 -0
  192. data/lib/dependabot/file_updaters/ruby/bundler.rb +121 -0
  193. data/lib/dependabot/file_updaters/ruby/bundler/gemfile_updater.rb +116 -0
  194. data/lib/dependabot/file_updaters/ruby/bundler/gemspec_dependency_name_finder.rb +52 -0
  195. data/lib/dependabot/file_updaters/ruby/bundler/gemspec_sanitizer.rb +298 -0
  196. data/lib/dependabot/file_updaters/ruby/bundler/gemspec_updater.rb +64 -0
  197. data/lib/dependabot/file_updaters/ruby/bundler/git_pin_replacer.rb +80 -0
  198. data/lib/dependabot/file_updaters/ruby/bundler/git_source_remover.rb +102 -0
  199. data/lib/dependabot/file_updaters/ruby/bundler/lockfile_updater.rb +384 -0
  200. data/lib/dependabot/file_updaters/ruby/bundler/requirement_replacer.rb +188 -0
  201. data/lib/dependabot/file_updaters/rust/cargo.rb +83 -0
  202. data/lib/dependabot/file_updaters/rust/cargo/lockfile_updater.rb +251 -0
  203. data/lib/dependabot/file_updaters/rust/cargo/manifest_updater.rb +162 -0
  204. data/lib/dependabot/git_commit_checker.rb +412 -0
  205. data/lib/dependabot/metadata_finders.rb +46 -0
  206. data/lib/dependabot/metadata_finders/README.md +53 -0
  207. data/lib/dependabot/metadata_finders/base.rb +117 -0
  208. data/lib/dependabot/metadata_finders/base/changelog_finder.rb +317 -0
  209. data/lib/dependabot/metadata_finders/base/changelog_pruner.rb +177 -0
  210. data/lib/dependabot/metadata_finders/base/commits_finder.rb +217 -0
  211. data/lib/dependabot/metadata_finders/base/release_finder.rb +251 -0
  212. data/lib/dependabot/metadata_finders/docker/docker.rb +18 -0
  213. data/lib/dependabot/metadata_finders/dotnet/nuget.rb +116 -0
  214. data/lib/dependabot/metadata_finders/elixir/hex.rb +69 -0
  215. data/lib/dependabot/metadata_finders/elm/elm_package.rb +22 -0
  216. data/lib/dependabot/metadata_finders/git/submodules.rb +20 -0
  217. data/lib/dependabot/metadata_finders/go/dep.rb +56 -0
  218. data/lib/dependabot/metadata_finders/java/maven.rb +173 -0
  219. data/lib/dependabot/metadata_finders/java_script/npm_and_yarn.rb +215 -0
  220. data/lib/dependabot/metadata_finders/php/composer.rb +66 -0
  221. data/lib/dependabot/metadata_finders/python/pip.rb +120 -0
  222. data/lib/dependabot/metadata_finders/ruby/bundler.rb +150 -0
  223. data/lib/dependabot/metadata_finders/rust/cargo.rb +64 -0
  224. data/lib/dependabot/pull_request_creator.rb +151 -0
  225. data/lib/dependabot/pull_request_creator/branch_namer.rb +170 -0
  226. data/lib/dependabot/pull_request_creator/commit_signer.rb +63 -0
  227. data/lib/dependabot/pull_request_creator/github.rb +233 -0
  228. data/lib/dependabot/pull_request_creator/gitlab.rb +122 -0
  229. data/lib/dependabot/pull_request_creator/labeler.rb +361 -0
  230. data/lib/dependabot/pull_request_creator/message_builder.rb +888 -0
  231. data/lib/dependabot/pull_request_updater.rb +43 -0
  232. data/lib/dependabot/pull_request_updater/github.rb +151 -0
  233. data/lib/dependabot/shared_helpers.rb +201 -0
  234. data/lib/dependabot/source.rb +120 -0
  235. data/lib/dependabot/update_checkers.rb +48 -0
  236. data/lib/dependabot/update_checkers/README.md +67 -0
  237. data/lib/dependabot/update_checkers/base.rb +220 -0
  238. data/lib/dependabot/update_checkers/docker/docker.rb +290 -0
  239. data/lib/dependabot/update_checkers/dotnet/nuget.rb +127 -0
  240. data/lib/dependabot/update_checkers/dotnet/nuget/property_updater.rb +97 -0
  241. data/lib/dependabot/update_checkers/dotnet/nuget/repository_finder.rb +232 -0
  242. data/lib/dependabot/update_checkers/dotnet/nuget/requirements_updater.rb +81 -0
  243. data/lib/dependabot/update_checkers/dotnet/nuget/version_finder.rb +231 -0
  244. data/lib/dependabot/update_checkers/elixir/hex.rb +274 -0
  245. data/lib/dependabot/update_checkers/elixir/hex/file_preparer.rb +193 -0
  246. data/lib/dependabot/update_checkers/elixir/hex/requirements_updater.rb +177 -0
  247. data/lib/dependabot/update_checkers/elixir/hex/version_resolver.rb +175 -0
  248. data/lib/dependabot/update_checkers/elm/elm_package.rb +126 -0
  249. data/lib/dependabot/update_checkers/elm/elm_package/cli_parser.rb +33 -0
  250. data/lib/dependabot/update_checkers/elm/elm_package/elm_18_version_resolver.rb +234 -0
  251. data/lib/dependabot/update_checkers/elm/elm_package/elm_19_version_resolver.rb +198 -0
  252. data/lib/dependabot/update_checkers/elm/elm_package/requirements_updater.rb +75 -0
  253. data/lib/dependabot/update_checkers/git/submodules.rb +52 -0
  254. data/lib/dependabot/update_checkers/go/dep.rb +311 -0
  255. data/lib/dependabot/update_checkers/go/dep/file_preparer.rb +221 -0
  256. data/lib/dependabot/update_checkers/go/dep/latest_version_finder.rb +169 -0
  257. data/lib/dependabot/update_checkers/go/dep/requirements_updater.rb +223 -0
  258. data/lib/dependabot/update_checkers/go/dep/version_resolver.rb +164 -0
  259. data/lib/dependabot/update_checkers/go/modules.rb +112 -0
  260. data/lib/dependabot/update_checkers/java/gradle.rb +148 -0
  261. data/lib/dependabot/update_checkers/java/gradle/multi_dependency_updater.rb +105 -0
  262. data/lib/dependabot/update_checkers/java/gradle/version_finder.rb +183 -0
  263. data/lib/dependabot/update_checkers/java/maven.rb +159 -0
  264. data/lib/dependabot/update_checkers/java/maven/property_updater.rb +127 -0
  265. data/lib/dependabot/update_checkers/java/maven/requirements_updater.rb +92 -0
  266. data/lib/dependabot/update_checkers/java/maven/version_finder.rb +225 -0
  267. data/lib/dependabot/update_checkers/java_script/npm_and_yarn.rb +280 -0
  268. data/lib/dependabot/update_checkers/java_script/npm_and_yarn/latest_version_finder.rb +342 -0
  269. data/lib/dependabot/update_checkers/java_script/npm_and_yarn/library_detector.rb +69 -0
  270. data/lib/dependabot/update_checkers/java_script/npm_and_yarn/registry_finder.rb +226 -0
  271. data/lib/dependabot/update_checkers/java_script/npm_and_yarn/requirements_updater.rb +197 -0
  272. data/lib/dependabot/update_checkers/java_script/npm_and_yarn/subdependency_version_resolver.rb +228 -0
  273. data/lib/dependabot/update_checkers/java_script/npm_and_yarn/version_resolver.rb +452 -0
  274. data/lib/dependabot/update_checkers/php/composer.rb +165 -0
  275. data/lib/dependabot/update_checkers/php/composer/requirements_updater.rb +243 -0
  276. data/lib/dependabot/update_checkers/php/composer/version_resolver.rb +203 -0
  277. data/lib/dependabot/update_checkers/python/pip.rb +227 -0
  278. data/lib/dependabot/update_checkers/python/pip/latest_version_finder.rb +252 -0
  279. data/lib/dependabot/update_checkers/python/pip/pip_compile_version_resolver.rb +380 -0
  280. data/lib/dependabot/update_checkers/python/pip/pipfile_version_resolver.rb +559 -0
  281. data/lib/dependabot/update_checkers/python/pip/poetry_version_resolver.rb +300 -0
  282. data/lib/dependabot/update_checkers/python/pip/requirements_updater.rb +367 -0
  283. data/lib/dependabot/update_checkers/ruby/bundler.rb +324 -0
  284. data/lib/dependabot/update_checkers/ruby/bundler/file_preparer.rb +278 -0
  285. data/lib/dependabot/update_checkers/ruby/bundler/force_updater.rb +261 -0
  286. data/lib/dependabot/update_checkers/ruby/bundler/latest_version_finder.rb +169 -0
  287. data/lib/dependabot/update_checkers/ruby/bundler/requirements_updater.rb +264 -0
  288. data/lib/dependabot/update_checkers/ruby/bundler/ruby_requirement_setter.rb +115 -0
  289. data/lib/dependabot/update_checkers/ruby/bundler/shared_bundler_helpers.rb +243 -0
  290. data/lib/dependabot/update_checkers/ruby/bundler/version_resolver.rb +255 -0
  291. data/lib/dependabot/update_checkers/rust/cargo.rb +282 -0
  292. data/lib/dependabot/update_checkers/rust/cargo/file_preparer.rb +202 -0
  293. data/lib/dependabot/update_checkers/rust/cargo/requirements_updater.rb +175 -0
  294. data/lib/dependabot/update_checkers/rust/cargo/version_resolver.rb +242 -0
  295. data/lib/dependabot/utils.rb +84 -0
  296. data/lib/dependabot/utils/docker/credentials_finder.rb +65 -0
  297. data/lib/dependabot/utils/dotnet/requirement.rb +90 -0
  298. data/lib/dependabot/utils/dotnet/version.rb +22 -0
  299. data/lib/dependabot/utils/elixir/requirement.rb +53 -0
  300. data/lib/dependabot/utils/elixir/version.rb +59 -0
  301. data/lib/dependabot/utils/elm/requirement.rb +92 -0
  302. data/lib/dependabot/utils/elm/version.rb +19 -0
  303. data/lib/dependabot/utils/go/path_converter.rb +74 -0
  304. data/lib/dependabot/utils/go/requirement.rb +152 -0
  305. data/lib/dependabot/utils/go/shared_helper.rb +20 -0
  306. data/lib/dependabot/utils/go/version.rb +40 -0
  307. data/lib/dependabot/utils/java/requirement.rb +110 -0
  308. data/lib/dependabot/utils/java/version.rb +179 -0
  309. data/lib/dependabot/utils/java_script/requirement.rb +117 -0
  310. data/lib/dependabot/utils/java_script/version.rb +30 -0
  311. data/lib/dependabot/utils/php/requirement.rb +97 -0
  312. data/lib/dependabot/utils/php/version.rb +22 -0
  313. data/lib/dependabot/utils/python/requirement.rb +130 -0
  314. data/lib/dependabot/utils/python/version.rb +88 -0
  315. data/lib/dependabot/utils/ruby/requirement.rb +26 -0
  316. data/lib/dependabot/utils/rust/requirement.rb +108 -0
  317. data/lib/dependabot/utils/rust/version.rb +32 -0
  318. data/lib/dependabot/version.rb +5 -0
  319. data/lib/python_requirement_parser.rb +33 -0
  320. data/lib/python_versions.rb +21 -0
  321. metadata +641 -0
@@ -0,0 +1,261 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler_definition_ruby_version_patch"
4
+ require "bundler_definition_bundler_version_patch"
5
+ require "bundler_git_source_patch"
6
+
7
+ require "dependabot/update_checkers/ruby/bundler"
8
+ require "dependabot/update_checkers/ruby/bundler/requirements_updater"
9
+ require "dependabot/file_updaters/ruby/bundler/lockfile_updater"
10
+ require "dependabot/file_parsers/ruby/bundler"
11
+ require "dependabot/shared_helpers"
12
+ require "dependabot/errors"
13
+
14
+ module Dependabot
15
+ module UpdateCheckers
16
+ module Ruby
17
+ class Bundler
18
+ class ForceUpdater
19
+ def initialize(dependency:, dependency_files:, credentials:,
20
+ target_version:)
21
+ @dependency = dependency
22
+ @dependency_files = dependency_files
23
+ @credentials = credentials
24
+ @target_version = target_version
25
+ end
26
+
27
+ def updated_dependencies
28
+ @updated_dependencies ||= force_update
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :dependency, :dependency_files, :credentials,
34
+ :target_version
35
+
36
+ def force_update
37
+ in_a_temporary_bundler_context do
38
+ other_updates = []
39
+
40
+ begin
41
+ definition = build_definition(other_updates: other_updates)
42
+ definition.resolve_remotely!
43
+ specs = definition.resolve
44
+ dependencies_from([dependency] + other_updates, specs)
45
+ rescue ::Bundler::VersionConflict => error
46
+ # TODO: Not sure this won't unlock way too many things...
47
+ new_dependencies_to_unlock =
48
+ new_dependencies_to_unlock_from(
49
+ error: error,
50
+ already_unlocked: other_updates
51
+ )
52
+
53
+ raise if new_dependencies_to_unlock.none?
54
+
55
+ other_updates += new_dependencies_to_unlock
56
+ retry
57
+ end
58
+ end
59
+ rescue SharedHelpers::ChildProcessFailed => error
60
+ raise_unresolvable_error(error)
61
+ end
62
+
63
+ #########################
64
+ # Bundler context setup #
65
+ #########################
66
+
67
+ def in_a_temporary_bundler_context
68
+ SharedHelpers.in_a_temporary_directory do
69
+ write_temporary_dependency_files
70
+
71
+ SharedHelpers.in_a_forked_process do
72
+ # Remove installed gems from the default Rubygems index
73
+ ::Gem::Specification.all = []
74
+
75
+ # Set auth details
76
+ relevant_credentials.each do |cred|
77
+ ::Bundler.settings.set_command_option(
78
+ cred.fetch("host"),
79
+ cred["token"] || "#{cred['username']}:#{cred['password']}"
80
+ )
81
+ end
82
+
83
+ # Only allow upgrades. Othewise it's unlikely that this
84
+ # resolution will be found by the FileUpdater
85
+ ::Bundler.settings.set_command_option(
86
+ "only_update_to_newer_versions",
87
+ true
88
+ )
89
+
90
+ yield
91
+ end
92
+ end
93
+ end
94
+
95
+ def new_dependencies_to_unlock_from(error:, already_unlocked:)
96
+ potentials_deps =
97
+ error.cause.conflicts.values.
98
+ flat_map(&:requirement_trees).
99
+ reject do |tree|
100
+ next true unless tree.last.requirement.specific?
101
+ next false unless tree.last.name == dependency.name
102
+
103
+ tree.last.requirement.satisfied_by?(
104
+ Gem::Version.new(target_version)
105
+ )
106
+ end.map(&:first)
107
+
108
+ potentials_deps.
109
+ reject { |dep| already_unlocked.map(&:name).include?(dep.name) }.
110
+ reject { |dep| [dependency.name, "ruby\0"].include?(dep.name) }.
111
+ uniq
112
+ end
113
+
114
+ def raise_unresolvable_error(error)
115
+ msg = error.error_class + " with message: " + error.error_message
116
+ raise Dependabot::DependencyFileNotResolvable, msg
117
+ end
118
+
119
+ def build_definition(other_updates:)
120
+ gems_to_unlock = other_updates.map(&:name) + [dependency.name]
121
+ definition = ::Bundler::Definition.build(
122
+ gemfile.name,
123
+ lockfile&.name,
124
+ gems: gems_to_unlock + subdependencies,
125
+ lock_shared_dependencies: true
126
+ )
127
+
128
+ # Remove the Gemfile / gemspec requirements on the gems we're
129
+ # unlocking (i.e., completely unlock them)
130
+ gems_to_unlock.each do |gem_name|
131
+ unlock_gem(definition: definition, gem_name: gem_name)
132
+ end
133
+
134
+ # Set the requirement for the gem we're forcing an update of
135
+ new_req = Gem::Requirement.create("= #{target_version}")
136
+ definition.dependencies.
137
+ find { |d| d.name == dependency.name }.
138
+ instance_variable_set(:@requirement, new_req)
139
+
140
+ definition
141
+ end
142
+
143
+ def subdependencies
144
+ # If there's no lockfile we don't need to worry about
145
+ # subdependencies
146
+ return [] unless lockfile
147
+
148
+ all_deps = ::Bundler::LockfileParser.new(sanitized_lockfile_body).
149
+ specs.map(&:name).map(&:to_s)
150
+ top_level = ::Bundler::Definition.
151
+ build(gemfile.name, lockfile.name, {}).
152
+ dependencies.map(&:name).map(&:to_s)
153
+
154
+ all_deps - top_level
155
+ end
156
+
157
+ def unlock_gem(definition:, gem_name:)
158
+ dep = definition.dependencies.find { |d| d.name == gem_name }
159
+ version = definition.locked_gems.specs.
160
+ find { |d| d.name == gem_name }.version
161
+
162
+ dep&.instance_variable_set(
163
+ :@requirement,
164
+ Gem::Requirement.create(">= #{version}")
165
+ )
166
+ end
167
+
168
+ def original_dependencies
169
+ @original_dependencies ||=
170
+ FileParsers::Ruby::Bundler.new(
171
+ dependency_files: dependency_files,
172
+ credentials: credentials,
173
+ source: nil
174
+ ).parse
175
+ end
176
+
177
+ def dependencies_from(updated_deps, specs)
178
+ # You might think we'd want to remove dependencies whose version
179
+ # hadn't changed from this array. We don't. We still need to unlock
180
+ # them to get Bundler to resolve, because unlocking them is what
181
+ # updates their subdependencies.
182
+ #
183
+ # This is kind of a bug in Bundler, and we should try to fix it,
184
+ # but resolving it won't necessarily be easy.
185
+ updated_deps.map do |dep|
186
+ original_dep =
187
+ original_dependencies.find { |d| d.name == dep.name }
188
+ spec = specs.find { |d| d.name == dep.name }
189
+
190
+ next if spec.version.to_s == original_dep.version
191
+
192
+ build_dependency(original_dep, spec)
193
+ end.compact
194
+ end
195
+
196
+ def build_dependency(original_dep, updated_spec)
197
+ Dependency.new(
198
+ name: updated_spec.name,
199
+ version: updated_spec.version.to_s,
200
+ requirements:
201
+ RequirementsUpdater.new(
202
+ requirements: original_dep.requirements,
203
+ library: library?,
204
+ updated_source: source_for(original_dep),
205
+ latest_version: updated_spec.version.to_s,
206
+ latest_resolvable_version: updated_spec.version.to_s
207
+ ).updated_requirements,
208
+ previous_version: original_dep.version,
209
+ previous_requirements: original_dep.requirements,
210
+ package_manager: original_dep.package_manager
211
+ )
212
+ end
213
+
214
+ def source_for(dependency)
215
+ dependency.requirements.
216
+ find { |r| r.fetch(:source) }&.
217
+ fetch(:source)
218
+ end
219
+
220
+ def gemfile
221
+ dependency_files.find { |f| f.name == "Gemfile" } ||
222
+ dependency_files.find { |f| f.name == "gems.rb" }
223
+ end
224
+
225
+ def lockfile
226
+ dependency_files.find { |f| f.name == "Gemfile.lock" } ||
227
+ dependency_files.find { |f| f.name == "gems.locked" }
228
+ end
229
+
230
+ def sanitized_lockfile_body
231
+ re = FileUpdaters::Ruby::Bundler::LockfileUpdater::LOCKFILE_ENDING
232
+ lockfile.content.gsub(re, "")
233
+ end
234
+
235
+ def library?
236
+ dependency.version.nil?
237
+ end
238
+
239
+ def write_temporary_dependency_files
240
+ dependency_files.each do |file|
241
+ path = file.name
242
+ FileUtils.mkdir_p(Pathname.new(path).dirname)
243
+ File.write(path, file.content)
244
+ end
245
+
246
+ File.write(lockfile.name, sanitized_lockfile_body) if lockfile
247
+ end
248
+
249
+ def relevant_credentials
250
+ credentials.select do |cred|
251
+ next true if cred["type"] == "git_source"
252
+ next true if cred["type"] == "rubygems_server"
253
+
254
+ false
255
+ end
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler_definition_ruby_version_patch"
4
+ require "bundler_definition_bundler_version_patch"
5
+ require "bundler_git_source_patch"
6
+
7
+ require "excon"
8
+
9
+ require "dependabot/update_checkers/ruby/bundler"
10
+ require "dependabot/utils/ruby/requirement"
11
+ require "dependabot/shared_helpers"
12
+ require "dependabot/errors"
13
+
14
+ module Dependabot
15
+ module UpdateCheckers
16
+ module Ruby
17
+ class Bundler
18
+ class LatestVersionFinder
19
+ require_relative "shared_bundler_helpers"
20
+ include SharedBundlerHelpers
21
+
22
+ def initialize(dependency:, dependency_files:, credentials:,
23
+ ignored_versions:)
24
+ @dependency = dependency
25
+ @dependency_files = dependency_files
26
+ @credentials = credentials
27
+ @ignored_versions = ignored_versions
28
+ end
29
+
30
+ def latest_version_details
31
+ @latest_version_details ||= fetch_latest_version_details
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :dependency, :dependency_files, :credentials,
37
+ :ignored_versions
38
+
39
+ def fetch_latest_version_details
40
+ if dependency.name == "bundler"
41
+ return latest_rubygems_version_details
42
+ end
43
+
44
+ case dependency_source
45
+ when NilClass then latest_rubygems_version_details
46
+ when ::Bundler::Source::Rubygems
47
+ if dependency_source.remotes.none? ||
48
+ dependency_source.remotes.first.to_s == "https://rubygems.org/"
49
+ latest_rubygems_version_details
50
+ else
51
+ latest_private_version_details
52
+ end
53
+ when ::Bundler::Source::Git then latest_git_version_details
54
+ end
55
+ end
56
+
57
+ def latest_rubygems_version_details
58
+ response = Excon.get(
59
+ "https://rubygems.org/api/v1/versions/#{dependency.name}.json",
60
+ idempotent: true,
61
+ **SharedHelpers.excon_defaults
62
+ )
63
+
64
+ relevant_versions =
65
+ JSON.parse(response.body).
66
+ reject do |d|
67
+ version = Gem::Version.new(d["number"])
68
+ next true if version.prerelease? && !wants_prerelease?
69
+ next true if ignore_reqs.any? { |r| r.satisfied_by?(version) }
70
+
71
+ false
72
+ end
73
+
74
+ dep = relevant_versions.max_by { |d| Gem::Version.new(d["number"]) }
75
+ return unless dep
76
+
77
+ {
78
+ version: Gem::Version.new(dep["number"]),
79
+ sha: dep["sha"]
80
+ }
81
+ rescue JSON::ParserError, Excon::Error::Timeout
82
+ nil
83
+ end
84
+
85
+ def latest_private_version_details
86
+ in_a_temporary_bundler_context do
87
+ spec =
88
+ dependency_source.
89
+ fetchers.flat_map do |fetcher|
90
+ fetcher.
91
+ specs_with_retry([dependency.name], dependency_source).
92
+ search_all(dependency.name).
93
+ reject { |s| s.version.prerelease? && !wants_prerelease? }.
94
+ reject do |s|
95
+ ignore_reqs.any? { |r| r.satisfied_by?(s.version) }
96
+ end
97
+ end.
98
+ max_by(&:version)
99
+ spec.nil? ? nil : { version: spec.version }
100
+ end
101
+ end
102
+
103
+ def latest_git_version_details
104
+ dependency_source_details =
105
+ dependency.requirements.map { |r| r.fetch(:source) }.
106
+ uniq.compact.first
107
+
108
+ in_a_temporary_bundler_context do
109
+ SharedHelpers.with_git_configured(credentials: credentials) do
110
+ # Note: we don't set `ref`, as we want to unpin the dependency
111
+ source = ::Bundler::Source::Git.new(
112
+ "uri" => dependency_source_details[:url],
113
+ "branch" => dependency_source_details[:branch],
114
+ "name" => dependency.name,
115
+ "submodules" => true
116
+ )
117
+
118
+ # Tell Bundler we're fine with fetching the source remotely
119
+ source.instance_variable_set(:@allow_remote, true)
120
+
121
+ spec = source.specs.first
122
+ { version: spec.version, commit_sha: spec.source.revision }
123
+ end
124
+ end
125
+ end
126
+
127
+ def wants_prerelease?
128
+ @wants_prerelease ||=
129
+ begin
130
+ current_version = dependency.version
131
+ if current_version && Gem::Version.correct?(current_version) &&
132
+ Gem::Version.new(current_version).prerelease?
133
+ return true
134
+ end
135
+
136
+ dependency.requirements.any? do |req|
137
+ req[:requirement].match?(/[a-z]/i)
138
+ end
139
+ end
140
+ end
141
+
142
+ def dependency_source
143
+ return nil unless gemfile
144
+
145
+ @dependency_source ||=
146
+ in_a_temporary_bundler_context do
147
+ definition = ::Bundler::Definition.build(gemfile.name, nil, {})
148
+
149
+ specified_source =
150
+ definition.dependencies.
151
+ find { |dep| dep.name == dependency.name }&.source
152
+
153
+ specified_source || definition.send(:sources).default_source
154
+ end
155
+ end
156
+
157
+ def ignore_reqs
158
+ ignored_versions.map { |req| Gem::Requirement.new(req.split(",")) }
159
+ end
160
+
161
+ def gemfile
162
+ dependency_files.find { |f| f.name == "Gemfile" } ||
163
+ dependency_files.find { |f| f.name == "gems.rb" }
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,264 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/update_checkers/ruby/bundler"
4
+
5
+ module Dependabot
6
+ module UpdateCheckers
7
+ module Ruby
8
+ class Bundler
9
+ class RequirementsUpdater
10
+ class UnfixableRequirement < StandardError; end
11
+
12
+ def initialize(requirements:, library:, updated_source:,
13
+ latest_version:, latest_resolvable_version:)
14
+ @requirements = requirements
15
+
16
+ @library = library
17
+
18
+ @latest_version = Gem::Version.new(latest_version) if latest_version
19
+ @updated_source = updated_source
20
+
21
+ return unless latest_resolvable_version
22
+
23
+ @latest_resolvable_version =
24
+ Gem::Version.new(latest_resolvable_version)
25
+ end
26
+
27
+ def updated_requirements
28
+ requirements.map do |req|
29
+ if req[:file].match?(/\.gemspec/)
30
+ updated_gemspec_requirement(req)
31
+ else
32
+ # If a requirement doesn't come from a gemspec, it must be from
33
+ # a Gemfile.
34
+ updated_gemfile_requirement(req)
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :requirements, :updated_source,
42
+ :latest_version, :latest_resolvable_version
43
+
44
+ def library?
45
+ @library
46
+ end
47
+
48
+ def updated_gemfile_requirement(req)
49
+ req = req.merge(source: updated_source)
50
+ return req unless latest_resolvable_version
51
+ return req if library? && new_version_satisfies?(req)
52
+
53
+ requirements =
54
+ req[:requirement].split(",").map { |r| Gem::Requirement.new(r) }
55
+
56
+ new_requirement =
57
+ if requirements.any?(&:exact?) then latest_resolvable_version.to_s
58
+ elsif requirements.any? { |r| r.to_s.start_with?("~>") }
59
+ tw_req = requirements.find { |r| r.to_s.start_with?("~>") }
60
+ update_twiddle_version(tw_req, latest_resolvable_version).to_s
61
+ else
62
+ update_gemfile_range(requirements).map(&:to_s).join(", ")
63
+ end
64
+
65
+ req.merge(requirement: new_requirement)
66
+ end
67
+
68
+ def new_version_satisfies?(req)
69
+ original_req = Gem::Requirement.new(req[:requirement].split(","))
70
+ original_req.satisfied_by?(latest_resolvable_version)
71
+ end
72
+
73
+ def update_gemfile_range(requirements)
74
+ updated_requirements =
75
+ requirements.flat_map do |r|
76
+ next r if r.satisfied_by?(latest_resolvable_version)
77
+
78
+ case op = r.requirements.first.first
79
+ when "<", "<="
80
+ [update_greatest_version(r, latest_resolvable_version)]
81
+ when "!="
82
+ []
83
+ else
84
+ raise "Unexpected operation for unsatisfied Gemfile "\
85
+ "requirement: #{op}"
86
+ end
87
+ end
88
+
89
+ binding_requirements(updated_requirements)
90
+ end
91
+
92
+ def at_same_precision(new_version, old_version)
93
+ release_precision =
94
+ old_version.to_s.split(".").select { |i| i.match?(/^\d+$/) }.count
95
+ prerelease_precision =
96
+ old_version.to_s.split(".").count - release_precision
97
+
98
+ new_release =
99
+ new_version.to_s.split(".").first(release_precision)
100
+ new_prerelease =
101
+ new_version.to_s.split(".").
102
+ drop_while { |i| i.match?(/^\d+$/) }.
103
+ first([prerelease_precision, 1].max)
104
+
105
+ [*new_release, *new_prerelease].join(".")
106
+ end
107
+
108
+ # rubocop:disable Metrics/PerceivedComplexity
109
+ def updated_gemspec_requirement(req)
110
+ return req unless latest_version && latest_resolvable_version
111
+
112
+ requirements =
113
+ req[:requirement].split(",").map { |r| Gem::Requirement.new(r) }
114
+
115
+ return req if requirements.all? do |r|
116
+ requirement_satisfied?(r, req[:groups])
117
+ end
118
+
119
+ updated_requirements =
120
+ requirements.flat_map do |r|
121
+ next r if requirement_satisfied?(r, req[:groups])
122
+
123
+ if req[:groups] == ["development"]
124
+ fixed_development_requirements(r)
125
+ else
126
+ fixed_requirements(r)
127
+ end
128
+ end
129
+
130
+ updated_requirements = binding_requirements(updated_requirements)
131
+ req.merge(requirement: updated_requirements.map(&:to_s).join(", "))
132
+ rescue UnfixableRequirement
133
+ req.merge(requirement: :unfixable)
134
+ end
135
+ # rubocop:enable Metrics/PerceivedComplexity
136
+
137
+ def requirement_satisfied?(req, groups)
138
+ if groups == ["development"]
139
+ req.satisfied_by?(latest_resolvable_version)
140
+ else
141
+ req.satisfied_by?(latest_version)
142
+ end
143
+ end
144
+
145
+ def binding_requirements(requirements)
146
+ grouped_by_operator =
147
+ requirements.group_by { |r| r.requirements.first.first }
148
+
149
+ binding_reqs = grouped_by_operator.flat_map do |operator, reqs|
150
+ case operator
151
+ when "<", "<=" then reqs.min_by { |r| r.requirements.first.last }
152
+ when ">", ">=" then reqs.max_by { |r| r.requirements.first.last }
153
+ else requirements
154
+ end
155
+ end.uniq
156
+
157
+ binding_reqs << Gem::Requirement.new if binding_reqs.empty?
158
+ binding_reqs.sort_by { |r| r.requirements.first.last }
159
+ end
160
+
161
+ def fixed_requirements(req)
162
+ op, version = req.requirements.first
163
+
164
+ case op
165
+ when "=", nil
166
+ if version < latest_resolvable_version
167
+ [Gem::Requirement.new("#{op} #{latest_resolvable_version}")]
168
+ else
169
+ req
170
+ end
171
+ when "<", "<=" then [update_greatest_version(req, latest_version)]
172
+ when "~>" then convert_twidle_to_range(req, latest_version)
173
+ when "!=" then []
174
+ when ">", ">=" then raise UnfixableRequirement
175
+ else raise "Unexpected operation for requirement: #{op}"
176
+ end
177
+ end
178
+
179
+ def fixed_development_requirements(req)
180
+ op, version = req.requirements.first
181
+
182
+ case op
183
+ when "=", nil
184
+ if version < latest_resolvable_version
185
+ [Gem::Requirement.new("#{op} #{latest_resolvable_version}")]
186
+ else
187
+ req
188
+ end
189
+ when "~>"
190
+ [update_twiddle_version(req, latest_resolvable_version)]
191
+ when "<", "<=" then [update_greatest_version(req, latest_version)]
192
+ when "!=" then []
193
+ when ">", ">=" then raise UnfixableRequirement
194
+ else raise "Unexpected operation for requirement: #{op}"
195
+ end
196
+ end
197
+
198
+ # rubocop:disable Metrics/AbcSize
199
+ def convert_twidle_to_range(requirement, version_to_be_permitted)
200
+ version = requirement.requirements.first.last
201
+ version = version.release if version.prerelease?
202
+
203
+ index_to_update = [version.segments.count - 2, 0].max
204
+
205
+ ub_segments = version_to_be_permitted.segments
206
+ ub_segments << 0 while ub_segments.count <= index_to_update
207
+ ub_segments = ub_segments[0..index_to_update]
208
+ ub_segments[index_to_update] += 1
209
+
210
+ lb_segments = version.segments
211
+ lb_segments.pop while lb_segments.any? && lb_segments.last.zero?
212
+
213
+ if lb_segments.none?
214
+ return [Gem::Requirement.new("< #{ub_segments.join('.')}")]
215
+ end
216
+
217
+ # Ensure versions have the same length as each other (cosmetic)
218
+ length = [lb_segments.count, ub_segments.count].max
219
+ lb_segments.fill(0, lb_segments.count...length)
220
+ ub_segments.fill(0, ub_segments.count...length)
221
+
222
+ [
223
+ Gem::Requirement.new(">= #{lb_segments.join('.')}"),
224
+ Gem::Requirement.new("< #{ub_segments.join('.')}")
225
+ ]
226
+ end
227
+ # rubocop:enable Metrics/AbcSize
228
+
229
+ # Updates the version in a "~>" constraint to allow the given version
230
+ def update_twiddle_version(requirement, version_to_be_permitted)
231
+ old_version = requirement.requirements.first.last
232
+ updated_v = at_same_precision(version_to_be_permitted, old_version)
233
+ Gem::Requirement.new("~> #{updated_v}")
234
+ end
235
+
236
+ # Updates the version in a "<" or "<=" constraint to allow the given
237
+ # version
238
+ def update_greatest_version(requirement, version_to_be_permitted)
239
+ if version_to_be_permitted.is_a?(String)
240
+ version_to_be_permitted =
241
+ Gem::Version.new(version_to_be_permitted)
242
+ end
243
+ op, version = requirement.requirements.first
244
+ version = version.release if version.prerelease?
245
+
246
+ index_to_update =
247
+ version.segments.map.with_index { |seg, i| seg.zero? ? 0 : i }.max
248
+
249
+ new_segments = version.segments.map.with_index do |_, index|
250
+ if index < index_to_update
251
+ version_to_be_permitted.segments[index]
252
+ elsif index == index_to_update
253
+ version_to_be_permitted.segments[index] + 1
254
+ else 0
255
+ end
256
+ end
257
+
258
+ Gem::Requirement.new("#{op} #{new_segments.join('.')}")
259
+ end
260
+ end
261
+ end
262
+ end
263
+ end
264
+ end