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,233 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "octokit"
4
+ require "securerandom"
5
+ require "dependabot/clients/github_with_retries"
6
+ require "dependabot/pull_request_creator"
7
+ require "dependabot/pull_request_creator/commit_signer"
8
+
9
+ module Dependabot
10
+ class PullRequestCreator
11
+ class Github
12
+ attr_reader :source, :branch_name, :base_commit, :credentials,
13
+ :files, :pr_description, :pr_name, :commit_message,
14
+ :author_details, :signature_key,
15
+ :labeler, :reviewers, :assignees, :milestone
16
+
17
+ def initialize(source:, branch_name:, base_commit:, credentials:,
18
+ files:, commit_message:, pr_description:, pr_name:,
19
+ author_details:, signature_key:,
20
+ labeler:, reviewers:, assignees:, milestone:)
21
+ @source = source
22
+ @branch_name = branch_name
23
+ @base_commit = base_commit
24
+ @credentials = credentials
25
+ @files = files
26
+ @commit_message = commit_message
27
+ @pr_description = pr_description
28
+ @pr_name = pr_name
29
+ @author_details = author_details
30
+ @signature_key = signature_key
31
+ @labeler = labeler
32
+ @reviewers = reviewers
33
+ @assignees = assignees
34
+ @milestone = milestone
35
+ end
36
+
37
+ def create
38
+ return if branch_exists? && pull_request_exists?
39
+
40
+ commit = create_commit
41
+ branch = create_or_update_branch(commit)
42
+ return unless branch
43
+
44
+ pull_request = create_pull_request
45
+ return unless pull_request
46
+
47
+ annotate_pull_request(pull_request)
48
+
49
+ pull_request
50
+ end
51
+
52
+ private
53
+
54
+ def github_client_for_source
55
+ @github_client_for_source ||=
56
+ Dependabot::Clients::GithubWithRetries.for_source(
57
+ source: source,
58
+ credentials: credentials
59
+ )
60
+ end
61
+
62
+ def branch_exists?
63
+ @branch_ref ||=
64
+ github_client_for_source.ref(source.repo, "heads/#{branch_name}")
65
+ if @branch_ref.is_a?(Array)
66
+ @branch_ref.any? { |r| r.ref == "refs/heads/#{branch_name}" }
67
+ else
68
+ @branch_ref.ref == "refs/heads/#{branch_name}"
69
+ end
70
+ rescue Octokit::NotFound
71
+ false
72
+ end
73
+
74
+ def pull_request_exists?
75
+ github_client_for_source.pull_requests(
76
+ source.repo,
77
+ head: "#{source.repo.split('/').first}:#{branch_name}",
78
+ state: "all"
79
+ ).any?
80
+ end
81
+
82
+ def create_commit
83
+ tree = create_tree
84
+
85
+ options = author_details&.any? ? { author: author_details } : {}
86
+
87
+ if options[:author]&.any? && signature_key
88
+ options[:author][:date] = Time.now.utc.iso8601
89
+ options[:signature] = commit_signature(tree, options[:author])
90
+ end
91
+
92
+ github_client_for_source.create_commit(
93
+ source.repo,
94
+ commit_message,
95
+ tree.sha,
96
+ base_commit,
97
+ options
98
+ )
99
+ end
100
+
101
+ def create_tree
102
+ file_trees = files.map do |file|
103
+ if file.type == "submodule"
104
+ {
105
+ path: file.path.sub(%r{^/}, ""),
106
+ mode: "160000",
107
+ type: "commit",
108
+ sha: file.content
109
+ }
110
+ else
111
+ {
112
+ path: file.path.sub(%r{^/}, ""),
113
+ mode: "100644",
114
+ type: "blob",
115
+ content: file.content
116
+ }
117
+ end
118
+ end
119
+
120
+ github_client_for_source.create_tree(
121
+ source.repo,
122
+ file_trees,
123
+ base_tree: base_commit
124
+ )
125
+ end
126
+
127
+ def create_or_update_branch(commit)
128
+ branch_exists? ? update_branch(commit) : create_branch(commit)
129
+ rescue Octokit::UnprocessableEntity
130
+ # A race condition may cause GitHub to fail here, in which case we retry
131
+ retry_count ||= 0
132
+ retry_count += 1
133
+ retry unless retry_count >= 2
134
+ end
135
+
136
+ def create_branch(commit)
137
+ github_client_for_source.create_ref(
138
+ source.repo,
139
+ "heads/#{branch_name}",
140
+ commit.sha
141
+ )
142
+ rescue Octokit::UnprocessableEntity => error
143
+ # Return quietly in the case of a race
144
+ return nil if error.message.match?(/Reference already exists/i)
145
+ raise if @retrying_branch_creation
146
+
147
+ @retrying_branch_creation = true
148
+
149
+ # Branch creation will fail if a branch called `dependabot` already
150
+ # exists, since git won't be able to create a folder with the same name
151
+ @branch_name = SecureRandom.hex[0..3] + @branch_name
152
+ retry
153
+ end
154
+
155
+ def update_branch(commit)
156
+ github_client_for_source.update_ref(
157
+ source.repo,
158
+ "heads/#{branch_name}",
159
+ commit.sha,
160
+ true
161
+ )
162
+ end
163
+
164
+ def annotate_pull_request(pull_request)
165
+ labeler.label_pull_request(pull_request.number)
166
+ add_reviewers_to_pull_request(pull_request) if reviewers&.any?
167
+ add_assignees_to_pull_request(pull_request) if assignees&.any?
168
+ add_milestone_to_pull_request(pull_request) if milestone
169
+ end
170
+
171
+ def add_reviewers_to_pull_request(pull_request)
172
+ reviewers_hash =
173
+ Hash[reviewers.keys.map { |k| [k.to_sym, reviewers[k]] }]
174
+
175
+ github_client_for_source.request_pull_request_review(
176
+ source.repo,
177
+ pull_request.number,
178
+ reviewers: reviewers_hash[:reviewers] || [],
179
+ team_reviewers: reviewers_hash[:team_reviewers] || []
180
+ )
181
+ rescue Octokit::UnprocessableEntity => error
182
+ return if error.message.include?("not a collaborator")
183
+ return if error.message.include?("Could not resolve to a node")
184
+
185
+ raise
186
+ end
187
+
188
+ def add_assignees_to_pull_request(pull_request)
189
+ github_client_for_source.add_assignees(
190
+ source.repo,
191
+ pull_request.number,
192
+ assignees
193
+ )
194
+ end
195
+
196
+ def add_milestone_to_pull_request(pull_request)
197
+ github_client_for_source.update_issue(
198
+ source.repo,
199
+ pull_request.number,
200
+ milestone: milestone
201
+ )
202
+ end
203
+
204
+ def create_pull_request
205
+ github_client_for_source.create_pull_request(
206
+ source.repo,
207
+ source.branch || default_branch,
208
+ branch_name,
209
+ pr_name,
210
+ pr_description
211
+ )
212
+ rescue Octokit::UnprocessableEntity => error
213
+ # Ignore races that we lose
214
+ raise unless error.message.include?("pull request already exists")
215
+ end
216
+
217
+ def default_branch
218
+ @default_branch ||=
219
+ github_client_for_source.repository(source.repo).default_branch
220
+ end
221
+
222
+ def commit_signature(tree, author_details_with_date)
223
+ CommitSigner.new(
224
+ author_details: author_details_with_date,
225
+ commit_message: commit_message,
226
+ tree_sha: tree.sha,
227
+ parent_sha: base_commit,
228
+ signature_key: signature_key
229
+ ).signature
230
+ end
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/clients/gitlab"
4
+ require "dependabot/pull_request_creator"
5
+ require "gitlab"
6
+
7
+ module Dependabot
8
+ class PullRequestCreator
9
+ class Gitlab
10
+ attr_reader :source, :branch_name, :base_commit, :credentials,
11
+ :files, :pr_description, :pr_name, :commit_message,
12
+ :author_details, :labeler, :assignee
13
+
14
+ def initialize(source:, branch_name:, base_commit:, credentials:,
15
+ files:, commit_message:, pr_description:, pr_name:,
16
+ author_details:, labeler:, assignee:)
17
+ @source = source
18
+ @branch_name = branch_name
19
+ @base_commit = base_commit
20
+ @credentials = credentials
21
+ @files = files
22
+ @commit_message = commit_message
23
+ @pr_description = pr_description
24
+ @pr_name = pr_name
25
+ @author_details = author_details
26
+ @labeler = labeler
27
+ @assignee = assignee
28
+ end
29
+
30
+ def create
31
+ return if branch_exists? && merge_request_exists?
32
+
33
+ if branch_exists?
34
+ create_commit unless commit_exists?
35
+ else
36
+ create_branch
37
+ create_commit
38
+ end
39
+
40
+ labeler.create_default_labels_if_required
41
+ create_merge_request
42
+ end
43
+
44
+ private
45
+
46
+ def gitlab_client_for_source
47
+ @gitlab_client_for_source ||= Dependabot::Clients::Gitlab.for_source(
48
+ source: source,
49
+ credentials: credentials
50
+ )
51
+ end
52
+
53
+ def branch_exists?
54
+ @branch_ref ||=
55
+ gitlab_client_for_source.branch(source.repo, branch_name)
56
+ true
57
+ rescue ::Gitlab::Error::NotFound
58
+ false
59
+ end
60
+
61
+ def commit_exists?
62
+ @commits ||=
63
+ gitlab_client_for_source.commits(source.repo, ref_name: branch_name)
64
+ @commits.first.message == commit_message
65
+ end
66
+
67
+ def merge_request_exists?
68
+ gitlab_client_for_source.merge_requests(
69
+ source.repo,
70
+ source_branch: branch_name,
71
+ target_branch: source.branch || default_branch,
72
+ state: "all"
73
+ ).any?
74
+ end
75
+
76
+ def create_branch
77
+ gitlab_client_for_source.create_branch(
78
+ source.repo,
79
+ branch_name,
80
+ base_commit
81
+ )
82
+ end
83
+
84
+ def create_commit
85
+ # TODO: Handle submodule updates on GitLab
86
+ # (see https://gitlab.com/gitlab-org/gitlab-ce/issues/41213)
87
+ actions = files.map do |file|
88
+ {
89
+ action: "update",
90
+ file_path: file.path,
91
+ content: file.content
92
+ }
93
+ end
94
+
95
+ gitlab_client_for_source.create_commit(
96
+ source.repo,
97
+ branch_name,
98
+ commit_message,
99
+ actions
100
+ )
101
+ end
102
+
103
+ def create_merge_request
104
+ gitlab_client_for_source.create_merge_request(
105
+ source.repo,
106
+ pr_name,
107
+ source_branch: branch_name,
108
+ target_branch: source.branch || default_branch,
109
+ description: pr_description,
110
+ remove_source_branch: true,
111
+ assignee_id: assignee,
112
+ labels: labeler.labels_for_pr.join(",")
113
+ )
114
+ end
115
+
116
+ def default_branch
117
+ @default_branch ||=
118
+ gitlab_client_for_source.project(source.repo).default_branch
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,361 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gitlab"
4
+ require "octokit"
5
+ require "dependabot/pull_request_creator"
6
+
7
+ # rubocop:disable Metrics/ClassLength
8
+ module Dependabot
9
+ class PullRequestCreator
10
+ class Labeler
11
+ DEPENDENCIES_LABEL_REGEX = %r{^[^/]*dependenc[^/]+$}i.freeze
12
+ LANGUAGE_LABEL_DETAILS = {
13
+ "bundler" => { name: "ruby", colour: "ce2d2d" },
14
+ "submodules" => { name: "submodules", colour: "000000" },
15
+ "docker" => { name: "docker", colour: "21ceff" },
16
+ "terraform" => { name: "terraform", colour: "5C4EE5" },
17
+ "nuget" => { name: ".NET", colour: "7121c6" },
18
+ "maven" => { name: "java", colour: "ffa221" },
19
+ "gradle" => { name: "java", colour: "ffa221" },
20
+ "npm_and_yarn" => { name: "javascript", colour: "168700" },
21
+ "pip" => { name: "python", colour: "2b67c6" },
22
+ "composer" => { name: "php", colour: "45229e" },
23
+ "hex" => { name: "elixir", colour: "9380dd" },
24
+ "cargo" => { name: "rust", colour: "000000" },
25
+ "dep" => { name: "go", colour: "16e2e2" },
26
+ "go_modules" => { name: "go", colour: "16e2e2" },
27
+ "elm-package" => { name: "elm", colour: "76d3f2" }
28
+ }.freeze
29
+
30
+ def initialize(source:, custom_labels:, credentials:, dependencies:,
31
+ includes_security_fixes:, label_language:)
32
+ @source = source
33
+ @custom_labels = custom_labels
34
+ @credentials = credentials
35
+ @dependencies = dependencies
36
+ @includes_security_fixes = includes_security_fixes
37
+ @label_language = label_language
38
+ end
39
+
40
+ def create_default_labels_if_required
41
+ create_default_dependencies_label_if_required
42
+ create_default_security_label_if_required
43
+ create_default_language_label_if_required
44
+ end
45
+
46
+ def labels_for_pr
47
+ [
48
+ *default_labels_for_pr,
49
+ includes_security_fixes? ? security_label : nil,
50
+ semver_labels_exist? ? semver_label : nil
51
+ ].compact.uniq
52
+ end
53
+
54
+ def label_pull_request(pull_request_number)
55
+ create_default_labels_if_required
56
+
57
+ return if labels_for_pr.none?
58
+ raise "Only GitHub!" unless source.provider == "github"
59
+
60
+ github_client_for_source.add_labels_to_an_issue(
61
+ source.repo,
62
+ pull_request_number,
63
+ labels_for_pr
64
+ )
65
+ end
66
+
67
+ private
68
+
69
+ attr_reader :source, :custom_labels, :credentials, :dependencies
70
+
71
+ def label_language?
72
+ @label_language
73
+ end
74
+
75
+ def includes_security_fixes?
76
+ @includes_security_fixes
77
+ end
78
+
79
+ # rubocop:disable Metrics/CyclomaticComplexity
80
+ # rubocop:disable Metrics/PerceivedComplexity
81
+ def update_type
82
+ return unless dependencies.any?(&:previous_version)
83
+
84
+ precison = dependencies.map do |dep|
85
+ new_version_parts = version(dep).split(".")
86
+ old_version_parts = previous_version(dep)&.split(".") || []
87
+ all_parts = new_version_parts.first(3) + old_version_parts.first(3)
88
+ next 0 unless all_parts.all? { |part| part.to_i.to_s == part }
89
+ next 1 if new_version_parts[0] != old_version_parts[0]
90
+ next 2 if new_version_parts[1] != old_version_parts[1]
91
+
92
+ 3
93
+ end.min
94
+
95
+ case precison
96
+ when 0 then "non-semver"
97
+ when 1 then "major"
98
+ when 2 then "minor"
99
+ when 3 then "patch"
100
+ end
101
+ end
102
+ # rubocop:enable Metrics/CyclomaticComplexity
103
+ # rubocop:enable Metrics/PerceivedComplexity
104
+
105
+ def version(dep)
106
+ return dep.version if version_class.correct?(dep.version)
107
+
108
+ source = dep.requirements.find { |r| r.fetch(:source) }&.fetch(:source)
109
+ type = source&.fetch("type", nil) || source&.fetch(:type)
110
+ return dep.version unless type == "git"
111
+
112
+ ref = source.fetch("ref", nil) || source.fetch(:ref)
113
+ version_from_ref = ref&.gsub(/^v/, "")
114
+ return dep.version unless version_from_ref
115
+ return dep.version unless version_class.correct?(version_from_ref)
116
+
117
+ version_from_ref
118
+ end
119
+
120
+ def previous_version(dep)
121
+ version_str = dep.previous_version
122
+ return version_str if version_class.correct?(version_str)
123
+
124
+ source = dep.previous_requirements.
125
+ find { |r| r.fetch(:source) }&.fetch(:source)
126
+ type = source&.fetch("type", nil) || source&.fetch(:type)
127
+ return version_str unless type == "git"
128
+
129
+ ref = source.fetch("ref", nil) || source.fetch(:ref)
130
+ version_from_ref = ref&.gsub(/^v/, "")
131
+ return version_str unless version_from_ref
132
+ return version_str unless version_class.correct?(version_from_ref)
133
+
134
+ version_from_ref
135
+ end
136
+
137
+ def create_default_dependencies_label_if_required
138
+ return if custom_labels
139
+ return if dependencies_label_exists?
140
+
141
+ create_dependencies_label
142
+ end
143
+
144
+ def create_default_security_label_if_required
145
+ return unless includes_security_fixes?
146
+ return if security_label_exists?
147
+
148
+ create_security_label
149
+ end
150
+
151
+ def create_default_language_label_if_required
152
+ return unless label_language?
153
+ return if custom_labels
154
+ return if language_label_exists?
155
+
156
+ create_language_label
157
+ end
158
+
159
+ def default_labels_for_pr
160
+ if custom_labels then custom_labels & labels
161
+ else
162
+ [
163
+ labels.find { |l| l.match?(DEPENDENCIES_LABEL_REGEX) },
164
+ label_language? ? language_label : nil
165
+ ].compact
166
+ end
167
+ end
168
+
169
+ def dependencies_label_exists?
170
+ labels.any? { |l| l.match?(DEPENDENCIES_LABEL_REGEX) }
171
+ end
172
+
173
+ def security_label_exists?
174
+ !security_label.nil?
175
+ end
176
+
177
+ def security_label
178
+ labels.find { |l| l.match?(/security/i) }
179
+ end
180
+
181
+ def semver_labels_exist?
182
+ (%w(major minor patch) - labels.map(&:downcase)).empty?
183
+ end
184
+
185
+ def semver_label
186
+ return unless update_type
187
+
188
+ labels.find { |l| l.downcase == update_type.to_s }
189
+ end
190
+
191
+ def language_label_exists?
192
+ !language_label.nil?
193
+ end
194
+
195
+ def language_label
196
+ label_name = LANGUAGE_LABEL_DETAILS.fetch(package_manager).fetch(:name)
197
+ labels.find { |l| l.casecmp(label_name).zero? }
198
+ end
199
+
200
+ def labels
201
+ @labels ||=
202
+ case source.provider
203
+ when "github" then fetch_github_labels
204
+ when "gitlab" then fetch_gitlab_labels
205
+ else raise "Unsupported provider #{source.provider}"
206
+ end
207
+ end
208
+
209
+ def fetch_github_labels
210
+ client = github_client_for_source
211
+
212
+ labels =
213
+ client.
214
+ labels(source.repo, per_page: 100).
215
+ map(&:name)
216
+
217
+ next_link = client.last_response.rels[:next]
218
+
219
+ while next_link
220
+ next_page = next_link.get
221
+ labels += next_page.data.map(&:name)
222
+ next_link = next_page.rels[:next]
223
+ end
224
+
225
+ labels
226
+ end
227
+
228
+ def fetch_gitlab_labels
229
+ gitlab_client_for_source.
230
+ labels(source.repo).
231
+ map(&:name)
232
+ end
233
+
234
+ def create_dependencies_label
235
+ case source.provider
236
+ when "github" then create_github_dependencies_label
237
+ when "gitlab" then create_gitlab_dependencies_label
238
+ else raise "Unsupported provider #{source.provider}"
239
+ end
240
+ end
241
+
242
+ def create_security_label
243
+ case source.provider
244
+ when "github" then create_github_security_label
245
+ when "gitlab" then create_gitlab_security_label
246
+ else raise "Unsupported provider #{source.provider}"
247
+ end
248
+ end
249
+
250
+ def create_language_label
251
+ case source.provider
252
+ when "github" then create_github_language_label
253
+ when "gitlab" then create_gitlab_language_label
254
+ else raise "Unsupported provider #{source.provider}"
255
+ end
256
+ end
257
+
258
+ def create_github_dependencies_label
259
+ github_client_for_source.add_label(
260
+ source.repo, "dependencies", "0025ff",
261
+ description: "Pull requests that update a dependency file",
262
+ accept: "application/vnd.github.symmetra-preview+json"
263
+ )
264
+ @labels = [*@labels, "dependencies"].uniq
265
+ rescue Octokit::UnprocessableEntity => error
266
+ raise unless error.errors.first.fetch(:code) == "already_exists"
267
+
268
+ @labels = [*@labels, "dependencies"].uniq
269
+ end
270
+
271
+ def create_gitlab_dependencies_label
272
+ gitlab_client_for_source.create_label(
273
+ source.repo, "dependencies", "#0025ff",
274
+ description: "Pull requests that update a dependency file"
275
+ )
276
+ @labels = [*@labels, "dependencies"].uniq
277
+ end
278
+
279
+ def create_github_security_label
280
+ github_client_for_source.add_label(
281
+ source.repo, "security", "ee0701",
282
+ description: "Pull requests that address a security vulnerability",
283
+ accept: "application/vnd.github.symmetra-preview+json"
284
+ )
285
+ @labels = [*@labels, "security"].uniq
286
+ rescue Octokit::UnprocessableEntity => error
287
+ raise unless error.errors.first.fetch(:code) == "already_exists"
288
+
289
+ @labels = [*@labels, "security"].uniq
290
+ end
291
+
292
+ def create_gitlab_security_label
293
+ gitlab_client_for_source.create_label(
294
+ source.repo, "security", "#ee0701",
295
+ description: "Pull requests that address a security vulnerability"
296
+ )
297
+ @labels = [*@labels, "security"].uniq
298
+ end
299
+
300
+ def create_github_language_label
301
+ langauge_name = LANGUAGE_LABEL_DETAILS.fetch(package_manager).
302
+ fetch(:name)
303
+ github_client_for_source.add_label(
304
+ source.repo,
305
+ langauge_name,
306
+ LANGUAGE_LABEL_DETAILS.fetch(package_manager).fetch(:colour),
307
+ description: "Pull requests that update #{langauge_name.capitalize} "\
308
+ "code",
309
+ accept: "application/vnd.github.symmetra-preview+json"
310
+ )
311
+ @labels = [*@labels, langauge_name].uniq
312
+ rescue Octokit::UnprocessableEntity => error
313
+ raise unless error.errors.first.fetch(:code) == "already_exists"
314
+
315
+ @labels = [*@labels, langauge_name].uniq
316
+ end
317
+
318
+ def create_gitlab_language_label
319
+ langauge_name = LANGUAGE_LABEL_DETAILS.fetch(package_manager).
320
+ fetch(:name)
321
+ gitlab_client_for_source.create_label(
322
+ source.repo,
323
+ langauge_name,
324
+ "#" + LANGUAGE_LABEL_DETAILS.fetch(package_manager).fetch(:colour)
325
+ )
326
+ @labels = [*@labels, langauge_name].uniq
327
+ end
328
+
329
+ def github_client_for_source
330
+ @github_client_for_source ||=
331
+ Dependabot::Clients::GithubWithRetries.for_source(
332
+ source: source,
333
+ credentials: credentials
334
+ )
335
+ end
336
+
337
+ def gitlab_client_for_source
338
+ access_token =
339
+ credentials.
340
+ select { |cred| cred["type"] == "git_source" }.
341
+ find { |cred| cred["host"] == source.hostname }&.
342
+ fetch("password")
343
+
344
+ @gitlab_client_for_source ||=
345
+ ::Gitlab.client(
346
+ endpoint: source.api_endpoint,
347
+ private_token: access_token || ""
348
+ )
349
+ end
350
+
351
+ def package_manager
352
+ @package_manager ||= dependencies.first.package_manager
353
+ end
354
+
355
+ def version_class
356
+ Utils.version_class_for_package_manager(package_manager)
357
+ end
358
+ end
359
+ end
360
+ end
361
+ # rubocop:enable Metrics/ClassLength