package-audit 0.7.1 → 0.8.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 +48 -23
- data/lib/package/audit/const/fields.rb +4 -6
- data/lib/package/audit/enum/option.rb +3 -0
- data/lib/package/audit/models/package.rb +7 -0
- data/lib/package/audit/services/command_parser.rb +63 -0
- data/lib/package/audit/services/package_printer.rb +14 -10
- data/lib/package/audit/util/bash_color.rb +4 -0
- data/lib/package/audit/util/risk_legend.rb +23 -23
- data/lib/package/audit/util/summary_printer.rb +22 -17
- data/lib/package/audit/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7305fff5b318e2831908713c3d49b984787b99baaca769115339518297dee6e4
|
|
4
|
+
data.tar.gz: 6db0ad1ecece32ddc3b93ea89fc9366b1fba59861e925d9e6955708173f3f32d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 32b8c325d2f938ead2ab5ab8ab190ac94f4591667cbf0eaf884258b64e8ac06dc9a367ca7ecefab5a8688e1713378543ae5834ce6a8dbdab6874fdccded4b528
|
|
7
|
+
data.tar.gz: ca7e0687952bd9bcb7708b159e2551ad6cfa84bec8636eb05e954cb5763bb714d407ef190651ef764756f2a333c83e33b694a52e07dbff633019ba2f1d5a5563
|
data/lib/package/audit/cli.rb
CHANGED
|
@@ -14,15 +14,24 @@ module Package
|
|
|
14
14
|
class CLI < Thor
|
|
15
15
|
default_task :default
|
|
16
16
|
|
|
17
|
-
class_option Enum::Option::
|
|
18
|
-
|
|
19
|
-
desc:
|
|
20
|
-
class_option Enum::Option::
|
|
21
|
-
|
|
22
|
-
desc: '
|
|
17
|
+
class_option Enum::Option::DEPRECATED,
|
|
18
|
+
type: :boolean,
|
|
19
|
+
desc: 'Filter to show only deprecated packages (or use --skip-deprecated to exclude them)'
|
|
20
|
+
class_option Enum::Option::OUTDATED,
|
|
21
|
+
type: :boolean,
|
|
22
|
+
desc: 'Filter to show only outdated packages (or use --skip-outdated to exclude them)'
|
|
23
|
+
class_option Enum::Option::VULNERABLE,
|
|
24
|
+
type: :boolean,
|
|
25
|
+
desc: 'Filter to show only vulnerable packages (or use --skip-vulnerable to exclude them)'
|
|
23
26
|
class_option Enum::Option::TECHNOLOGY,
|
|
24
27
|
aliases: '-t', repeatable: true,
|
|
25
28
|
desc: 'Technology to be audited (repeat this flag for each technology)'
|
|
29
|
+
class_option Enum::Option::GROUP,
|
|
30
|
+
aliases: '-g', repeatable: true,
|
|
31
|
+
desc: 'Group to be audited (repeat this flag for each group)'
|
|
32
|
+
class_option Enum::Option::CONFIG,
|
|
33
|
+
aliases: '-c', banner: 'FILE',
|
|
34
|
+
desc: "Path to a custom configuration file, default: #{Const::File::CONFIG})"
|
|
26
35
|
class_option Enum::Option::INCLUDE_IGNORED,
|
|
27
36
|
type: :boolean, default: false,
|
|
28
37
|
desc: 'Include packages ignored by a configuration file'
|
|
@@ -38,23 +47,8 @@ module Package
|
|
|
38
47
|
|
|
39
48
|
desc '[DIR]', 'Show a report of potentially deprecated, outdated or vulnerable packages'
|
|
40
49
|
def default(dir = Dir.pwd)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
desc 'deprecated [DIR]',
|
|
45
|
-
"Show packages with no updates by author for at least #{Const::Time::YEARS_ELAPSED_TO_BE_OUTDATED} years"
|
|
46
|
-
def deprecated(dir = Dir.pwd)
|
|
47
|
-
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::DEPRECATED).run }
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
desc 'outdated [DIR]', 'Show packages that are out of date'
|
|
51
|
-
def outdated(dir = Dir.pwd)
|
|
52
|
-
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::OUTDATED).run }
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
desc 'vulnerable [DIR]', 'Show packages and their dependencies that have security vulnerabilities'
|
|
56
|
-
def vulnerable(dir = Dir.pwd)
|
|
57
|
-
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::VULNERABLE).run }
|
|
50
|
+
report = determine_report_type
|
|
51
|
+
within_rescue_block { exit CommandParser.new(dir, options, report).run }
|
|
58
52
|
end
|
|
59
53
|
|
|
60
54
|
desc 'risk', 'Print information on how risk is calculated'
|
|
@@ -81,6 +75,37 @@ module Package
|
|
|
81
75
|
|
|
82
76
|
private
|
|
83
77
|
|
|
78
|
+
def determine_report_type # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
79
|
+
deprecated = options[Enum::Option::DEPRECATED]
|
|
80
|
+
outdated = options[Enum::Option::OUTDATED]
|
|
81
|
+
vulnerable = options[Enum::Option::VULNERABLE]
|
|
82
|
+
|
|
83
|
+
# Count positive filters (true) and negative filters (false)
|
|
84
|
+
positive_filters = [deprecated, outdated, vulnerable].count(true)
|
|
85
|
+
negative_filters = [deprecated, outdated, vulnerable].count(false)
|
|
86
|
+
|
|
87
|
+
# If any explicit filters are set (positive or negative), we need to filter
|
|
88
|
+
# Otherwise all are nil (not specified) and we show everything
|
|
89
|
+
has_explicit_filters = [deprecated, outdated, vulnerable].any? { |v| !v.nil? }
|
|
90
|
+
|
|
91
|
+
# If no filters specified at all, return ALL
|
|
92
|
+
return Enum::Report::ALL unless has_explicit_filters
|
|
93
|
+
|
|
94
|
+
# If only positive filters, handle them
|
|
95
|
+
if positive_filters.positive? && negative_filters.zero?
|
|
96
|
+
# Single positive filter - use specific report type
|
|
97
|
+
return Enum::Report::DEPRECATED if positive_filters == 1 && deprecated
|
|
98
|
+
return Enum::Report::OUTDATED if positive_filters == 1 && outdated
|
|
99
|
+
return Enum::Report::VULNERABLE if positive_filters == 1 && vulnerable
|
|
100
|
+
|
|
101
|
+
# Multiple positive filters - fetch ALL and filter in CommandParser
|
|
102
|
+
return Enum::Report::ALL
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# If we have any filters (positive or negative), fetch ALL and filter in CommandParser
|
|
106
|
+
Enum::Report::ALL
|
|
107
|
+
end
|
|
108
|
+
|
|
84
109
|
def within_rescue_block
|
|
85
110
|
yield
|
|
86
111
|
rescue StandardError => e
|
|
@@ -8,13 +8,12 @@ module Package
|
|
|
8
8
|
version_date
|
|
9
9
|
latest_version
|
|
10
10
|
latest_version_date
|
|
11
|
-
|
|
11
|
+
flags
|
|
12
12
|
vulnerabilities
|
|
13
13
|
risk_type
|
|
14
|
-
risk_explanation
|
|
15
14
|
]
|
|
16
15
|
|
|
17
|
-
DEFAULT = %i[name version latest_version latest_version_date
|
|
16
|
+
DEFAULT = %i[name version latest_version latest_version_date flags vulnerabilities risk_type]
|
|
18
17
|
|
|
19
18
|
# the names of these fields must match the instance variables in the Dependency class
|
|
20
19
|
HEADERS = {
|
|
@@ -23,10 +22,9 @@ module Package
|
|
|
23
22
|
version_date: 'Version Date',
|
|
24
23
|
latest_version: 'Latest',
|
|
25
24
|
latest_version_date: 'Latest Date',
|
|
26
|
-
|
|
25
|
+
flags: 'Flags',
|
|
27
26
|
vulnerabilities: 'Vulnerabilities',
|
|
28
|
-
risk_type: 'Risk'
|
|
29
|
-
risk_explanation: 'Risk Explanation'
|
|
27
|
+
risk_type: 'Risk'
|
|
30
28
|
}
|
|
31
29
|
end
|
|
32
30
|
end
|
|
@@ -52,6 +52,7 @@ module Package
|
|
|
52
52
|
all_pkgs, ignored_pkgs = PackageFinder.new(@config, @dir, @report, @groups).run(technology)
|
|
53
53
|
ignored_pkgs = [] if @options[Enum::Option::INCLUDE_IGNORED]
|
|
54
54
|
active_pkgs = (all_pkgs || []) - (ignored_pkgs || [])
|
|
55
|
+
active_pkgs = filter_by_flags(active_pkgs) if any_filters_set?
|
|
55
56
|
cumulative_pkgs += active_pkgs
|
|
56
57
|
mutex.synchronize { all_packages_for_config += all_pkgs || [] }
|
|
57
58
|
|
|
@@ -74,6 +75,8 @@ module Package
|
|
|
74
75
|
@spinner.stop # Stop spinner before cleaning config to ensure clean output
|
|
75
76
|
clean_config(all_packages_for_config)
|
|
76
77
|
|
|
78
|
+
puts unless @options[Enum::Option::FORMAT] # Add final blank line for default format
|
|
79
|
+
|
|
77
80
|
cumulative_pkgs.any? ? 1 : 0
|
|
78
81
|
ensure
|
|
79
82
|
@spinner.stop
|
|
@@ -147,6 +150,66 @@ module Package
|
|
|
147
150
|
|
|
148
151
|
"#{array[0..-2].join(', ')}, and #{array.last}"
|
|
149
152
|
end
|
|
153
|
+
|
|
154
|
+
def any_filters_set?
|
|
155
|
+
deprecated = @options[Enum::Option::DEPRECATED]
|
|
156
|
+
outdated = @options[Enum::Option::OUTDATED]
|
|
157
|
+
vulnerable = @options[Enum::Option::VULNERABLE]
|
|
158
|
+
|
|
159
|
+
# Check if any filter was explicitly set (not nil)
|
|
160
|
+
[deprecated, outdated, vulnerable].any? { |v| !v.nil? }
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def filter_by_flags(pkgs) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
164
|
+
deprecated = @options[Enum::Option::DEPRECATED]
|
|
165
|
+
outdated = @options[Enum::Option::OUTDATED]
|
|
166
|
+
vulnerable = @options[Enum::Option::VULNERABLE]
|
|
167
|
+
|
|
168
|
+
# Determine which filters are positive (include) vs negative (exclude)
|
|
169
|
+
positive_filters = []
|
|
170
|
+
negative_filters = []
|
|
171
|
+
|
|
172
|
+
positive_filters << :deprecated if deprecated == true
|
|
173
|
+
positive_filters << :outdated if outdated == true
|
|
174
|
+
positive_filters << :vulnerable if vulnerable == true
|
|
175
|
+
|
|
176
|
+
negative_filters << :deprecated if deprecated == false
|
|
177
|
+
negative_filters << :outdated if outdated == false
|
|
178
|
+
negative_filters << :vulnerable if vulnerable == false
|
|
179
|
+
|
|
180
|
+
pkgs.select do |pkg|
|
|
181
|
+
# If we have positive filters, package must match at least one
|
|
182
|
+
if positive_filters.any?
|
|
183
|
+
matches_positive = positive_filters.any? do |filter|
|
|
184
|
+
case filter
|
|
185
|
+
when :deprecated then pkg.deprecated?
|
|
186
|
+
when :outdated then pkg.outdated?
|
|
187
|
+
when :vulnerable then pkg.vulnerable?
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
next false unless matches_positive
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# If we have negative filters (skip flags), use different logic:
|
|
194
|
+
# A package should be excluded ONLY if ALL of its risk types are being skipped
|
|
195
|
+
if negative_filters.any?
|
|
196
|
+
# Determine which risk types we're showing (not skipping)
|
|
197
|
+
showing_deprecated = deprecated != false
|
|
198
|
+
showing_outdated = outdated != false
|
|
199
|
+
showing_vulnerable = vulnerable != false
|
|
200
|
+
|
|
201
|
+
# Check if package has at least one risk type that we're showing
|
|
202
|
+
has_shown_risk = false
|
|
203
|
+
has_shown_risk = true if pkg.deprecated? && showing_deprecated
|
|
204
|
+
has_shown_risk = true if pkg.outdated? && showing_outdated
|
|
205
|
+
has_shown_risk = true if pkg.vulnerable? && showing_vulnerable
|
|
206
|
+
|
|
207
|
+
next false unless has_shown_risk
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
true
|
|
211
|
+
end
|
|
212
|
+
end
|
|
150
213
|
end
|
|
151
214
|
end
|
|
152
215
|
end
|
|
@@ -24,12 +24,13 @@ module Package
|
|
|
24
24
|
case @options[Enum::Option::FORMAT]
|
|
25
25
|
when Enum::Format::CSV
|
|
26
26
|
csv(fields, exclude_headers: @options[Enum::Option::CSV_EXCLUDE_HEADERS])
|
|
27
|
+
puts
|
|
27
28
|
when Enum::Format::MARKDOWN
|
|
28
29
|
markdown(fields)
|
|
30
|
+
puts
|
|
29
31
|
else
|
|
30
32
|
pretty(fields)
|
|
31
33
|
end
|
|
32
|
-
puts
|
|
33
34
|
end
|
|
34
35
|
|
|
35
36
|
private
|
|
@@ -47,19 +48,24 @@ module Package
|
|
|
47
48
|
header = fields.map.with_index do |field, index|
|
|
48
49
|
Const::Fields::HEADERS[field].gsub(BASH_FORMATTING_REGEX, '').ljust(max_widths[index])
|
|
49
50
|
end.join(' ' * COLUMN_GAP)
|
|
50
|
-
|
|
51
|
+
separator_plain = max_widths.map { |width| '─' * width }.join('─' * COLUMN_GAP)
|
|
52
|
+
separator = Util::BashColor.light_green(separator_plain)
|
|
51
53
|
|
|
52
|
-
puts
|
|
53
|
-
puts
|
|
54
|
-
puts
|
|
54
|
+
puts ' '
|
|
55
|
+
puts " #{separator}"
|
|
56
|
+
puts " #{header}"
|
|
57
|
+
puts " #{separator}"
|
|
55
58
|
|
|
56
59
|
@pkgs.each do |pkg|
|
|
57
|
-
|
|
60
|
+
row = fields.map.with_index do |key, index|
|
|
58
61
|
val = get_field_value(pkg, key)
|
|
59
62
|
formatting_length = val.length - val.gsub(BASH_FORMATTING_REGEX, '').length
|
|
60
63
|
val.ljust(max_widths[index] + formatting_length)
|
|
61
|
-
|
|
64
|
+
end.join(' ' * COLUMN_GAP)
|
|
65
|
+
puts " #{row}"
|
|
62
66
|
end
|
|
67
|
+
|
|
68
|
+
puts " #{separator}"
|
|
63
69
|
end
|
|
64
70
|
|
|
65
71
|
def csv(fields = Const::Fields::DEFAULT, exclude_headers: false)
|
|
@@ -99,10 +105,8 @@ module Package
|
|
|
99
105
|
end
|
|
100
106
|
end
|
|
101
107
|
|
|
102
|
-
def get_field_value(pkg, field)
|
|
108
|
+
def get_field_value(pkg, field)
|
|
103
109
|
case field
|
|
104
|
-
when :groups
|
|
105
|
-
pkg.group_list
|
|
106
110
|
when :risk_type
|
|
107
111
|
Formatter::Risk.new(pkg.risk_type).format
|
|
108
112
|
when :version
|
|
@@ -6,42 +6,42 @@ module Package
|
|
|
6
6
|
module Util
|
|
7
7
|
module RiskLegend
|
|
8
8
|
def self.print # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
9
|
-
puts Util::BashColor.blue('1. Check if the package has a security vulnerability.')
|
|
10
|
-
puts '
|
|
11
|
-
puts "
|
|
12
|
-
puts "
|
|
13
|
-
puts "
|
|
14
|
-
puts "
|
|
15
|
-
puts "
|
|
16
|
-
puts "
|
|
9
|
+
puts " #{Util::BashColor.blue('1. Check if the package has a security vulnerability.')}"
|
|
10
|
+
puts ' If yes, the following vulnerability -> risk mapping is used:'
|
|
11
|
+
puts " - #{Util::BashColor.red('unknown')} vulnerability\t-> #{Util::BashColor.red('high')} risk"
|
|
12
|
+
puts " - #{Util::BashColor.red('critical')} vulnerability\t-> #{Util::BashColor.red('high')} risk"
|
|
13
|
+
puts " - #{Util::BashColor.red('high')} vulnerability\t-> #{Util::BashColor.red('high')} risk"
|
|
14
|
+
puts " - #{Util::BashColor.orange('medium')} vulnerability\t-> #{Util::BashColor.orange('medium')} risk"
|
|
15
|
+
puts " - #{Util::BashColor.orange('moderate')} vulnerability\t-> #{Util::BashColor.orange('medium')} risk" # rubocop:disable Layout/LineLength
|
|
16
|
+
puts " - #{Util::BashColor.yellow('low')} vulnerability\t-> #{Util::BashColor.yellow('low')} risk"
|
|
17
17
|
|
|
18
18
|
puts
|
|
19
19
|
|
|
20
|
-
puts Util::BashColor.blue('2. Check the package for potential deprecation.')
|
|
21
|
-
puts "
|
|
22
|
-
puts "
|
|
20
|
+
puts " #{Util::BashColor.blue('2. Check the package for potential deprecation.')}"
|
|
21
|
+
puts " If no new releases by author for at least #{Const::Time::YEARS_ELAPSED_TO_BE_OUTDATED} years:"
|
|
22
|
+
puts " - assign the risk to\t-> #{Util::BashColor.orange('medium')} risk"
|
|
23
23
|
|
|
24
24
|
puts
|
|
25
25
|
|
|
26
|
-
puts Util::BashColor.blue('3. Check if a newer version of the package is available.')
|
|
26
|
+
puts " #{Util::BashColor.blue('3. Check if a newer version of the package is available.')}"
|
|
27
27
|
|
|
28
|
-
puts '
|
|
29
|
-
puts "
|
|
30
|
-
puts "
|
|
31
|
-
puts "
|
|
32
|
-
puts "
|
|
28
|
+
puts ' If yes, assign risk as follows:'
|
|
29
|
+
puts " - #{Util::BashColor.orange('major version')} mismatch\t-> #{Util::BashColor.orange('medium')} risk" # rubocop:disable Layout/LineLength
|
|
30
|
+
puts " - #{Util::BashColor.yellow('minor version')} mismatch\t-> #{Util::BashColor.yellow('low')} risk"
|
|
31
|
+
puts " - #{Util::BashColor.green('patch version')} mismatch\t-> #{Util::BashColor.yellow('low')} risk"
|
|
32
|
+
puts " - #{Util::BashColor.green('build version')} mismatch\t-> #{Util::BashColor.yellow('low')} risk"
|
|
33
33
|
|
|
34
34
|
puts
|
|
35
35
|
|
|
36
|
-
puts Util::BashColor.blue('4. Take the highest risk from the first 3 steps.')
|
|
37
|
-
puts '
|
|
38
|
-
puts "
|
|
36
|
+
puts " #{Util::BashColor.blue('4. Take the highest risk from the first 3 steps.')}"
|
|
37
|
+
puts ' If two risks match in severity, use the following precedence:'
|
|
38
|
+
puts " - #{Util::BashColor.red('vulnerability')} > #{Util::BashColor.orange('deprecation')} > #{Util::BashColor.yellow('outdatedness')}" # rubocop:disable Layout/LineLength
|
|
39
39
|
|
|
40
40
|
puts
|
|
41
41
|
|
|
42
|
-
puts Util::BashColor.blue('5. Check whether the package is used in production or not.')
|
|
43
|
-
puts '
|
|
44
|
-
puts "
|
|
42
|
+
puts " #{Util::BashColor.blue('5. Check whether the package is used in production or not.')}"
|
|
43
|
+
puts ' If a package is limited to a non-production group:'
|
|
44
|
+
puts " - cap risk severity to\t -> #{Util::BashColor.yellow('low')} risk"
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
end
|
|
@@ -6,31 +6,34 @@ module Package
|
|
|
6
6
|
module Util
|
|
7
7
|
module SummaryPrinter
|
|
8
8
|
def self.all
|
|
9
|
-
printf("
|
|
9
|
+
printf(" %<info>s\n %<cmd>s\n",
|
|
10
10
|
info: Util::BashColor.blue('To show how risk is calculated run:'),
|
|
11
11
|
cmd: Util::BashColor.magenta(' > package-audit risk'))
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def self.deprecated
|
|
15
|
-
puts Util::BashColor.blue('Although the packages above have no recent updates,
|
|
16
|
-
|
|
15
|
+
puts " #{Util::BashColor.blue('Although the packages above have no recent updates, ' \
|
|
16
|
+
'they may not be deprecated.')}"
|
|
17
|
+
puts " #{Util::BashColor.blue('Please contact the package author for more information about its status.')}"
|
|
18
|
+
puts
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def self.vulnerable(technology, cmd)
|
|
20
|
-
printf("%<info>s\n%<cmd>s\n
|
|
22
|
+
printf(" %<info>s\n %<cmd>s\n",
|
|
21
23
|
info: Util::BashColor.blue("For more information about #{technology.capitalize} vulnerabilities run:"),
|
|
22
24
|
cmd: Util::BashColor.magenta(" > #{cmd}"))
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
def self.total(technology, report, pkgs, ignored_pkgs)
|
|
26
28
|
if ignored_pkgs.any?
|
|
27
|
-
puts Util::BashColor.cyan("Found a total of #{pkgs.length} #{technology.capitalize} packages " \
|
|
28
|
-
|
|
29
|
+
puts " #{Util::BashColor.cyan("Found a total of #{pkgs.length} #{technology.capitalize} packages " \
|
|
30
|
+
"(#{ignored_pkgs.length} ignored).")}"
|
|
29
31
|
elsif pkgs.any?
|
|
30
|
-
puts Util::BashColor.cyan("Found a total of #{pkgs.length} #{technology.capitalize} packages
|
|
32
|
+
puts " #{Util::BashColor.cyan("Found a total of #{pkgs.length} #{technology.capitalize} packages.")}"
|
|
31
33
|
else
|
|
32
|
-
puts Util::BashColor.green("There are no #{report} #{technology.capitalize} packages
|
|
34
|
+
puts " #{Util::BashColor.green("There are no #{report} #{technology.capitalize} packages!")}"
|
|
33
35
|
end
|
|
36
|
+
puts
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
def self.statistics(format, technology, report, pkgs, ignored_pkgs)
|
|
@@ -58,26 +61,28 @@ module Package
|
|
|
58
61
|
|
|
59
62
|
private_class_method def self.display_results(format, technology, report, pkgs, ignored_pkgs, stats) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/ParameterLists
|
|
60
63
|
if pkgs.any?
|
|
61
|
-
print status_message(stats)
|
|
64
|
+
print " #{status_message(stats)}"
|
|
62
65
|
print Util::BashColor.cyan(' \\') if format == Enum::Format::MARKDOWN
|
|
63
66
|
puts
|
|
64
67
|
total(technology, report, pkgs, ignored_pkgs)
|
|
65
68
|
elsif ignored_pkgs.any?
|
|
66
|
-
print status_message(stats)
|
|
69
|
+
print " #{status_message(stats)}"
|
|
67
70
|
print Util::BashColor.cyan(' \\') if format == Enum::Format::MARKDOWN
|
|
68
71
|
puts
|
|
69
|
-
puts Util::BashColor.green(
|
|
70
|
-
|
|
72
|
+
puts " #{Util::BashColor.green('There are no deprecated, outdated or vulnerable ' \
|
|
73
|
+
"#{technology.capitalize} packages (#{ignored_pkgs.length} ignored)!")}"
|
|
74
|
+
puts
|
|
71
75
|
else
|
|
72
|
-
puts Util::BashColor.green(
|
|
73
|
-
|
|
76
|
+
puts " #{Util::BashColor.green('There are no deprecated, outdated or vulnerable ' \
|
|
77
|
+
"#{technology.capitalize} packages!")}"
|
|
78
|
+
puts
|
|
74
79
|
end
|
|
75
80
|
end
|
|
76
81
|
|
|
77
82
|
private_class_method def self.status_message(stats)
|
|
78
|
-
outdated_str = "#{stats[:outdated]}
|
|
79
|
-
deprecated_str = "#{stats[:deprecated]}
|
|
80
|
-
vulnerable_str = "#{stats[:vulnerable]}
|
|
83
|
+
outdated_str = "#{stats[:outdated]} ⦗O⦘utdated" + outdated_details(stats)
|
|
84
|
+
deprecated_str = "#{stats[:deprecated]} ⦗D⦘eprecated" + deprecated_details(stats)
|
|
85
|
+
vulnerable_str = "#{stats[:vulnerable]} ⦗V⦘ulnerable" + vulnerability_details(stats)
|
|
81
86
|
|
|
82
87
|
Util::BashColor.cyan("#{vulnerable_str}, #{outdated_str}, #{deprecated_str}.")
|
|
83
88
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: package-audit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vadim Kononov
|
|
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
111
111
|
- !ruby/object:Gem::Version
|
|
112
112
|
version: '0'
|
|
113
113
|
requirements: []
|
|
114
|
-
rubygems_version: 3.
|
|
114
|
+
rubygems_version: 3.7.2
|
|
115
115
|
specification_version: 4
|
|
116
116
|
summary: A helper tool to find outdated, deprecated and vulnerable dependencies.
|
|
117
117
|
test_files: []
|