package-audit 0.4.1 → 0.5.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/lib/package/audit/cli.rb +3 -0
- data/lib/package/audit/const/fields.rb +2 -4
- data/lib/package/audit/enum/environment.rb +9 -5
- data/lib/package/audit/enum/option.rb +1 -0
- data/lib/package/audit/npm/npm_meta_data.rb +9 -3
- data/lib/package/audit/npm/vulnerability_finder.rb +1 -1
- data/lib/package/audit/npm/yarn_lock_parser.rb +8 -2
- data/lib/package/audit/ruby/gem_collection.rb +4 -4
- data/lib/package/audit/ruby/gem_meta_data.rb +8 -3
- data/lib/package/audit/services/command_parser.rb +41 -22
- data/lib/package/audit/services/package_finder.rb +15 -3
- data/lib/package/audit/services/package_printer.rb +4 -4
- data/lib/package/audit/services/risk_calculator.rb +1 -1
- data/lib/package/audit/util/spinner.rb +48 -0
- data/lib/package/audit/util/summary_printer.rb +1 -1
- data/lib/package/audit/version.rb +1 -1
- data/sig/package/audit/const/fields.rbs +1 -4
- data/sig/package/audit/enum/environment.rbs +7 -5
- data/sig/package/audit/enum/option.rbs +1 -0
- data/sig/package/audit/models/package.rbs +2 -2
- data/sig/package/audit/ruby/gem_meta_data.rbs +2 -1
- data/sig/package/audit/services/command_parser.rbs +5 -3
- data/sig/package/audit/services/package_finder.rbs +4 -1
- data/sig/package/audit/util/spinner.rbs +24 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c2f009e294663828a3055ac8b8facb3106251875a240f9abf74754747102cef
|
4
|
+
data.tar.gz: 0a11812a839205caa7793c5b34baf31006438b020e9f535ffe1fd5b3ee0333ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e7a294008ddcb510e8335193ac013447c38b27a71f440325ae2221f5bd0dea29bf714a88e6089b451d50c64f24964da04215c5e54c74c0729fa37a3f277d44b
|
7
|
+
data.tar.gz: 29bb2f4dbef1bb9a6c38eb7d4b17c9aa299f943916765d05a02b14b8f48a0e8ce212bc834e4657285b99d9ba0eb33c80df479e907b673f13fa6834c098e8649e
|
data/lib/package/audit/cli.rb
CHANGED
@@ -15,6 +15,9 @@ module Package
|
|
15
15
|
class_option Enum::Option::CONFIG,
|
16
16
|
aliases: '-c', banner: 'FILE',
|
17
17
|
desc: "Path to a custom configuration file, default: #{Const::File::CONFIG})"
|
18
|
+
class_option Enum::Option::ENVIRONMENT,
|
19
|
+
aliases: '-e', repeatable: true,
|
20
|
+
desc: 'Environment to be audited (repeat this flag for each environment)'
|
18
21
|
class_option Enum::Option::TECHNOLOGY,
|
19
22
|
aliases: '-t', repeatable: true,
|
20
23
|
desc: 'Technology to be audited (repeat this flag for each technology)'
|
@@ -14,15 +14,13 @@ module Package
|
|
14
14
|
risk_explanation
|
15
15
|
]
|
16
16
|
|
17
|
-
|
18
|
-
DEPRECATED = %i[name version latest_version latest_version_date groups]
|
19
|
-
OUTDATED = %i[name version latest_version latest_version_date groups]
|
20
|
-
VULNERABLE = %i[name version latest_version groups vulnerabilities]
|
17
|
+
DEFAULT = %i[name version latest_version latest_version_date groups vulnerabilities risk_type risk_explanation]
|
21
18
|
|
22
19
|
# the names of these fields must match the instance variables in the Dependency class
|
23
20
|
HEADERS = {
|
24
21
|
name: 'Package',
|
25
22
|
version: 'Version',
|
23
|
+
version_date: 'Version Date',
|
26
24
|
latest_version: 'Latest',
|
27
25
|
latest_version_date: 'Latest Date',
|
28
26
|
groups: 'Groups',
|
@@ -2,11 +2,15 @@ module Package
|
|
2
2
|
module Audit
|
3
3
|
module Enum
|
4
4
|
module Environment
|
5
|
-
DEV =
|
6
|
-
TEST =
|
7
|
-
STAGING =
|
8
|
-
PRODUCTION =
|
9
|
-
DEFAULT =
|
5
|
+
DEV = 'development'
|
6
|
+
TEST = 'test'
|
7
|
+
STAGING = 'staging'
|
8
|
+
PRODUCTION = 'production'
|
9
|
+
DEFAULT = 'default'
|
10
|
+
|
11
|
+
def self.all
|
12
|
+
constants.map { |key| Enum::Environment.const_get(key) }.sort
|
13
|
+
end
|
10
14
|
end
|
11
15
|
end
|
12
16
|
end
|
@@ -11,17 +11,23 @@ module Package
|
|
11
11
|
@packages = packages
|
12
12
|
end
|
13
13
|
|
14
|
-
def fetch
|
14
|
+
def fetch # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
15
15
|
threads = @packages.map do |package|
|
16
16
|
Thread.new do
|
17
17
|
response = Net::HTTP.get_response(URI.parse("#{REGISTRY_URL}/#{package.name}"))
|
18
|
-
raise
|
18
|
+
raise "Unable to fetch meta data for #{package.name} from #{REGISTRY_URL} (#{response.class})" unless
|
19
|
+
response.is_a?(Net::HTTPSuccess)
|
19
20
|
|
20
21
|
json_package = JSON.parse(response.body, symbolize_names: true)
|
21
22
|
update_meta_data(package, json_package)
|
23
|
+
rescue StandardError => e
|
24
|
+
Thread.current[:exception] = e
|
22
25
|
end
|
23
26
|
end
|
24
|
-
threads.each
|
27
|
+
threads.each do |thread|
|
28
|
+
thread.join
|
29
|
+
raise thread[:exception] if thread[:exception]
|
30
|
+
end
|
25
31
|
@packages
|
26
32
|
end
|
27
33
|
|
@@ -36,7 +36,7 @@ module Package
|
|
36
36
|
|
37
37
|
@vuln_hash[full_name] = Package.new(name, version, 'node') unless @vuln_hash.key? full_name
|
38
38
|
@vuln_hash[full_name].update vulnerabilities: @vuln_hash[full_name].vulnerabilities + [vulnerability]
|
39
|
-
@vuln_hash[full_name].update groups: @pkg_hash[parent_name].groups
|
39
|
+
@vuln_hash[full_name].update groups: @pkg_hash[parent_name].groups.map(&:to_s)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative '../enum/environment'
|
2
|
+
|
1
3
|
module Package
|
2
4
|
module Audit
|
3
5
|
module Npm
|
@@ -7,13 +9,17 @@ module Package
|
|
7
9
|
@yarn_lock_path = yarn_lock_path
|
8
10
|
end
|
9
11
|
|
10
|
-
def fetch(default_deps, dev_deps)
|
12
|
+
def fetch(default_deps, dev_deps) # rubocop:disable Metrics/MethodLength
|
11
13
|
pkgs = []
|
12
14
|
default_deps.merge(dev_deps).each do |dep_name, expected_version|
|
13
15
|
pkg_block = fetch_package_block(dep_name, expected_version)
|
14
16
|
version = fetch_package_version(dep_name, pkg_block)
|
15
17
|
pks = Package.new(dep_name.to_s, version, 'node')
|
16
|
-
pks.update groups: dev_deps.key?(dep_name)
|
18
|
+
pks.update groups: if dev_deps.key?(dep_name)
|
19
|
+
[Enum::Environment::DEV]
|
20
|
+
else
|
21
|
+
[Enum::Environment::DEFAULT, Enum::Environment::DEV]
|
22
|
+
end
|
17
23
|
pkgs << pks
|
18
24
|
end
|
19
25
|
pkgs
|
@@ -31,27 +31,27 @@ module Package
|
|
31
31
|
specs = BundlerSpecs.gemfile(@dir)
|
32
32
|
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
33
33
|
vulnerable_pkgs = VulnerabilityFinder.new(@dir).run
|
34
|
-
pkgs = GemMetaData.new(pkgs + vulnerable_pkgs).fetch.filter(&:risk?)
|
34
|
+
pkgs = GemMetaData.new(@dir, pkgs + vulnerable_pkgs).fetch.filter(&:risk?)
|
35
35
|
DuplicatePackageMerger.new(pkgs).run
|
36
36
|
end
|
37
37
|
|
38
38
|
def deprecated
|
39
39
|
specs = BundlerSpecs.gemfile(@dir)
|
40
40
|
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
41
|
-
pkgs = GemMetaData.new(pkgs).fetch.filter(&:deprecated?)
|
41
|
+
pkgs = GemMetaData.new(@dir, pkgs).fetch.filter(&:deprecated?)
|
42
42
|
DuplicatePackageMerger.new(pkgs).run
|
43
43
|
end
|
44
44
|
|
45
45
|
def outdated(include_implicit: false)
|
46
46
|
specs = include_implicit ? BundlerSpecs.all(@dir) : BundlerSpecs.gemfile(@dir)
|
47
47
|
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
48
|
-
pkgs = GemMetaData.new(pkgs).fetch.filter(&:outdated?)
|
48
|
+
pkgs = GemMetaData.new(@dir, pkgs).fetch.filter(&:outdated?)
|
49
49
|
DuplicatePackageMerger.new(pkgs).run
|
50
50
|
end
|
51
51
|
|
52
52
|
def vulnerable
|
53
53
|
pkgs = VulnerabilityFinder.new(@dir).run
|
54
|
-
pkgs = GemMetaData.new(pkgs).fetch.filter(&:vulnerable?)
|
54
|
+
pkgs = GemMetaData.new(@dir, pkgs).fetch.filter(&:vulnerable?)
|
55
55
|
DuplicatePackageMerger.new(pkgs).run
|
56
56
|
end
|
57
57
|
end
|
@@ -4,7 +4,8 @@ module Package
|
|
4
4
|
module Audit
|
5
5
|
module Ruby
|
6
6
|
class GemMetaData
|
7
|
-
def initialize(pkgs)
|
7
|
+
def initialize(dir, pkgs)
|
8
|
+
@dir = dir
|
8
9
|
@pkgs = pkgs
|
9
10
|
@gem_hash = {}
|
10
11
|
end
|
@@ -45,12 +46,16 @@ module Package
|
|
45
46
|
end
|
46
47
|
|
47
48
|
def assign_groups # rubocop:disable Metrics/AbcSize
|
48
|
-
definition = Bundler.
|
49
|
+
definition = Bundler::Definition.build Pathname("#{@dir}/Gemfile"), Pathname("#{@dir}/Gemfile.lock"), nil
|
50
|
+
Bundler.ui.level = 'error'
|
51
|
+
definition.resolve_remotely!
|
49
52
|
groups = definition.groups.uniq.sort
|
50
53
|
groups.each do |group|
|
51
54
|
specs = definition.specs_for([group])
|
52
55
|
specs.each do |spec|
|
53
|
-
|
56
|
+
if @gem_hash.key? spec.name
|
57
|
+
@gem_hash[spec.name].update(groups: (@gem_hash[spec.name].groups | [group]).map(&:to_s))
|
58
|
+
end
|
54
59
|
end
|
55
60
|
end
|
56
61
|
end
|
@@ -4,6 +4,7 @@ require_relative '../enum/option'
|
|
4
4
|
require_relative '../enum/report'
|
5
5
|
require_relative '../technology/detector'
|
6
6
|
require_relative '../technology/validator'
|
7
|
+
require_relative '../util/spinner'
|
7
8
|
require_relative '../util/summary_printer'
|
8
9
|
require_relative 'package_finder'
|
9
10
|
require_relative 'package_printer'
|
@@ -18,26 +19,46 @@ module Package
|
|
18
19
|
@options = options
|
19
20
|
@report = report
|
20
21
|
@config = parse_config_file
|
22
|
+
@environments = parse_environments
|
21
23
|
@technologies = parse_technologies
|
24
|
+
@spinner = Util::Spinner.new('Evaluating packages and their dependencies...')
|
22
25
|
end
|
23
26
|
|
24
|
-
def run
|
27
|
+
def run # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
28
|
+
mutex = Mutex.new
|
25
29
|
cumulative_pkgs = []
|
30
|
+
thread_index = 0
|
26
31
|
|
27
|
-
@
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
@spinner.start
|
33
|
+
threads = @technologies.map.with_index do |technology, technology_index|
|
34
|
+
Thread.new do
|
35
|
+
all_pkgs, ignored_pkgs = PackageFinder.new(@config, @dir, @report, @environments).run(technology)
|
36
|
+
ignored_pkgs = [] if @options[Enum::Option::INCLUDE_IGNORED]
|
37
|
+
cumulative_pkgs += all_pkgs || []
|
38
|
+
sleep 0.1 while technology_index != thread_index # print each technology in order
|
39
|
+
mutex.synchronize do
|
40
|
+
@spinner.stop
|
41
|
+
print_results(technology, (all_pkgs || []) - (ignored_pkgs || []), ignored_pkgs || [])
|
42
|
+
thread_index += 1
|
43
|
+
@spinner.start
|
44
|
+
end
|
45
|
+
rescue StandardError => e
|
46
|
+
Thread.current[:exception] = e
|
47
|
+
end
|
32
48
|
end
|
33
|
-
|
34
|
-
|
49
|
+
threads.each do |thread|
|
50
|
+
thread.join
|
51
|
+
raise thread[:exception] if thread[:exception]
|
52
|
+
end
|
53
|
+
cumulative_pkgs.any? ? 1 : 0
|
54
|
+
ensure
|
55
|
+
@spinner.stop
|
35
56
|
end
|
36
57
|
|
37
58
|
private
|
38
59
|
|
39
60
|
def print_results(technology, pkgs, ignored_pkgs)
|
40
|
-
PackagePrinter.new(@options, pkgs).print(
|
61
|
+
PackagePrinter.new(@options, pkgs).print(Const::Fields::DEFAULT)
|
41
62
|
print_summary(technology, pkgs, ignored_pkgs) unless @options[Enum::Option::CSV]
|
42
63
|
print_disclaimer(technology) unless @options[Enum::Option::CSV] || pkgs.empty?
|
43
64
|
end
|
@@ -70,19 +91,6 @@ module Package
|
|
70
91
|
end
|
71
92
|
end
|
72
93
|
|
73
|
-
def report_fields
|
74
|
-
case @report
|
75
|
-
when Enum::Report::DEPRECATED
|
76
|
-
Const::Fields::DEPRECATED
|
77
|
-
when Enum::Report::OUTDATED
|
78
|
-
Const::Fields::OUTDATED
|
79
|
-
when Enum::Report::VULNERABLE
|
80
|
-
Const::Fields::VULNERABLE
|
81
|
-
else
|
82
|
-
Const::Fields::ALL
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
94
|
def parse_config_file
|
87
95
|
if @options[Enum::Option::CONFIG].nil?
|
88
96
|
YAML.load_file("#{@dir}/#{Const::File::CONFIG}") if File.exist? "#{@dir}/#{Const::File::CONFIG}"
|
@@ -93,6 +101,17 @@ module Package
|
|
93
101
|
end
|
94
102
|
end
|
95
103
|
|
104
|
+
def parse_environments
|
105
|
+
unsupported_technologies = (@options[Enum::Option::ENVIRONMENT] || []) - Enum::Environment.all
|
106
|
+
|
107
|
+
if unsupported_technologies.any?
|
108
|
+
raise ArgumentError, "#{unsupported_technologies} is not valid list of environments, " \
|
109
|
+
"use one of #{Enum::Environment.all}"
|
110
|
+
end
|
111
|
+
|
112
|
+
(@options[Enum::Option::ENVIRONMENT] || Enum::Environment.all) | [Enum::Environment::DEFAULT]
|
113
|
+
end
|
114
|
+
|
96
115
|
def parse_technologies
|
97
116
|
technology_validator = Technology::Validator.new(@dir)
|
98
117
|
@options[Enum::Option::TECHNOLOGY]&.each { |technology| technology_validator.validate! technology }
|
@@ -11,16 +11,19 @@ require 'yaml'
|
|
11
11
|
module Package
|
12
12
|
module Audit
|
13
13
|
class PackageFinder
|
14
|
-
def initialize(config, dir, report)
|
14
|
+
def initialize(config, dir, report, environments)
|
15
15
|
@config = config
|
16
16
|
@dir = dir
|
17
17
|
@report = report
|
18
|
+
@environments = environments
|
18
19
|
end
|
19
20
|
|
20
21
|
def run(technology)
|
21
22
|
all_pkgs = find_by_technology(technology)
|
22
|
-
|
23
|
-
|
23
|
+
ignored_by_environment_pkgs = filter_pkgs_based_on_environment(all_pkgs)
|
24
|
+
active_pkgs = all_pkgs - ignored_by_environment_pkgs
|
25
|
+
ignored_by_config_pkgs = filter_pkgs_based_on_config(active_pkgs)
|
26
|
+
[active_pkgs, ignored_by_config_pkgs]
|
24
27
|
end
|
25
28
|
|
26
29
|
private
|
@@ -53,6 +56,15 @@ module Package
|
|
53
56
|
end
|
54
57
|
ignored_pkgs
|
55
58
|
end
|
59
|
+
|
60
|
+
def filter_pkgs_based_on_environment(pkgs)
|
61
|
+
ignored_pkgs = []
|
62
|
+
|
63
|
+
pkgs.each do |pkg|
|
64
|
+
ignored_pkgs << pkg unless (pkg.groups & @environments).any?
|
65
|
+
end
|
66
|
+
ignored_pkgs
|
67
|
+
end
|
56
68
|
end
|
57
69
|
end
|
58
70
|
end
|
@@ -32,14 +32,14 @@ module Package
|
|
32
32
|
private
|
33
33
|
|
34
34
|
def check_fields(fields)
|
35
|
-
return unless (fields - Const::Fields::
|
35
|
+
return unless (fields - Const::Fields::DEFAULT).any?
|
36
36
|
|
37
37
|
raise ArgumentError,
|
38
|
-
"#{fields - Const::Fields::
|
39
|
-
"Available fields names are: #{Const::Fields::
|
38
|
+
"#{fields - Const::Fields::DEFAULT} are not valid field names. " \
|
39
|
+
"Available fields names are: #{Const::Fields::DEFAULT}."
|
40
40
|
end
|
41
41
|
|
42
|
-
def pretty(fields = Const::Fields::
|
42
|
+
def pretty(fields = Const::Fields::DEFAULT) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
43
43
|
# find the maximum length of each field across all the packages so we know how many
|
44
44
|
# characters of horizontal space to allocate for each field when printing
|
45
45
|
fields.each do |key|
|
@@ -16,7 +16,7 @@ module Package
|
|
16
16
|
unless production_dependency?
|
17
17
|
risks.each_with_index do |risk, index|
|
18
18
|
risks[index] =
|
19
|
-
[risk, Risk.new(Enum::RiskType::
|
19
|
+
[risk, Risk.new(Enum::RiskType::LOW, risk.explanation)].min || Risk.new(Enum::RiskType::NONE)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
risks
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Package
|
2
|
+
module Audit
|
3
|
+
module Util
|
4
|
+
class Spinner
|
5
|
+
ANIMATION_SPEED = 0.1
|
6
|
+
STATES = %w[| / - \\]
|
7
|
+
|
8
|
+
def initialize(message = 'Loading...')
|
9
|
+
@message = message
|
10
|
+
@running = false
|
11
|
+
@thread = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def start # rubocop:disable Metrics/MethodLength
|
15
|
+
return if ENV['RACK_ENV'] == 'test'
|
16
|
+
raise 'Loading indicator already started.' if @running
|
17
|
+
|
18
|
+
@running = true
|
19
|
+
@thread = Thread.new do
|
20
|
+
step = 0
|
21
|
+
while @running
|
22
|
+
if @running && (ENV['RUBY_ENV'] != 'test' && ENV['RACK_ENV'] != 'test')
|
23
|
+
print "\r#{@message} #{STATES[step % STATES.length]}"
|
24
|
+
end
|
25
|
+
sleep ANIMATION_SPEED
|
26
|
+
step += 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def stop
|
32
|
+
return if ENV['RACK_ENV'] == 'test'
|
33
|
+
return unless @running
|
34
|
+
|
35
|
+
@running = false
|
36
|
+
@thread&.join
|
37
|
+
clear_console_line
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def clear_console_line
|
43
|
+
print "\r#{' ' * (@message.length + 2)}\r"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -85,7 +85,7 @@ module Package
|
|
85
85
|
|
86
86
|
puts Util::BashColor.blue('5. Check whether the package is used in production or not.')
|
87
87
|
puts ' If a package is limited to a non-production environment:'
|
88
|
-
puts " - cap risk severity to\t -> #{Util::BashColor.
|
88
|
+
puts " - cap risk severity to\t -> #{Util::BashColor.yellow('low')} risk"
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
@@ -2,12 +2,9 @@ module Package
|
|
2
2
|
module Audit
|
3
3
|
module Const
|
4
4
|
module Fields
|
5
|
-
ALL: Array[Symbol]
|
6
5
|
AVAILABLE: Array[Symbol]
|
7
|
-
|
6
|
+
DEFAULT: Array[Symbol]
|
8
7
|
HEADERS: Hash[Symbol, String]
|
9
|
-
OUTDATED: Array[Symbol]
|
10
|
-
VULNERABLE: Array[Symbol]
|
11
8
|
end
|
12
9
|
end
|
13
10
|
end
|
@@ -2,11 +2,13 @@ module Package
|
|
2
2
|
module Audit
|
3
3
|
module Enum
|
4
4
|
module Environment
|
5
|
-
DEFAULT:
|
6
|
-
DEV:
|
7
|
-
PRODUCTION:
|
8
|
-
STAGING:
|
9
|
-
TEST:
|
5
|
+
DEFAULT: String
|
6
|
+
DEV: String
|
7
|
+
PRODUCTION: String
|
8
|
+
STAGING: String
|
9
|
+
TEST: String
|
10
|
+
|
11
|
+
def self.all: -> Array[String]
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Package
|
2
2
|
module Audit
|
3
3
|
class Package
|
4
|
-
@groups: Array[
|
4
|
+
@groups: Array[String]
|
5
5
|
@risks: Array[Risk]
|
6
6
|
@technology: String
|
7
7
|
@vulnerabilities: Array[String]
|
8
8
|
|
9
|
-
attr_accessor groups: Array[
|
9
|
+
attr_accessor groups: Array[String]
|
10
10
|
attr_accessor latest_version: String
|
11
11
|
attr_accessor latest_version_date: String
|
12
12
|
attr_reader name: String
|
@@ -2,10 +2,11 @@ module Package
|
|
2
2
|
module Audit
|
3
3
|
module Ruby
|
4
4
|
class GemMetaData
|
5
|
+
@dir: String
|
5
6
|
@gem_hash: Hash[String, Package]
|
6
7
|
@pkgs: Array[Package]
|
7
8
|
|
8
|
-
def initialize: (Array[Package]) -> void
|
9
|
+
def initialize: (String, Array[Package]) -> void
|
9
10
|
|
10
11
|
def fetch: -> Array[Package]
|
11
12
|
|
@@ -3,13 +3,15 @@ module Package
|
|
3
3
|
class CommandParser
|
4
4
|
@config: Hash[String, untyped]?
|
5
5
|
@dir: String
|
6
|
+
@environments: Array[String]
|
7
|
+
@spinner: Util::Spinner
|
6
8
|
@options: Hash[String, untyped]
|
7
9
|
@report: Symbol
|
8
10
|
@technologies: Array[String]
|
9
11
|
|
10
12
|
def initialize: (String, Hash[String, untyped], Symbol) -> void
|
11
13
|
|
12
|
-
def run: ->
|
14
|
+
def run: -> int
|
13
15
|
|
14
16
|
private
|
15
17
|
|
@@ -17,6 +19,8 @@ module Package
|
|
17
19
|
|
18
20
|
def parse_config_file: -> Hash[String, untyped]?
|
19
21
|
|
22
|
+
def parse_environments: -> Array[String]
|
23
|
+
|
20
24
|
def parse_technologies: -> Array[String]
|
21
25
|
|
22
26
|
def print_disclaimer: (String) -> void
|
@@ -24,8 +28,6 @@ module Package
|
|
24
28
|
def print_results: (String, Array[Package], Array[Package]) -> void
|
25
29
|
|
26
30
|
def print_summary: (String, Array[Package], Array[Package]) -> void
|
27
|
-
|
28
|
-
def report_fields: -> Array[Symbol]
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
@@ -4,8 +4,9 @@ module Package
|
|
4
4
|
@config: Hash[String, untyped]?
|
5
5
|
@dir: String
|
6
6
|
@report: Symbol
|
7
|
+
@environments: Array[String]
|
7
8
|
|
8
|
-
def initialize: (Hash[String, untyped]?, String, Symbol) -> void
|
9
|
+
def initialize: (Hash[String, untyped]?, String, Symbol, Array[String]) -> void
|
9
10
|
|
10
11
|
def run: (String) -> Array[Array[Package]]
|
11
12
|
|
@@ -13,6 +14,8 @@ module Package
|
|
13
14
|
|
14
15
|
def filter_pkgs_based_on_config: (Array[Package]) -> Array[Package]
|
15
16
|
|
17
|
+
def filter_pkgs_based_on_environment: (Array[Package]) -> Array[Package]
|
18
|
+
|
16
19
|
def find_by_technology: (String) -> Array[Package]
|
17
20
|
|
18
21
|
def find_node: -> Array[Package]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Package
|
2
|
+
module Audit
|
3
|
+
module Util
|
4
|
+
class Spinner
|
5
|
+
ANIMATION_SPEED: Float
|
6
|
+
STATES: Array[String]
|
7
|
+
|
8
|
+
@message: String
|
9
|
+
@running: bool
|
10
|
+
@thread: Thread?
|
11
|
+
|
12
|
+
def initialize: (?String) -> void
|
13
|
+
|
14
|
+
def start: -> void
|
15
|
+
|
16
|
+
def stop: -> void
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def clear_console_line: -> void
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: package-audit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Tactica Communications Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler-audit
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- lib/package/audit/technology/detector.rb
|
86
86
|
- lib/package/audit/technology/validator.rb
|
87
87
|
- lib/package/audit/util/bash_color.rb
|
88
|
+
- lib/package/audit/util/spinner.rb
|
88
89
|
- lib/package/audit/util/summary_printer.rb
|
89
90
|
- lib/package/audit/version.rb
|
90
91
|
- sig/package/audit/cli.rbs
|
@@ -124,6 +125,7 @@ files:
|
|
124
125
|
- sig/package/audit/technology/detector.rbs
|
125
126
|
- sig/package/audit/technology/validator.rbs
|
126
127
|
- sig/package/audit/util/bash_color.rbs
|
128
|
+
- sig/package/audit/util/spinner.rbs
|
127
129
|
- sig/package/audit/util/summary_printer.rbs
|
128
130
|
- sig/package/audit/version.rbs
|
129
131
|
homepage: https://github.com/tactica/package-audit
|
@@ -148,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
150
|
- !ruby/object:Gem::Version
|
149
151
|
version: '0'
|
150
152
|
requirements: []
|
151
|
-
rubygems_version: 3.4.
|
153
|
+
rubygems_version: 3.4.22
|
152
154
|
signing_key:
|
153
155
|
specification_version: 4
|
154
156
|
summary: A helper tool to find outdated, deprecated and vulnerable dependencies.
|