spandx 0.13.3 → 0.15.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -2
- data/exe/spandx +0 -1
- data/ext/spandx/spandx.c +7 -3
- data/lib/spandx.rb +1 -1
- data/lib/spandx/cli.rb +2 -2
- data/lib/spandx/cli/commands/pull.rb +33 -4
- data/lib/spandx/cli/commands/scan.rb +19 -22
- data/lib/spandx/cli/main.rb +3 -3
- data/lib/spandx/cli/printer.rb +27 -0
- data/lib/spandx/cli/printers/csv.rb +17 -0
- data/lib/spandx/cli/printers/json.rb +17 -0
- data/lib/spandx/cli/printers/table.rb +42 -0
- data/lib/spandx/core/dependency.rb +48 -13
- data/lib/spandx/core/git.rb +6 -6
- data/lib/spandx/core/http.rb +6 -6
- data/lib/spandx/core/license_plugin.rb +10 -4
- data/lib/spandx/core/parser.rb +9 -4
- data/lib/spandx/core/path_traversal.rb +4 -13
- data/lib/spandx/core/plugin.rb +6 -0
- data/lib/spandx/core/thread_pool.rb +49 -0
- data/lib/spandx/dotnet/nuget_gateway.rb +1 -1
- data/lib/spandx/dotnet/parsers/csproj.rb +7 -7
- data/lib/spandx/dotnet/parsers/packages_config.rb +7 -7
- data/lib/spandx/dotnet/parsers/sln.rb +10 -13
- data/lib/spandx/dotnet/project_file.rb +3 -3
- data/lib/spandx/java/parsers/maven.rb +7 -7
- data/lib/spandx/js/parsers/npm.rb +8 -8
- data/lib/spandx/js/parsers/yarn.rb +7 -7
- data/lib/spandx/js/yarn_pkg.rb +1 -1
- data/lib/spandx/os/parsers/apk.rb +51 -0
- data/lib/spandx/os/parsers/dpkg.rb +69 -0
- data/lib/spandx/php/packagist_gateway.rb +1 -1
- data/lib/spandx/php/parsers/composer.rb +7 -7
- data/lib/spandx/python/parsers/pipfile_lock.rb +4 -4
- data/lib/spandx/python/pypi.rb +19 -7
- data/lib/spandx/python/source.rb +1 -1
- data/lib/spandx/ruby/gateway.rb +1 -1
- data/lib/spandx/ruby/parsers/gemfile_lock.rb +10 -9
- data/lib/spandx/spdx/catalogue.rb +1 -1
- data/lib/spandx/version.rb +1 -1
- data/spandx.gemspec +5 -4
- metadata +38 -20
- data/lib/spandx/core/report.rb +0 -60
- data/lib/spandx/core/spinner.rb +0 -51
- data/lib/spandx/core/table.rb +0 -29
data/lib/spandx/js/yarn_pkg.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spandx
|
4
|
+
module Os
|
5
|
+
module Parsers
|
6
|
+
class Apk < ::Spandx::Core::Parser
|
7
|
+
def match?(path)
|
8
|
+
path.basename.fnmatch?('installed')
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse(lockfile)
|
12
|
+
path = lockfile.to_s
|
13
|
+
|
14
|
+
[].tap do |items|
|
15
|
+
lockfile.open(mode: 'r') do |io|
|
16
|
+
each_package(io) do |data|
|
17
|
+
items.push(map_from(data, path))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def each_package(io)
|
26
|
+
package = {}
|
27
|
+
|
28
|
+
until io.eof?
|
29
|
+
line = io.readline.chomp
|
30
|
+
if line.empty?
|
31
|
+
yield package
|
32
|
+
|
33
|
+
package = {}
|
34
|
+
else
|
35
|
+
line.split(':').tap { |(key, value)| package[key] = value }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def map_from(data, path)
|
41
|
+
::Spandx::Core::Dependency.new(
|
42
|
+
path: path,
|
43
|
+
name: data['P'],
|
44
|
+
version: data['V'],
|
45
|
+
meta: data.merge('license' => [data['L']])
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spandx
|
4
|
+
module Os
|
5
|
+
module Parsers
|
6
|
+
class Dpkg < ::Spandx::Core::Parser
|
7
|
+
class LineReader
|
8
|
+
attr_reader :io
|
9
|
+
|
10
|
+
def initialize(io)
|
11
|
+
@io = io
|
12
|
+
end
|
13
|
+
|
14
|
+
def each
|
15
|
+
yield read_package(io, Hash.new(''), nil) until io.eof?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def read_package(io, package, prev_key)
|
21
|
+
return package if io.eof?
|
22
|
+
|
23
|
+
line = io.readline.chomp
|
24
|
+
return package if line.empty?
|
25
|
+
|
26
|
+
key, value = split(line, prev_key)
|
27
|
+
package[key] += value
|
28
|
+
read_package(io, package, key)
|
29
|
+
end
|
30
|
+
|
31
|
+
def split(line, prev_key)
|
32
|
+
if prev_key && line.start_with?(' ')
|
33
|
+
[prev_key, line]
|
34
|
+
else
|
35
|
+
key, *rest = line.split(':')
|
36
|
+
value = rest&.join(':')&.strip
|
37
|
+
[key, value]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def match?(path)
|
43
|
+
path.basename.fnmatch?('status')
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse(lockfile)
|
47
|
+
[].tap do |items|
|
48
|
+
lockfile.open(mode: 'r') do |io|
|
49
|
+
LineReader.new(io).each do |data|
|
50
|
+
items.push(map_from(data, lockfile.to_s))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def map_from(data, path)
|
59
|
+
::Spandx::Core::Dependency.new(
|
60
|
+
path: path,
|
61
|
+
name: data['Package'],
|
62
|
+
version: data['Version'],
|
63
|
+
meta: data
|
64
|
+
)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -17,7 +17,7 @@ module Spandx
|
|
17
17
|
response = http.get("https://repo.packagist.org/p/#{dependency.name}.json")
|
18
18
|
return [] unless http.ok?(response)
|
19
19
|
|
20
|
-
json =
|
20
|
+
json = Oj.load(response.body)
|
21
21
|
json['packages'][dependency.name][dependency.version]['license']
|
22
22
|
end
|
23
23
|
end
|
@@ -4,24 +4,24 @@ module Spandx
|
|
4
4
|
module Php
|
5
5
|
module Parsers
|
6
6
|
class Composer < ::Spandx::Core::Parser
|
7
|
-
def
|
8
|
-
|
7
|
+
def match?(path)
|
8
|
+
path.basename.fnmatch? 'composer.lock'
|
9
9
|
end
|
10
10
|
|
11
|
-
def parse(
|
11
|
+
def parse(path)
|
12
12
|
items = Set.new
|
13
|
-
composer_lock =
|
13
|
+
composer_lock = Oj.load(path.read)
|
14
14
|
composer_lock['packages'].concat(composer_lock['packages-dev']).each do |dependency|
|
15
|
-
items.add(map_from(dependency))
|
15
|
+
items.add(map_from(path, dependency))
|
16
16
|
end
|
17
17
|
items
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
21
21
|
|
22
|
-
def map_from(dependency)
|
22
|
+
def map_from(path, dependency)
|
23
23
|
Spandx::Core::Dependency.new(
|
24
|
-
|
24
|
+
path: path,
|
25
25
|
name: dependency['name'],
|
26
26
|
version: dependency['version'],
|
27
27
|
meta: dependency
|
@@ -4,8 +4,8 @@ module Spandx
|
|
4
4
|
module Python
|
5
5
|
module Parsers
|
6
6
|
class PipfileLock < ::Spandx::Core::Parser
|
7
|
-
def
|
8
|
-
|
7
|
+
def match?(path)
|
8
|
+
path.basename.fnmatch?('Pipfile*.lock')
|
9
9
|
end
|
10
10
|
|
11
11
|
def parse(lockfile)
|
@@ -19,10 +19,10 @@ module Spandx
|
|
19
19
|
private
|
20
20
|
|
21
21
|
def dependencies_from(lockfile)
|
22
|
-
json =
|
22
|
+
json = Oj.load(lockfile.read)
|
23
23
|
each_dependency(json) do |name, version|
|
24
24
|
yield ::Spandx::Core::Dependency.new(
|
25
|
-
|
25
|
+
path: lockfile,
|
26
26
|
name: name,
|
27
27
|
version: version,
|
28
28
|
meta: json
|
data/lib/spandx/python/pypi.rb
CHANGED
@@ -49,19 +49,26 @@ module Spandx
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def version_from(url)
|
52
|
-
path =
|
53
|
-
memo.gsub(item, '')
|
54
|
-
end
|
55
|
-
|
52
|
+
path = cleanup(url)
|
56
53
|
return if path.rindex('-').nil?
|
57
54
|
|
58
|
-
path.scan(/-\d+\..*/)
|
55
|
+
section = path.scan(/-\d+\..*/)
|
56
|
+
section = path.scan(/-\d+\.?.*/) if section.empty?
|
57
|
+
section[-1][1..-1]
|
58
|
+
rescue StandardError => error
|
59
|
+
warn([url, error].inspect)
|
59
60
|
end
|
60
61
|
|
61
62
|
private
|
62
63
|
|
63
64
|
attr_reader :http
|
64
65
|
|
66
|
+
def cleanup(url)
|
67
|
+
SUBSTITUTIONS.inject(URI.parse(url).path.split('/')[-1]) do |memo, item|
|
68
|
+
memo.gsub(item, '')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
65
72
|
def sources_for(dependency)
|
66
73
|
return default_sources if dependency.meta.empty?
|
67
74
|
|
@@ -76,7 +83,7 @@ module Spandx
|
|
76
83
|
sources.each do |source|
|
77
84
|
html_from(source, '/simple/').css('a[href*="/simple"]').each do |node|
|
78
85
|
each_version(source, node[:href]) do |dependency|
|
79
|
-
definition = source.lookup(dependency[:name], dependency[:version])
|
86
|
+
definition = source.lookup(dependency[:name], dependency[:version], http: http)
|
80
87
|
yield dependency.merge(license: definition['license'])
|
81
88
|
end
|
82
89
|
end
|
@@ -93,7 +100,12 @@ module Spandx
|
|
93
100
|
|
94
101
|
def html_from(source, path)
|
95
102
|
url = URI.join(source.uri.to_s, path).to_s
|
96
|
-
|
103
|
+
response = http.get(url)
|
104
|
+
if http.ok?(response)
|
105
|
+
Nokogiri::HTML(response.body)
|
106
|
+
else
|
107
|
+
Nokogiri::HTML('<html><head></head><body></body></html>')
|
108
|
+
end
|
97
109
|
end
|
98
110
|
end
|
99
111
|
end
|
data/lib/spandx/python/source.rb
CHANGED
data/lib/spandx/ruby/gateway.rb
CHANGED
@@ -6,31 +6,32 @@ module Spandx
|
|
6
6
|
class GemfileLock < ::Spandx::Core::Parser
|
7
7
|
STRIP_BUNDLED_WITH = /^BUNDLED WITH$(\r?\n) (?<major>\d+)\.\d+\.\d+/m.freeze
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
9
|
+
def match?(pathname)
|
10
|
+
basename = pathname.basename
|
11
|
+
basename.fnmatch?('Gemfile*.lock') ||
|
12
|
+
basename.fnmatch?('gems*.lock')
|
12
13
|
end
|
13
14
|
|
14
15
|
def parse(lockfile)
|
15
16
|
dependencies_from(lockfile).map do |specification|
|
16
|
-
map_from(specification)
|
17
|
+
map_from(lockfile, specification)
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
21
|
private
|
21
22
|
|
22
23
|
def dependencies_from(filepath)
|
23
|
-
content =
|
24
|
-
Dir.chdir(
|
24
|
+
content = filepath.read.sub(STRIP_BUNDLED_WITH, '')
|
25
|
+
Dir.chdir(filepath.dirname) do
|
25
26
|
::Bundler::LockfileParser
|
26
|
-
.new(content
|
27
|
+
.new(content)
|
27
28
|
.specs
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
31
|
-
def map_from(specification)
|
32
|
+
def map_from(lockfile, specification)
|
32
33
|
::Spandx::Core::Dependency.new(
|
33
|
-
|
34
|
+
path: lockfile,
|
34
35
|
name: specification.name,
|
35
36
|
version: specification.version.to_s,
|
36
37
|
meta: {
|
data/lib/spandx/version.rb
CHANGED
data/spandx.gemspec
CHANGED
@@ -34,12 +34,13 @@ Gem::Specification.new do |spec|
|
|
34
34
|
|
35
35
|
spec.add_dependency 'addressable', '~> 2.7'
|
36
36
|
spec.add_dependency 'bundler', '>= 1.16', '< 3.0.0'
|
37
|
-
spec.add_dependency '
|
38
|
-
spec.add_dependency 'net-hippie', '~> 0.3'
|
37
|
+
spec.add_dependency 'net-hippie', '~> 1.0'
|
39
38
|
spec.add_dependency 'nokogiri', '~> 1.10'
|
39
|
+
spec.add_dependency 'oj', '~> 3.10'
|
40
40
|
spec.add_dependency 'parslet', '~> 2.0'
|
41
|
+
spec.add_dependency 'terminal-table', '~> 1.8'
|
41
42
|
spec.add_dependency 'thor'
|
42
|
-
spec.add_dependency 'tty-
|
43
|
+
spec.add_dependency 'tty-spinner', '~> 0.9'
|
43
44
|
spec.add_dependency 'zeitwerk', '~> 2.3'
|
44
45
|
|
45
46
|
spec.add_development_dependency 'benchmark-ips', '~> 2.8'
|
@@ -53,6 +54,6 @@ Gem::Specification.new do |spec|
|
|
53
54
|
spec.add_development_dependency 'rubocop', '~> 0.52'
|
54
55
|
spec.add_development_dependency 'rubocop-rspec', '~> 1.22'
|
55
56
|
spec.add_development_dependency 'ruby-prof', '~> 1.3'
|
56
|
-
spec.add_development_dependency 'vcr', '~>
|
57
|
+
spec.add_development_dependency 'vcr', '~> 6.0'
|
57
58
|
spec.add_development_dependency 'webmock', '~> 3.7'
|
58
59
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spandx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Can Eldem
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-11-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: addressable
|
@@ -46,47 +46,47 @@ dependencies:
|
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 3.0.0
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
|
-
name:
|
49
|
+
name: net-hippie
|
50
50
|
requirement: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.0
|
54
|
+
version: '1.0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0
|
61
|
+
version: '1.0'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
63
|
+
name: nokogiri
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '1.10'
|
69
69
|
type: :runtime
|
70
70
|
prerelease: false
|
71
71
|
version_requirements: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '1.10'
|
76
76
|
- !ruby/object:Gem::Dependency
|
77
|
-
name:
|
77
|
+
name: oj
|
78
78
|
requirement: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '3.10'
|
83
83
|
type: :runtime
|
84
84
|
prerelease: false
|
85
85
|
version_requirements: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '3.10'
|
90
90
|
- !ruby/object:Gem::Dependency
|
91
91
|
name: parslet
|
92
92
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,6 +101,20 @@ dependencies:
|
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '2.0'
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: terminal-table
|
106
|
+
requirement: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.8'
|
111
|
+
type: :runtime
|
112
|
+
prerelease: false
|
113
|
+
version_requirements: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.8'
|
104
118
|
- !ruby/object:Gem::Dependency
|
105
119
|
name: thor
|
106
120
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,19 +130,19 @@ dependencies:
|
|
116
130
|
- !ruby/object:Gem::Version
|
117
131
|
version: '0'
|
118
132
|
- !ruby/object:Gem::Dependency
|
119
|
-
name: tty-
|
133
|
+
name: tty-spinner
|
120
134
|
requirement: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
136
|
- - "~>"
|
123
137
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0.
|
138
|
+
version: '0.9'
|
125
139
|
type: :runtime
|
126
140
|
prerelease: false
|
127
141
|
version_requirements: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
143
|
- - "~>"
|
130
144
|
- !ruby/object:Gem::Version
|
131
|
-
version: '0.
|
145
|
+
version: '0.9'
|
132
146
|
- !ruby/object:Gem::Dependency
|
133
147
|
name: zeitwerk
|
134
148
|
requirement: !ruby/object:Gem::Requirement
|
@@ -303,14 +317,14 @@ dependencies:
|
|
303
317
|
requirements:
|
304
318
|
- - "~>"
|
305
319
|
- !ruby/object:Gem::Version
|
306
|
-
version: '
|
320
|
+
version: '6.0'
|
307
321
|
type: :development
|
308
322
|
prerelease: false
|
309
323
|
version_requirements: !ruby/object:Gem::Requirement
|
310
324
|
requirements:
|
311
325
|
- - "~>"
|
312
326
|
- !ruby/object:Gem::Version
|
313
|
-
version: '
|
327
|
+
version: '6.0'
|
314
328
|
- !ruby/object:Gem::Dependency
|
315
329
|
name: webmock
|
316
330
|
requirement: !ruby/object:Gem::Requirement
|
@@ -353,6 +367,10 @@ files:
|
|
353
367
|
- lib/spandx/cli/commands/pull.rb
|
354
368
|
- lib/spandx/cli/commands/scan.rb
|
355
369
|
- lib/spandx/cli/main.rb
|
370
|
+
- lib/spandx/cli/printer.rb
|
371
|
+
- lib/spandx/cli/printers/csv.rb
|
372
|
+
- lib/spandx/cli/printers/json.rb
|
373
|
+
- lib/spandx/cli/printers/table.rb
|
356
374
|
- lib/spandx/core/cache.rb
|
357
375
|
- lib/spandx/core/circuit.rb
|
358
376
|
- lib/spandx/core/content.rb
|
@@ -369,10 +387,8 @@ files:
|
|
369
387
|
- lib/spandx/core/plugin.rb
|
370
388
|
- lib/spandx/core/registerable.rb
|
371
389
|
- lib/spandx/core/relation.rb
|
372
|
-
- lib/spandx/core/report.rb
|
373
390
|
- lib/spandx/core/score.rb
|
374
|
-
- lib/spandx/core/
|
375
|
-
- lib/spandx/core/table.rb
|
391
|
+
- lib/spandx/core/thread_pool.rb
|
376
392
|
- lib/spandx/dotnet/index.rb
|
377
393
|
- lib/spandx/dotnet/nuget_gateway.rb
|
378
394
|
- lib/spandx/dotnet/package_reference.rb
|
@@ -388,6 +404,8 @@ files:
|
|
388
404
|
- lib/spandx/js/parsers/yarn.rb
|
389
405
|
- lib/spandx/js/yarn_lock.rb
|
390
406
|
- lib/spandx/js/yarn_pkg.rb
|
407
|
+
- lib/spandx/os/parsers/apk.rb
|
408
|
+
- lib/spandx/os/parsers/dpkg.rb
|
391
409
|
- lib/spandx/php/packagist_gateway.rb
|
392
410
|
- lib/spandx/php/parsers/composer.rb
|
393
411
|
- lib/spandx/python/index.rb
|
@@ -425,7 +443,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
425
443
|
- !ruby/object:Gem::Version
|
426
444
|
version: '0'
|
427
445
|
requirements: []
|
428
|
-
rubygems_version: 3.1.
|
446
|
+
rubygems_version: 3.1.4
|
429
447
|
signing_key:
|
430
448
|
specification_version: 4
|
431
449
|
summary: A ruby interface to the SPDX catalogue.
|