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,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/update_checkers/ruby/bundler"
4
+ require "dependabot/update_checkers/python/pip"
5
+ require "dependabot/update_checkers/java_script/npm_and_yarn"
6
+ require "dependabot/update_checkers/java/maven"
7
+ require "dependabot/update_checkers/java/gradle"
8
+ require "dependabot/update_checkers/php/composer"
9
+ require "dependabot/update_checkers/git/submodules"
10
+ require "dependabot/update_checkers/docker/docker"
11
+ require "dependabot/update_checkers/elixir/hex"
12
+ require "dependabot/update_checkers/rust/cargo"
13
+ require "dependabot/update_checkers/dotnet/nuget"
14
+ require "dependabot/update_checkers/go/dep"
15
+ require "dependabot/update_checkers/go/modules"
16
+ require "dependabot/update_checkers/elm/elm_package"
17
+
18
+ module Dependabot
19
+ module UpdateCheckers
20
+ @update_checkers = {
21
+ "bundler" => UpdateCheckers::Ruby::Bundler,
22
+ "npm_and_yarn" => UpdateCheckers::JavaScript::NpmAndYarn,
23
+ "maven" => UpdateCheckers::Java::Maven,
24
+ "gradle" => UpdateCheckers::Java::Gradle,
25
+ "pip" => UpdateCheckers::Python::Pip,
26
+ "composer" => UpdateCheckers::Php::Composer,
27
+ "submodules" => UpdateCheckers::Git::Submodules,
28
+ "docker" => UpdateCheckers::Docker::Docker,
29
+ "hex" => UpdateCheckers::Elixir::Hex,
30
+ "cargo" => UpdateCheckers::Rust::Cargo,
31
+ "nuget" => UpdateCheckers::Dotnet::Nuget,
32
+ "dep" => UpdateCheckers::Go::Dep,
33
+ "go_modules" => UpdateCheckers::Go::Modules,
34
+ "elm-package" => UpdateCheckers::Elm::ElmPackage
35
+ }
36
+
37
+ def self.for_package_manager(package_manager)
38
+ update_checker = @update_checkers[package_manager]
39
+ return update_checker if update_checker
40
+
41
+ raise "Unsupported package_manager #{package_manager}"
42
+ end
43
+
44
+ def self.register(package_manager, update_checker)
45
+ @update_checkers[package_manager] = update_checker
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,67 @@
1
+ # Update checkers
2
+
3
+ Update checkers check whether a given dependency is up-to-date. If it isn't,
4
+ they augment it with details of the version to update to.
5
+
6
+ There is a `Dependabot::UpdateCheckers` class for each language Dependabot
7
+ supports.
8
+
9
+ ## Public API
10
+
11
+ Each `Dependabot::UpdateCheckers` class implements the following methods:
12
+
13
+ | Method | Description |
14
+ |------------------------------|-----------------------------------------------------------------------------------------------|
15
+ | `#up_to_date?` | Returns a boolean for whether the dependency this instance was created with is currently at the latest version. |
16
+ | `#can_update?` | Returns a boolean for whether the dependency this instance was created with needs updating. This will be true if the dependency and/or its requirements can be updated to support a newer version whilst keeping the dependency files it came from resolvable. |
17
+ | `#updated_dependencies` | Returns an array of updated `Dependabot::Dependency` instance with updated `version` and `requirements` attributes. The previous valuse are stored on the instance as `previous_version` and `previous_requirements`. |
18
+ | `#latest_version` | See the "Writing an update checker" section. |
19
+ | `#latest_resolvable_version` | See the "Writing an update checker" section. |
20
+ | `#updated_requirements` | See the "Writing an update checker" section. |
21
+
22
+ An integration might look as follows:
23
+
24
+ ```ruby
25
+ require 'dependabot/update_checkers'
26
+
27
+ dependency = dependencies.first
28
+
29
+ update_checker_class = Dependabot::UpdateCheckers::Ruby::Bundler
30
+ update_checker = update_checker_class.new(
31
+ dependency: dependency,
32
+ dependency_files: files,
33
+ credentials: [{
34
+ "type" => "git_source",
35
+ "host" => "github.com",
36
+ "username" => "x-access-token",
37
+ "password" => "token"
38
+ }]
39
+ )
40
+
41
+ puts "Update needed for #{dependency.name}? "\
42
+ "#{update_checker.can_update?(requirements_to_update: :own)}"
43
+ ```
44
+
45
+ ## Writing an update checker for a new language
46
+
47
+ All new update checkers should inherit from `Dependabot::UpdateCheckers::Base` and
48
+ implement the following methods:
49
+
50
+ | Method | Description |
51
+ |------------------------------|-----------------------------------------------------------------------------------------------|
52
+ | `#latest_version` | The latest version of the dependency, ignoring resolvability. This is used to short-circuit update checking when the dependency is already at the latest version (since checking resolvability is typically slow). |
53
+ | `#latest_resolvable_version` | The latest version of the dependency that will still allow the full dependency set to resolve. |
54
+ | `#latest_resolvable_version_with_no_unlock` | The latest version of the dependency that satisfies the dependency's current version constraints and will still allow the full dependency set to resolve. |
55
+ | `#updated_requirements` | An updated set of requirements for the dependency that should replace the existing requirements in the manifest file. Use by the file updater class when updating the manifest file. |
56
+ | `#latest_version_resolvable_with_full_unlock?` | A boolean for whether the latest version can be resolved if all other dependencies are unlocked in the manifest file. Can be set to always return `false` if multi-dependency updates aren't yet supported. |
57
+ | `#updated_dependencies_after_full_unlock` | And updated set of dependencies after a full unlock and update has taken place. Not required if `latest_version_resolvable_with_full_unlock?` always returns false. |
58
+
59
+
60
+ To ensure the above are implemented, you should include
61
+ `it_behaves_like "a dependency update checker"` in your specs for the new update
62
+ checker.
63
+
64
+ Writing update checkers generally gets tricky when resolvability has to
65
+ be taken into account. It is almost always easiest to do so in the language your
66
+ update checker relates to, so you may wish to shell out to that language. See
67
+ `UpdateCheckers::Php::Composer` for an example of how to do so.
@@ -0,0 +1,220 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "dependabot/utils"
5
+
6
+ module Dependabot
7
+ module UpdateCheckers
8
+ class Base
9
+ attr_reader :dependency, :dependency_files, :credentials,
10
+ :ignored_versions, :requirements_update_strategy
11
+
12
+ def initialize(dependency:, dependency_files:, credentials:,
13
+ ignored_versions: [], requirements_update_strategy: nil)
14
+ @dependency = dependency
15
+ @dependency_files = dependency_files
16
+ @credentials = credentials
17
+ @requirements_update_strategy = requirements_update_strategy
18
+ @ignored_versions = ignored_versions
19
+ end
20
+
21
+ def up_to_date?
22
+ if dependency.appears_in_lockfile?
23
+ version_up_to_date?
24
+ else
25
+ requirements_up_to_date?
26
+ end
27
+ end
28
+
29
+ def can_update?(requirements_to_unlock:)
30
+ if dependency.appears_in_lockfile?
31
+ version_can_update?(requirements_to_unlock: requirements_to_unlock)
32
+ else
33
+ # TODO: Handle full unlock updates for dependencies without a lockfile
34
+ return false if requirements_to_unlock == :none
35
+
36
+ requirements_can_update?
37
+ end
38
+ end
39
+
40
+ def updated_dependencies(requirements_to_unlock:)
41
+ unless can_update?(requirements_to_unlock: requirements_to_unlock)
42
+ return []
43
+ end
44
+
45
+ case requirements_to_unlock&.to_sym
46
+ when :none then [updated_dependency_without_unlock]
47
+ when :own then [updated_dependency_with_own_req_unlock]
48
+ when :all then updated_dependencies_after_full_unlock
49
+ else raise "Unknown unlock level '#{requirements_to_unlock}'"
50
+ end
51
+ end
52
+
53
+ def latest_version
54
+ raise NotImplementedError
55
+ end
56
+
57
+ def latest_resolvable_version
58
+ raise NotImplementedError
59
+ end
60
+
61
+ def latest_resolvable_version_with_no_unlock
62
+ raise NotImplementedError
63
+ end
64
+
65
+ def updated_requirements
66
+ raise NotImplementedError
67
+ end
68
+
69
+ def version_class
70
+ Utils.version_class_for_package_manager(dependency.package_manager)
71
+ end
72
+
73
+ def requirement_class
74
+ Utils.requirement_class_for_package_manager(dependency.package_manager)
75
+ end
76
+
77
+ # For some langauges, the manifest file may be constructed such that
78
+ # Dependabot has no way to update it (e.g., if it fetches its versions
79
+ # from a web API). This method is overridden in those cases.
80
+ def requirements_unlocked_or_can_be?
81
+ true
82
+ end
83
+
84
+ private
85
+
86
+ def latest_version_resolvable_with_full_unlock?
87
+ raise NotImplementedError
88
+ end
89
+
90
+ def updated_dependency_without_unlock
91
+ Dependency.new(
92
+ name: dependency.name,
93
+ version: latest_resolvable_version_with_no_unlock.to_s,
94
+ requirements: dependency.requirements,
95
+ previous_version: dependency.version,
96
+ previous_requirements: dependency.requirements,
97
+ package_manager: dependency.package_manager
98
+ )
99
+ end
100
+
101
+ def updated_dependency_with_own_req_unlock
102
+ Dependency.new(
103
+ name: dependency.name,
104
+ version: latest_resolvable_version.to_s,
105
+ requirements: updated_requirements,
106
+ previous_version: dependency.version,
107
+ previous_requirements: dependency.requirements,
108
+ package_manager: dependency.package_manager
109
+ )
110
+ end
111
+
112
+ def updated_dependencies_after_full_unlock
113
+ raise NotImplementedError
114
+ end
115
+
116
+ def version_up_to_date?
117
+ return sha1_version_up_to_date? if existing_version_is_sha?
118
+
119
+ numeric_version_up_to_date?
120
+ end
121
+
122
+ def version_can_update?(requirements_to_unlock:)
123
+ if existing_version_is_sha?
124
+ return sha1_version_can_update?(
125
+ requirements_to_unlock: requirements_to_unlock
126
+ )
127
+ end
128
+
129
+ numeric_version_can_update?(
130
+ requirements_to_unlock: requirements_to_unlock
131
+ )
132
+ end
133
+
134
+ def existing_version_is_sha?
135
+ return false if version_class.correct?(dependency.version)
136
+
137
+ dependency.version.match?(/^[0-9a-f]{6,}$/)
138
+ end
139
+
140
+ def sha1_version_up_to_date?
141
+ latest_version&.to_s&.start_with?(dependency.version)
142
+ end
143
+
144
+ def sha1_version_can_update?(requirements_to_unlock:)
145
+ return false if sha1_version_up_to_date?
146
+
147
+ # All we can do with SHA-1 hashes is check for presence and equality
148
+ case requirements_to_unlock&.to_sym
149
+ when :none
150
+ new_version = latest_resolvable_version_with_no_unlock
151
+ new_version && !new_version.to_s.start_with?(dependency.version)
152
+ when :own
153
+ new_version = latest_resolvable_version
154
+ new_version && !new_version.to_s.start_with?(dependency.version)
155
+ when :all
156
+ latest_version_resolvable_with_full_unlock?
157
+ else raise "Unknown unlock level '#{requirements_to_unlock}'"
158
+ end
159
+ end
160
+
161
+ def numeric_version_up_to_date?
162
+ return false unless latest_version
163
+
164
+ # If a lockfile isn't out of date and the package has switched to a git
165
+ # source then we'll get a numeric version switching to a git SHA. In
166
+ # this case we treat the verison as up-to-date so that it's ignored.
167
+ return true if latest_version.to_s.match?(/^[0-9a-f]{40}$/)
168
+
169
+ latest_version <= version_class.new(dependency.version)
170
+ end
171
+
172
+ def numeric_version_can_update?(requirements_to_unlock:)
173
+ return false if numeric_version_up_to_date?
174
+
175
+ case requirements_to_unlock&.to_sym
176
+ when :none
177
+ new_version = latest_resolvable_version_with_no_unlock
178
+ new_version && new_version > version_class.new(dependency.version)
179
+ when :own
180
+ new_version = latest_resolvable_version
181
+ new_version && new_version > version_class.new(dependency.version)
182
+ when :all
183
+ latest_version_resolvable_with_full_unlock?
184
+ else raise "Unknown unlock level '#{requirements_to_unlock}'"
185
+ end
186
+ end
187
+
188
+ def requirements_up_to_date?
189
+ return true if (updated_requirements - dependency.requirements).none?
190
+ return false unless latest_version
191
+ return false unless version_class.correct?(latest_version.to_s)
192
+ return false unless version_from_requirements
193
+
194
+ version_from_requirements >= version_class.new(latest_version.to_s)
195
+ end
196
+
197
+ def version_from_requirements
198
+ @version_from_requirements ||=
199
+ dependency.requirements.map { |r| r.fetch(:requirement) }.compact.
200
+ flat_map { |req_str| requirement_class.requirements_array(req_str) }.
201
+ flat_map(&:requirements).
202
+ reject { |req_array| req_array.first.start_with?("<") }.
203
+ map(&:last).
204
+ max
205
+ end
206
+
207
+ def requirements_can_update?
208
+ changed_reqs = updated_requirements - dependency.requirements
209
+
210
+ return false if changed_reqs.none?
211
+
212
+ changed_reqs.none? { |r| r[:requirement] == :unfixable }
213
+ end
214
+
215
+ def ignore_reqs
216
+ ignored_versions.map { |req| requirement_class.new(req.split(",")) }
217
+ end
218
+ end
219
+ end
220
+ end
@@ -0,0 +1,290 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "docker_registry2"
4
+
5
+ require "dependabot/update_checkers/base"
6
+ require "dependabot/errors"
7
+ require "dependabot/utils/docker/credentials_finder"
8
+
9
+ module Dependabot
10
+ module UpdateCheckers
11
+ module Docker
12
+ class Docker < Dependabot::UpdateCheckers::Base
13
+ VERSION_REGEX = /(?<version>[0-9]+(?:\.[a-zA-Z0-9]+)*)/.freeze
14
+ VERSION_WITH_SUFFIX =
15
+ /^#{VERSION_REGEX}(?<affix>-[a-z0-9.\-]+)?$/.freeze
16
+ VERSION_WITH_PREFIX =
17
+ /^(?<affix>[a-z0-9.\-]+-)?#{VERSION_REGEX}$/.freeze
18
+ NAME_WITH_VERSION =
19
+ /#{VERSION_WITH_PREFIX}|#{VERSION_WITH_SUFFIX}/.freeze
20
+
21
+ def latest_version
22
+ @latest_version ||= fetch_latest_version
23
+ end
24
+
25
+ def latest_resolvable_version
26
+ # Resolvability isn't an issue for Docker containers.
27
+ latest_version
28
+ end
29
+
30
+ def latest_resolvable_version_with_no_unlock
31
+ # No concept of "unlocking" for Docker containers
32
+ dependency.version
33
+ end
34
+
35
+ def updated_requirements
36
+ dependency.requirements.map do |req|
37
+ updated_source = req.fetch(:source).dup
38
+ updated_source[:digest] = updated_digest if req[:source][:digest]
39
+ updated_source[:tag] = latest_version if req[:source][:tag]
40
+
41
+ req.merge(source: updated_source)
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def latest_version_resolvable_with_full_unlock?
48
+ # Full unlock checks aren't relevant for Dockerfiles
49
+ false
50
+ end
51
+
52
+ def updated_dependencies_after_full_unlock
53
+ raise NotImplementedError
54
+ end
55
+
56
+ def version_can_update?(*)
57
+ !version_up_to_date?
58
+ end
59
+
60
+ def version_up_to_date?
61
+ # If the tag isn't up-to-date then we can definitely update
62
+ return false if version_tag_up_to_date? == false
63
+
64
+ # Otherwise, if the Dockerfile specifies a digest check that that is
65
+ # up-to-date
66
+ digest_up_to_date?
67
+ end
68
+
69
+ def version_tag_up_to_date?
70
+ return unless dependency.version.match?(NAME_WITH_VERSION)
71
+
72
+ old_v = numeric_version_from(dependency.version)
73
+ latest_v = numeric_version_from(latest_version)
74
+
75
+ return true if version_class.new(latest_v) <= version_class.new(old_v)
76
+
77
+ # Check the precision of the potentially higher tag is the same as the
78
+ # one it would replace. In the event that it's not the same, check the
79
+ # digests are also unequal. Avoids 'updating' ruby-2 -> ruby-2.5.1
80
+ return false if old_v.split(".").count == latest_v.split(".").count
81
+
82
+ digest_of(dependency.version) == digest_of(latest_version)
83
+ end
84
+
85
+ def digest_up_to_date?
86
+ dependency.requirements.all? do |req|
87
+ next true unless req.fetch(:source)[:digest]
88
+
89
+ req.fetch(:source).fetch(:digest) == digest_of(dependency.version)
90
+ end
91
+ end
92
+
93
+ # Note: It's important that this *always* returns a version (even if
94
+ # it's the existing one) as it is what we later check the digest of.
95
+ def fetch_latest_version
96
+ unless dependency.version.match?(NAME_WITH_VERSION)
97
+ return dependency.version
98
+ end
99
+
100
+ # Prune out any downgrade tags before checking for pre-releases
101
+ # (which requires a call to the registry for each tag, so can be slow)
102
+ candidate_tags = comparable_tags_from_registry
103
+ non_downgrade_tags = remove_version_downgrades(candidate_tags)
104
+ candidate_tags = non_downgrade_tags if non_downgrade_tags.any?
105
+
106
+ wants_prerelease = prerelease?(dependency.version)
107
+ candidate_tags =
108
+ candidate_tags.
109
+ reject { |tag| prerelease?(tag) && !wants_prerelease }.
110
+ reject do |tag|
111
+ version = version_class.new(numeric_version_from(tag))
112
+ ignore_reqs.any? { |r| r.satisfied_by?(version) }
113
+ end
114
+
115
+ latest_tag =
116
+ candidate_tags.
117
+ max_by { |tag| version_class.new(numeric_version_from(tag)) }
118
+
119
+ latest_tag || dependency.version
120
+ end
121
+
122
+ def comparable_tags_from_registry
123
+ original_affix = affix_of(dependency.version)
124
+
125
+ tags_from_registry.
126
+ select { |tag| tag.match?(NAME_WITH_VERSION) }.
127
+ select { |tag| affix_of(tag) == original_affix }.
128
+ reject { |tag| commit_sha_suffix?(tag) }
129
+ end
130
+
131
+ def remove_version_downgrades(candidate_tags)
132
+ candidate_tags.select do |tag|
133
+ version_class.new(numeric_version_from(tag)) >=
134
+ version_class.new(numeric_version_from(dependency.version))
135
+ end
136
+ end
137
+
138
+ def commit_sha_suffix?(tag)
139
+ # Some people suffix their versions with commit SHAs. Dependabot
140
+ # can't order on those but will try to, so instead we should exclude
141
+ # them (unless there's a `latest` version pushed to the registry, in
142
+ # which case we'll use that to find the latest version)
143
+ return false unless tag.match?(/(^|\-)[0-9a-f]{7,}$/)
144
+
145
+ !tag.match?(/(^|\-)20[0-1]\d{5}$/)
146
+ end
147
+
148
+ def version_of_latest_tag
149
+ return unless latest_digest
150
+
151
+ tags_from_registry.
152
+ select { |tag| canonical_version?(tag) }.
153
+ select { |t| digest_of(t) == latest_digest }.
154
+ map { |t| version_class.new(numeric_version_from(t)) }.
155
+ max
156
+ end
157
+
158
+ def canonical_version?(tag)
159
+ return false unless numeric_version_from(tag)
160
+ return true if tag == numeric_version_from(tag)
161
+
162
+ # .NET tags are suffixed with -sdk. There may be other cases we need
163
+ # to consider in future, too.
164
+ tag == numeric_version_from(tag) + "-sdk"
165
+ end
166
+
167
+ def updated_digest
168
+ @updated_digest ||=
169
+ begin
170
+ docker_registry_client.digest(docker_repo_name, latest_version)
171
+ rescue RestClient::Exceptions::Timeout
172
+ attempt ||= 1
173
+ attempt += 1
174
+ raise if attempt > 3
175
+
176
+ retry
177
+ end
178
+ rescue DockerRegistry2::RegistryAuthenticationException,
179
+ RestClient::Forbidden
180
+ raise PrivateSourceAuthenticationFailure, registry_hostname
181
+ end
182
+
183
+ def tags_from_registry
184
+ @tags_from_registry ||=
185
+ begin
186
+ docker_registry_client.tags(docker_repo_name).fetch("tags")
187
+ rescue RestClient::Exceptions::Timeout
188
+ attempt ||= 1
189
+ attempt += 1
190
+ raise if attempt > 3
191
+
192
+ retry
193
+ end
194
+ rescue DockerRegistry2::RegistryAuthenticationException,
195
+ RestClient::Forbidden
196
+ raise PrivateSourceAuthenticationFailure, registry_hostname
197
+ end
198
+
199
+ def latest_digest
200
+ return unless tags_from_registry.include?("latest")
201
+
202
+ digest_of("latest")
203
+ end
204
+
205
+ def digest_of(tag)
206
+ @digests ||= {}
207
+ return @digests[tag] if @digests.key?(tag)
208
+
209
+ @digests[tag] =
210
+ begin
211
+ docker_registry_client.digest(docker_repo_name, tag)
212
+ rescue *transient_docker_errors => e
213
+ attempt ||= 1
214
+ attempt += 1
215
+ return if attempt > 3 && e.is_a?(DockerRegistry2::NotFound)
216
+ raise if attempt > 3
217
+
218
+ retry
219
+ end
220
+ end
221
+
222
+ def transient_docker_errors
223
+ [RestClient::Exceptions::Timeout, DockerRegistry2::NotFound]
224
+ end
225
+
226
+ def affix_of(tag)
227
+ tag.match(NAME_WITH_VERSION).named_captures.fetch("affix")
228
+ end
229
+
230
+ def prerelease?(tag)
231
+ return true if numeric_version_from(tag).match?(/[a-zA-Z]/)
232
+
233
+ # If we're dealing with a numeric version we can compare it against
234
+ # the digest for the `latest` tag.
235
+ return false unless numeric_version_from(tag)
236
+ return false unless latest_digest
237
+ return false unless version_of_latest_tag
238
+
239
+ version_class.new(numeric_version_from(tag)) > version_of_latest_tag
240
+ end
241
+
242
+ def numeric_version_from(tag)
243
+ return unless tag.match?(NAME_WITH_VERSION)
244
+
245
+ tag.match(NAME_WITH_VERSION).named_captures.fetch("version")
246
+ end
247
+
248
+ def registry_hostname
249
+ dependency.requirements.first[:source][:registry] ||
250
+ "registry.hub.docker.com"
251
+ end
252
+
253
+ def using_dockerhub?
254
+ registry_hostname == "registry.hub.docker.com"
255
+ end
256
+
257
+ def registry_credentials
258
+ credentials_finder.credentials_for_registry(registry_hostname)
259
+ end
260
+
261
+ def credentials_finder
262
+ @credentials_finder ||=
263
+ Utils::Docker::CredentialsFinder.new(credentials)
264
+ end
265
+
266
+ def docker_repo_name
267
+ return dependency.name unless using_dockerhub?
268
+ return dependency.name unless dependency.name.split("/").count < 2
269
+
270
+ "library/#{dependency.name}"
271
+ end
272
+
273
+ def docker_registry_client
274
+ @docker_registry_client ||=
275
+ DockerRegistry2::Registry.new(
276
+ "https://#{registry_hostname}",
277
+ user: registry_credentials&.fetch("username"),
278
+ password: registry_credentials&.fetch("password")
279
+ )
280
+ end
281
+
282
+ def ignore_reqs
283
+ # Note: we use Gem::Requirement here because ignore conditions will
284
+ # be passed as Ruby ranges
285
+ ignored_versions.map { |req| Gem::Requirement.new(req.split(",")) }
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end