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,193 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/dependency_file"
4
+ require "dependabot/update_checkers/elixir/hex"
5
+ require "dependabot/file_updaters/elixir/hex/mixfile_requirement_updater"
6
+ require "dependabot/file_updaters/elixir/hex/mixfile_git_pin_updater"
7
+ require "dependabot/file_updaters/elixir/hex/mixfile_sanitizer"
8
+ require "dependabot/utils/elixir/version"
9
+
10
+ module Dependabot
11
+ module UpdateCheckers
12
+ module Elixir
13
+ class Hex
14
+ # This class takes a set of dependency files and sanitizes them for use
15
+ # in UpdateCheckers::Elixir::Hex.
16
+ class FilePreparer
17
+ def initialize(dependency_files:, dependency:,
18
+ unlock_requirement: true,
19
+ replacement_git_pin: nil,
20
+ latest_allowable_version: nil)
21
+ @dependency_files = dependency_files
22
+ @dependency = dependency
23
+ @unlock_requirement = unlock_requirement
24
+ @replacement_git_pin = replacement_git_pin
25
+ @latest_allowable_version = latest_allowable_version
26
+ end
27
+
28
+ def prepared_dependency_files
29
+ files = []
30
+ files += mixfiles.map do |file|
31
+ DependencyFile.new(
32
+ name: file.name,
33
+ content: mixfile_content_for_update_check(file),
34
+ directory: file.directory
35
+ )
36
+ end
37
+ files << lockfile if lockfile
38
+ files += support_files
39
+ files
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :dependency_files, :dependency, :replacement_git_pin,
45
+ :latest_allowable_version
46
+
47
+ def unlock_requirement?
48
+ @unlock_requirement
49
+ end
50
+
51
+ def replace_git_pin?
52
+ !replacement_git_pin.nil?
53
+ end
54
+
55
+ def mixfile_content_for_update_check(file)
56
+ content = file.content
57
+
58
+ unless dependency_appears_in_file?(file.name)
59
+ return sanitize_mixfile(content)
60
+ end
61
+
62
+ content = relax_version(content, filename: file.name)
63
+ if replace_git_pin?
64
+ content = replace_git_pin(content, filename: file.name)
65
+ end
66
+
67
+ sanitize_mixfile(content)
68
+ end
69
+
70
+ def relax_version(content, filename:)
71
+ old_requirement =
72
+ dependency.requirements.find { |r| r.fetch(:file) == filename }.
73
+ fetch(:requirement)
74
+
75
+ FileUpdaters::Elixir::Hex::MixfileRequirementUpdater.new(
76
+ dependency_name: dependency.name,
77
+ mixfile_content: content,
78
+ previous_requirement: old_requirement,
79
+ updated_requirement: updated_version_requirement_string(filename),
80
+ insert_if_bare: true
81
+ ).updated_content
82
+ end
83
+
84
+ def updated_version_requirement_string(filename)
85
+ lower_bound_req = updated_version_req_lower_bound(filename)
86
+
87
+ return lower_bound_req if latest_allowable_version.nil?
88
+ unless version_class.correct?(latest_allowable_version)
89
+ return lower_bound_req
90
+ end
91
+
92
+ lower_bound_req + " and <= #{latest_allowable_version}"
93
+ end
94
+
95
+ # rubocop:disable Metrics/AbcSize
96
+ # rubocop:disable Metrics/PerceivedComplexity
97
+ def updated_version_req_lower_bound(filename)
98
+ original_req = dependency.requirements.
99
+ find { |r| r.fetch(:file) == filename }&.
100
+ fetch(:requirement)
101
+
102
+ if original_req && !unlock_requirement? then original_req
103
+ elsif dependency.version&.match?(/^[0-9a-f]{40}$/) then ">= 0"
104
+ elsif dependency.version then ">= #{dependency.version}"
105
+ else
106
+ version_for_requirement =
107
+ dependency.requirements.map { |r| r[:requirement] }.compact.
108
+ reject { |req_string| req_string.start_with?("<") }.
109
+ select { |req_string| req_string.match?(version_regex) }.
110
+ map { |req_string| req_string.match(version_regex) }.
111
+ select { |version| version_class.correct?(version.to_s) }.
112
+ max_by { |version| version_class.new(version.to_s) }
113
+
114
+ return ">= 0" unless version_for_requirement
115
+
116
+ # Elixir requires that versions are specified to three places
117
+ # when used with a >= specifier
118
+ parts = version_for_requirement.to_s.split(".")
119
+ parts << "0" while parts.count < 3
120
+ ">= #{parts.join('.')}"
121
+ end
122
+ end
123
+ # rubocop:enable Metrics/AbcSize
124
+ # rubocop:enable Metrics/PerceivedComplexity
125
+
126
+ def replace_git_pin(content, filename:)
127
+ old_pin =
128
+ dependency.requirements.find { |r| r.fetch(:file) == filename }&.
129
+ dig(:source, :ref)
130
+
131
+ return content unless old_pin
132
+ return content if old_pin == replacement_git_pin
133
+
134
+ FileUpdaters::Elixir::Hex::MixfileGitPinUpdater.new(
135
+ dependency_name: dependency.name,
136
+ mixfile_content: content,
137
+ previous_pin: old_pin,
138
+ updated_pin: replacement_git_pin
139
+ ).updated_content
140
+ end
141
+
142
+ def sanitize_mixfile(content)
143
+ FileUpdaters::Elixir::Hex::MixfileSanitizer.new(
144
+ mixfile_content: content
145
+ ).sanitized_content
146
+ end
147
+
148
+ def mixfiles
149
+ mixfiles =
150
+ dependency_files.
151
+ select { |f| f.name.end_with?("mix.exs") }
152
+ raise "No mix.exs!" if mixfiles.none?
153
+
154
+ mixfiles
155
+ end
156
+
157
+ def lockfile
158
+ @lockfile ||= dependency_files.find { |f| f.name == "mix.lock" }
159
+ end
160
+
161
+ def support_files
162
+ @support_files ||= dependency_files.select(&:support_file)
163
+ end
164
+
165
+ def wants_prerelease?
166
+ current_version = dependency.version
167
+ if current_version &&
168
+ version_class.correct?(current_version) &&
169
+ version_class.new(current_version).prerelease?
170
+ return true
171
+ end
172
+
173
+ dependency.requirements.any? do |req|
174
+ req[:requirement].match?(/\d-[A-Za-z0-9]/)
175
+ end
176
+ end
177
+
178
+ def version_class
179
+ Utils::Elixir::Version
180
+ end
181
+
182
+ def version_regex
183
+ version_class::VERSION_PATTERN
184
+ end
185
+
186
+ def dependency_appears_in_file?(file_name)
187
+ dependency.requirements.any? { |r| r[:file] == file_name }
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/utils/elixir/version"
4
+ require "dependabot/utils/elixir/requirement"
5
+ require "dependabot/update_checkers/elixir/hex"
6
+
7
+ module Dependabot
8
+ module UpdateCheckers
9
+ module Elixir
10
+ class Hex
11
+ class RequirementsUpdater
12
+ OPERATORS = />=|<=|>|<|==|~>/.freeze
13
+ AND_SEPARATOR = /\s+and\s+/.freeze
14
+ OR_SEPARATOR = /\s+or\s+/.freeze
15
+ SEPARATOR = /#{AND_SEPARATOR}|#{OR_SEPARATOR}/.freeze
16
+
17
+ def initialize(requirements:, latest_resolvable_version:,
18
+ updated_source:)
19
+ @requirements = requirements
20
+ @updated_source = updated_source
21
+
22
+ return unless latest_resolvable_version
23
+ unless Utils::Elixir::Version.correct?(latest_resolvable_version)
24
+ return
25
+ end
26
+
27
+ @latest_resolvable_version =
28
+ Utils::Elixir::Version.new(latest_resolvable_version)
29
+ end
30
+
31
+ def updated_requirements
32
+ requirements.map { |req| updated_mixfile_requirement(req) }
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :requirements, :latest_resolvable_version, :updated_source
38
+
39
+ # rubocop:disable Metrics/AbcSize
40
+ # rubocop:disable PerceivedComplexity
41
+ def updated_mixfile_requirement(req)
42
+ req = update_source(req)
43
+ return req unless latest_resolvable_version && req[:requirement]
44
+ return req if req_satisfied_by_latest_resolvable?(req[:requirement])
45
+
46
+ or_string_reqs = req[:requirement].split(OR_SEPARATOR)
47
+ last_string_reqs = or_string_reqs.last.split(AND_SEPARATOR).
48
+ map(&:strip)
49
+
50
+ new_requirement =
51
+ if last_string_reqs.any? { |r| r.match(/^(?:\d|=)/) }
52
+ exact_req = last_string_reqs.find { |r| r.match(/^(?:\d|=)/) }
53
+ update_exact_version(exact_req, latest_resolvable_version).to_s
54
+ elsif last_string_reqs.any? { |r| r.start_with?("~>") }
55
+ tw_req = last_string_reqs.find { |r| r.start_with?("~>") }
56
+ update_twiddle_version(tw_req, latest_resolvable_version).to_s
57
+ else
58
+ update_mixfile_range(last_string_reqs).map(&:to_s).join(" and ")
59
+ end
60
+
61
+ if or_string_reqs.count > 1
62
+ new_requirement = req[:requirement] + " or " + new_requirement
63
+ end
64
+
65
+ req.merge(requirement: new_requirement)
66
+ end
67
+ # rubocop:enable Metrics/AbcSize
68
+ # rubocop:enable PerceivedComplexity
69
+
70
+ def update_source(requirement_hash)
71
+ # Only git sources ever need to be updated. Anything else should be
72
+ # left alone.
73
+ unless requirement_hash.dig(:source, :type) == "git"
74
+ return requirement_hash
75
+ end
76
+
77
+ requirement_hash.merge(source: updated_source)
78
+ end
79
+
80
+ def req_satisfied_by_latest_resolvable?(requirement_string)
81
+ ruby_requirements(requirement_string).
82
+ any? { |r| r.satisfied_by?(latest_resolvable_version) }
83
+ end
84
+
85
+ def ruby_requirements(requirement_string)
86
+ requirement_class.requirements_array(requirement_string)
87
+ end
88
+
89
+ def update_exact_version(previous_req, new_version)
90
+ op = previous_req.match(OPERATORS).to_s
91
+ old_version =
92
+ Utils::Elixir::Version.new(previous_req.gsub(OPERATORS, ""))
93
+ updated_version = at_same_precision(new_version, old_version)
94
+ "#{op} #{updated_version}".strip
95
+ end
96
+
97
+ def update_twiddle_version(previous_req, new_version)
98
+ previous_req = requirement_class.new(previous_req)
99
+ old_version = previous_req.requirements.first.last
100
+ updated_version = at_same_precision(new_version, old_version)
101
+ requirement_class.new("~> #{updated_version}")
102
+ end
103
+
104
+ def update_mixfile_range(requirements)
105
+ requirements = requirements.map { |r| requirement_class.new(r) }
106
+ updated_requirements =
107
+ requirements.flat_map do |r|
108
+ next r if r.satisfied_by?(latest_resolvable_version)
109
+
110
+ case op = r.requirements.first.first
111
+ when "<", "<="
112
+ [update_greatest_version(r, latest_resolvable_version)]
113
+ when "!="
114
+ []
115
+ else
116
+ raise "Unexpected operation for unsatisfied Gemfile "\
117
+ "requirement: #{op}"
118
+ end
119
+ end
120
+
121
+ binding_requirements(updated_requirements)
122
+ end
123
+
124
+ def at_same_precision(new_version, old_version)
125
+ precision = old_version.to_s.split(".").count
126
+ new_version.to_s.split(".").first(precision).join(".")
127
+ end
128
+
129
+ # Updates the version in a "<" or "<=" constraint to allow the given
130
+ # version
131
+ def update_greatest_version(requirement, version_to_be_permitted)
132
+ if version_to_be_permitted.is_a?(String)
133
+ version_to_be_permitted =
134
+ Utils::Elixir::Version.new(version_to_be_permitted)
135
+ end
136
+ op, version = requirement.requirements.first
137
+ version = version.release if version.prerelease?
138
+
139
+ index_to_update =
140
+ version.segments.map.with_index { |seg, i| seg.zero? ? 0 : i }.max
141
+
142
+ new_segments = version.segments.map.with_index do |_, index|
143
+ if index < index_to_update
144
+ version_to_be_permitted.segments[index]
145
+ elsif index == index_to_update
146
+ version_to_be_permitted.segments[index] + 1
147
+ else 0
148
+ end
149
+ end
150
+
151
+ requirement_class.new("#{op} #{new_segments.join('.')}")
152
+ end
153
+
154
+ def binding_requirements(requirements)
155
+ grouped_by_operator =
156
+ requirements.group_by { |r| r.requirements.first.first }
157
+
158
+ binding_reqs = grouped_by_operator.flat_map do |operator, reqs|
159
+ case operator
160
+ when "<", "<=" then reqs.min_by { |r| r.requirements.first.last }
161
+ when ">", ">=" then reqs.max_by { |r| r.requirements.first.last }
162
+ else requirements
163
+ end
164
+ end.uniq
165
+
166
+ binding_reqs << requirement_class.new if binding_reqs.empty?
167
+ binding_reqs.sort_by { |r| r.requirements.first.last }
168
+ end
169
+
170
+ def requirement_class
171
+ Utils::Elixir::Requirement
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/utils/elixir/version"
4
+ require "dependabot/update_checkers/elixir/hex"
5
+ require "dependabot/shared_helpers"
6
+ require "dependabot/errors"
7
+
8
+ module Dependabot
9
+ module UpdateCheckers
10
+ module Elixir
11
+ class Hex
12
+ class VersionResolver
13
+ def initialize(dependency:, credentials:,
14
+ original_dependency_files:, prepared_dependency_files:)
15
+ @dependency = dependency
16
+ @original_dependency_files = original_dependency_files
17
+ @prepared_dependency_files = prepared_dependency_files
18
+ @credentials = credentials
19
+ end
20
+
21
+ def latest_resolvable_version
22
+ @latest_resolvable_version ||= fetch_latest_resolvable_version
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :dependency, :credentials,
28
+ :original_dependency_files, :prepared_dependency_files
29
+
30
+ def fetch_latest_resolvable_version
31
+ latest_resolvable_version =
32
+ SharedHelpers.in_a_temporary_directory do
33
+ write_temporary_dependency_files
34
+ FileUtils.cp(
35
+ elixir_helper_check_update_path,
36
+ "check_update.exs"
37
+ )
38
+
39
+ SharedHelpers.with_git_configured(credentials: credentials) do
40
+ run_elixir_update_checker
41
+ end
42
+ end
43
+
44
+ return if latest_resolvable_version.nil?
45
+ if latest_resolvable_version.match?(/^[0-9a-f]{40}$/)
46
+ return latest_resolvable_version
47
+ end
48
+
49
+ version_class.new(latest_resolvable_version)
50
+ rescue SharedHelpers::HelperSubprocessFailed => error
51
+ handle_hex_errors(error)
52
+ end
53
+
54
+ def run_elixir_update_checker
55
+ SharedHelpers.run_helper_subprocess(
56
+ env: mix_env,
57
+ command: "mix run #{elixir_helper_path}",
58
+ function: "get_latest_resolvable_version",
59
+ args: [Dir.pwd,
60
+ dependency.name,
61
+ organization_credentials],
62
+ popen_opts: { err: %i(child out) }
63
+ )
64
+ end
65
+
66
+ def handle_hex_errors(error)
67
+ if error.message.include?("No authenticated organization found")
68
+ org = error.message.match(/found for ([a-z_]+)\./).captures.first
69
+ raise Dependabot::PrivateSourceAuthenticationFailure, org
70
+ end
71
+
72
+ if error.message.include?("Failed to fetch record for")
73
+ org_match = error.message.match(%r{for 'hexpm:([a-z_]+)/})
74
+ org = org_match&.captures&.first
75
+ raise Dependabot::PrivateSourceAuthenticationFailure, org if org
76
+ end
77
+
78
+ # TODO: This isn't pretty. It would be much nicer to catch the
79
+ # warnings as part of the Elixir module.
80
+ return error_result(error) if includes_result?(error)
81
+
82
+ # Ignore dependencies which don't resolve due to mis-matching
83
+ # environment specifications.
84
+ # TODO: Update the environment specifications instead
85
+ return if error.message.include?("Dependencies have diverged")
86
+
87
+ check_original_requirements_resolvable
88
+ raise error
89
+ end
90
+
91
+ def error_result(error)
92
+ return false unless includes_result?(error)
93
+
94
+ result_json = error.message&.split("\n")&.last
95
+ result = JSON.parse(result_json)["result"]
96
+ return version_class.new(result) if version_class.correct?(result)
97
+
98
+ result
99
+ end
100
+
101
+ def includes_result?(error)
102
+ result = error.message&.split("\n")&.last
103
+ return false unless result
104
+
105
+ JSON.parse(error.message&.split("\n")&.last)["result"]
106
+ true
107
+ rescue JSON::ParserError
108
+ false
109
+ end
110
+
111
+ def check_original_requirements_resolvable
112
+ SharedHelpers.in_a_temporary_directory do
113
+ write_temporary_dependency_files(prepared: false)
114
+ FileUtils.cp(
115
+ elixir_helper_check_update_path,
116
+ "check_update.exs"
117
+ )
118
+
119
+ SharedHelpers.with_git_configured(credentials: credentials) do
120
+ run_elixir_update_checker
121
+ end
122
+ end
123
+
124
+ true
125
+ rescue SharedHelpers::HelperSubprocessFailed => error
126
+ raise Dependabot::DependencyFileNotResolvable, error.message
127
+ end
128
+
129
+ def write_temporary_dependency_files(prepared: true)
130
+ files = if prepared then prepared_dependency_files
131
+ else original_dependency_files
132
+ end
133
+
134
+ files.each do |file|
135
+ path = file.name
136
+ FileUtils.mkdir_p(Pathname.new(path).dirname)
137
+ File.write(path, file.content)
138
+ end
139
+ end
140
+
141
+ def version_class
142
+ Utils::Elixir::Version
143
+ end
144
+
145
+ def mix_env
146
+ {
147
+ "MIX_EXS" => File.join(project_root, "helpers/elixir/mix.exs"),
148
+ "MIX_LOCK" => File.join(project_root, "helpers/elixir/mix.lock"),
149
+ "MIX_DEPS" => File.join(project_root, "helpers/elixir/deps"),
150
+ "MIX_QUIET" => "1"
151
+ }
152
+ end
153
+
154
+ def elixir_helper_path
155
+ File.join(project_root, "helpers/elixir/bin/run.exs")
156
+ end
157
+
158
+ def elixir_helper_check_update_path
159
+ File.join(project_root, "helpers/elixir/bin/check_update.exs")
160
+ end
161
+
162
+ def project_root
163
+ File.join(File.dirname(__FILE__), "../../../../..")
164
+ end
165
+
166
+ def organization_credentials
167
+ credentials.
168
+ select { |cred| cred["type"] == "hex_organization" }.
169
+ flat_map { |cred| [cred["organization"], cred["token"]] }
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end