spandx 0.13.4 → 0.13.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -2
- data/exe/spandx +0 -1
- data/lib/spandx.rb +1 -1
- data/lib/spandx/cli.rb +2 -2
- data/lib/spandx/cli/commands/scan.rb +18 -20
- data/lib/spandx/cli/main.rb +2 -2
- 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 +41 -0
- data/lib/spandx/core/git.rb +6 -6
- 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/js/parsers/npm.rb +2 -2
- data/lib/spandx/js/yarn_pkg.rb +1 -1
- data/lib/spandx/php/packagist_gateway.rb +1 -1
- data/lib/spandx/php/parsers/composer.rb +1 -1
- data/lib/spandx/python/parsers/pipfile_lock.rb +1 -1
- 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/version.rb +1 -1
- data/spandx.gemspec +3 -3
- metadata +21 -18
- data/lib/spandx/core/report.rb +0 -54
- data/lib/spandx/core/spinner.rb +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01abc42f6e315aee9f35bf60cdad7a4801ee95ae4a186ef3ee001f2617c9891e
|
4
|
+
data.tar.gz: 78248675cdddbcb197f347239c85016862254a113b17894e4d6ffe7ecd33cddd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6d4462c74dc412f9016ff576f55e67bdc9a6b341059d3b372b505f6e7ee730a92da53a4b5d0ab836df298b2cb527d0890c599fdc48f92a848b3d93c6c7d67ab
|
7
|
+
data.tar.gz: fdc618b97c619aa7d8a99b799dc5b1569d8396e9cfbbee5ee91cf7b994335e7fcbd9a5abac03b87a21615b23eef7913d5b59aabf277cacaa3eeac8497d795f38
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Version 0.13.
|
1
|
+
Version 0.13.5
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
@@ -8,6 +8,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
8
8
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
9
9
|
|
10
10
|
## [Unreleased]
|
11
|
+
## [0.13.5] - 2020-05-26
|
12
|
+
### Fixed
|
13
|
+
- Process PyPI package urls with single digit versions.
|
14
|
+
- Remove unsupported `hash` report from help text.
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
- Stream output to output stream as soon as results are available.
|
18
|
+
- Switch to `Oj` for JSON parsing.
|
19
|
+
- Run spinner on background thread.
|
11
20
|
|
12
21
|
## [0.13.4] - 2020-05-26
|
13
22
|
### Added
|
@@ -189,7 +198,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
189
198
|
### Added
|
190
199
|
- Provide ruby API to the latest SPDX catalogue.
|
191
200
|
|
192
|
-
[Unreleased]: https://github.com/spandx/spandx/compare/v0.13.
|
201
|
+
[Unreleased]: https://github.com/spandx/spandx/compare/v0.13.5...HEAD
|
202
|
+
[0.13.5]: https://github.com/spandx/spandx/compare/v0.13.4...v0.13.5
|
203
|
+
[0.13.4]: https://github.com/spandx/spandx/compare/v0.13.3...v0.13.4
|
193
204
|
[0.13.3]: https://github.com/spandx/spandx/compare/v0.13.2...v0.13.3
|
194
205
|
[0.13.2]: https://github.com/spandx/spandx/compare/v0.13.1...v0.13.2
|
195
206
|
[0.13.1]: https://github.com/spandx/spandx/compare/v0.13.0...v0.13.1
|
data/exe/spandx
CHANGED
data/lib/spandx.rb
CHANGED
@@ -8,11 +8,11 @@ require 'json'
|
|
8
8
|
require 'logger'
|
9
9
|
require 'net/hippie'
|
10
10
|
require 'nokogiri'
|
11
|
+
require 'oj'
|
11
12
|
require 'parslet'
|
12
13
|
require 'pathname'
|
13
14
|
require 'yaml'
|
14
15
|
require 'zeitwerk'
|
15
|
-
require 'terminal-table'
|
16
16
|
require 'spandx/spandx'
|
17
17
|
|
18
18
|
loader = Zeitwerk::Loader.for_gem
|
data/lib/spandx/cli.rb
CHANGED
@@ -4,51 +4,49 @@ module Spandx
|
|
4
4
|
module Cli
|
5
5
|
module Commands
|
6
6
|
class Scan
|
7
|
-
|
7
|
+
include Spandx::Core
|
8
|
+
attr_reader :scan_path
|
8
9
|
|
9
10
|
def initialize(scan_path, options)
|
10
11
|
@scan_path = ::Pathname.new(scan_path)
|
11
12
|
@options = options
|
12
|
-
@spinner = options[:show_progress] ? ::Spandx::Core::Spinner.new : ::Spandx::Core::Spinner::NULL
|
13
13
|
require(options[:require]) if options[:require]
|
14
14
|
end
|
15
15
|
|
16
16
|
def execute(output: $stdout)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
each_dependency_from(file) do |dependency|
|
21
|
-
spinner.spin(file)
|
22
|
-
report.add(dependency)
|
17
|
+
with_printer(output) do |printer|
|
18
|
+
each_dependency do |dependency|
|
19
|
+
printer.print_line(Plugin.enhance(dependency), output)
|
23
20
|
end
|
24
21
|
end
|
25
|
-
spinner.stop
|
26
|
-
output.puts(format(report.to(@options[:format])))
|
27
22
|
end
|
28
23
|
|
29
24
|
private
|
30
25
|
|
31
26
|
def each_file
|
32
|
-
|
27
|
+
PathTraversal
|
33
28
|
.new(scan_path, recursive: @options[:recursive])
|
34
29
|
.each { |file| yield file }
|
35
30
|
end
|
36
31
|
|
37
|
-
def
|
38
|
-
|
39
|
-
.parse(file)
|
40
|
-
|
41
|
-
|
32
|
+
def each_dependency
|
33
|
+
each_file do |file|
|
34
|
+
Parser.parse(file).each do |dependency|
|
35
|
+
yield dependency
|
36
|
+
end
|
37
|
+
end
|
42
38
|
end
|
43
39
|
|
44
40
|
def format(output)
|
45
41
|
Array(output).map(&:to_s)
|
46
42
|
end
|
47
43
|
|
48
|
-
def
|
49
|
-
::Spandx::
|
50
|
-
|
51
|
-
|
44
|
+
def with_printer(output)
|
45
|
+
printer = ::Spandx::Cli::Printer.for(@options[:format])
|
46
|
+
printer.print_header(output)
|
47
|
+
yield printer
|
48
|
+
ensure
|
49
|
+
printer.print_footer(output)
|
52
50
|
end
|
53
51
|
end
|
54
52
|
end
|
data/lib/spandx/cli/main.rb
CHANGED
@@ -8,14 +8,14 @@ module Spandx
|
|
8
8
|
method_option :recursive, aliases: '-R', type: :boolean, desc: 'Perform recursive scan', default: false
|
9
9
|
method_option :airgap, aliases: '-a', type: :boolean, desc: 'Disable network connections', default: false
|
10
10
|
method_option :logfile, aliases: '-l', type: :string, desc: 'Path to a logfile', default: '/dev/null'
|
11
|
-
method_option :format, aliases: '-f', type: :string, desc: 'Format of report. (table, csv, json
|
11
|
+
method_option :format, aliases: '-f', type: :string, desc: 'Format of report. (table, csv, json)', default: 'table'
|
12
12
|
method_option :pull, aliases: '-p', type: :boolean, desc: 'Pull the latest cache before the scan', default: false
|
13
13
|
method_option :require, aliases: '-r', type: :string, desc: 'Causes spandx to load the library using require.', default: nil
|
14
|
-
method_option :show_progress, aliases: '-sp', type: :boolean, desc: 'Shows a progress bar', default: true
|
15
14
|
def scan(lockfile = Pathname.pwd)
|
16
15
|
if options[:help]
|
17
16
|
invoke :help, ['scan']
|
18
17
|
else
|
18
|
+
Oj.default_options = { mode: :strict }
|
19
19
|
Spandx.airgap = options[:airgap]
|
20
20
|
Spandx.logger = Logger.new(options[:logfile])
|
21
21
|
pull if options[:pull]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spandx
|
4
|
+
module Cli
|
5
|
+
class Printer
|
6
|
+
def match?(_format)
|
7
|
+
raise ::Spandx::Error, :match?
|
8
|
+
end
|
9
|
+
|
10
|
+
def print_header(io); end
|
11
|
+
|
12
|
+
def print_line(dependency, io)
|
13
|
+
io.puts(dependency.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def print_footer(io); end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
include Core::Registerable
|
20
|
+
|
21
|
+
def for(format)
|
22
|
+
find { |x| x.match?(format) } || new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spandx
|
4
|
+
module Cli
|
5
|
+
module Printers
|
6
|
+
class Csv < Printer
|
7
|
+
def match?(format)
|
8
|
+
format.to_sym == :csv
|
9
|
+
end
|
10
|
+
|
11
|
+
def print_line(dependency, io)
|
12
|
+
io.puts(CSV.generate_line(dependency.to_a))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spandx
|
4
|
+
module Cli
|
5
|
+
module Printers
|
6
|
+
class Json < Printer
|
7
|
+
def match?(format)
|
8
|
+
format.to_sym == :json
|
9
|
+
end
|
10
|
+
|
11
|
+
def print_line(dependency, io)
|
12
|
+
io.puts(Oj.dump(dependency.to_h))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spandx
|
4
|
+
module Cli
|
5
|
+
module Printers
|
6
|
+
class Table < Printer
|
7
|
+
HEADINGS = ['Name', 'Version', 'Licenses', 'Location'].freeze
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@spinner = TTY::Spinner.new(output: $stderr)
|
11
|
+
end
|
12
|
+
|
13
|
+
def match?(format)
|
14
|
+
format.to_sym == :table
|
15
|
+
end
|
16
|
+
|
17
|
+
def print_header(_io)
|
18
|
+
@dependencies = SortedSet.new
|
19
|
+
@spinner.auto_spin
|
20
|
+
end
|
21
|
+
|
22
|
+
def print_line(dependency, _io)
|
23
|
+
@dependencies << dependency
|
24
|
+
end
|
25
|
+
|
26
|
+
def print_footer(io)
|
27
|
+
@spinner.stop
|
28
|
+
io.puts(to_table(@dependencies.map(&:to_a)))
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def to_table(rows)
|
34
|
+
Terminal::Table.new(headings: HEADINGS) do |table|
|
35
|
+
rows.each { |row| table.add_row(row) }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/spandx/core/git.rb
CHANGED
@@ -11,9 +11,8 @@ module Spandx
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def read(path)
|
14
|
-
full_path =
|
15
|
-
|
16
|
-
IO.read(full_path) if File.exist?(full_path)
|
14
|
+
full_path = root.join(path)
|
15
|
+
full_path.read if full_path.exist?
|
17
16
|
end
|
18
17
|
|
19
18
|
def update!
|
@@ -25,15 +24,16 @@ module Spandx
|
|
25
24
|
def path_for(url)
|
26
25
|
uri = URI.parse(url)
|
27
26
|
name = uri.path.gsub(/\.git$/, '')
|
28
|
-
File.expand_path(File.join(Dir.home, '.local', 'share', name))
|
27
|
+
Pathname(File.expand_path(File.join(Dir.home, '.local', 'share', name)))
|
29
28
|
end
|
30
29
|
|
31
30
|
def dotgit?
|
32
|
-
|
31
|
+
root.join('.git').directory?
|
33
32
|
end
|
34
33
|
|
35
34
|
def clone!
|
36
|
-
system('
|
35
|
+
system('rm', '-rf', root.to_s) if root.exist?
|
36
|
+
system('git', 'clone', '--quiet', '--depth=1', '--single-branch', '--branch', 'master', url, root.to_s)
|
37
37
|
end
|
38
38
|
|
39
39
|
def pull!
|
data/lib/spandx/core/plugin.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spandx
|
4
|
+
module Core
|
5
|
+
class ThreadPool
|
6
|
+
def initialize(size: 1)
|
7
|
+
@size = size
|
8
|
+
@queue = Queue.new
|
9
|
+
@pool = size.times.map { start_worker_thread(@queue) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def run(*args, &job)
|
13
|
+
@queue.enq([job, args])
|
14
|
+
end
|
15
|
+
|
16
|
+
def done?
|
17
|
+
@queue.empty?
|
18
|
+
end
|
19
|
+
|
20
|
+
def shutdown
|
21
|
+
@size.times do
|
22
|
+
run { throw :exit }
|
23
|
+
end
|
24
|
+
|
25
|
+
@pool.map(&:join)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.open(**args)
|
29
|
+
pool = new(**args)
|
30
|
+
yield pool
|
31
|
+
ensure
|
32
|
+
pool.shutdown
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def start_worker_thread(queue)
|
38
|
+
Thread.new(queue) do |q|
|
39
|
+
catch(:exit) do
|
40
|
+
loop do
|
41
|
+
job, args = q.deq
|
42
|
+
job.call(args)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -18,8 +18,8 @@ module Spandx
|
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
-
def each_metadata(
|
22
|
-
package_lock =
|
21
|
+
def each_metadata(path)
|
22
|
+
package_lock = Oj.load(path.read)
|
23
23
|
package_lock['dependencies'].each do |name, metadata|
|
24
24
|
yield metadata.merge('name' => name)
|
25
25
|
end
|
data/lib/spandx/js/yarn_pkg.rb
CHANGED
@@ -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
|
@@ -10,7 +10,7 @@ module Spandx
|
|
10
10
|
|
11
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
15
|
items.add(map_from(path, dependency))
|
16
16
|
end
|
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
data/lib/spandx/version.rb
CHANGED
data/spandx.gemspec
CHANGED
@@ -34,13 +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 'nanospinner', '~> 1.0.0'
|
38
37
|
spec.add_dependency 'net-hippie', '~> 0.3'
|
39
38
|
spec.add_dependency 'nokogiri', '~> 1.10'
|
39
|
+
spec.add_dependency 'oj', '~> 3.10'
|
40
40
|
spec.add_dependency 'parslet', '~> 2.0'
|
41
41
|
spec.add_dependency 'terminal-table', '~> 1.8'
|
42
42
|
spec.add_dependency 'thor'
|
43
|
-
spec.add_dependency 'tty-
|
43
|
+
spec.add_dependency 'tty-spinner', '~> 0.9'
|
44
44
|
spec.add_dependency 'zeitwerk', '~> 2.3'
|
45
45
|
|
46
46
|
spec.add_development_dependency 'benchmark-ips', '~> 2.8'
|
@@ -54,6 +54,6 @@ Gem::Specification.new do |spec|
|
|
54
54
|
spec.add_development_dependency 'rubocop', '~> 0.52'
|
55
55
|
spec.add_development_dependency 'rubocop-rspec', '~> 1.22'
|
56
56
|
spec.add_development_dependency 'ruby-prof', '~> 1.3'
|
57
|
-
spec.add_development_dependency 'vcr', '~>
|
57
|
+
spec.add_development_dependency 'vcr', '~> 6.0'
|
58
58
|
spec.add_development_dependency 'webmock', '~> 3.7'
|
59
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.13.
|
4
|
+
version: 0.13.5
|
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-06-23 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:
|
54
|
+
version: '0.3'
|
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:
|
61
|
+
version: '0.3'
|
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
|
@@ -130,19 +130,19 @@ dependencies:
|
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
- !ruby/object:Gem::Dependency
|
133
|
-
name: tty-
|
133
|
+
name: tty-spinner
|
134
134
|
requirement: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '0.
|
138
|
+
version: '0.9'
|
139
139
|
type: :runtime
|
140
140
|
prerelease: false
|
141
141
|
version_requirements: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '0.
|
145
|
+
version: '0.9'
|
146
146
|
- !ruby/object:Gem::Dependency
|
147
147
|
name: zeitwerk
|
148
148
|
requirement: !ruby/object:Gem::Requirement
|
@@ -317,14 +317,14 @@ dependencies:
|
|
317
317
|
requirements:
|
318
318
|
- - "~>"
|
319
319
|
- !ruby/object:Gem::Version
|
320
|
-
version: '
|
320
|
+
version: '6.0'
|
321
321
|
type: :development
|
322
322
|
prerelease: false
|
323
323
|
version_requirements: !ruby/object:Gem::Requirement
|
324
324
|
requirements:
|
325
325
|
- - "~>"
|
326
326
|
- !ruby/object:Gem::Version
|
327
|
-
version: '
|
327
|
+
version: '6.0'
|
328
328
|
- !ruby/object:Gem::Dependency
|
329
329
|
name: webmock
|
330
330
|
requirement: !ruby/object:Gem::Requirement
|
@@ -367,6 +367,10 @@ files:
|
|
367
367
|
- lib/spandx/cli/commands/pull.rb
|
368
368
|
- lib/spandx/cli/commands/scan.rb
|
369
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
|
370
374
|
- lib/spandx/core/cache.rb
|
371
375
|
- lib/spandx/core/circuit.rb
|
372
376
|
- lib/spandx/core/content.rb
|
@@ -383,9 +387,8 @@ files:
|
|
383
387
|
- lib/spandx/core/plugin.rb
|
384
388
|
- lib/spandx/core/registerable.rb
|
385
389
|
- lib/spandx/core/relation.rb
|
386
|
-
- lib/spandx/core/report.rb
|
387
390
|
- lib/spandx/core/score.rb
|
388
|
-
- lib/spandx/core/
|
391
|
+
- lib/spandx/core/thread_pool.rb
|
389
392
|
- lib/spandx/dotnet/index.rb
|
390
393
|
- lib/spandx/dotnet/nuget_gateway.rb
|
391
394
|
- lib/spandx/dotnet/package_reference.rb
|
data/lib/spandx/core/report.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spandx
|
4
|
-
module Core
|
5
|
-
class Report
|
6
|
-
attr_reader :dependencies
|
7
|
-
|
8
|
-
FORMATS = {
|
9
|
-
csv: :to_csv,
|
10
|
-
hash: :to_h,
|
11
|
-
json: :to_json,
|
12
|
-
table: :to_table,
|
13
|
-
}.freeze
|
14
|
-
|
15
|
-
def initialize
|
16
|
-
@dependencies = SortedSet.new
|
17
|
-
end
|
18
|
-
|
19
|
-
def add(dependency)
|
20
|
-
@dependencies << dependency
|
21
|
-
end
|
22
|
-
|
23
|
-
def to(format, formats: FORMATS)
|
24
|
-
public_send(formats.fetch(format&.to_sym, :to_json))
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_table
|
28
|
-
Terminal::Table.new(headings: ['Name', 'Version', 'Licenses', 'Location']) do |t|
|
29
|
-
dependencies.each do |d|
|
30
|
-
t.add_row d.to_a
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def to_h
|
36
|
-
{ version: '1.0', dependencies: [] }.tap do |report|
|
37
|
-
dependencies.each do |dependency|
|
38
|
-
report[:dependencies].push(dependency.to_h)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def to_json(*_args)
|
44
|
-
JSON.pretty_generate(to_h)
|
45
|
-
end
|
46
|
-
|
47
|
-
def to_csv
|
48
|
-
dependencies.map do |dependency|
|
49
|
-
CSV.generate_line(dependency.to_a)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
data/lib/spandx/core/spinner.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spandx
|
4
|
-
module Core
|
5
|
-
class Spinner
|
6
|
-
NULL = Class.new do
|
7
|
-
def self.spin(*args); end
|
8
|
-
|
9
|
-
def self.stop(*args); end
|
10
|
-
end
|
11
|
-
|
12
|
-
attr_reader :columns, :spinner
|
13
|
-
|
14
|
-
def initialize(columns: TTY::Screen.columns, output: $stderr)
|
15
|
-
@columns = columns
|
16
|
-
@spinner = Nanospinner.new(output)
|
17
|
-
@queue = Queue.new
|
18
|
-
@thread = Thread.new { work }
|
19
|
-
end
|
20
|
-
|
21
|
-
def spin(message)
|
22
|
-
@queue.enq(justify(message))
|
23
|
-
yield if block_given?
|
24
|
-
end
|
25
|
-
|
26
|
-
def stop
|
27
|
-
@queue.clear
|
28
|
-
@queue.enq(:stop)
|
29
|
-
@thread.join
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def justify(message)
|
35
|
-
message.to_s.ljust(columns - 3)
|
36
|
-
end
|
37
|
-
|
38
|
-
def work
|
39
|
-
last_message = justify('')
|
40
|
-
loop do
|
41
|
-
message = @queue.empty? ? last_message : @queue.deq
|
42
|
-
break if message == :stop
|
43
|
-
|
44
|
-
spinner.spin(message)
|
45
|
-
last_message = message
|
46
|
-
sleep 0.1
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|