dependabot-core 0.79.4 → 0.80.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/dependabot/file_fetchers.rb +0 -2
- data/lib/dependabot/file_parsers.rb +0 -2
- data/lib/dependabot/file_updaters.rb +0 -2
- data/lib/dependabot/file_updaters/ruby/.DS_Store +0 -0
- data/lib/dependabot/metadata_finders.rb +0 -2
- data/lib/dependabot/update_checkers.rb +0 -2
- data/lib/dependabot/utils.rb +0 -4
- data/lib/dependabot/version.rb +1 -1
- metadata +2 -20
- data/lib/dependabot/file_fetchers/dotnet/nuget.rb +0 -215
- data/lib/dependabot/file_fetchers/dotnet/nuget/import_paths_finder.rb +0 -51
- data/lib/dependabot/file_fetchers/dotnet/nuget/sln_project_paths_finder.rb +0 -55
- data/lib/dependabot/file_parsers/dotnet/nuget.rb +0 -85
- data/lib/dependabot/file_parsers/dotnet/nuget/packages_config_parser.rb +0 -65
- data/lib/dependabot/file_parsers/dotnet/nuget/project_file_parser.rb +0 -156
- data/lib/dependabot/file_parsers/dotnet/nuget/property_value_finder.rb +0 -131
- data/lib/dependabot/file_updaters/dotnet/nuget.rb +0 -151
- data/lib/dependabot/file_updaters/dotnet/nuget/packages_config_declaration_finder.rb +0 -69
- data/lib/dependabot/file_updaters/dotnet/nuget/project_file_declaration_finder.rb +0 -78
- data/lib/dependabot/file_updaters/dotnet/nuget/property_value_updater.rb +0 -64
- data/lib/dependabot/metadata_finders/dotnet/nuget.rb +0 -116
- data/lib/dependabot/update_checkers/dotnet/nuget.rb +0 -127
- data/lib/dependabot/update_checkers/dotnet/nuget/property_updater.rb +0 -97
- data/lib/dependabot/update_checkers/dotnet/nuget/repository_finder.rb +0 -232
- data/lib/dependabot/update_checkers/dotnet/nuget/requirements_updater.rb +0 -81
- data/lib/dependabot/update_checkers/dotnet/nuget/version_finder.rb +0 -231
- data/lib/dependabot/utils/dotnet/requirement.rb +0 -90
- data/lib/dependabot/utils/dotnet/version.rb +0 -22
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pathname"
|
4
|
-
require "dependabot/file_fetchers/dotnet/nuget"
|
5
|
-
|
6
|
-
module Dependabot
|
7
|
-
module FileFetchers
|
8
|
-
module Dotnet
|
9
|
-
class Nuget
|
10
|
-
class SlnProjectPathsFinder
|
11
|
-
PROJECT_PATH_REGEX =
|
12
|
-
/(?<=["'])[^"']*?\.(?:vb|cs|fs)proj(?=["'])/.freeze
|
13
|
-
|
14
|
-
def initialize(sln_file:)
|
15
|
-
@sln_file = sln_file
|
16
|
-
end
|
17
|
-
|
18
|
-
def project_paths
|
19
|
-
paths = []
|
20
|
-
sln_file_lines = sln_file.content.lines
|
21
|
-
|
22
|
-
sln_file_lines.each_with_index do |line, index|
|
23
|
-
next unless line.match?(/^\s*Project/)
|
24
|
-
|
25
|
-
# Don't know how to handle multi-line project declarations yet
|
26
|
-
next unless sln_file_lines[index + 1]&.match?(/^\s*EndProject/)
|
27
|
-
|
28
|
-
path = line.split('"')[5]
|
29
|
-
path = path.tr("\\", "/")
|
30
|
-
|
31
|
-
# If the path doesn't have an extension it's probably a directory
|
32
|
-
next unless path.match?(/\.[a-z]{2}proj$/)
|
33
|
-
|
34
|
-
path = File.join(current_dir, path) unless current_dir.nil?
|
35
|
-
paths << Pathname.new(path).cleanpath.to_path
|
36
|
-
end
|
37
|
-
|
38
|
-
paths
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
attr_reader :sln_file
|
44
|
-
|
45
|
-
def current_dir
|
46
|
-
parts = sln_file.name.split("/")[0..-2]
|
47
|
-
return if parts.empty?
|
48
|
-
|
49
|
-
parts.join("/")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "nokogiri"
|
4
|
-
|
5
|
-
require "dependabot/dependency"
|
6
|
-
require "dependabot/file_parsers/base"
|
7
|
-
|
8
|
-
# For details on how dotnet handles version constraints, see:
|
9
|
-
# https://docs.microsoft.com/en-us/nuget/reference/package-versioning
|
10
|
-
module Dependabot
|
11
|
-
module FileParsers
|
12
|
-
module Dotnet
|
13
|
-
class Nuget < Dependabot::FileParsers::Base
|
14
|
-
require "dependabot/file_parsers/base/dependency_set"
|
15
|
-
require "dependabot/file_parsers/dotnet/nuget/project_file_parser"
|
16
|
-
require "dependabot/file_parsers/dotnet/nuget/packages_config_parser"
|
17
|
-
|
18
|
-
PACKAGE_CONF_DEPENDENCY_SELECTOR = "packages > packages"
|
19
|
-
|
20
|
-
def parse
|
21
|
-
dependency_set = DependencySet.new
|
22
|
-
dependency_set += project_file_dependencies
|
23
|
-
dependency_set += packages_config_dependencies
|
24
|
-
dependency_set.dependencies
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def project_file_dependencies
|
30
|
-
dependency_set = DependencySet.new
|
31
|
-
|
32
|
-
(project_files + project_import_files).each do |file|
|
33
|
-
parser = project_file_parser
|
34
|
-
dependency_set += parser.dependency_set(project_file: file)
|
35
|
-
end
|
36
|
-
|
37
|
-
dependency_set
|
38
|
-
end
|
39
|
-
|
40
|
-
def packages_config_dependencies
|
41
|
-
dependency_set = DependencySet.new
|
42
|
-
|
43
|
-
packages_config_files.each do |file|
|
44
|
-
parser = PackagesConfigParser.new(packages_config: file)
|
45
|
-
dependency_set += parser.dependency_set
|
46
|
-
end
|
47
|
-
|
48
|
-
dependency_set
|
49
|
-
end
|
50
|
-
|
51
|
-
def project_file_parser
|
52
|
-
@project_file_parser ||=
|
53
|
-
ProjectFileParser.new(dependency_files: dependency_files)
|
54
|
-
end
|
55
|
-
|
56
|
-
def project_files
|
57
|
-
dependency_files.select { |df| df.name.match?(/\.[a-z]{2}proj$/) }
|
58
|
-
end
|
59
|
-
|
60
|
-
def packages_config_files
|
61
|
-
dependency_files.select do |f|
|
62
|
-
f.name.split("/").last.casecmp("packages.config").zero?
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def project_import_files
|
67
|
-
dependency_files -
|
68
|
-
project_files -
|
69
|
-
packages_config_files -
|
70
|
-
[nuget_config]
|
71
|
-
end
|
72
|
-
|
73
|
-
def nuget_config
|
74
|
-
dependency_files.find { |f| f.name.casecmp("nuget.config").zero? }
|
75
|
-
end
|
76
|
-
|
77
|
-
def check_required_files
|
78
|
-
return if project_files.any? || packages_config_files.any?
|
79
|
-
|
80
|
-
raise "No project file or packages.config!"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "nokogiri"
|
4
|
-
|
5
|
-
require "dependabot/dependency"
|
6
|
-
require "dependabot/file_parsers/dotnet/nuget"
|
7
|
-
|
8
|
-
# For details on packages.config files see:
|
9
|
-
# https://docs.microsoft.com/en-us/nuget/reference/packages-config
|
10
|
-
module Dependabot
|
11
|
-
module FileParsers
|
12
|
-
module Dotnet
|
13
|
-
class Nuget
|
14
|
-
class PackagesConfigParser
|
15
|
-
require "dependabot/file_parsers/base/dependency_set"
|
16
|
-
|
17
|
-
DEPENDENCY_SELECTOR = "packages > package"
|
18
|
-
|
19
|
-
def initialize(packages_config:)
|
20
|
-
@packages_config = packages_config
|
21
|
-
end
|
22
|
-
|
23
|
-
def dependency_set
|
24
|
-
dependency_set = Dependabot::FileParsers::Base::DependencySet.new
|
25
|
-
|
26
|
-
doc = Nokogiri::XML(packages_config.content)
|
27
|
-
doc.remove_namespaces!
|
28
|
-
doc.css(DEPENDENCY_SELECTOR).each do |dependency_node|
|
29
|
-
dependency_set <<
|
30
|
-
Dependency.new(
|
31
|
-
name: dependency_name(dependency_node),
|
32
|
-
version: dependency_version(dependency_node),
|
33
|
-
package_manager: "nuget",
|
34
|
-
requirements: [{
|
35
|
-
requirement: dependency_version(dependency_node),
|
36
|
-
file: packages_config.name,
|
37
|
-
groups: [],
|
38
|
-
source: nil
|
39
|
-
}]
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
dependency_set
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
attr_reader :packages_config
|
49
|
-
|
50
|
-
def dependency_name(dependency_node)
|
51
|
-
dependency_node.attribute("id")&.value&.strip ||
|
52
|
-
dependency_node.at_xpath("./id")&.content&.strip
|
53
|
-
end
|
54
|
-
|
55
|
-
def dependency_version(dependency_node)
|
56
|
-
# Ranges and wildcards aren't allowed in a packages.config - the
|
57
|
-
# specified requirement is always an exact version.
|
58
|
-
dependency_node.attribute("version")&.value&.strip ||
|
59
|
-
dependency_node.at_xpath("./version")&.content&.strip
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,156 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "nokogiri"
|
4
|
-
|
5
|
-
require "dependabot/dependency"
|
6
|
-
require "dependabot/file_parsers/dotnet/nuget"
|
7
|
-
|
8
|
-
# For details on how dotnet handles version constraints, see:
|
9
|
-
# https://docs.microsoft.com/en-us/nuget/reference/package-versioning
|
10
|
-
module Dependabot
|
11
|
-
module FileParsers
|
12
|
-
module Dotnet
|
13
|
-
class Nuget
|
14
|
-
class ProjectFileParser
|
15
|
-
require "dependabot/file_parsers/base/dependency_set"
|
16
|
-
require_relative "property_value_finder"
|
17
|
-
|
18
|
-
DEPENDENCY_SELECTOR = "ItemGroup > PackageReference, "\
|
19
|
-
"ItemGroup > Dependency, "\
|
20
|
-
"ItemGroup > DevelopmentDependency"
|
21
|
-
|
22
|
-
PROPERTY_REGEX = /\$\((?<property>.*?)\)/.freeze
|
23
|
-
|
24
|
-
def initialize(dependency_files:)
|
25
|
-
@dependency_files = dependency_files
|
26
|
-
end
|
27
|
-
|
28
|
-
def dependency_set(project_file:)
|
29
|
-
dependency_set = Dependabot::FileParsers::Base::DependencySet.new
|
30
|
-
|
31
|
-
doc = Nokogiri::XML(project_file.content)
|
32
|
-
doc.remove_namespaces!
|
33
|
-
doc.css(DEPENDENCY_SELECTOR).each do |dependency_node|
|
34
|
-
name = dependency_name(dependency_node, project_file)
|
35
|
-
req = dependency_requirement(dependency_node, project_file)
|
36
|
-
version = dependency_version(dependency_node, project_file)
|
37
|
-
prop_name = req_property_name(dependency_node)
|
38
|
-
|
39
|
-
dependency =
|
40
|
-
build_dependency(name, req, version, prop_name, project_file)
|
41
|
-
dependency_set << dependency if dependency
|
42
|
-
end
|
43
|
-
|
44
|
-
dependency_set
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
attr_reader :dependency_files
|
50
|
-
|
51
|
-
def build_dependency(name, req, version, prop_name, project_file)
|
52
|
-
return unless name
|
53
|
-
|
54
|
-
# Exclude any dependencies specified using interpolation
|
55
|
-
return if [name, req, version].any? { |s| s&.include?("%(") }
|
56
|
-
|
57
|
-
requirement = {
|
58
|
-
requirement: req,
|
59
|
-
file: project_file.name,
|
60
|
-
groups: [],
|
61
|
-
source: nil
|
62
|
-
}
|
63
|
-
|
64
|
-
if prop_name
|
65
|
-
# Get the root property name unless no details could be found,
|
66
|
-
# in which case use the top-level name to ease debugging
|
67
|
-
root_prop_name = details_for_property(prop_name, project_file)&.
|
68
|
-
fetch(:root_property_name) || prop_name
|
69
|
-
requirement[:metadata] = { property_name: root_prop_name }
|
70
|
-
end
|
71
|
-
|
72
|
-
Dependency.new(
|
73
|
-
name: name,
|
74
|
-
version: version,
|
75
|
-
package_manager: "nuget",
|
76
|
-
requirements: [requirement]
|
77
|
-
)
|
78
|
-
end
|
79
|
-
|
80
|
-
def dependency_name(dependency_node, project_file)
|
81
|
-
raw_name =
|
82
|
-
dependency_node.attribute("Include")&.value&.strip ||
|
83
|
-
dependency_node.at_xpath("./Include")&.content&.strip
|
84
|
-
return unless raw_name
|
85
|
-
|
86
|
-
evaluated_value(raw_name, project_file)
|
87
|
-
end
|
88
|
-
|
89
|
-
def dependency_requirement(dependency_node, project_file)
|
90
|
-
raw_requirement =
|
91
|
-
dependency_node.attribute("Version")&.value&.strip ||
|
92
|
-
dependency_node.at_xpath("./Version")&.content&.strip
|
93
|
-
return unless raw_requirement
|
94
|
-
|
95
|
-
evaluated_value(raw_requirement, project_file)
|
96
|
-
end
|
97
|
-
|
98
|
-
def dependency_version(dependency_node, project_file)
|
99
|
-
requirement = dependency_requirement(dependency_node, project_file)
|
100
|
-
return unless requirement
|
101
|
-
|
102
|
-
# Remove brackets if present
|
103
|
-
version = requirement.gsub(/[\(\)\[\]]/, "").strip
|
104
|
-
|
105
|
-
# We don't know the version for range requirements or wildcard
|
106
|
-
# requirements, so return `nil` for these.
|
107
|
-
return if version.include?(",") || version.include?("*") ||
|
108
|
-
version == ""
|
109
|
-
|
110
|
-
version
|
111
|
-
end
|
112
|
-
|
113
|
-
def req_property_name(dependency_node)
|
114
|
-
raw_requirement =
|
115
|
-
dependency_node.attribute("Version")&.value&.strip ||
|
116
|
-
dependency_node.at_xpath("./Version")&.content&.strip
|
117
|
-
return unless raw_requirement
|
118
|
-
|
119
|
-
return unless raw_requirement.match?(PROPERTY_REGEX)
|
120
|
-
|
121
|
-
raw_requirement.
|
122
|
-
match(PROPERTY_REGEX).
|
123
|
-
named_captures.fetch("property")
|
124
|
-
end
|
125
|
-
|
126
|
-
def evaluated_value(value, project_file)
|
127
|
-
return value unless value.match?(PROPERTY_REGEX)
|
128
|
-
|
129
|
-
property_name = value.match(PROPERTY_REGEX).
|
130
|
-
named_captures.fetch("property")
|
131
|
-
property_details = details_for_property(property_name, project_file)
|
132
|
-
|
133
|
-
# Don't halt parsing for a missing property value until we're
|
134
|
-
# confident we're fetching property values correctly
|
135
|
-
return value unless property_details&.fetch(:value)
|
136
|
-
|
137
|
-
value.gsub(PROPERTY_REGEX, property_details&.fetch(:value))
|
138
|
-
end
|
139
|
-
|
140
|
-
def details_for_property(property_name, project_file)
|
141
|
-
property_value_finder.
|
142
|
-
property_details(
|
143
|
-
property_name: property_name,
|
144
|
-
callsite_file: project_file
|
145
|
-
)
|
146
|
-
end
|
147
|
-
|
148
|
-
def property_value_finder
|
149
|
-
@property_value_finder ||=
|
150
|
-
PropertyValueFinder.new(dependency_files: dependency_files)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
@@ -1,131 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dependabot/file_fetchers/dotnet/nuget/import_paths_finder"
|
4
|
-
require "dependabot/file_parsers/dotnet/nuget"
|
5
|
-
|
6
|
-
# For docs, see:
|
7
|
-
# - https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-properties
|
8
|
-
# - https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build
|
9
|
-
module Dependabot
|
10
|
-
module FileParsers
|
11
|
-
module Dotnet
|
12
|
-
class Nuget
|
13
|
-
class PropertyValueFinder
|
14
|
-
PROPERTY_REGEX = /\$\((?<property>.*?)\)/.freeze
|
15
|
-
|
16
|
-
def initialize(dependency_files:)
|
17
|
-
@dependency_files = dependency_files
|
18
|
-
end
|
19
|
-
|
20
|
-
def property_details(property_name:, callsite_file:, stack: [])
|
21
|
-
stack += [[property_name, callsite_file.name]]
|
22
|
-
|
23
|
-
node_details = deep_find_prop_node(
|
24
|
-
property: property_name,
|
25
|
-
file: callsite_file
|
26
|
-
)
|
27
|
-
|
28
|
-
node_details ||=
|
29
|
-
find_property_in_directory_build_props(
|
30
|
-
property: property_name,
|
31
|
-
callsite_file: callsite_file
|
32
|
-
)
|
33
|
-
|
34
|
-
return unless node_details
|
35
|
-
return node_details unless node_details[:value] =~ PROPERTY_REGEX
|
36
|
-
|
37
|
-
check_next_level_of_stack(node_details, stack)
|
38
|
-
end
|
39
|
-
|
40
|
-
def check_next_level_of_stack(node_details, stack)
|
41
|
-
property_name = node_details.fetch(:value).
|
42
|
-
match(PROPERTY_REGEX).
|
43
|
-
named_captures.fetch("property")
|
44
|
-
callsite_file = dependency_files.
|
45
|
-
find { |f| f.name == node_details.fetch(:file) }
|
46
|
-
|
47
|
-
if stack.include?([property_name, callsite_file.name])
|
48
|
-
raise "Circular reference!"
|
49
|
-
end
|
50
|
-
|
51
|
-
property_details(
|
52
|
-
property_name: property_name,
|
53
|
-
callsite_file: callsite_file,
|
54
|
-
stack: stack
|
55
|
-
)
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
attr_reader :dependency_files
|
61
|
-
|
62
|
-
def deep_find_prop_node(property:, file:)
|
63
|
-
doc = Nokogiri::XML(file.content)
|
64
|
-
doc.remove_namespaces!
|
65
|
-
node = doc.at_xpath(property_xpath(property))
|
66
|
-
|
67
|
-
# If we found a value for the property, return it
|
68
|
-
if node
|
69
|
-
return node_details(file: file, node: node, property: property)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Otherwise, we need to look in an imported file
|
73
|
-
import_path_finder =
|
74
|
-
FileFetchers::Dotnet::Nuget::ImportPathsFinder.
|
75
|
-
new(project_file: file)
|
76
|
-
|
77
|
-
import_paths = [
|
78
|
-
*import_path_finder.import_paths,
|
79
|
-
*import_path_finder.project_reference_paths
|
80
|
-
]
|
81
|
-
|
82
|
-
file = import_paths.
|
83
|
-
map { |p| dependency_files.find { |f| f.name == p } }.
|
84
|
-
compact.
|
85
|
-
find { |f| deep_find_prop_node(property: property, file: f) }
|
86
|
-
|
87
|
-
return unless file
|
88
|
-
|
89
|
-
deep_find_prop_node(property: property, file: file)
|
90
|
-
end
|
91
|
-
|
92
|
-
def find_property_in_directory_build_props(property:, callsite_file:)
|
93
|
-
file = buildfile_for_project(callsite_file)
|
94
|
-
return unless file
|
95
|
-
|
96
|
-
deep_find_prop_node(property: property, file: file)
|
97
|
-
end
|
98
|
-
|
99
|
-
def buildfile_for_project(project_file)
|
100
|
-
dir = File.dirname(project_file.name)
|
101
|
-
|
102
|
-
# Nuget walks up the directory structure looking for a
|
103
|
-
# Directory.Build.props file
|
104
|
-
possible_paths = dir.split("/").map.with_index do |_, i|
|
105
|
-
base = dir.split("/").first(i + 1).join("/")
|
106
|
-
Pathname.new(base + "/Directory.Build.props").cleanpath.to_path
|
107
|
-
end.reverse + ["Directory.Build.props"]
|
108
|
-
|
109
|
-
path = possible_paths.uniq.
|
110
|
-
find { |p| dependency_files.find { |f| f.name == p } }
|
111
|
-
|
112
|
-
dependency_files.find { |f| f.name == path }
|
113
|
-
end
|
114
|
-
|
115
|
-
def property_xpath(property_name)
|
116
|
-
"/Project/PropertyGroup/#{property_name}"
|
117
|
-
end
|
118
|
-
|
119
|
-
def node_details(file:, node:, property:)
|
120
|
-
{
|
121
|
-
file: file.name,
|
122
|
-
node: node,
|
123
|
-
value: node.content.strip,
|
124
|
-
root_property_name: property
|
125
|
-
}
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|