dependabot-core 0.87.15 → 0.88.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/dependabot/file_fetchers.rb +0 -2
  4. data/lib/dependabot/file_parsers.rb +0 -2
  5. data/lib/dependabot/file_updaters.rb +0 -2
  6. data/lib/dependabot/metadata_finders.rb +0 -2
  7. data/lib/dependabot/pull_request_creator/message_builder.rb +1 -1
  8. data/lib/dependabot/update_checkers.rb +0 -2
  9. data/lib/dependabot/update_checkers/php/composer/version_resolver.rb +3 -2
  10. data/lib/dependabot/utils.rb +0 -4
  11. data/lib/dependabot/version.rb +1 -1
  12. metadata +1 -22
  13. data/helpers/elixir/bin/check_update.exs +0 -92
  14. data/helpers/elixir/bin/do_update.exs +0 -39
  15. data/helpers/elixir/bin/parse_deps.exs +0 -103
  16. data/helpers/elixir/bin/run.exs +0 -76
  17. data/helpers/elixir/mix.exs +0 -21
  18. data/helpers/elixir/mix.lock +0 -3
  19. data/lib/dependabot/file_fetchers/elixir/hex.rb +0 -78
  20. data/lib/dependabot/file_parsers/elixir/hex.rb +0 -134
  21. data/lib/dependabot/file_updaters/elixir/hex.rb +0 -71
  22. data/lib/dependabot/file_updaters/elixir/hex/lockfile_updater.rb +0 -147
  23. data/lib/dependabot/file_updaters/elixir/hex/mixfile_git_pin_updater.rb +0 -53
  24. data/lib/dependabot/file_updaters/elixir/hex/mixfile_requirement_updater.rb +0 -74
  25. data/lib/dependabot/file_updaters/elixir/hex/mixfile_sanitizer.rb +0 -28
  26. data/lib/dependabot/file_updaters/elixir/hex/mixfile_updater.rb +0 -98
  27. data/lib/dependabot/metadata_finders/elixir/hex.rb +0 -69
  28. data/lib/dependabot/update_checkers/elixir/hex.rb +0 -274
  29. data/lib/dependabot/update_checkers/elixir/hex/file_preparer.rb +0 -193
  30. data/lib/dependabot/update_checkers/elixir/hex/requirements_updater.rb +0 -177
  31. data/lib/dependabot/update_checkers/elixir/hex/version_resolver.rb +0 -175
  32. data/lib/dependabot/utils/elixir/requirement.rb +0 -54
  33. data/lib/dependabot/utils/elixir/version.rb +0 -66
