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,227 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "excon"
4
+ require "toml-rb"
5
+
6
+ require "python_requirement_parser"
7
+ require "dependabot/update_checkers/base"
8
+ require "dependabot/shared_helpers"
9
+ require "dependabot/utils/python/requirement"
10
+
11
+ module Dependabot
12
+ module UpdateCheckers
13
+ module Python
14
+ class Pip < Dependabot::UpdateCheckers::Base
15
+ require_relative "pip/poetry_version_resolver"
16
+ require_relative "pip/pipfile_version_resolver"
17
+ require_relative "pip/pip_compile_version_resolver"
18
+ require_relative "pip/requirements_updater"
19
+ require_relative "pip/latest_version_finder"
20
+
21
+ MAIN_PYPI_INDEXES = %w(
22
+ https://pypi.python.org/simple/
23
+ https://pypi.org/simple/
24
+ ).freeze
25
+
26
+ def latest_version
27
+ @latest_version ||= fetch_latest_version
28
+ end
29
+
30
+ def latest_resolvable_version
31
+ @latest_resolvable_version ||=
32
+ case resolver_type
33
+ when :pipfile
34
+ PipfileVersionResolver.new(
35
+ resolver_args.merge(unlock_requirement: true)
36
+ ).latest_resolvable_version
37
+ when :poetry
38
+ PoetryVersionResolver.new(
39
+ resolver_args.merge(unlock_requirement: true)
40
+ ).latest_resolvable_version
41
+ when :pip_compile
42
+ PipCompileVersionResolver.new(
43
+ resolver_args.merge(unlock_requirement: true)
44
+ ).latest_resolvable_version
45
+ when :requirements
46
+ # pip doesn't (yet) do any dependency resolution, so if we don't
47
+ # have a Pipfile or a pip-compile file, we just return the latest
48
+ # version.
49
+ latest_version
50
+ else raise "Unexpected resolver type #{resolver_type}"
51
+ end
52
+ end
53
+
54
+ def latest_resolvable_version_with_no_unlock
55
+ @latest_resolvable_version_with_no_unlock ||=
56
+ case resolver_type
57
+ when :pipfile
58
+ PipfileVersionResolver.new(
59
+ resolver_args.merge(unlock_requirement: false)
60
+ ).latest_resolvable_version
61
+ when :poetry
62
+ PoetryVersionResolver.new(
63
+ resolver_args.merge(unlock_requirement: false)
64
+ ).latest_resolvable_version
65
+ when :pip_compile
66
+ PipCompileVersionResolver.new(
67
+ resolver_args.merge(unlock_requirement: false)
68
+ ).latest_resolvable_version
69
+ when :requirements
70
+ latest_pip_version_with_no_unlock
71
+ else raise "Unexpected resolver type #{resolver_type}"
72
+ end
73
+ end
74
+
75
+ def updated_requirements
76
+ RequirementsUpdater.new(
77
+ requirements: dependency.requirements,
78
+ latest_version: latest_version&.to_s,
79
+ latest_resolvable_version: latest_resolvable_version&.to_s,
80
+ update_strategy: requirements_update_strategy,
81
+ has_lockfile: pipfile_lock || poetry_lock || pyproject_lock
82
+ ).updated_requirements
83
+ end
84
+
85
+ def requirements_update_strategy
86
+ # If passed in as an option (in the base class) honour that option
87
+ if @requirements_update_strategy
88
+ return @requirements_update_strategy.to_sym
89
+ end
90
+
91
+ # Otherwise, check if this is a poetry library or not
92
+ poetry_library? ? :widen_ranges : :bump_versions
93
+ end
94
+
95
+ private
96
+
97
+ def latest_version_resolvable_with_full_unlock?
98
+ # Full unlock checks aren't implemented for pip because they're not
99
+ # relevant (pip doesn't have a resolver). This method always returns
100
+ # false to ensure `updated_dependencies_after_full_unlock` is never
101
+ # called.
102
+ false
103
+ end
104
+
105
+ def updated_dependencies_after_full_unlock
106
+ raise NotImplementedError
107
+ end
108
+
109
+ # rubocop:disable Metrics/PerceivedComplexity
110
+ def resolver_type
111
+ reqs = dependency.requirements
112
+ req_files = reqs.map { |r| r.fetch(:file) }
113
+
114
+ # If there are no requirements then this is a sub-dependency. It
115
+ # must come from one of Pipenv, Poetry or pip-tools, and can't come
116
+ # from the first two unless they have a lockfile.
117
+ return subdependency_resolver if reqs.none?
118
+
119
+ # Otherwise, this is a top-level dependency, and we can figure out
120
+ # which resolver to use based on the filename of its requirements
121
+ return :pipfile if req_files.any? { |f| f == "Pipfile" }
122
+ return :poetry if req_files.any? { |f| f == "pyproject.toml" }
123
+ return :pip_compile if req_files.any? { |f| f.end_with?(".in") }
124
+
125
+ if dependency.version && !exact_requirement?(reqs)
126
+ subdependency_resolver
127
+ else
128
+ :requirements
129
+ end
130
+ end
131
+ # rubocop:enable Metrics/PerceivedComplexity
132
+
133
+ def subdependency_resolver
134
+ return :pipfile if pipfile_lock
135
+ return :poetry if poetry_lock || pyproject_lock
136
+ return :pip_compile if pip_compile_files.any?
137
+
138
+ raise "Claimed to be a sub-dependency, but no lockfile exists!"
139
+ end
140
+
141
+ def exact_requirement?(reqs)
142
+ reqs = reqs.map { |r| r.fetch(:requirement) }
143
+ reqs = reqs.compact
144
+ reqs = reqs.flat_map { |r| r.split(",").map(&:strip) }
145
+ reqs.any? { |r| Utils::Python::Requirement.new(r).exact? }
146
+ end
147
+
148
+ def resolver_args
149
+ {
150
+ dependency: dependency,
151
+ dependency_files: dependency_files,
152
+ credentials: credentials,
153
+ latest_allowable_version: latest_version
154
+ }
155
+ end
156
+
157
+ def fetch_latest_version
158
+ latest_version_finder.latest_version
159
+ end
160
+
161
+ def latest_pip_version_with_no_unlock
162
+ latest_version_finder.latest_version_with_no_unlock
163
+ end
164
+
165
+ def latest_version_finder
166
+ @latest_version_finder ||= LatestVersionFinder.new(
167
+ dependency: dependency,
168
+ dependency_files: dependency_files,
169
+ credentials: credentials,
170
+ ignored_versions: ignored_versions
171
+ )
172
+ end
173
+
174
+ def poetry_library?
175
+ return false unless pyproject
176
+
177
+ # Hit PyPi and check whether there are details for a library with a
178
+ # matching name and description
179
+ details = TomlRB.parse(pyproject.content).dig("tool", "poetry")
180
+ return false unless details
181
+
182
+ index_response = Excon.get(
183
+ "https://pypi.org/pypi/#{normalised_name(details['name'])}/json",
184
+ idempotent: true,
185
+ **SharedHelpers.excon_defaults
186
+ )
187
+
188
+ return false unless index_response.status == 200
189
+
190
+ pypi_info = JSON.parse(index_response.body)["info"] || {}
191
+ pypi_info["summary"] == details["description"]
192
+ rescue URI::InvalidURIError
193
+ false
194
+ end
195
+
196
+ # See https://www.python.org/dev/peps/pep-0503/#normalized-names
197
+ def normalised_name(name)
198
+ name.downcase.gsub(/[-_.]+/, "-")
199
+ end
200
+
201
+ def pipfile
202
+ dependency_files.find { |f| f.name == "Pipfile" }
203
+ end
204
+
205
+ def pipfile_lock
206
+ dependency_files.find { |f| f.name == "Pipfile.lock" }
207
+ end
208
+
209
+ def pyproject
210
+ dependency_files.find { |f| f.name == "pyproject.toml" }
211
+ end
212
+
213
+ def pyproject_lock
214
+ dependency_files.find { |f| f.name == "pyproject.lock" }
215
+ end
216
+
217
+ def poetry_lock
218
+ dependency_files.find { |f| f.name == "poetry.lock" }
219
+ end
220
+
221
+ def pip_compile_files
222
+ dependency_files.select { |f| f.name.end_with?(".in") }
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,252 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "excon"
4
+
5
+ require "dependabot/update_checkers/python/pip"
6
+ require "dependabot/shared_helpers"
7
+
8
+ module Dependabot
9
+ module UpdateCheckers
10
+ module Python
11
+ class Pip
12
+ class LatestVersionFinder
13
+ def initialize(dependency:, dependency_files:, credentials:,
14
+ ignored_versions:)
15
+ @dependency = dependency
16
+ @dependency_files = dependency_files
17
+ @credentials = credentials
18
+ @ignored_versions = ignored_versions
19
+ end
20
+
21
+ def latest_version
22
+ @latest_version ||= fetch_latest_version
23
+ end
24
+
25
+ def latest_version_with_no_unlock
26
+ @latest_version_with_no_unlock ||=
27
+ fetch_latest_version_with_no_unlock
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :dependency, :dependency_files, :credentials,
33
+ :ignored_versions
34
+
35
+ def fetch_latest_version
36
+ versions = available_versions
37
+ versions.reject! { |v| ignore_reqs.any? { |r| r.satisfied_by?(v) } }
38
+ versions.reject!(&:prerelease?) unless wants_prerelease?
39
+ versions.max
40
+ end
41
+
42
+ def fetch_latest_version_with_no_unlock
43
+ versions = available_versions
44
+ reqs = dependency.requirements.map do |r|
45
+ reqs = (r.fetch(:requirement) || "").split(",").map(&:strip)
46
+ requirement_class.new(reqs)
47
+ end
48
+ versions.reject!(&:prerelease?) unless wants_prerelease?
49
+ versions.sort.reverse.
50
+ reject { |v| ignore_reqs.any? { |r| r.satisfied_by?(v) } }.
51
+ find { |v| reqs.all? { |r| r.satisfied_by?(v) } }
52
+ end
53
+
54
+ def wants_prerelease?
55
+ if dependency.version
56
+ version = version_class.new(dependency.version.tr("+", "."))
57
+ return version.prerelease?
58
+ end
59
+
60
+ dependency.requirements.any? do |req|
61
+ reqs = (req.fetch(:requirement) || "").split(",").map(&:strip)
62
+ reqs.any? { |r| r.match?(/[A-Za-z]/) }
63
+ end
64
+ end
65
+
66
+ # See https://www.python.org/dev/peps/pep-0503/ for details of the
67
+ # Simple Repository API we use here.
68
+ def available_versions
69
+ index_urls.flat_map do |index_url|
70
+ sanitized_url = index_url.gsub(%r{(?<=//).*(?=@)}, "redacted")
71
+ index_response = registry_response_for_dependency(index_url)
72
+
73
+ if [401, 403].include?(index_response.status) &&
74
+ [401, 403].include?(registry_index_response(index_url).status)
75
+ raise PrivateSourceAuthenticationFailure, sanitized_url
76
+ end
77
+
78
+ index_response.body.
79
+ scan(%r{<a\s.*?>(.*?)</a>}m).flatten.
80
+ select { |n| n.match?(name_regex) }.
81
+ map do |filename|
82
+ version =
83
+ filename.
84
+ gsub(/#{name_regex}-/i, "").
85
+ split(/-|(\.tar\.)/).
86
+ first
87
+ next unless version_class.correct?(version)
88
+
89
+ version_class.new(version)
90
+ end.compact
91
+ rescue Excon::Error::Timeout, Excon::Error::Socket
92
+ next if MAIN_PYPI_INDEXES.include?(index_url)
93
+
94
+ raise PrivateSourceAuthenticationFailure, sanitized_url
95
+ end
96
+ end
97
+
98
+ def index_urls
99
+ main_index_url =
100
+ config_variable_index_urls[:main] ||
101
+ pipfile_index_urls[:main] ||
102
+ requirement_file_index_urls[:main] ||
103
+ pip_conf_index_urls[:main] ||
104
+ "https://pypi.python.org/simple/"
105
+
106
+ if main_index_url
107
+ main_index_url = main_index_url.strip.gsub(%r{/*$}, "") + "/"
108
+ end
109
+
110
+ extra_index_urls =
111
+ config_variable_index_urls[:extra] +
112
+ pipfile_index_urls[:extra] +
113
+ requirement_file_index_urls[:extra] +
114
+ pip_conf_index_urls[:extra]
115
+
116
+ extra_index_urls =
117
+ extra_index_urls.map { |url| url.strip.gsub(%r{/*$}, "") + "/" }
118
+
119
+ [main_index_url, *extra_index_urls].uniq
120
+ end
121
+
122
+ def registry_response_for_dependency(index_url)
123
+ Excon.get(
124
+ index_url + normalised_name + "/",
125
+ idempotent: true,
126
+ **SharedHelpers.excon_defaults
127
+ )
128
+ end
129
+
130
+ def registry_index_response(index_url)
131
+ Excon.get(
132
+ index_url,
133
+ idempotent: true,
134
+ **SharedHelpers.excon_defaults
135
+ )
136
+ end
137
+
138
+ def requirement_file_index_urls
139
+ urls = { main: nil, extra: [] }
140
+
141
+ requirements_files.each do |file|
142
+ if file.content.match?(/^--index-url\s(.+)/)
143
+ urls[:main] =
144
+ file.content.match(/^--index-url\s(.+)/).captures.first
145
+ end
146
+ urls[:extra] += file.content.scan(/^--extra-index-url\s(.+)/).
147
+ flatten
148
+ end
149
+
150
+ urls
151
+ end
152
+
153
+ def pip_conf_index_urls
154
+ urls = { main: nil, extra: [] }
155
+
156
+ return urls unless pip_conf
157
+
158
+ content = pip_conf.content
159
+
160
+ if content.match?(/^index-url\s*=/x)
161
+ urls[:main] = content.match(/^index-url\s*=\s*(.+)/).
162
+ captures.first
163
+ end
164
+ urls[:extra] += content.scan(/^extra-index-url\s*=(.+)/).flatten
165
+
166
+ urls
167
+ end
168
+
169
+ def pipfile_index_urls
170
+ urls = { main: nil, extra: [] }
171
+
172
+ return urls unless pipfile
173
+
174
+ pipfile_object = TomlRB.parse(pipfile.content)
175
+
176
+ urls[:main] = pipfile_object["source"]&.first&.fetch("url", nil)
177
+
178
+ pipfile_object["source"]&.each do |source|
179
+ urls[:extra] << source.fetch("url") if source["url"]
180
+ end
181
+ urls[:extra] = urls[:extra].uniq
182
+
183
+ urls
184
+ rescue TomlRB::ParseError
185
+ urls
186
+ end
187
+
188
+ def config_variable_index_urls
189
+ urls = { main: nil, extra: [] }
190
+
191
+ index_url_creds = credentials.
192
+ select { |cred| cred["type"] == "python_index" }
193
+ urls[:main] =
194
+ index_url_creds.
195
+ find { |cred| cred["replaces-base"] }&.
196
+ fetch("index-url")
197
+ urls[:extra] =
198
+ index_url_creds.
199
+ reject { |cred| cred["replaces-base"] }.
200
+ map { |cred| cred["index-url"] }
201
+
202
+ urls
203
+ end
204
+
205
+ def ignore_reqs
206
+ ignored_versions.map { |req| requirement_class.new(req.split(",")) }
207
+ end
208
+
209
+ # See https://www.python.org/dev/peps/pep-0503/#normalized-names
210
+ def normalised_name
211
+ dependency.name.downcase.gsub(/[-_.]+/, "-")
212
+ end
213
+
214
+ def name_regex
215
+ parts = dependency.name.split(/[\s_.-]/).map { |n| Regexp.quote(n) }
216
+ /#{parts.join("[\s_.-]")}/i
217
+ end
218
+
219
+ def pip_conf
220
+ dependency_files.find { |f| f.name == "pip.conf" }
221
+ end
222
+
223
+ def pipfile
224
+ dependency_files.find { |f| f.name == "Pipfile" }
225
+ end
226
+
227
+ def pyproject
228
+ dependency_files.find { |f| f.name == "pyproject.toml" }
229
+ end
230
+
231
+ def requirements_files
232
+ dependency_files.select { |f| f.name.match?(/requirements/x) }
233
+ end
234
+
235
+ def pip_compile_files
236
+ dependency_files.select { |f| f.name.end_with?(".in") }
237
+ end
238
+
239
+ def version_class
240
+ Utils.version_class_for_package_manager(dependency.package_manager)
241
+ end
242
+
243
+ def requirement_class
244
+ Utils.requirement_class_for_package_manager(
245
+ dependency.package_manager
246
+ )
247
+ end
248
+ end
249
+ end
250
+ end
251
+ end
252
+ end