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,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "excon"
4
+ require "dependabot/update_checkers/base"
5
+ require "dependabot/shared_helpers"
6
+ require "dependabot/errors"
7
+
8
+ require "json"
9
+
10
+ module Dependabot
11
+ module UpdateCheckers
12
+ module Php
13
+ class Composer < Dependabot::UpdateCheckers::Base
14
+ require_relative "composer/requirements_updater"
15
+ require_relative "composer/version_resolver"
16
+
17
+ def latest_version
18
+ return nil if path_dependency?
19
+
20
+ # Fall back to latest_resolvable_version if no listings found
21
+ latest_version_from_registry || latest_resolvable_version
22
+ end
23
+
24
+ def latest_resolvable_version
25
+ return nil if path_dependency?
26
+
27
+ @latest_resolvable_version ||=
28
+ VersionResolver.new(
29
+ credentials: credentials,
30
+ dependency: dependency,
31
+ dependency_files: dependency_files,
32
+ latest_allowable_version: latest_version_from_registry,
33
+ requirements_to_unlock: :own
34
+ ).latest_resolvable_version
35
+ end
36
+
37
+ def latest_resolvable_version_with_no_unlock
38
+ return nil if path_dependency?
39
+
40
+ @latest_resolvable_version_with_no_unlock ||=
41
+ VersionResolver.new(
42
+ credentials: credentials,
43
+ dependency: dependency,
44
+ dependency_files: dependency_files,
45
+ latest_allowable_version: latest_version_from_registry,
46
+ requirements_to_unlock: :none
47
+ ).latest_resolvable_version
48
+ end
49
+
50
+ def updated_requirements
51
+ RequirementsUpdater.new(
52
+ requirements: dependency.requirements,
53
+ latest_version: latest_version&.to_s,
54
+ latest_resolvable_version: latest_resolvable_version&.to_s,
55
+ library: library?
56
+ ).updated_requirements
57
+ end
58
+
59
+ private
60
+
61
+ def latest_version_resolvable_with_full_unlock?
62
+ # Full unlock checks aren't implemented for Composer (yet)
63
+ false
64
+ end
65
+
66
+ def latest_version_from_registry
67
+ versions =
68
+ registry_versions.
69
+ select { |version| version_class.correct?(version.gsub(/^v/, "")) }.
70
+ map { |version| version_class.new(version.gsub(/^v/, "")) }
71
+
72
+ versions.reject!(&:prerelease?) unless wants_prerelease?
73
+ versions.reject! { |v| ignore_reqs.any? { |r| r.satisfied_by?(v) } }
74
+ versions.max
75
+ end
76
+
77
+ def wants_prerelease?
78
+ current_version = dependency.version
79
+ if current_version && version_class.new(current_version).prerelease?
80
+ return true
81
+ end
82
+
83
+ dependency.requirements.any? do |req|
84
+ req[:requirement].match?(/\d-[A-Za-z]/)
85
+ end
86
+ end
87
+
88
+ def updated_dependencies_after_full_unlock
89
+ raise NotImplementedError
90
+ end
91
+
92
+ def path_dependency?
93
+ dependency.requirements.any? { |r| r.dig(:source, :type) == "path" }
94
+ end
95
+
96
+ def composer_file
97
+ composer_file =
98
+ dependency_files.find { |f| f.name == "composer.json" }
99
+ raise "No composer.json!" unless composer_file
100
+
101
+ composer_file
102
+ end
103
+
104
+ def lockfile
105
+ dependency_files.find { |f| f.name == "composer.lock" }
106
+ end
107
+
108
+ def registry_versions
109
+ return @registry_versions unless @registry_versions.nil?
110
+
111
+ repositories =
112
+ JSON.parse(composer_file.content).
113
+ fetch("repositories", []).
114
+ select { |r| r.is_a?(Hash) }
115
+
116
+ urls = repositories.
117
+ select { |h| h["type"] == "composer" }.
118
+ map { |h| h["url"] }.compact.
119
+ map { |url| url.gsub(%r{\/$}, "") + "/packages.json" }
120
+
121
+ unless repositories.any? { |rep| rep["packagist.org"] == false }
122
+ urls << "https://packagist.org/p/#{dependency.name.downcase}.json"
123
+ end
124
+
125
+ @registry_versions = []
126
+ urls.each do |url|
127
+ @registry_versions += fetch_registry_versions_from_url(url)
128
+ end
129
+ @registry_versions.uniq
130
+ end
131
+
132
+ def fetch_registry_versions_from_url(url)
133
+ cred = registry_credentials.find { |c| url.include?(c["registry"]) }
134
+
135
+ response = Excon.get(
136
+ url,
137
+ idempotent: true,
138
+ user: cred&.fetch("username", nil),
139
+ password: cred&.fetch("password", nil),
140
+ **SharedHelpers.excon_defaults
141
+ )
142
+
143
+ return [] unless response.status == 200
144
+
145
+ listing = JSON.parse(response.body)
146
+ return [] if listing.nil?
147
+ return [] if listing.fetch("packages", []) == []
148
+ return [] unless listing.dig("packages", dependency.name.downcase)
149
+
150
+ listing.dig("packages", dependency.name.downcase).keys
151
+ rescue Excon::Error::Socket, Excon::Error::Timeout
152
+ []
153
+ end
154
+
155
+ def library?
156
+ JSON.parse(composer_file.content)["type"] == "library"
157
+ end
158
+
159
+ def registry_credentials
160
+ credentials.select { |cred| cred["type"] == "composer_repository" }
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,243 @@
1
+ # frozen_string_literal: true
2
+
3
+ ################################################################################
4
+ # For more details on Composer version constraints, see: #
5
+ # https://getcomposer.org/doc/articles/versions.md#writing-version-constraints #
6
+ ################################################################################
7
+
8
+ require "dependabot/update_checkers/php/composer"
9
+ require "dependabot/utils/php/version"
10
+ require "dependabot/utils/php/requirement"
11
+
12
+ module Dependabot
13
+ module UpdateCheckers
14
+ module Php
15
+ class Composer
16
+ class RequirementsUpdater
17
+ ALIAS_REGEX = /[a-z0-9\-_\.]*\sas\s+/.freeze
18
+ VERSION_REGEX =
19
+ /(?:#{ALIAS_REGEX})?[0-9]+(?:\.[a-zA-Z0-9*\-]+)*/.freeze
20
+ AND_SEPARATOR =
21
+ /(?<=[a-zA-Z0-9*])(?<!\sas)[\s,]+(?![\s,]*[|-]|as)/.freeze
22
+ OR_SEPARATOR = /(?<=[a-zA-Z0-9*])[\s,]*\|\|?\s*/.freeze
23
+ SEPARATOR = /(?:#{AND_SEPARATOR})|(?:#{OR_SEPARATOR})/.freeze
24
+
25
+ def initialize(requirements:, library:,
26
+ latest_version:, latest_resolvable_version:)
27
+ @requirements = requirements
28
+ @library = library
29
+
30
+ if latest_version
31
+ @latest_version = version_class.new(latest_version)
32
+ end
33
+
34
+ return unless latest_resolvable_version
35
+
36
+ @latest_resolvable_version =
37
+ version_class.new(latest_resolvable_version)
38
+ end
39
+
40
+ def updated_requirements
41
+ return requirements unless latest_resolvable_version
42
+
43
+ requirements.map { |req| updated_requirement(req) }
44
+ end
45
+
46
+ private
47
+
48
+ attr_reader :requirements, :latest_version, :latest_resolvable_version
49
+
50
+ # rubocop:disable Metrics/PerceivedComplexity
51
+ def updated_requirement(req)
52
+ req_string = req[:requirement].strip
53
+ or_string_reqs = req_string.split(OR_SEPARATOR)
54
+ or_separator = req_string.match(OR_SEPARATOR)&.to_s || " || "
55
+ numeric_or_string_reqs = or_string_reqs.
56
+ reject { |r| r.start_with?("dev-") }
57
+ branch_or_string_reqs = or_string_reqs.
58
+ select { |r| r.start_with?("dev-") }
59
+
60
+ return req unless req_string.match?(/\d/)
61
+ return req if numeric_or_string_reqs.none?
62
+ return updated_alias(req) if req_string.match?(ALIAS_REGEX)
63
+ return req if req_satisfied_by_latest_resolvable?(req_string)
64
+
65
+ new_req =
66
+ if library? then updated_library_requirement(req, or_separator)
67
+ else updated_app_requirement(req, or_separator)
68
+ end
69
+
70
+ new_req_string =
71
+ [new_req[:requirement], *branch_or_string_reqs].join(or_separator)
72
+ new_req.merge(requirement: new_req_string)
73
+ end
74
+ # rubocop:enable Metrics/PerceivedComplexity
75
+
76
+ def updated_alias(req)
77
+ req_string = req[:requirement]
78
+ real_version = req_string.split(/\sas\s/).first.strip
79
+
80
+ # If the version we're aliasing isn't a version then we don't know
81
+ # how to update it, so we just return the existing requirement.
82
+ return req unless version_class.correct?(real_version)
83
+
84
+ new_version_string = latest_resolvable_version.to_s
85
+ new_req = req_string.sub(real_version, new_version_string)
86
+ req.merge(requirement: new_req)
87
+ end
88
+
89
+ def library?
90
+ @library
91
+ end
92
+
93
+ def updated_app_requirement(req, or_separator)
94
+ current_requirement = req[:requirement]
95
+ reqs = current_requirement.strip.split(SEPARATOR).map(&:strip)
96
+
97
+ updated_requirement =
98
+ if reqs.count > 1
99
+ "^#{latest_resolvable_version}"
100
+ elsif reqs.any? { |r| r.match?(/<|(\s+-\s+)/) }
101
+ update_range_requirement(current_requirement, or_separator)
102
+ else
103
+ update_version_string(current_requirement)
104
+ end
105
+
106
+ req.merge(requirement: updated_requirement)
107
+ end
108
+
109
+ def updated_library_requirement(req, or_separator)
110
+ current_requirement = req[:requirement]
111
+ reqs = current_requirement.strip.split(SEPARATOR).map(&:strip)
112
+
113
+ updated_requirement =
114
+ if reqs.any? { |r| r.start_with?("^") }
115
+ update_caret_requirement(current_requirement, or_separator)
116
+ elsif reqs.any? { |r| r.start_with?("~") }
117
+ update_tilda_requirement(current_requirement, or_separator)
118
+ elsif reqs.any? { |r| r.include?("*") }
119
+ update_wildcard_requirement(current_requirement, or_separator)
120
+ elsif reqs.any? { |r| r.match?(/<|(\s+-\s+)/) }
121
+ update_range_requirement(current_requirement, or_separator)
122
+ else
123
+ update_version_string(current_requirement)
124
+ end
125
+
126
+ req.merge(requirement: updated_requirement)
127
+ end
128
+
129
+ def req_satisfied_by_latest_resolvable?(requirement_string)
130
+ ruby_requirements(requirement_string).
131
+ any? { |r| r.satisfied_by?(latest_resolvable_version) }
132
+ end
133
+
134
+ def update_version_string(req_string)
135
+ req_string.
136
+ sub(VERSION_REGEX) do |old_version|
137
+ unless req_string.match?(/[~*\^]/)
138
+ next latest_resolvable_version.to_s
139
+ end
140
+
141
+ old_parts = old_version.split(".")
142
+ new_parts = latest_resolvable_version.to_s.split(".").
143
+ first(old_parts.count)
144
+ new_parts.map.with_index do |part, i|
145
+ old_parts[i] == "*" ? "*" : part
146
+ end.join(".")
147
+ end
148
+ end
149
+
150
+ def ruby_requirements(requirement_string)
151
+ Utils::Php::Requirement.requirements_array(requirement_string)
152
+ end
153
+
154
+ def update_caret_requirement(req_string, or_separator)
155
+ caret_requirements =
156
+ req_string.split(SEPARATOR).select { |r| r.start_with?("^") }
157
+ version_parts = latest_resolvable_version.segments
158
+
159
+ min_existing_precision =
160
+ caret_requirements.map { |r| r.split(".").count }.min
161
+ first_non_zero_index =
162
+ version_parts.count.times.find { |i| version_parts[i] != 0 }
163
+
164
+ precision = [min_existing_precision, first_non_zero_index + 1].max
165
+ version = version_parts.first(precision).map.with_index do |part, i|
166
+ i <= first_non_zero_index ? part : 0
167
+ end.join(".")
168
+
169
+ req_string + "#{or_separator}^#{version}"
170
+ end
171
+
172
+ def update_tilda_requirement(req_string, or_separator)
173
+ tilda_requirements =
174
+ req_string.split(SEPARATOR).select { |r| r.start_with?("~") }
175
+ precision = tilda_requirements.map { |r| r.split(".").count }.min
176
+
177
+ version_parts = latest_resolvable_version.segments.first(precision)
178
+ version_parts[-1] = 0
179
+ version = version_parts.join(".")
180
+
181
+ req_string + "#{or_separator}~#{version}"
182
+ end
183
+
184
+ def update_wildcard_requirement(req_string, or_separator)
185
+ wildcard_requirements =
186
+ req_string.split(SEPARATOR).select { |r| r.include?("*") }
187
+ precision = wildcard_requirements.map do |r|
188
+ r.split(".").reject { |s| s == "*" }.count
189
+ end.min
190
+ wildcard_count = wildcard_requirements.map do |r|
191
+ r.split(".").select { |s| s == "*" }.count
192
+ end.min
193
+
194
+ version_parts = latest_resolvable_version.segments.first(precision)
195
+ version = version_parts.join(".")
196
+
197
+ req_string + "#{or_separator}#{version}#{'.*' * wildcard_count}"
198
+ end
199
+
200
+ def update_range_requirement(req_string, or_separator)
201
+ range_requirements =
202
+ req_string.split(SEPARATOR).select { |r| r.match?(/<|(\s+-\s+)/) }
203
+
204
+ if range_requirements.count == 1
205
+ range_requirement = range_requirements.first
206
+ versions = range_requirement.scan(VERSION_REGEX)
207
+ upper_bound = versions.map { |v| version_class.new(v) }.max
208
+ new_upper_bound = update_greatest_version(
209
+ upper_bound,
210
+ latest_resolvable_version
211
+ )
212
+
213
+ req_string.sub(upper_bound.to_s, new_upper_bound.to_s)
214
+ else
215
+ req_string + "#{or_separator}^#{latest_resolvable_version}"
216
+ end
217
+ end
218
+
219
+ def update_greatest_version(old_version, version_to_be_permitted)
220
+ version = version_class.new(old_version)
221
+ version = version.release if version.prerelease?
222
+
223
+ index_to_update =
224
+ version.segments.map.with_index { |seg, i| seg.zero? ? 0 : i }.max
225
+
226
+ version.segments.map.with_index do |_, index|
227
+ if index < index_to_update
228
+ version_to_be_permitted.segments[index]
229
+ elsif index == index_to_update
230
+ version_to_be_permitted.segments[index] + 1
231
+ else 0
232
+ end
233
+ end.join(".")
234
+ end
235
+
236
+ def version_class
237
+ Utils::Php::Version
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end
@@ -0,0 +1,203 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/shared_helpers"
4
+ require "dependabot/update_checkers/php/composer"
5
+ require "dependabot/utils/php/version"
6
+
7
+ module Dependabot
8
+ module UpdateCheckers
9
+ module Php
10
+ class Composer
11
+ class VersionResolver
12
+ VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/.freeze
13
+ SOURCE_TIMED_OUT_REGEX =
14
+ /The "(?<url>[^"]+packages\.json)".*timed out/.freeze
15
+
16
+ def initialize(credentials:, dependency:, dependency_files:,
17
+ requirements_to_unlock:, latest_allowable_version:)
18
+ @credentials = credentials
19
+ @dependency = dependency
20
+ @dependency_files = dependency_files
21
+ @requirements_to_unlock = requirements_to_unlock
22
+ @latest_allowable_version = latest_allowable_version
23
+ end
24
+
25
+ def latest_resolvable_version
26
+ @latest_resolvable_version ||= fetch_latest_resolvable_version
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :credentials, :dependency, :dependency_files,
32
+ :requirements_to_unlock, :latest_allowable_version
33
+
34
+ def fetch_latest_resolvable_version
35
+ version = fetch_latest_resolvable_version_string
36
+ return if version.nil?
37
+ return unless Utils::Php::Version.correct?(version)
38
+
39
+ Utils::Php::Version.new(version)
40
+ end
41
+
42
+ def fetch_latest_resolvable_version_string
43
+ base_directory = dependency_files.first.directory
44
+ SharedHelpers.in_a_temporary_directory(base_directory) do
45
+ File.write("composer.json", prepared_composer_json_content)
46
+ File.write("composer.lock", lockfile.content) if lockfile
47
+
48
+ run_update_checker
49
+ end
50
+ rescue SharedHelpers::HelperSubprocessFailed => error
51
+ retry_count ||= 0
52
+ retry_count += 1
53
+ retry if retry_count < 2 && error.message.include?("404 Not Found")
54
+ retry if retry_count < 2 && error.message.include?("timed out")
55
+ handle_composer_errors(error)
56
+ end
57
+
58
+ def run_update_checker
59
+ SharedHelpers.with_git_configured(credentials: credentials) do
60
+ SharedHelpers.run_helper_subprocess(
61
+ command: "php -d memory_limit=-1 #{php_helper_path}",
62
+ function: "get_latest_resolvable_version",
63
+ args: [
64
+ Dir.pwd,
65
+ dependency.name.downcase,
66
+ git_credentials,
67
+ registry_credentials
68
+ ]
69
+ )
70
+ end
71
+ end
72
+
73
+ def prepared_composer_json_content
74
+ content = composer_file.content
75
+
76
+ content.gsub(
77
+ /"#{Regexp.escape(dependency.name)}"\s*:\s*".*"/,
78
+ %("#{dependency.name}": "#{updated_version_requirement_string}")
79
+ )
80
+ end
81
+
82
+ def updated_version_requirement_string
83
+ lower_bound =
84
+ if requirements_to_unlock == :none
85
+ dependency.requirements.first&.fetch(:requirement) || ">= 0"
86
+ elsif dependency.version
87
+ ">= #{dependency.version}"
88
+ else
89
+ version_for_requirement =
90
+ dependency.requirements.map { |r| r[:requirement] }.compact.
91
+ reject { |req_string| req_string.start_with?("<") }.
92
+ select { |req_string| req_string.match?(VERSION_REGEX) }.
93
+ map { |req_string| req_string.match(VERSION_REGEX) }.
94
+ select { |version| Gem::Version.correct?(version) }.
95
+ max_by { |version| Gem::Version.new(version) }
96
+
97
+ ">= #{version_for_requirement || 0}"
98
+ end
99
+
100
+ # Add the latest_allowable_version as an upper bound. This means
101
+ # ignore conditions are considered when checking for the latest
102
+ # resolvable version.
103
+ #
104
+ # NOTE: This isn't perfect. If v2.x is ignored and v3 is out but
105
+ # unresolvable then the `latest_allowable_version` will be v3, and
106
+ # we won't be ignoring v2.x releases like we should be.
107
+ return lower_bound unless latest_allowable_version
108
+
109
+ lower_bound + ", <= #{latest_allowable_version}"
110
+ end
111
+
112
+ # rubocop:disable Metrics/PerceivedComplexity
113
+ # rubocop:disable Metrics/AbcSize
114
+ # rubocop:disable Metrics/CyclomaticComplexity
115
+ # rubocop:disable Metrics/MethodLength
116
+ def handle_composer_errors(error)
117
+ if error.message.start_with?("Failed to execute git clone")
118
+ dependency_url =
119
+ error.message.match(/--mirror '(?<url>.*?)'/).
120
+ named_captures.fetch("url")
121
+ raise Dependabot::GitDependenciesNotReachable, dependency_url
122
+ elsif error.message.start_with?("Failed to clone")
123
+ dependency_url =
124
+ error.message.match(/Failed to clone (?<url>.*?) via/).
125
+ named_captures.fetch("url")
126
+ raise Dependabot::GitDependenciesNotReachable, dependency_url
127
+ elsif error.message.start_with?("Could not parse version")
128
+ raise Dependabot::DependencyFileNotResolvable, error.message
129
+ elsif error.message.include?("requested PHP extension")
130
+ extensions = error.message.scan(/\sext\-.*?\s/).map(&:strip).uniq
131
+ msg = "Dependabot's installed extensions didn't match those "\
132
+ "required by your application. Please add the following "\
133
+ "extensions to the platform config in your composer.json: "\
134
+ "#{extensions.join(', ')}.\n\n"\
135
+ "The full error raised was:\n\n#{error.message}"
136
+ raise Dependabot::DependencyFileNotResolvable, msg
137
+ elsif error.message.include?("package requires php") ||
138
+ error.message.include?("cannot require itself")
139
+ raise Dependabot::DependencyFileNotResolvable, error.message
140
+ elsif error.message.include?("requirements could not be resolved")
141
+ # We should raise a Dependabot::DependencyFileNotResolvable error
142
+ # here, but can't confidently distinguish between cases where we
143
+ # can't install and cases where we can't update. For now, we
144
+ # therefore just ignore the dependency.
145
+ nil
146
+ elsif error.message.include?("URL required authentication") ||
147
+ error.message.include?("403 Forbidden")
148
+ source =
149
+ error.message.match(%r{https?://(?<source>[^/]+)/}).
150
+ named_captures.fetch("source")
151
+ raise Dependabot::PrivateSourceAuthenticationFailure, source
152
+ elsif error.message.match?(SOURCE_TIMED_OUT_REGEX)
153
+ url = error.message.match(SOURCE_TIMED_OUT_REGEX).
154
+ named_captures.fetch("url")
155
+ raise if url.include?("packagist.org")
156
+
157
+ source = url.gsub(%r{/packages.json$}, "")
158
+ raise Dependabot::PrivateSourceTimedOut, source
159
+ elsif error.message.start_with?("Allowed memory size")
160
+ raise Dependabot::OutOfMemory
161
+ elsif error.message.start_with?("Package not found in updated") &&
162
+ !dependency.top_level?
163
+ # If we can't find the dependency in the composer.lock after an
164
+ # update, but it was originally a sub-dependency, it's because the
165
+ # dependency is no longer required and is just cruft in the
166
+ # composer.json. In this case we just ignore the dependency.
167
+ nil
168
+ else
169
+ raise error
170
+ end
171
+ end
172
+ # rubocop:enable Metrics/PerceivedComplexity
173
+ # rubocop:enable Metrics/AbcSize
174
+ # rubocop:enable Metrics/CyclomaticComplexity
175
+ # rubocop:enable Metrics/MethodLength
176
+
177
+ def php_helper_path
178
+ project_root = File.join(File.dirname(__FILE__), "../../../../..")
179
+ File.join(project_root, "helpers/php/bin/run.php")
180
+ end
181
+
182
+ def composer_file
183
+ @composer_file ||=
184
+ dependency_files.find { |f| f.name == "composer.json" }
185
+ end
186
+
187
+ def lockfile
188
+ @lockfile ||=
189
+ dependency_files.find { |f| f.name == "composer.lock" }
190
+ end
191
+
192
+ def git_credentials
193
+ credentials.select { |cred| cred["type"] == "git_source" }
194
+ end
195
+
196
+ def registry_credentials
197
+ credentials.select { |cred| cred["type"] == "composer_repository" }
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end