@@ -1,76 +0,0 @@
1
- defmodule DependencyHelper do
2
- def main() do
3
- IO.read(:stdio, :all)
4
- |> Jason.decode!()
5
- |> run()
6
- |> case do
7
- {output, 0} ->
8
- if output =~ "No authenticated organization found" do
9
- {:error, output}
10
- else
11
- {:ok, :erlang.binary_to_term(output)}
12
- end
13
-
14
- {error, 1} -> {:error, error}
15
- end
16
- |> handle_result()
17
- end
18
-
19
- defp handle_result({:ok, {:ok, result}}) do
20
- encode_and_write(%{"result" => result})
21
- end
22
-
23
- defp handle_result({:ok, {:error, reason}}) do
24
- encode_and_write(%{"error" => reason})
25
- System.halt(1)
26
- end
27
-
28
- defp handle_result({:error, reason}) do
29
- encode_and_write(%{"error" => reason})
30
- System.halt(1)
31
- end
32
-
33
- defp encode_and_write(content) do
34
- content
35
- |> Jason.encode!()
36
- |> IO.write()
37
- end
38
-
39
- defp run(%{"function" => "parse", "args" => [dir]}) do
40
- run_script("parse_deps.exs", dir)
41
- end
42
-
43
- defp run(%{"function" => "get_latest_resolvable_version", "args" => [dir, dependency_name, credentials]}) do
44
- run_script("check_update.exs", dir, [dependency_name] ++ credentials)
45
- end
46
-
47
- defp run(%{"function" => "get_updated_lockfile", "args" => [dir, dependency_name, credentials]}) do
48
- run_script("do_update.exs", dir, [dependency_name] ++ credentials)
49
- end
50
-
51
- defp run_script(script, dir, args \\ []) do
52
- args = [
53
- "run",
54
- "--no-deps-check",
55
- "--no-start",
56
- "--no-compile",
57
- "--no-elixir-version-check",
58
- script
59
- ] ++ args
60
-
61
- System.cmd(
62
- "mix",
63
- args,
64
- [
65
- cd: dir,
66
- env: %{
67
- "MIX_EXS" => nil,
68
- "MIX_LOCK" => nil,
69
- "MIX_DEPS" => nil
70
- }
71
- ]
72
- )
73
- end
74
- end
75
-
76
- DependencyHelper.main()
@@ -1,21 +0,0 @@
1
- defmodule DependabotCore.Mixfile do
2
- use Mix.Project
3
-
4
- def project do
5
- [app: :dependabot_core,
6
- version: "0.1.0",
7
- elixir: "~> 1.5",
8
- start_permanent: Mix.env == :prod,
9
- lockfile: System.get_env("MIX_LOCK") || "mix.lock",
10
- deps_path: System.get_env("MIX_DEPS") || "deps",
11
- deps: deps()]
12
- end
13
-
14
- def application do
15
- [extra_applications: [:logger]]
16
- end
17
-
18
- defp deps() do
19
- [{:jason, "~> 1.0-rc"}]
20
- end
21
- end
@@ -1,3 +0,0 @@
1
- %{
2
- "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
3
- }
@@ -1,78 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_fetchers/base"
4
-
5
- module Dependabot
6
- module FileFetchers
7
- module Elixir
8
- class Hex < Dependabot::FileFetchers::Base
9
- APPS_PATH_REGEX = /apps_path:\s*"(?<path>.*?)"/m.freeze
10
- STRING_ARG = %{(?:["'](.*?)["'])}
11
- EVAL_FILE = /Code\.eval_file\(#{STRING_ARG}(?:\s*,\s*#{STRING_ARG})?\)/.
12
- freeze
13
-
14
- def self.required_files_in?(filenames)
15
- filenames.include?("mix.exs")
16
- end
17
-
18
- def self.required_files_message
19
- "Repo must contain a mix.exs."
20
- end
21
-
22
- private
23
-
24
- def fetch_files
25
- fetched_files = []
26
- fetched_files << mixfile
27
- fetched_files << lockfile if lockfile
28
- fetched_files += subapp_mixfiles
29
- fetched_files += evaled_files
30
- fetched_files
31
- end
32
-
33
- def mixfile
34
- @mixfile ||= fetch_file_from_host("mix.exs")
35
- end
36
-
37
- def lockfile
38
- return @lockfile if @lockfile_lookup_attempted
39
-
40
- @lockfile_lookup_attempted = true
41
- @lockfile ||= fetch_file_from_host("mix.lock")
42
- rescue Dependabot::DependencyFileNotFound
43
- nil
44
- end
45
-
46
- def subapp_mixfiles
47
- apps_path = mixfile.content.match(APPS_PATH_REGEX)&.
48
- named_captures&.fetch("path")
49
- return [] unless apps_path
50
-
51
- app_directories = repo_contents(dir: apps_path).
52
- select { |f| f.type == "dir" }
53
-
54
- app_directories.map do |dir|
55
- fetch_file_from_host("#{dir.path}/mix.exs")
56
- rescue Dependabot::DependencyFileNotFound
57
- # If the folder doesn't have a mix.exs it *might* be because it's
58
- # not an app. Ignore the fact we couldn't fetch one and proceed with
59
- # updating (it will blow up later if there are problems)
60
- nil
61
- end.compact
62
- rescue Octokit::NotFound, Gitlab::Error::NotFound
63
- # If the path specified in apps_path doesn't exist then it's not being
64
- # used. We can just return an empty array of subapp files.
65
- []
66
- end
67
-
68
- def evaled_files
69
- mixfile.content.scan(EVAL_FILE).map do |eval_file_args|
70
- path = Pathname.new(File.join(*eval_file_args.reverse)).
71
- cleanpath.to_path
72
- fetch_file_from_host(path).tap { |f| f.support_file = true }
73
- end
74
- end
75
- end
76
- end
77
- end
78
- end
@@ -1,134 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/dependency"
4
- require "dependabot/file_parsers/base"
5
- require "dependabot/file_fetchers/elixir/hex"
6
- require "dependabot/shared_helpers"
7
- require "dependabot/errors"
8
-
9
- # For docs, see https://hexdocs.pm/mix/Mix.Tasks.Deps.html
10
- module Dependabot
11
- module FileParsers
12
- module Elixir
13
- class Hex < Dependabot::FileParsers::Base
14
- require "dependabot/file_parsers/base/dependency_set"
15
-
16
- def parse
17
- dependency_set = DependencySet.new
18
-
19
- dependency_details.each do |dep|
20
- git_dependency = dep["source"]&.fetch("type") == "git"
21
-
22
- dependency_set <<
23
- Dependency.new(
24
- name: dep["name"],
25
- version: git_dependency ? dep["checksum"] : dep["version"],
26
- requirements: [{
27
- requirement: dep["requirement"],
28
- groups: dep["groups"],
29
- source: dep["source"] && symbolize_keys(dep["source"]),
30
- file: dep["from"]
31
- }],
32
- package_manager: "hex"
33
- )
34
- end
35
-
36
- dependency_set.dependencies.sort_by(&:name)
37
- end
38
-
39
- private
40
-
41
- def dependency_details
42
- SharedHelpers.in_a_temporary_directory do
43
- write_sanitized_mixfiles
44
- write_supporting_files
45
- File.write("mix.lock", lockfile.content) if lockfile
46
- FileUtils.cp(elixir_helper_parse_deps_path, "parse_deps.exs")
47
-
48
- SharedHelpers.run_helper_subprocess(
49
- env: mix_env,
50
- command: "mix run #{elixir_helper_path}",
51
- function: "parse",
52
- args: [Dir.pwd],
53
- popen_opts: { err: %i(child out) }
54
- )
55
- end
56
- rescue Dependabot::SharedHelpers::HelperSubprocessFailed => error
57
- result_json =
58
- error.message.lines.
59
- drop_while { |l| !l.start_with?('{"result":') }.
60
- join
61
-
62
- if result_json.empty?
63
- raise DependencyFileNotEvaluatable, error.message
64
- end
65
-
66
- JSON.parse(result_json).fetch("result")
67
- end
68
-
69
- def write_sanitized_mixfiles
70
- mixfiles.each do |file|
71
- path = file.name
72
- FileUtils.mkdir_p(Pathname.new(path).dirname)
73
- File.write(path, sanitize_mixfile(file.content))
74
- end
75
- end
76
-
77
- def write_supporting_files
78
- dependency_files.select(&:support_file).each do |file|
79
- path = file.name
80
- FileUtils.mkdir_p(Pathname.new(path).dirname)
81
- File.write(path, file.content)
82
- end
83
- end
84
-
85
- def sanitize_mixfile(content)
86
- content.
87
- gsub(/File\.read!\(.*?\)/, '"0.0.1"').
88
- gsub(/File\.read\(.*?\)/, '{:ok, "0.0.1"}')
89
- end
90
-
91
- def mix_env
92
- {
93
- "MIX_EXS" => File.join(project_root, "helpers/elixir/mix.exs"),
94
- "MIX_LOCK" => File.join(project_root, "helpers/elixir/mix.lock"),
95
- "MIX_DEPS" => File.join(project_root, "helpers/elixir/deps"),
96
- "MIX_QUIET" => "1"
97
- }
98
- end
99
-
100
- def elixir_helper_path
101
- File.join(project_root, "helpers/elixir/bin/run.exs")
102
- end
103
-
104
- def elixir_helper_parse_deps_path
105
- File.join(project_root, "helpers/elixir/bin/parse_deps.exs")
106
- end
107
-
108
- def required_files
109
- Dependabot::FileFetchers::Elixir::Hex.required_files
110
- end
111
-
112
- def check_required_files
113
- raise "No mixfile!" if mixfiles.none?
114
- end
115
-
116
- def project_root
117
- File.join(File.dirname(__FILE__), "../../../..")
118
- end
119
-
120
- def symbolize_keys(hash)
121
- Hash[hash.keys.map { |k| [k.to_sym, hash[k]] }]
122
- end
123
-
124
- def mixfiles
125
- dependency_files.select { |f| f.name.end_with?("mix.exs") }
126
- end
127
-
128
- def lockfile
129
- @lockfile ||= get_original_file("mix.lock")
130
- end
131
- end
132
- end
133
- end
134
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_updaters/base"
4
- require "dependabot/utils/elixir/version"
5
- require "dependabot/shared_helpers"
6
-
7
- module Dependabot
8
- module FileUpdaters
9
- module Elixir
10
- class Hex < Base
11
- require_relative "hex/mixfile_updater"
12
- require_relative "hex/lockfile_updater"
13
-
14
- def self.updated_files_regex
15
- [
16
- /^mix\.exs$/,
17
- /^mix\.lock$/
18
- ]
19
- end
20
-
21
- def updated_dependency_files
22
- updated_files = []
23
-
24
- mixfiles.each do |file|
25
- if file_changed?(file)
26
- updated_files <<
27
- updated_file(file: file, content: updated_mixfile_content(file))
28
- end
29
- end
30
-
31
- if lockfile
32
- updated_files <<
33
- updated_file(file: lockfile, content: updated_lockfile_content)
34
- end
35
-
36
- updated_files
37
- end
38
-
39
- private
40
-
41
- def check_required_files
42
- raise "No mix.exs!" unless get_original_file("mix.exs")
43
- end
44
-
45
- def updated_mixfile_content(file)
46
- MixfileUpdater.new(
47
- dependencies: dependencies,
48
- mixfile: file
49
- ).updated_mixfile_content
50
- end
51
-
52
- def updated_lockfile_content
53
- @updated_lockfile_content ||=
54
- LockfileUpdater.new(
55
- dependencies: dependencies,
56
- dependency_files: dependency_files,
57
- credentials: credentials
58
- ).updated_lockfile_content
59
- end
60
-
61
- def mixfiles
62
- dependency_files.select { |f| f.name.end_with?("mix.exs") }
63
- end
64
-
65
- def lockfile
66
- @lockfile ||= get_original_file("mix.lock")
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,147 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_updaters/elixir/hex"
4
- require "dependabot/file_updaters/elixir/hex/mixfile_updater"
5
- require "dependabot/file_updaters/elixir/hex/mixfile_sanitizer"
6
- require "dependabot/file_updaters/elixir/hex/mixfile_requirement_updater"
7
- require "dependabot/utils/elixir/version"
8
- require "dependabot/shared_helpers"
9
-
10
- module Dependabot
11
- module FileUpdaters
12
- module Elixir
13
- class Hex
14
- class LockfileUpdater
15
- def initialize(dependencies:, dependency_files:, credentials:)
16
- @dependencies = dependencies
17
- @dependency_files = dependency_files
18
- @credentials = credentials
19
- end
20
-
21
- def updated_lockfile_content
22
- @updated_lockfile_content ||=
23
- SharedHelpers.in_a_temporary_directory do
24
- write_temporary_dependency_files
25
- FileUtils.cp(elixir_helper_do_update_path, "do_update.exs")
26
-
27
- SharedHelpers.with_git_configured(credentials: credentials) do
28
- SharedHelpers.run_helper_subprocess(
29
- env: mix_env,
30
- command: "mix run #{elixir_helper_path}",
31
- function: "get_updated_lockfile",
32
- args: [Dir.pwd, dependency.name, organization_credentials]
33
- )
34
- end
35
- end
36
-
37
- post_process_lockfile(@updated_lockfile_content)
38
- end
39
-
40
- private
41
-
42
- attr_reader :dependencies, :dependency_files, :credentials
43
-
44
- def dependency
45
- # For now, we'll only ever be updating a single dep for Elixir
46
- dependencies.first
47
- end
48
-
49
- def post_process_lockfile(content)
50
- return content unless lockfile.content.start_with?("%{\"")
51
- return content if content.start_with?("%{\"")
52
-
53
- # Substitute back old file beginning and ending
54
- content.sub(/\A%\{\n "/, "%{\"").sub(/\},\n\}/, "}}")
55
- end
56
-
57
- def write_temporary_dependency_files
58
- mixfiles.each do |file|
59
- path = file.name
60
- FileUtils.mkdir_p(Pathname.new(path).dirname)
61
- File.write(path, mixfile_content_for_lockfile_generation(file))
62
- end
63
-
64
- File.write("mix.lock", lockfile.content)
65
-
66
- dependency_files.select(&:support_file).each do |file|
67
- path = file.name
68
- FileUtils.mkdir_p(Pathname.new(path).dirname)
69
- File.write(path, file.content)
70
- end
71
- end
72
-
73
- def mixfile_content_for_lockfile_generation(file)
74
- content = updated_mixfile_content(file)
75
- content = lock_mixfile_dependency_versions(content, file.name)
76
- sanitize_mixfile(content)
77
- end
78
-
79
- def updated_mixfile_content(file)
80
- MixfileUpdater.new(
81
- dependencies: dependencies,
82
- mixfile: file
83
- ).updated_mixfile_content
84
- end
85
-
86
- def lock_mixfile_dependency_versions(mixfile_content, filename)
87
- dependencies.
88
- reduce(mixfile_content.dup) do |content, dep|
89
- # Run on the updated mixfile content, so we're updating from the
90
- # updated requirements
91
- req_details = dep.requirements.find { |r| r[:file] == filename }
92
-
93
- next content unless req_details
94
- next content unless Utils::Elixir::Version.correct?(dep.version)
95
-
96
- MixfileRequirementUpdater.new(
97
- dependency_name: dep.name,
98
- mixfile_content: content,
99
- previous_requirement: req_details.fetch(:requirement),
100
- updated_requirement: dep.version,
101
- insert_if_bare: true
102
- ).updated_content
103
- end
104
- end
105
-
106
- def sanitize_mixfile(content)
107
- MixfileSanitizer.new(mixfile_content: content).sanitized_content
108
- end
109
-
110
- def mix_env
111
- {
112
- "MIX_EXS" => File.join(project_root, "helpers/elixir/mix.exs"),
113
- "MIX_LOCK" => File.join(project_root, "helpers/elixir/mix.lock"),
114
- "MIX_DEPS" => File.join(project_root, "helpers/elixir/deps"),
115
- "MIX_QUIET" => "1"
116
- }
117
- end
118
-
119
- def elixir_helper_path
120
- File.join(project_root, "helpers/elixir/bin/run.exs")
121
- end
122
-
123
- def elixir_helper_do_update_path
124
- File.join(project_root, "helpers/elixir/bin/do_update.exs")
125
- end
126
-
127
- def project_root
128
- File.join(File.dirname(__FILE__), "../../../../..")
129
- end
130
-
131
- def mixfiles
132
- dependency_files.select { |f| f.name.end_with?("mix.exs") }
133
- end
134
-
135
- def lockfile
136
- @lockfile ||= dependency_files.find { |f| f.name == "mix.lock" }
137
- end
138
-
139
- def organization_credentials
140
- credentials.select { |cred| cred["type"] == "hex_organization" }.
141
- flat_map { |cred| [cred["organization"], cred["token"]] }
142
- end
143
- end
144
- end
145
- end
146
- end
147
- end