bibliothecary 8.7.4 → 8.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +21 -4
- data/.rubocop.yml +32 -941
- data/Gemfile +1 -1
- data/Rakefile +10 -0
- data/bibliothecary.gemspec +2 -2
- data/lib/bibliothecary/analyser.rb +6 -6
- data/lib/bibliothecary/cli.rb +8 -8
- data/lib/bibliothecary/configuration.rb +8 -8
- data/lib/bibliothecary/file_info.rb +2 -2
- data/lib/bibliothecary/multi_parsers/bundler_like_manifest.rb +1 -1
- data/lib/bibliothecary/multi_parsers/cyclonedx.rb +16 -17
- data/lib/bibliothecary/multi_parsers/dependencies_csv.rb +16 -16
- data/lib/bibliothecary/multi_parsers/json_runtime.rb +3 -3
- data/lib/bibliothecary/multi_parsers/spdx.rb +14 -14
- data/lib/bibliothecary/parsers/bower.rb +7 -7
- data/lib/bibliothecary/parsers/cargo.rb +15 -15
- data/lib/bibliothecary/parsers/carthage.rb +16 -16
- data/lib/bibliothecary/parsers/clojars.rb +7 -7
- data/lib/bibliothecary/parsers/cocoapods.rb +20 -20
- data/lib/bibliothecary/parsers/conda.rb +9 -9
- data/lib/bibliothecary/parsers/cpan.rb +12 -12
- data/lib/bibliothecary/parsers/cran.rb +12 -12
- data/lib/bibliothecary/parsers/dub.rb +8 -8
- data/lib/bibliothecary/parsers/elm.rb +8 -8
- data/lib/bibliothecary/parsers/go.rb +131 -66
- data/lib/bibliothecary/parsers/hackage.rb +13 -13
- data/lib/bibliothecary/parsers/haxelib.rb +4 -4
- data/lib/bibliothecary/parsers/hex.rb +11 -11
- data/lib/bibliothecary/parsers/julia.rb +4 -4
- data/lib/bibliothecary/parsers/maven.rb +88 -89
- data/lib/bibliothecary/parsers/meteor.rb +4 -4
- data/lib/bibliothecary/parsers/npm.rb +31 -31
- data/lib/bibliothecary/parsers/nuget.rb +44 -44
- data/lib/bibliothecary/parsers/packagist.rb +14 -14
- data/lib/bibliothecary/parsers/pub.rb +13 -13
- data/lib/bibliothecary/parsers/pypi.rb +71 -71
- data/lib/bibliothecary/parsers/rubygems.rb +15 -15
- data/lib/bibliothecary/parsers/shard.rb +13 -13
- data/lib/bibliothecary/parsers/swift_pm.rb +6 -6
- data/lib/bibliothecary/purl_util.rb +1 -1
- data/lib/bibliothecary/runner.rb +4 -4
- data/lib/bibliothecary/version.rb +1 -1
- data/lib/bibliothecary.rb +3 -3
- data/lib/sdl_parser.rb +5 -5
- metadata +2 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
require "json"
|
2
|
-
require
|
2
|
+
require "deb_control"
|
3
3
|
|
4
4
|
module Bibliothecary
|
5
5
|
module Parsers
|
@@ -9,13 +9,13 @@ module Bibliothecary
|
|
9
9
|
def self.mapping
|
10
10
|
{
|
11
11
|
match_extension(".cabal") => {
|
12
|
-
kind:
|
13
|
-
parser: :parse_cabal
|
12
|
+
kind: "manifest",
|
13
|
+
parser: :parse_cabal,
|
14
14
|
},
|
15
15
|
match_extension("cabal.config") => {
|
16
|
-
kind:
|
17
|
-
parser: :parse_cabal_config
|
18
|
-
}
|
16
|
+
kind: "lockfile",
|
17
|
+
parser: :parse_cabal_config,
|
18
|
+
},
|
19
19
|
}
|
20
20
|
end
|
21
21
|
|
@@ -23,9 +23,9 @@ module Bibliothecary
|
|
23
23
|
add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
|
24
24
|
add_multi_parser(Bibliothecary::MultiParsers::Spdx)
|
25
25
|
|
26
|
-
def self.parse_cabal(file_contents, options: {})
|
26
|
+
def self.parse_cabal(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
27
27
|
headers = {
|
28
|
-
|
28
|
+
"Content-Type" => "text/plain;charset=utf-8",
|
29
29
|
}
|
30
30
|
|
31
31
|
response = Typhoeus.post("#{Bibliothecary.configuration.cabal_parser_host}/parse", headers: headers, body: file_contents)
|
@@ -34,15 +34,15 @@ module Bibliothecary
|
|
34
34
|
JSON.parse(response.body, symbolize_names: true)
|
35
35
|
end
|
36
36
|
|
37
|
-
def self.parse_cabal_config(file_contents, options: {})
|
37
|
+
def self.parse_cabal_config(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
38
38
|
manifest = DebControl::ControlFileBase.parse(file_contents)
|
39
|
-
deps = manifest.first[
|
39
|
+
deps = manifest.first["constraints"].delete("\n").split(",").map(&:strip)
|
40
40
|
deps.map do |dependency|
|
41
|
-
dep = dependency.delete("==").split(
|
41
|
+
dep = dependency.delete("==").split(" ")
|
42
42
|
{
|
43
43
|
name: dep[0],
|
44
|
-
requirement: dep[1] ||
|
45
|
-
type:
|
44
|
+
requirement: dep[1] || "*",
|
45
|
+
type: "runtime",
|
46
46
|
}
|
47
47
|
end
|
48
48
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "json"
|
2
2
|
|
3
3
|
module Bibliothecary
|
4
4
|
module Parsers
|
@@ -9,9 +9,9 @@ module Bibliothecary
|
|
9
9
|
def self.mapping
|
10
10
|
{
|
11
11
|
match_filename("haxelib.json") => {
|
12
|
-
kind:
|
13
|
-
parser: :parse_json_runtime_manifest
|
14
|
-
}
|
12
|
+
kind: "manifest",
|
13
|
+
parser: :parse_json_runtime_manifest,
|
14
|
+
},
|
15
15
|
}
|
16
16
|
end
|
17
17
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "json"
|
2
2
|
|
3
3
|
module Bibliothecary
|
4
4
|
module Parsers
|
@@ -8,13 +8,13 @@ module Bibliothecary
|
|
8
8
|
def self.mapping
|
9
9
|
{
|
10
10
|
match_filename("mix.exs") => {
|
11
|
-
kind:
|
12
|
-
parser: :parse_mix
|
11
|
+
kind: "manifest",
|
12
|
+
parser: :parse_mix,
|
13
13
|
},
|
14
14
|
match_filename("mix.lock") => {
|
15
|
-
kind:
|
16
|
-
parser: :parse_mix_lock
|
17
|
-
}
|
15
|
+
kind: "lockfile",
|
16
|
+
parser: :parse_mix_lock,
|
17
|
+
},
|
18
18
|
}
|
19
19
|
end
|
20
20
|
|
@@ -22,7 +22,7 @@ module Bibliothecary
|
|
22
22
|
add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
|
23
23
|
add_multi_parser(Bibliothecary::MultiParsers::Spdx)
|
24
24
|
|
25
|
-
def self.parse_mix(file_contents, options: {})
|
25
|
+
def self.parse_mix(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
26
26
|
response = Typhoeus.post("#{Bibliothecary.configuration.mix_parser_host}/", body: file_contents)
|
27
27
|
raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{Bibliothecary.configuration.mix_parser_host}/", response.response_code) unless response.success?
|
28
28
|
json = JSON.parse response.body
|
@@ -31,12 +31,12 @@ module Bibliothecary
|
|
31
31
|
{
|
32
32
|
name: name,
|
33
33
|
requirement: version,
|
34
|
-
type: "runtime"
|
34
|
+
type: "runtime",
|
35
35
|
}
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
def self.parse_mix_lock(file_contents, options: {})
|
39
|
+
def self.parse_mix_lock(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
40
40
|
response = Typhoeus.post("#{Bibliothecary.configuration.mix_parser_host}/lock", body: file_contents)
|
41
41
|
raise Bibliothecary::RemoteParsingError.new("Http Error #{response.response_code} when contacting: #{Bibliothecary.configuration.mix_parser_host}/", response.response_code) unless response.success?
|
42
42
|
json = JSON.parse response.body
|
@@ -44,8 +44,8 @@ module Bibliothecary
|
|
44
44
|
json.map do |name, info|
|
45
45
|
{
|
46
46
|
name: name,
|
47
|
-
requirement: info[
|
48
|
-
type: "runtime"
|
47
|
+
requirement: info["version"],
|
48
|
+
type: "runtime",
|
49
49
|
}
|
50
50
|
end
|
51
51
|
end
|
@@ -7,14 +7,14 @@ module Bibliothecary
|
|
7
7
|
{
|
8
8
|
match_filename("REQUIRE", case_insensitive: true) => {
|
9
9
|
kind: "manifest",
|
10
|
-
parser: :parse_require
|
11
|
-
}
|
10
|
+
parser: :parse_require,
|
11
|
+
},
|
12
12
|
}
|
13
13
|
end
|
14
14
|
|
15
15
|
add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
|
16
16
|
|
17
|
-
def self.parse_require(file_contents, options: {})
|
17
|
+
def self.parse_require(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
18
18
|
deps = []
|
19
19
|
file_contents.split("\n").each do |line|
|
20
20
|
next if line.match(/^#/) || line.empty?
|
@@ -32,7 +32,7 @@ module Bibliothecary
|
|
32
32
|
deps << {
|
33
33
|
name: name,
|
34
34
|
requirement: reqs,
|
35
|
-
type: "runtime"
|
35
|
+
type: "runtime",
|
36
36
|
}
|
37
37
|
end
|
38
38
|
deps
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "ox"
|
2
|
+
require "strings-ansi"
|
3
3
|
|
4
4
|
# Known shortcomings and unimplemented Maven features:
|
5
5
|
# pom.xml
|
@@ -11,19 +11,19 @@ module Bibliothecary
|
|
11
11
|
include Bibliothecary::Analyser
|
12
12
|
|
13
13
|
# e.g. "annotationProcessor - Annotation processors and their dependencies for source set 'main'."
|
14
|
-
|
14
|
+
GRADLE_TYPE_REGEXP = /^(\w+)/
|
15
15
|
|
16
16
|
# e.g. "| \\--- com.google.guava:guava:23.5-jre (*)"
|
17
|
-
|
17
|
+
GRADLE_DEP_REGEXP = /(\+---|\\---){1}/
|
18
18
|
|
19
19
|
# Dependencies that are on-disk projects, eg:
|
20
20
|
# e.g. "\--- project :api:my-internal-project"
|
21
21
|
# e.g. "+--- my-group:my-alias:1.2.3 -> project :client (*)"
|
22
|
-
|
22
|
+
GRADLE_PROJECT_REGEXP = /project :(\S+)?/
|
23
23
|
|
24
24
|
# line ending legend: (c) means a dependency constraint, (n) means not resolved, or (*) means resolved previously, e.g. org.springframework.boot:spring-boot-starter-web:2.1.0.M3 (*)
|
25
25
|
# e.g. the "(n)" in "+--- my-group:my-name:1.2.3 (n)"
|
26
|
-
|
26
|
+
GRADLE_LINE_ENDING_REGEXP = /(\((c|n|\*)\))$/
|
27
27
|
|
28
28
|
# Builtin methods: https://docs.gradle.org/current/userguide/java_plugin.html#tab:configurations
|
29
29
|
# Deprecated methods: https://docs.gradle.org/current/userguide/upgrading_version_6.html#sec:configuration_removal
|
@@ -32,70 +32,70 @@ module Bibliothecary
|
|
32
32
|
# Intentionally overly-simplified regexes to scrape deps from build.gradle (Groovy) and build.gradle.kts (Kotlin) files.
|
33
33
|
# To be truly useful bibliothecary would need full Groovy / Kotlin parsers that speaks Gradle,
|
34
34
|
# because the Groovy and Kotlin DSLs have many dynamic ways of declaring dependencies.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
GRADLE_VERSION_REGEXP = /[\w.-]+/ # e.g. '1.2.3'
|
36
|
+
GRADLE_VAR_INTERPOLATION_REGEXP = /\$\w+/ # e.g. '$myVersion'
|
37
|
+
GRADLE_CODE_INTERPOLATION_REGEXP = /\$\{.*\}/ # e.g. '${my-project-settings["version"]}'
|
38
|
+
GRADLE_GAV_REGEXP = /([\w.-]+)\:([\w.-]+)(?:\:(#{GRADLE_VERSION_REGEXP}|#{GRADLE_VAR_INTERPOLATION_REGEXP}|#{GRADLE_CODE_INTERPOLATION_REGEXP}))?/ # e.g. "group:artifactId:1.2.3"
|
39
|
+
GRADLE_GROOVY_SIMPLE_REGEXP = /(#{GRADLE_DEPENDENCY_METHODS.join('|')})\s*\(?\s*['"]#{GRADLE_GAV_REGEXP}['"]/m
|
40
|
+
GRADLE_KOTLIN_SIMPLE_REGEXP = /(#{GRADLE_DEPENDENCY_METHODS.join('|')})\s*\(\s*"#{GRADLE_GAV_REGEXP}"/m
|
41
|
+
|
42
|
+
MAVEN_PROPERTY_REGEXP = /\$\{(.+?)\}/
|
43
43
|
MAX_DEPTH = 5
|
44
44
|
|
45
45
|
# e.g. "[info] test:"
|
46
|
-
|
46
|
+
SBT_TYPE_REGEXP = /^\[info\]\s+([-\w]+):$/
|
47
47
|
|
48
48
|
# e.g. "[info] org.typelevel:spire-util_2.12"
|
49
|
-
|
49
|
+
SBT_DEP_REGEXP = /^\[info\]\s+(.+)$/
|
50
50
|
|
51
51
|
# e.g. "[info] - 1.7.5"
|
52
|
-
|
52
|
+
SBT_VERSION_REGEXP = /^\[info\]\s+-\s+(.+)$/
|
53
53
|
|
54
54
|
# e.g. "[info] homepage: http://www.slf4j.org"
|
55
|
-
|
55
|
+
SBT_FIELD_REGEXP = /^\[info\]\s+([^:]+):\s+(.+)$/
|
56
56
|
|
57
57
|
# e.g. "[info] "
|
58
|
-
|
58
|
+
SBT_IGNORE_REGEXP = /^\[info\]\s*$/
|
59
59
|
|
60
60
|
def self.mapping
|
61
61
|
{
|
62
62
|
match_filename("ivy.xml", case_insensitive: true) => {
|
63
|
-
kind:
|
64
|
-
parser: :parse_ivy_manifest
|
63
|
+
kind: "manifest",
|
64
|
+
parser: :parse_ivy_manifest,
|
65
65
|
},
|
66
66
|
match_filename("pom.xml", case_insensitive: true) => {
|
67
|
-
kind:
|
68
|
-
parser: :parse_standalone_pom_manifest
|
67
|
+
kind: "manifest",
|
68
|
+
parser: :parse_standalone_pom_manifest,
|
69
69
|
},
|
70
70
|
match_filename("build.gradle", case_insensitive: true) => {
|
71
|
-
kind:
|
72
|
-
parser: :parse_gradle
|
71
|
+
kind: "manifest",
|
72
|
+
parser: :parse_gradle,
|
73
73
|
},
|
74
74
|
match_filename("build.gradle.kts", case_insensitive: true) => {
|
75
|
-
kind:
|
76
|
-
parser: :parse_gradle_kts
|
75
|
+
kind: "manifest",
|
76
|
+
parser: :parse_gradle_kts,
|
77
77
|
},
|
78
78
|
match_extension(".xml", case_insensitive: true) => {
|
79
79
|
content_matcher: :ivy_report?,
|
80
|
-
kind:
|
81
|
-
parser: :parse_ivy_report
|
80
|
+
kind: "lockfile",
|
81
|
+
parser: :parse_ivy_report,
|
82
82
|
},
|
83
83
|
match_filename("gradle-dependencies-q.txt", case_insensitive: true) => {
|
84
|
-
kind:
|
85
|
-
parser: :parse_gradle_resolved
|
84
|
+
kind: "lockfile",
|
85
|
+
parser: :parse_gradle_resolved,
|
86
86
|
},
|
87
87
|
match_filename("maven-resolved-dependencies.txt", case_insensitive: true) => {
|
88
|
-
kind:
|
89
|
-
parser: :parse_maven_resolved
|
88
|
+
kind: "lockfile",
|
89
|
+
parser: :parse_maven_resolved,
|
90
90
|
},
|
91
91
|
match_filename("sbt-update-full.txt", case_insensitive: true) => {
|
92
|
-
kind:
|
93
|
-
parser: :parse_sbt_update_full
|
92
|
+
kind: "lockfile",
|
93
|
+
parser: :parse_sbt_update_full,
|
94
94
|
},
|
95
95
|
match_filename("maven-dependency-tree.txt", case_insensitive: true) => {
|
96
|
-
kind:
|
97
|
-
parser: :parse_maven_tree
|
98
|
-
}
|
96
|
+
kind: "lockfile",
|
97
|
+
parser: :parse_maven_tree,
|
98
|
+
},
|
99
99
|
}
|
100
100
|
end
|
101
101
|
|
@@ -103,14 +103,14 @@ module Bibliothecary
|
|
103
103
|
add_multi_parser(Bibliothecary::MultiParsers::Spdx)
|
104
104
|
add_multi_parser(Bibliothecary::MultiParsers::DependenciesCSV)
|
105
105
|
|
106
|
-
def self.parse_ivy_manifest(file_contents, options: {})
|
106
|
+
def self.parse_ivy_manifest(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
107
107
|
manifest = Ox.parse file_contents
|
108
|
-
manifest.dependencies.locate(
|
108
|
+
manifest.dependencies.locate("dependency").map do |dependency|
|
109
109
|
attrs = dependency.attributes
|
110
110
|
{
|
111
111
|
name: "#{attrs[:org]}:#{attrs[:name]}",
|
112
112
|
requirement: attrs[:rev],
|
113
|
-
type:
|
113
|
+
type: "runtime",
|
114
114
|
}
|
115
115
|
end
|
116
116
|
end
|
@@ -126,7 +126,7 @@ module Bibliothecary
|
|
126
126
|
false
|
127
127
|
end
|
128
128
|
|
129
|
-
def self.parse_ivy_report(file_contents, options: {})
|
129
|
+
def self.parse_ivy_report(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
130
130
|
doc = Ox.parse file_contents
|
131
131
|
root = doc.locate("ivy-report").first
|
132
132
|
raise "ivy-report document does not have ivy-report at the root" if root.nil?
|
@@ -139,44 +139,44 @@ module Bibliothecary
|
|
139
139
|
attrs = mod.attributes
|
140
140
|
org = attrs[:organisation]
|
141
141
|
name = attrs[:name]
|
142
|
-
version = mod.locate(
|
142
|
+
version = mod.locate("revision").first&.attributes[:name]
|
143
143
|
|
144
144
|
next nil if org.nil? or name.nil? or version.nil?
|
145
145
|
|
146
146
|
{
|
147
147
|
name: "#{org}:#{name}",
|
148
148
|
requirement: version,
|
149
|
-
type: type
|
149
|
+
type: type,
|
150
150
|
}
|
151
151
|
end.compact
|
152
152
|
end
|
153
153
|
|
154
|
-
def self.parse_gradle_resolved(file_contents, options: {})
|
154
|
+
def self.parse_gradle_resolved(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
155
155
|
current_type = nil
|
156
156
|
|
157
157
|
file_contents.split("\n").map do |line|
|
158
|
-
current_type_match =
|
158
|
+
current_type_match = GRADLE_TYPE_REGEXP.match(line)
|
159
159
|
current_type = current_type_match.captures[0] if current_type_match
|
160
160
|
|
161
|
-
gradle_dep_match =
|
161
|
+
gradle_dep_match = GRADLE_DEP_REGEXP.match(line)
|
162
162
|
next unless gradle_dep_match
|
163
163
|
|
164
164
|
split = gradle_dep_match.captures[0]
|
165
165
|
|
166
166
|
# gradle can import on-disk projects and deps will be listed under them, e.g. `+--- project :test:integration`,
|
167
167
|
# so we treat these projects as "internal" deps with requirement of "1.0.0"
|
168
|
-
if (project_match = line.match(
|
168
|
+
if (project_match = line.match(GRADLE_PROJECT_REGEXP))
|
169
169
|
# an empty project name is self-referential (i.e. a cycle), and we don't need to track the manifest's project itself, e.g. "+--- project :"
|
170
170
|
next if project_match[1].nil?
|
171
171
|
|
172
172
|
# project names can have colons (e.g. for gradle projects in subfolders), which breaks maven artifact naming assumptions, so just replace them with hyphens.
|
173
173
|
project_name = project_match[1].gsub(/:/, "-")
|
174
|
-
line = line.sub(
|
174
|
+
line = line.sub(GRADLE_PROJECT_REGEXP, "internal:#{project_name}:1.0.0")
|
175
175
|
end
|
176
176
|
|
177
177
|
dep = line
|
178
178
|
.split(split)[1]
|
179
|
-
.sub(
|
179
|
+
.sub(GRADLE_LINE_ENDING_REGEXP, "")
|
180
180
|
.sub(/ FAILED$/, "") # dependency could not be resolved (but still may have a version)
|
181
181
|
.sub(" -> ", ":") # handle version arrow syntax
|
182
182
|
.strip
|
@@ -193,7 +193,7 @@ module Bibliothecary
|
|
193
193
|
original_requirement: dep[2],
|
194
194
|
name: dep[-3..-2].join(":"),
|
195
195
|
requirement: dep[-1],
|
196
|
-
type: current_type
|
196
|
+
type: current_type,
|
197
197
|
}
|
198
198
|
elsif dep.count == 5
|
199
199
|
# get name from renamed package resolution "org:name -> renamed_org:name:version"
|
@@ -202,14 +202,14 @@ module Bibliothecary
|
|
202
202
|
original_requirement: "*",
|
203
203
|
name: dep[-3..-2].join(":"),
|
204
204
|
requirement: dep[-1],
|
205
|
-
type: current_type
|
205
|
+
type: current_type,
|
206
206
|
}
|
207
207
|
else
|
208
208
|
# get name from version conflict resolution ("org:name:version -> version") and no-resolution ("org:name:version")
|
209
209
|
{
|
210
210
|
name: dep[0..1].join(":"),
|
211
211
|
requirement: dep[-1],
|
212
|
-
type: current_type
|
212
|
+
type: current_type,
|
213
213
|
}
|
214
214
|
end
|
215
215
|
end
|
@@ -217,7 +217,7 @@ module Bibliothecary
|
|
217
217
|
.uniq { |item| item.values_at(:name, :requirement, :type, :original_name, :original_requirement) }
|
218
218
|
end
|
219
219
|
|
220
|
-
def self.parse_maven_resolved(file_contents, options: {})
|
220
|
+
def self.parse_maven_resolved(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
221
221
|
Strings::ANSI.sanitize(file_contents)
|
222
222
|
.split("\n")
|
223
223
|
.map(&method(:parse_resolved_dep_line))
|
@@ -225,7 +225,7 @@ module Bibliothecary
|
|
225
225
|
.uniq
|
226
226
|
end
|
227
227
|
|
228
|
-
def self.parse_maven_tree(file_contents, options: {})
|
228
|
+
def self.parse_maven_tree(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
229
229
|
captures = Strings::ANSI.sanitize(file_contents)
|
230
230
|
.gsub(/\r\n?/, "\n")
|
231
231
|
.scan(/^\[INFO\](?:(?:\+-)|\||(?:\\-)|\s)+((?:[\w\.-]+:)+[\w\.\-${}]+)/)
|
@@ -244,7 +244,7 @@ module Bibliothecary
|
|
244
244
|
{
|
245
245
|
name: parts[0..1].join(":"),
|
246
246
|
requirement: version,
|
247
|
-
type: type
|
247
|
+
type: type,
|
248
248
|
}
|
249
249
|
end
|
250
250
|
|
@@ -264,7 +264,7 @@ module Bibliothecary
|
|
264
264
|
{
|
265
265
|
name: dep_parts[0, 2].join(":"),
|
266
266
|
requirement: dep_parts[3],
|
267
|
-
type: dep_parts[4].split("--").first.strip
|
267
|
+
type: dep_parts[4].split("--").first.strip,
|
268
268
|
}
|
269
269
|
end
|
270
270
|
|
@@ -274,9 +274,9 @@ module Bibliothecary
|
|
274
274
|
|
275
275
|
# parent_properties is used by Libraries:
|
276
276
|
# https://github.com/librariesio/libraries.io/blob/e970925aade2596a03268b6e1be785eba8502c62/app/models/package_manager/maven.rb#L129
|
277
|
-
def self.parse_pom_manifest(file_contents, parent_properties = {}, options: {})
|
277
|
+
def self.parse_pom_manifest(file_contents, parent_properties = {}, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
278
278
|
manifest = Ox.parse file_contents
|
279
|
-
xml = manifest.respond_to?(
|
279
|
+
xml = manifest.respond_to?("project") ? manifest.project : manifest
|
280
280
|
[].tap do |deps|
|
281
281
|
# <dependencyManagement> is a namespace to specify artifact configuration (e.g. version), but it doesn't
|
282
282
|
# actually add dependencies to your project. Grab these and keep them for reference while parsing <dependencies>
|
@@ -292,10 +292,10 @@ module Bibliothecary
|
|
292
292
|
end
|
293
293
|
# <dependencies> is the namespace that will add dependencies to your project.
|
294
294
|
xml.locate("dependencies/dependency").each do |dep|
|
295
|
-
groupId = extract_pom_dep_info(xml, dep,
|
296
|
-
artifactId = extract_pom_dep_info(xml, dep,
|
297
|
-
version = extract_pom_dep_info(xml, dep,
|
298
|
-
scope = extract_pom_dep_info(xml, dep,
|
295
|
+
groupId = extract_pom_dep_info(xml, dep, "groupId", parent_properties)
|
296
|
+
artifactId = extract_pom_dep_info(xml, dep, "artifactId", parent_properties)
|
297
|
+
version = extract_pom_dep_info(xml, dep, "version", parent_properties)
|
298
|
+
scope = extract_pom_dep_info(xml, dep, "scope", parent_properties)
|
299
299
|
|
300
300
|
# Use any dep configurations from <dependencyManagement> as fallbacks
|
301
301
|
if (depConfig = dependencyManagement.find { |d| d[:groupId] == groupId && d[:artifactId] == artifactId })
|
@@ -306,38 +306,38 @@ module Bibliothecary
|
|
306
306
|
dep_hash = {
|
307
307
|
name: "#{groupId}:#{artifactId}",
|
308
308
|
requirement: version,
|
309
|
-
type: scope ||
|
309
|
+
type: scope || "runtime",
|
310
310
|
}
|
311
311
|
# optional field is, itself, optional, and will be either "true" or "false"
|
312
|
-
optional = extract_pom_dep_info(xml, dep,
|
312
|
+
optional = extract_pom_dep_info(xml, dep, "optional", parent_properties)
|
313
313
|
dep_hash[:optional] = optional == "true" unless optional.nil?
|
314
314
|
deps.push(dep_hash)
|
315
315
|
end
|
316
316
|
end
|
317
317
|
end
|
318
318
|
|
319
|
-
def self.parse_gradle(file_contents, options: {})
|
319
|
+
def self.parse_gradle(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
320
320
|
file_contents
|
321
|
-
|
322
|
-
|
323
|
-
|
321
|
+
.scan(GRADLE_GROOVY_SIMPLE_REGEXP) # match 'implementation "group:artifactId:version"'
|
322
|
+
.reject { |(_type, group, artifactId, _version)| group.nil? || artifactId.nil? } # remove any matches with missing group/artifactId
|
323
|
+
.map { |(type, group, artifactId, version)|
|
324
324
|
{
|
325
325
|
name: [group, artifactId].join(":"),
|
326
326
|
requirement: version || "*",
|
327
|
-
type: type
|
327
|
+
type: type,
|
328
|
+
}
|
328
329
|
}
|
329
|
-
}
|
330
330
|
end
|
331
331
|
|
332
|
-
def self.parse_gradle_kts(file_contents, options: {})
|
332
|
+
def self.parse_gradle_kts(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
333
333
|
file_contents
|
334
|
-
.scan(
|
334
|
+
.scan(GRADLE_KOTLIN_SIMPLE_REGEXP) # match 'implementation("group:artifactId:version")'
|
335
335
|
.reject { |(_type, group, artifactId, _version)| group.nil? || artifactId.nil? } # remove any matches with missing group/artifactId
|
336
336
|
.map { |(type, group, artifactId, version)|
|
337
337
|
{
|
338
338
|
name: [group, artifactId].join(":"),
|
339
339
|
requirement: version || "*",
|
340
|
-
type: type
|
340
|
+
type: type,
|
341
341
|
}
|
342
342
|
}
|
343
343
|
end
|
@@ -371,7 +371,7 @@ module Bibliothecary
|
|
371
371
|
value = value.value if value.is_a?(Ox::CData)
|
372
372
|
# whitespace in dependency tags should be ignored
|
373
373
|
value = value&.strip
|
374
|
-
match = value&.match(
|
374
|
+
match = value&.match(MAVEN_PROPERTY_REGEXP)
|
375
375
|
if match
|
376
376
|
return extract_property(xml, match[1], value, parent_properties)
|
377
377
|
else
|
@@ -390,7 +390,7 @@ module Bibliothecary
|
|
390
390
|
|
391
391
|
resolved_value = replace_value_with_prop(value, prop_value, property_name)
|
392
392
|
# check to see if we just resolved to another property name
|
393
|
-
match = resolved_value.match(
|
393
|
+
match = resolved_value.match(MAVEN_PROPERTY_REGEXP)
|
394
394
|
if match && depth < MAX_DEPTH
|
395
395
|
depth += 1
|
396
396
|
return extract_property(xml, match[1], resolved_value, parent_properties, depth)
|
@@ -407,8 +407,8 @@ module Bibliothecary
|
|
407
407
|
|
408
408
|
prop_field = xml.properties.locate(property_name).first if xml.respond_to?("properties")
|
409
409
|
parent_prop = parent_properties[property_name] || # e.g. "${foo}"
|
410
|
-
parent_properties[property_name.sub(/^project\./,
|
411
|
-
parent_properties[property_name.sub(/^project\.parent\./,
|
410
|
+
parent_properties[property_name.sub(/^project\./, "")] || # e.g. "${project.foo}"
|
411
|
+
parent_properties[property_name.sub(/^project\.parent\./, "")] # e.g. "${project.parent.foo}"
|
412
412
|
|
413
413
|
if prop_field
|
414
414
|
prop_field.nodes.first
|
@@ -425,14 +425,13 @@ module Bibliothecary
|
|
425
425
|
end
|
426
426
|
end
|
427
427
|
|
428
|
-
def self.parse_sbt_update_full(file_contents, options: {})
|
428
|
+
def self.parse_sbt_update_full(file_contents, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
429
429
|
all_deps = []
|
430
|
-
type = nil
|
431
430
|
lines = file_contents.split("\n")
|
432
431
|
while lines.any?
|
433
432
|
line = lines.shift
|
434
433
|
|
435
|
-
type_match =
|
434
|
+
type_match = SBT_TYPE_REGEXP.match(line)
|
436
435
|
next unless type_match
|
437
436
|
type = type_match.captures[0]
|
438
437
|
|
@@ -464,12 +463,12 @@ module Bibliothecary
|
|
464
463
|
|
465
464
|
def self.parse_sbt_deps(type, lines)
|
466
465
|
deps = []
|
467
|
-
while lines.any? and not
|
466
|
+
while lines.any? and not SBT_TYPE_REGEXP.match(lines[0])
|
468
467
|
line = lines.shift
|
469
468
|
|
470
|
-
next if
|
469
|
+
next if SBT_IGNORE_REGEXP.match(line)
|
471
470
|
|
472
|
-
dep_match =
|
471
|
+
dep_match = SBT_DEP_REGEXP.match(line)
|
473
472
|
if dep_match
|
474
473
|
versions = parse_sbt_versions(type, dep_match.captures[0], lines)
|
475
474
|
deps.concat(versions)
|
@@ -484,10 +483,10 @@ module Bibliothecary
|
|
484
483
|
|
485
484
|
def self.parse_sbt_versions(type, name, lines)
|
486
485
|
versions = []
|
487
|
-
while lines.any? and not
|
486
|
+
while lines.any? and not SBT_TYPE_REGEXP.match(lines[0])
|
488
487
|
line = lines.shift
|
489
488
|
|
490
|
-
version_match =
|
489
|
+
version_match = SBT_VERSION_REGEXP.match(line)
|
491
490
|
if version_match
|
492
491
|
versions.push(parse_sbt_version(type, name, version_match.captures[0], lines))
|
493
492
|
else
|
@@ -501,10 +500,10 @@ module Bibliothecary
|
|
501
500
|
|
502
501
|
def self.parse_sbt_version(type, name, version, lines)
|
503
502
|
fields = {}
|
504
|
-
while lines.any? and not
|
503
|
+
while lines.any? and not SBT_TYPE_REGEXP.match(lines[0])
|
505
504
|
line = lines.shift
|
506
505
|
|
507
|
-
field_match =
|
506
|
+
field_match = SBT_FIELD_REGEXP.match(line)
|
508
507
|
if field_match
|
509
508
|
fields[field_match.captures[0]] = field_match.captures[1]
|
510
509
|
else
|
@@ -518,7 +517,7 @@ module Bibliothecary
|
|
518
517
|
requirement: version,
|
519
518
|
type: type,
|
520
519
|
# we post-process using some of these fields and then delete them again
|
521
|
-
fields: fields
|
520
|
+
fields: fields,
|
522
521
|
}
|
523
522
|
end
|
524
523
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "json"
|
2
2
|
|
3
3
|
module Bibliothecary
|
4
4
|
module Parsers
|
@@ -9,9 +9,9 @@ module Bibliothecary
|
|
9
9
|
def self.mapping
|
10
10
|
{
|
11
11
|
match_filename("versions.json") => {
|
12
|
-
kind:
|
13
|
-
parser: :parse_json_runtime_manifest
|
14
|
-
}
|
12
|
+
kind: "manifest",
|
13
|
+
parser: :parse_json_runtime_manifest,
|
14
|
+
},
|
15
15
|
}
|
16
16
|
end
|
17
17
|
|