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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a14d75d3c6f64af8c327c492e0d0c1bcf98fc3119964e63d944fc33fc6ce6b8e
4
- data.tar.gz: 01f5eaac43d53a65ac42a46a736793b8dbe56f4ad3531a8e649d9516b85a5027
3
+ metadata.gz: 7305fff5b318e2831908713c3d49b984787b99baaca769115339518297dee6e4
4
+ data.tar.gz: 6db0ad1ecece32ddc3b93ea89fc9366b1fba59861e925d9e6955708173f3f32d
5
5
  SHA512:
6
- metadata.gz: 9f2599769354017f84a5eb4f5da8cb6b67b69be12ed6f67126ed0701b1746461960c24ecd1ba7d2cf81d5719ca18234f1f9bdcb645a5bb9d8916faaca040ee96
7
- data.tar.gz: 9eeeb933dd6e5535c0fdcdfca6fea339ca34fc1a611460b68ea0274da083ec08be63424eb82c7229ed939cf05fe49621bbf9f4d04af9abffc6001f7a43e507cb
6
+ metadata.gz: 32b8c325d2f938ead2ab5ab8ab190ac94f4591667cbf0eaf884258b64e8ac06dc9a367ca7ecefab5a8688e1713378543ae5834ce6a8dbdab6874fdccded4b528
7
+ data.tar.gz: ca7e0687952bd9bcb7708b159e2551ad6cfa84bec8636eb05e954cb5763bb714d407ef190651ef764756f2a333c83e33b694a52e07dbff633019ba2f1d5a5563
@@ -14,15 +14,24 @@ module Package
14
14
  class CLI < Thor
15
15
  default_task :default
16
16
 
17
- class_option Enum::Option::CONFIG,
18
- aliases: '-c', banner: 'FILE',
19
- desc: "Path to a custom configuration file, default: #{Const::File::CONFIG})"
20
- class_option Enum::Option::GROUP,
21
- aliases: '-g', repeatable: true,
22
- desc: 'Group to be audited (repeat this flag for each group)'
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
- within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::ALL).run }
42
- end
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
- groups
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 groups vulnerabilities risk_type risk_explanation]
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
- groups: 'Groups',
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
@@ -8,6 +8,9 @@ module Package
8
8
  GROUP = 'group'
9
9
  INCLUDE_IGNORED = 'include-ignored'
10
10
  TECHNOLOGY = 'technology'
11
+ DEPRECATED = 'deprecated'
12
+ OUTDATED = 'outdated'
13
+ VULNERABLE = 'vulnerable'
11
14
  end
12
15
  end
13
16
  end
@@ -80,6 +80,13 @@ module Package
80
80
  false
81
81
  end
82
82
 
83
+ def flags
84
+ v = vulnerable? ? 'V' : '·'
85
+ o = outdated? ? 'O' : '·'
86
+ d = deprecated? ? 'D' : '·'
87
+ "⦗#{v}#{o}#{d}⦘"
88
+ end
89
+
83
90
  def to_csv(fields)
84
91
  fields.map { |field| send(field) }.join(',')
85
92
  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
- separator = max_widths.map { |width| '=' * width }.join('=' * COLUMN_GAP)
51
+ separator_plain = max_widths.map { |width| '' * width }.join('' * COLUMN_GAP)
52
+ separator = Util::BashColor.light_green(separator_plain)
51
53
 
52
- puts separator
53
- puts header
54
- puts separator
54
+ puts ' '
55
+ puts " #{separator}"
56
+ puts " #{header}"
57
+ puts " #{separator}"
55
58
 
56
59
  @pkgs.each do |pkg|
57
- puts fields.map.with_index { |key, index|
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
- }.join(' ' * COLUMN_GAP)
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) # rubocop:disable Metrics/MethodLength
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
@@ -29,6 +29,10 @@ module Package
29
29
  def self.blue(str)
30
30
  "\e[34m#{str}\e[0m"
31
31
  end
32
+
33
+ def self.light_green(str)
34
+ "\e[38;5;154m#{str}\e[0m"
35
+ end
32
36
  end
33
37
  end
34
38
  end
@@ -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 ' 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"
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 " 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"
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 ' 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"
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 ' 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
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 ' If a package is limited to a non-production group:'
44
- puts " - cap risk severity to\t -> #{Util::BashColor.yellow('low')} risk"
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("\n%<info>s\n%<cmd>s\n\n",
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, they may not be deprecated.')
16
- puts Util::BashColor.blue("Please contact the package author for more information about its status.\n")
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\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
- "(#{ignored_pkgs.length} ignored).\n")
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.\n")
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!\n")
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("There are no deprecated, outdated or vulnerable #{technology.capitalize} " \
70
- "packages (#{ignored_pkgs.length} ignored)!\n")
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("There are no deprecated, outdated or vulnerable #{technology.capitalize} " \
73
- "packages!\n")
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]} outdated" + outdated_details(stats)
79
- deprecated_str = "#{stats[:deprecated]} deprecated" + deprecated_details(stats)
80
- vulnerable_str = "#{stats[:vulnerable]} vulnerable" + vulnerability_details(stats)
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
@@ -1,5 +1,5 @@
1
1
  module Package
2
2
  module Audit
3
- VERSION = '0.7.1'
3
+ VERSION = '0.8.0'
4
4
  end
5
5
  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.7.1
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.6.9
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: []