dependabot-core 0.93.17 → 0.94.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/dependabot/dependency.rb +16 -21
- data/lib/dependabot/file_fetchers.rb +1 -5
- data/lib/dependabot/file_parsers.rb +1 -5
- data/lib/dependabot/file_updaters.rb +1 -5
- data/lib/dependabot/metadata_finders.rb +1 -5
- data/lib/dependabot/pull_request_creator/labeler.rb +26 -24
- data/lib/dependabot/update_checkers.rb +1 -5
- data/lib/dependabot/utils.rb +2 -12
- data/lib/dependabot/version.rb +1 -1
- metadata +1 -28
- data/lib/dependabot/file_fetchers/ruby/bundler.rb +0 -215
- data/lib/dependabot/file_fetchers/ruby/bundler/child_gemfile_finder.rb +0 -70
- data/lib/dependabot/file_fetchers/ruby/bundler/gemspec_finder.rb +0 -98
- data/lib/dependabot/file_fetchers/ruby/bundler/path_gemspec_finder.rb +0 -114
- data/lib/dependabot/file_fetchers/ruby/bundler/require_relative_finder.rb +0 -67
- data/lib/dependabot/file_parsers/ruby/bundler.rb +0 -294
- data/lib/dependabot/file_parsers/ruby/bundler/file_preparer.rb +0 -86
- data/lib/dependabot/file_parsers/ruby/bundler/gemfile_checker.rb +0 -48
- data/lib/dependabot/file_updaters/ruby/bundler.rb +0 -123
- data/lib/dependabot/file_updaters/ruby/bundler/gemfile_updater.rb +0 -116
- data/lib/dependabot/file_updaters/ruby/bundler/gemspec_dependency_name_finder.rb +0 -52
- data/lib/dependabot/file_updaters/ruby/bundler/gemspec_sanitizer.rb +0 -298
- data/lib/dependabot/file_updaters/ruby/bundler/gemspec_updater.rb +0 -64
- data/lib/dependabot/file_updaters/ruby/bundler/git_pin_replacer.rb +0 -80
- data/lib/dependabot/file_updaters/ruby/bundler/git_source_remover.rb +0 -102
- data/lib/dependabot/file_updaters/ruby/bundler/lockfile_updater.rb +0 -389
- data/lib/dependabot/file_updaters/ruby/bundler/requirement_replacer.rb +0 -223
- data/lib/dependabot/metadata_finders/ruby/bundler.rb +0 -202
- data/lib/dependabot/update_checkers/ruby/bundler.rb +0 -331
- data/lib/dependabot/update_checkers/ruby/bundler/file_preparer.rb +0 -281
- data/lib/dependabot/update_checkers/ruby/bundler/force_updater.rb +0 -261
- data/lib/dependabot/update_checkers/ruby/bundler/latest_version_finder.rb +0 -169
- data/lib/dependabot/update_checkers/ruby/bundler/requirements_updater.rb +0 -283
- data/lib/dependabot/update_checkers/ruby/bundler/ruby_requirement_setter.rb +0 -115
- data/lib/dependabot/update_checkers/ruby/bundler/shared_bundler_helpers.rb +0 -246
- data/lib/dependabot/update_checkers/ruby/bundler/version_resolver.rb +0 -272
- data/lib/dependabot/utils/ruby/requirement.rb +0 -26
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dependabot/dependency_file"
|
4
|
-
require "dependabot/file_parsers/ruby/bundler"
|
5
|
-
require "dependabot/file_updaters/ruby/bundler/gemspec_sanitizer"
|
6
|
-
|
7
|
-
module Dependabot
|
8
|
-
module FileParsers
|
9
|
-
module Ruby
|
10
|
-
class Bundler
|
11
|
-
class FilePreparer
|
12
|
-
def initialize(dependency_files:)
|
13
|
-
@dependency_files = dependency_files
|
14
|
-
end
|
15
|
-
|
16
|
-
def prepared_dependency_files
|
17
|
-
files = []
|
18
|
-
|
19
|
-
gemspecs.compact.each do |file|
|
20
|
-
files << DependencyFile.new(
|
21
|
-
name: file.name,
|
22
|
-
content: sanitize_gemspec_content(file.content),
|
23
|
-
directory: file.directory,
|
24
|
-
support_file: file.support_file?
|
25
|
-
)
|
26
|
-
end
|
27
|
-
|
28
|
-
files += [
|
29
|
-
gemfile,
|
30
|
-
*evaled_gemfiles,
|
31
|
-
lockfile,
|
32
|
-
ruby_version_file,
|
33
|
-
*imported_ruby_files
|
34
|
-
].compact
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
attr_reader :dependency_files
|
40
|
-
|
41
|
-
def gemfile
|
42
|
-
dependency_files.find { |f| f.name == "Gemfile" } ||
|
43
|
-
dependency_files.find { |f| f.name == "gems.rb" }
|
44
|
-
end
|
45
|
-
|
46
|
-
def evaled_gemfiles
|
47
|
-
dependency_files.
|
48
|
-
reject { |f| f.name.end_with?(".gemspec") }.
|
49
|
-
reject { |f| f.name.end_with?(".lock") }.
|
50
|
-
reject { |f| f.name.end_with?(".ruby-version") }.
|
51
|
-
reject { |f| f.name == "Gemfile" }.
|
52
|
-
reject { |f| f.name == "gems.rb" }.
|
53
|
-
reject { |f| f.name == "gems.locked" }
|
54
|
-
end
|
55
|
-
|
56
|
-
def lockfile
|
57
|
-
dependency_files.find { |f| f.name == "Gemfile.lock" } ||
|
58
|
-
dependency_files.find { |f| f.name == "gems.locked" }
|
59
|
-
end
|
60
|
-
|
61
|
-
def gemspecs
|
62
|
-
dependency_files.select { |f| f.name.end_with?(".gemspec") }
|
63
|
-
end
|
64
|
-
|
65
|
-
def ruby_version_file
|
66
|
-
dependency_files.find { |f| f.name == ".ruby-version" }
|
67
|
-
end
|
68
|
-
|
69
|
-
def imported_ruby_files
|
70
|
-
dependency_files.
|
71
|
-
select { |f| f.name.end_with?(".rb") }.
|
72
|
-
reject { |f| f.name == "gems.rb" }
|
73
|
-
end
|
74
|
-
|
75
|
-
def sanitize_gemspec_content(gemspec_content)
|
76
|
-
# No need to set the version correctly - this is just an update
|
77
|
-
# check so we're not going to persist any changes to the lockfile.
|
78
|
-
FileUpdaters::Ruby::Bundler::GemspecSanitizer.
|
79
|
-
new(replacement_version: "0.0.1").
|
80
|
-
rewrite(gemspec_content)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "parser/current"
|
4
|
-
require "dependabot/file_parsers/ruby/bundler"
|
5
|
-
|
6
|
-
module Dependabot
|
7
|
-
module FileParsers
|
8
|
-
module Ruby
|
9
|
-
class Bundler
|
10
|
-
# Checks whether a dependency is declared in a Gemfile
|
11
|
-
class GemfileChecker
|
12
|
-
def initialize(dependency:, gemfile:)
|
13
|
-
@dependency = dependency
|
14
|
-
@gemfile = gemfile
|
15
|
-
end
|
16
|
-
|
17
|
-
def includes_dependency?
|
18
|
-
return false unless Parser::CurrentRuby.parse(gemfile.content)
|
19
|
-
|
20
|
-
Parser::CurrentRuby.parse(gemfile.content).children.any? do |node|
|
21
|
-
deep_check_for_gem(node)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
attr_reader :dependency, :gemfile
|
28
|
-
|
29
|
-
def deep_check_for_gem(node)
|
30
|
-
return true if declares_targeted_gem?(node)
|
31
|
-
return false unless node.is_a?(Parser::AST::Node)
|
32
|
-
|
33
|
-
node.children.any? do |child_node|
|
34
|
-
deep_check_for_gem(child_node)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def declares_targeted_gem?(node)
|
39
|
-
return false unless node.is_a?(Parser::AST::Node)
|
40
|
-
return false unless node.children[1] == :gem
|
41
|
-
|
42
|
-
node.children[2].children.first == dependency.name
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,123 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dependabot/file_updaters/base"
|
4
|
-
|
5
|
-
module Dependabot
|
6
|
-
module FileUpdaters
|
7
|
-
module Ruby
|
8
|
-
class Bundler < Dependabot::FileUpdaters::Base
|
9
|
-
require_relative "bundler/gemfile_updater"
|
10
|
-
require_relative "bundler/gemspec_updater"
|
11
|
-
require_relative "bundler/lockfile_updater"
|
12
|
-
|
13
|
-
def self.updated_files_regex
|
14
|
-
[
|
15
|
-
/^Gemfile$/,
|
16
|
-
/^Gemfile\.lock$/,
|
17
|
-
/^gems\.rb$/,
|
18
|
-
/^gems\.locked$/,
|
19
|
-
/^*\.gemspec$/
|
20
|
-
]
|
21
|
-
end
|
22
|
-
|
23
|
-
def updated_dependency_files
|
24
|
-
updated_files = []
|
25
|
-
|
26
|
-
if gemfile && file_changed?(gemfile)
|
27
|
-
updated_files <<
|
28
|
-
updated_file(
|
29
|
-
file: gemfile,
|
30
|
-
content: updated_gemfile_content(gemfile)
|
31
|
-
)
|
32
|
-
end
|
33
|
-
|
34
|
-
if lockfile && dependencies.any?(&:appears_in_lockfile?)
|
35
|
-
updated_files <<
|
36
|
-
updated_file(file: lockfile, content: updated_lockfile_content)
|
37
|
-
end
|
38
|
-
|
39
|
-
top_level_gemspecs.each do |file|
|
40
|
-
next unless file_changed?(file)
|
41
|
-
|
42
|
-
updated_files <<
|
43
|
-
updated_file(file: file, content: updated_gemspec_content(file))
|
44
|
-
end
|
45
|
-
|
46
|
-
evaled_gemfiles.each do |file|
|
47
|
-
next unless file_changed?(file)
|
48
|
-
|
49
|
-
updated_files <<
|
50
|
-
updated_file(file: file, content: updated_gemfile_content(file))
|
51
|
-
end
|
52
|
-
|
53
|
-
updated_files
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def check_required_files
|
59
|
-
file_names = dependency_files.map(&:name)
|
60
|
-
|
61
|
-
if lockfile && !gemfile
|
62
|
-
raise "A Gemfile must be provided if a lockfile is!"
|
63
|
-
end
|
64
|
-
|
65
|
-
return if file_names.any? { |name| name.match?(%r{^[^/]*\.gemspec$}) }
|
66
|
-
return if gemfile
|
67
|
-
|
68
|
-
raise "A gemspec or Gemfile must be provided!"
|
69
|
-
end
|
70
|
-
|
71
|
-
def gemfile
|
72
|
-
@gemfile ||= get_original_file("Gemfile") ||
|
73
|
-
get_original_file("gems.rb")
|
74
|
-
end
|
75
|
-
|
76
|
-
def lockfile
|
77
|
-
@lockfile ||= get_original_file("Gemfile.lock") ||
|
78
|
-
get_original_file("gems.locked")
|
79
|
-
end
|
80
|
-
|
81
|
-
def evaled_gemfiles
|
82
|
-
@evaled_gemfiles ||=
|
83
|
-
dependency_files.
|
84
|
-
reject { |f| f.name.end_with?(".gemspec") }.
|
85
|
-
reject { |f| f.name.end_with?(".lock") }.
|
86
|
-
reject { |f| f.name.end_with?(".ruby-version") }.
|
87
|
-
reject { |f| f.name == "Gemfile" }.
|
88
|
-
reject { |f| f.name == "gems.rb" }.
|
89
|
-
reject { |f| f.name == "gems.locked" }
|
90
|
-
end
|
91
|
-
|
92
|
-
def updated_gemfile_content(file)
|
93
|
-
GemfileUpdater.new(
|
94
|
-
dependencies: dependencies,
|
95
|
-
gemfile: file
|
96
|
-
).updated_gemfile_content
|
97
|
-
end
|
98
|
-
|
99
|
-
def updated_gemspec_content(gemspec)
|
100
|
-
GemspecUpdater.new(
|
101
|
-
dependencies: dependencies,
|
102
|
-
gemspec: gemspec
|
103
|
-
).updated_gemspec_content
|
104
|
-
end
|
105
|
-
|
106
|
-
def updated_lockfile_content
|
107
|
-
@updated_lockfile_content ||=
|
108
|
-
LockfileUpdater.new(
|
109
|
-
dependencies: dependencies,
|
110
|
-
dependency_files: dependency_files,
|
111
|
-
credentials: credentials
|
112
|
-
).updated_lockfile_content
|
113
|
-
end
|
114
|
-
|
115
|
-
def top_level_gemspecs
|
116
|
-
dependency_files.
|
117
|
-
select { |file| file.name.end_with?(".gemspec") }.
|
118
|
-
reject(&:support_file?)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dependabot/file_updaters/ruby/bundler"
|
4
|
-
|
5
|
-
module Dependabot
|
6
|
-
module FileUpdaters
|
7
|
-
module Ruby
|
8
|
-
class Bundler
|
9
|
-
class GemfileUpdater
|
10
|
-
require_relative "git_pin_replacer"
|
11
|
-
require_relative "git_source_remover"
|
12
|
-
require_relative "requirement_replacer"
|
13
|
-
|
14
|
-
def initialize(dependencies:, gemfile:)
|
15
|
-
@dependencies = dependencies
|
16
|
-
@gemfile = gemfile
|
17
|
-
end
|
18
|
-
|
19
|
-
def updated_gemfile_content
|
20
|
-
content = gemfile.content
|
21
|
-
|
22
|
-
dependencies.each do |dependency|
|
23
|
-
content = replace_gemfile_version_requirement(
|
24
|
-
dependency,
|
25
|
-
gemfile,
|
26
|
-
content
|
27
|
-
)
|
28
|
-
|
29
|
-
if remove_git_source?(dependency)
|
30
|
-
content = remove_gemfile_git_source(dependency, content)
|
31
|
-
end
|
32
|
-
|
33
|
-
if update_git_pin?(dependency)
|
34
|
-
content = update_gemfile_git_pin(dependency, gemfile, content)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
content
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
attr_reader :dependencies, :gemfile
|
44
|
-
|
45
|
-
def replace_gemfile_version_requirement(dependency, file, content)
|
46
|
-
return content unless requirement_changed?(file, dependency)
|
47
|
-
|
48
|
-
updated_requirement =
|
49
|
-
dependency.requirements.
|
50
|
-
find { |r| r[:file] == file.name }.
|
51
|
-
fetch(:requirement)
|
52
|
-
|
53
|
-
previous_requirement =
|
54
|
-
dependency.previous_requirements.
|
55
|
-
find { |r| r[:file] == file.name }.
|
56
|
-
fetch(:requirement)
|
57
|
-
|
58
|
-
RequirementReplacer.new(
|
59
|
-
dependency: dependency,
|
60
|
-
file_type: :gemfile,
|
61
|
-
updated_requirement: updated_requirement,
|
62
|
-
previous_requirement: previous_requirement
|
63
|
-
).rewrite(content)
|
64
|
-
end
|
65
|
-
|
66
|
-
def requirement_changed?(file, dependency)
|
67
|
-
changed_requirements =
|
68
|
-
dependency.requirements - dependency.previous_requirements
|
69
|
-
|
70
|
-
changed_requirements.any? { |f| f[:file] == file.name }
|
71
|
-
end
|
72
|
-
|
73
|
-
def remove_git_source?(dependency)
|
74
|
-
old_gemfile_req =
|
75
|
-
dependency.previous_requirements.
|
76
|
-
find { |f| %w(Gemfile gems.rb).include?(f[:file]) }
|
77
|
-
|
78
|
-
return false unless old_gemfile_req&.dig(:source, :type) == "git"
|
79
|
-
|
80
|
-
new_gemfile_req =
|
81
|
-
dependency.requirements.
|
82
|
-
find { |f| %w(Gemfile gems.rb).include?(f[:file]) }
|
83
|
-
|
84
|
-
new_gemfile_req[:source].nil?
|
85
|
-
end
|
86
|
-
|
87
|
-
def update_git_pin?(dependency)
|
88
|
-
new_gemfile_req =
|
89
|
-
dependency.requirements.
|
90
|
-
find { |f| %w(Gemfile gems.rb).include?(f[:file]) }
|
91
|
-
return false unless new_gemfile_req&.dig(:source, :type) == "git"
|
92
|
-
|
93
|
-
# If the new requirement is a git dependency with a ref then there's
|
94
|
-
# no harm in doing an update
|
95
|
-
new_gemfile_req.dig(:source, :ref)
|
96
|
-
end
|
97
|
-
|
98
|
-
def remove_gemfile_git_source(dependency, content)
|
99
|
-
GitSourceRemover.new(dependency: dependency).rewrite(content)
|
100
|
-
end
|
101
|
-
|
102
|
-
def update_gemfile_git_pin(dependency, file, content)
|
103
|
-
new_pin =
|
104
|
-
dependency.requirements.
|
105
|
-
find { |f| f[:file] == file.name }.
|
106
|
-
fetch(:source).fetch(:ref)
|
107
|
-
|
108
|
-
GitPinReplacer.
|
109
|
-
new(dependency: dependency, new_pin: new_pin).
|
110
|
-
rewrite(content)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "parser/current"
|
4
|
-
require "dependabot/file_updaters/ruby/bundler"
|
5
|
-
|
6
|
-
module Dependabot
|
7
|
-
module FileUpdaters
|
8
|
-
module Ruby
|
9
|
-
class Bundler
|
10
|
-
class GemspecDependencyNameFinder
|
11
|
-
attr_reader :gemspec_content
|
12
|
-
|
13
|
-
def initialize(gemspec_content:)
|
14
|
-
@gemspec_content = gemspec_content
|
15
|
-
end
|
16
|
-
|
17
|
-
# rubocop:disable Security/Eval
|
18
|
-
def dependency_name
|
19
|
-
ast = Parser::CurrentRuby.parse(gemspec_content)
|
20
|
-
dependency_name_node = find_dependency_name_node(ast)
|
21
|
-
return unless dependency_name_node
|
22
|
-
|
23
|
-
begin
|
24
|
-
eval(dependency_name_node.children[2].loc.expression.source)
|
25
|
-
rescue StandardError
|
26
|
-
nil # If we can't evaluate the expression just return nil
|
27
|
-
end
|
28
|
-
end
|
29
|
-
# rubocop:enable Security/Eval
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def find_dependency_name_node(node)
|
34
|
-
return unless node.is_a?(Parser::AST::Node)
|
35
|
-
return node if declares_dependency_name?(node)
|
36
|
-
|
37
|
-
node.children.find do |cn|
|
38
|
-
dependency_name_node = find_dependency_name_node(cn)
|
39
|
-
break dependency_name_node if dependency_name_node
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def declares_dependency_name?(node)
|
44
|
-
return false unless node.is_a?(Parser::AST::Node)
|
45
|
-
|
46
|
-
node.children[1] == :name=
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,298 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "parser/current"
|
4
|
-
require "dependabot/file_updaters/ruby/bundler"
|
5
|
-
|
6
|
-
module Dependabot
|
7
|
-
module FileUpdaters
|
8
|
-
module Ruby
|
9
|
-
class Bundler
|
10
|
-
class GemspecSanitizer
|
11
|
-
UNNECESSARY_ASSIGNMENTS = %i(
|
12
|
-
bindir=
|
13
|
-
cert_chain=
|
14
|
-
email=
|
15
|
-
executables=
|
16
|
-
extra_rdoc_files=
|
17
|
-
homepage=
|
18
|
-
license=
|
19
|
-
licenses=
|
20
|
-
metadata=
|
21
|
-
post_install_message=
|
22
|
-
rdoc_options=
|
23
|
-
).freeze
|
24
|
-
|
25
|
-
attr_reader :replacement_version
|
26
|
-
|
27
|
-
def initialize(replacement_version:)
|
28
|
-
@replacement_version = replacement_version
|
29
|
-
end
|
30
|
-
|
31
|
-
def rewrite(content)
|
32
|
-
buffer = Parser::Source::Buffer.new("(gemspec_content)")
|
33
|
-
buffer.source = content
|
34
|
-
ast = Parser::CurrentRuby.new.parse(buffer)
|
35
|
-
|
36
|
-
Rewriter.
|
37
|
-
new(replacement_version: replacement_version).
|
38
|
-
rewrite(buffer, ast)
|
39
|
-
end
|
40
|
-
|
41
|
-
class Rewriter < Parser::TreeRewriter
|
42
|
-
def initialize(replacement_version:)
|
43
|
-
@replacement_version = replacement_version
|
44
|
-
end
|
45
|
-
|
46
|
-
def on_send(node)
|
47
|
-
# Wrap any `require` or `require_relative` calls in a rescue
|
48
|
-
# block, as we might not have the required files
|
49
|
-
wrap_require(node) if requires_file?(node)
|
50
|
-
|
51
|
-
# Remove any assignments to a VERSION constant (or similar), as
|
52
|
-
# that constant probably comes from a required file
|
53
|
-
replace_version_assignments(node)
|
54
|
-
|
55
|
-
# Replace the `s.files= ...` assignment with a blank array, as
|
56
|
-
# occassionally a File.open(..).readlines pattern is used
|
57
|
-
replace_file_assignments(node)
|
58
|
-
|
59
|
-
# Replace the `s.require_path= ...` assignment, as
|
60
|
-
# occassionally a Dir['lib'] pattern is used
|
61
|
-
replace_require_paths_assignments(node)
|
62
|
-
|
63
|
-
# Replace any `File.read(...)` calls with a dummy string
|
64
|
-
replace_file_reads(node)
|
65
|
-
|
66
|
-
# Remove the arguments from any `Find.find(...)` calls
|
67
|
-
remove_find_dot_find_args(node)
|
68
|
-
|
69
|
-
remove_unnecessary_assignments(node)
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
attr_reader :replacement_version
|
75
|
-
|
76
|
-
def requires_file?(node)
|
77
|
-
%i(require require_relative).include?(node.children[1])
|
78
|
-
end
|
79
|
-
|
80
|
-
def wrap_require(node)
|
81
|
-
replace(
|
82
|
-
node.loc.expression,
|
83
|
-
"begin\n"\
|
84
|
-
"#{node.loc.expression.source_line}\n"\
|
85
|
-
"rescue LoadError\n"\
|
86
|
-
"end"
|
87
|
-
)
|
88
|
-
end
|
89
|
-
|
90
|
-
def replace_version_assignments(node)
|
91
|
-
return unless node.is_a?(Parser::AST::Node)
|
92
|
-
|
93
|
-
if node_assigns_to_version_constant?(node)
|
94
|
-
return replace_constant(node)
|
95
|
-
end
|
96
|
-
|
97
|
-
node.children.each { |child| replace_version_assignments(child) }
|
98
|
-
end
|
99
|
-
|
100
|
-
def replace_file_assignments(node)
|
101
|
-
return unless node.is_a?(Parser::AST::Node)
|
102
|
-
|
103
|
-
if node_assigns_files_to_var?(node)
|
104
|
-
return replace_file_assignment(node)
|
105
|
-
end
|
106
|
-
|
107
|
-
node.children.each { |child| replace_file_assignments(child) }
|
108
|
-
end
|
109
|
-
|
110
|
-
def replace_require_paths_assignments(node)
|
111
|
-
return unless node.is_a?(Parser::AST::Node)
|
112
|
-
|
113
|
-
if node_assigns_require_paths?(node)
|
114
|
-
return replace_require_paths_assignment(node)
|
115
|
-
end
|
116
|
-
|
117
|
-
node.children.each do |child|
|
118
|
-
replace_require_paths_assignments(child)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def node_assigns_to_version_constant?(node)
|
123
|
-
return false unless node.is_a?(Parser::AST::Node)
|
124
|
-
return false unless node.children.first.is_a?(Parser::AST::Node)
|
125
|
-
return false unless node.children.first&.type == :lvar
|
126
|
-
|
127
|
-
return true if node.children[1] == :version=
|
128
|
-
return true if node_is_version_constant?(node.children.last)
|
129
|
-
return true if node_calls_version_constant?(node.children.last)
|
130
|
-
|
131
|
-
node_interpolates_version_constant?(node.children.last)
|
132
|
-
end
|
133
|
-
|
134
|
-
def node_assigns_files_to_var?(node)
|
135
|
-
return false unless node.is_a?(Parser::AST::Node)
|
136
|
-
return false unless node.children.first.is_a?(Parser::AST::Node)
|
137
|
-
return false unless node.children.first&.type == :lvar
|
138
|
-
return false unless node.children[1] == :files=
|
139
|
-
|
140
|
-
node.children[2]&.type == :send
|
141
|
-
end
|
142
|
-
|
143
|
-
def node_assigns_require_paths?(node)
|
144
|
-
return false unless node.is_a?(Parser::AST::Node)
|
145
|
-
return false unless node.children.first.is_a?(Parser::AST::Node)
|
146
|
-
return false unless node.children.first&.type == :lvar
|
147
|
-
|
148
|
-
node.children[1] == :require_paths=
|
149
|
-
end
|
150
|
-
|
151
|
-
def replace_file_reads(node)
|
152
|
-
return unless node.is_a?(Parser::AST::Node)
|
153
|
-
return if node.children[1] == :version=
|
154
|
-
return replace_file_read(node) if node_reads_a_file?(node)
|
155
|
-
return replace_file_readlines(node) if node_uses_readlines?(node)
|
156
|
-
|
157
|
-
node.children.each { |child| replace_file_reads(child) }
|
158
|
-
end
|
159
|
-
|
160
|
-
def node_reads_a_file?(node)
|
161
|
-
return false unless node.is_a?(Parser::AST::Node)
|
162
|
-
return false unless node.children.first.is_a?(Parser::AST::Node)
|
163
|
-
return false unless node.children.first&.type == :const
|
164
|
-
return false unless node.children.first.children.last == :File
|
165
|
-
|
166
|
-
node.children[1] == :read
|
167
|
-
end
|
168
|
-
|
169
|
-
def node_uses_readlines?(node)
|
170
|
-
return false unless node.is_a?(Parser::AST::Node)
|
171
|
-
return false unless node.children.first.is_a?(Parser::AST::Node)
|
172
|
-
return false unless node.children.first&.type == :const
|
173
|
-
return false unless node.children.first.children.last == :File
|
174
|
-
|
175
|
-
node.children[1] == :readlines
|
176
|
-
end
|
177
|
-
|
178
|
-
def remove_find_dot_find_args(node)
|
179
|
-
return unless node.is_a?(Parser::AST::Node)
|
180
|
-
return if node.children[1] == :version=
|
181
|
-
return remove_find_args(node) if node_calls_find_dot_find?(node)
|
182
|
-
|
183
|
-
node.children.each { |child| remove_find_dot_find_args(child) }
|
184
|
-
end
|
185
|
-
|
186
|
-
def node_calls_find_dot_find?(node)
|
187
|
-
return false unless node.is_a?(Parser::AST::Node)
|
188
|
-
return false unless node.children.first.is_a?(Parser::AST::Node)
|
189
|
-
return false unless node.children.first&.type == :const
|
190
|
-
return false unless node.children.first.children.last == :Find
|
191
|
-
|
192
|
-
node.children[1] == :find
|
193
|
-
end
|
194
|
-
|
195
|
-
def remove_unnecessary_assignments(node)
|
196
|
-
return unless node.is_a?(Parser::AST::Node)
|
197
|
-
|
198
|
-
if unnecessary_assignment?(node) &&
|
199
|
-
node.children.last&.location&.respond_to?(:heredoc_end)
|
200
|
-
range_to_remove = node.loc.expression.join(
|
201
|
-
node.children.last.location.heredoc_end
|
202
|
-
)
|
203
|
-
return replace(range_to_remove, '"sanitized"')
|
204
|
-
elsif unnecessary_assignment?(node)
|
205
|
-
return replace(node.loc.expression, '"sanitized"')
|
206
|
-
end
|
207
|
-
|
208
|
-
node.children.each do |child|
|
209
|
-
remove_unnecessary_assignments(child)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def unnecessary_assignment?(node)
|
214
|
-
return false unless node.is_a?(Parser::AST::Node)
|
215
|
-
return false unless node.children.first.is_a?(Parser::AST::Node)
|
216
|
-
return false unless node.children.first&.type == :lvar
|
217
|
-
|
218
|
-
UNNECESSARY_ASSIGNMENTS.include?(node.children[1])
|
219
|
-
end
|
220
|
-
|
221
|
-
def node_is_version_constant?(node)
|
222
|
-
return false unless node.is_a?(Parser::AST::Node)
|
223
|
-
return false unless node.type == :const
|
224
|
-
|
225
|
-
node.children.last.to_s.match?(/version/i)
|
226
|
-
end
|
227
|
-
|
228
|
-
def node_calls_version_constant?(node)
|
229
|
-
return false unless node.is_a?(Parser::AST::Node)
|
230
|
-
return false unless node.type == :send
|
231
|
-
|
232
|
-
node.children.any? { |n| node_is_version_constant?(n) }
|
233
|
-
end
|
234
|
-
|
235
|
-
def node_interpolates_version_constant?(node)
|
236
|
-
return false unless node.is_a?(Parser::AST::Node)
|
237
|
-
return false unless node.type == :dstr
|
238
|
-
|
239
|
-
node.children.
|
240
|
-
select { |n| n.type == :begin }.
|
241
|
-
flat_map(&:children).
|
242
|
-
any? { |n| node_is_version_constant?(n) }
|
243
|
-
end
|
244
|
-
|
245
|
-
def replace_constant(node)
|
246
|
-
case node.children.last&.type
|
247
|
-
when :str, :int then nil # no-op
|
248
|
-
when :const, :send, :lvar
|
249
|
-
replace(
|
250
|
-
node.children.last.loc.expression,
|
251
|
-
%("#{replacement_version}")
|
252
|
-
)
|
253
|
-
when :dstr
|
254
|
-
node.children.last.children.
|
255
|
-
select { |n| n.type == :begin }.
|
256
|
-
flat_map(&:children).
|
257
|
-
select { |n| node_is_version_constant?(n) }.
|
258
|
-
each do |n|
|
259
|
-
replace(
|
260
|
-
n.loc.expression,
|
261
|
-
%("#{replacement_version}")
|
262
|
-
)
|
263
|
-
end
|
264
|
-
else
|
265
|
-
raise "Unexpected node type #{node.children.last&.type}"
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
def replace_file_assignment(node)
|
270
|
-
replace(node.children.last.loc.expression, "[]")
|
271
|
-
end
|
272
|
-
|
273
|
-
def replace_require_paths_assignment(node)
|
274
|
-
replace(node.children.last.loc.expression, "['lib']")
|
275
|
-
end
|
276
|
-
|
277
|
-
def replace_file_read(node)
|
278
|
-
replace(node.loc.expression, '"text"')
|
279
|
-
end
|
280
|
-
|
281
|
-
def replace_file_readlines(node)
|
282
|
-
replace(node.loc.expression, '["text"]')
|
283
|
-
end
|
284
|
-
|
285
|
-
def remove_find_args(node)
|
286
|
-
last_arg = node.children.last
|
287
|
-
|
288
|
-
range_to_remove =
|
289
|
-
last_arg.loc.expression.join(node.children[2].loc.begin.begin)
|
290
|
-
|
291
|
-
remove(range_to_remove)
|
292
|
-
end
|
293
|
-
end
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|