package-audit 0.4.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d30d08ba36373c75427371f922cb0a5819a021868bf82001428e0541571df9f8
4
- data.tar.gz: ac4dce54e3905dd56de9b137a62101de7267262c1f6b0310e4697c8f016a36b8
3
+ metadata.gz: 4c2f009e294663828a3055ac8b8facb3106251875a240f9abf74754747102cef
4
+ data.tar.gz: 0a11812a839205caa7793c5b34baf31006438b020e9f535ffe1fd5b3ee0333ab
5
5
  SHA512:
6
- metadata.gz: 00be4151f4f124614d117a739a558f9f2816f0f72095f222ddadf5101a6d089b40bdc5369c4a68c9b096b1547932561394f1fee5ca58712e13a4909c4a8c9558
7
- data.tar.gz: f224c2c2fe2ff39586d20989ef6999d7b2a52acd2276dcdd9895441105ccaebc5991523676b88545a5afa96d4ffcac10291ab76dfab735b65d42aabc4598d7e4
6
+ metadata.gz: 7e7a294008ddcb510e8335193ac013447c38b27a71f440325ae2221f5bd0dea29bf714a88e6089b451d50c64f24964da04215c5e54c74c0729fa37a3f277d44b
7
+ data.tar.gz: 29bb2f4dbef1bb9a6c38eb7d4b17c9aa299f943916765d05a02b14b8f48a0e8ce212bc834e4657285b99d9ba0eb33c80df479e907b673f13fa6834c098e8649e
@@ -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
- ALL = %i[name version latest_version latest_version_date groups vulnerabilities risk_type risk_explanation]
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 = :development
6
- TEST = :test
7
- STAGING = :staging
8
- PRODUCTION = :production
9
- DEFAULT = :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
@@ -5,6 +5,7 @@ module Package
5
5
  CONFIG = 'config'
6
6
  CSV = 'csv'
7
7
  CSV_EXCLUDE_HEADERS = 'exclude-headers'
8
+ ENVIRONMENT = 'environment'
8
9
  INCLUDE_IGNORED = 'include-ignored'
9
10
  TECHNOLOGY = 'technology'
10
11
  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 response.error unless response.is_a?(Net::HTTPSuccess)
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(&:join)
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) ? %i[development] : %i[default development]
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
@@ -22,7 +28,7 @@ module Package
22
28
  private
23
29
 
24
30
  def fetch_package_block(dep_name, expected_version)
25
- regex = /#{Regexp.escape(dep_name)}@#{Regexp.escape(expected_version)}.*?:.*?(\n\n|\z)/m
31
+ regex = regex_pattern_for_package(dep_name, expected_version)
26
32
  blocks = @yarn_lock_file.match(regex)
27
33
  if blocks.nil? || blocks[0].nil?
28
34
  raise NoMatchingPatternError, "Unable to find \"#{dep_name}\" in #{@yarn_lock_path}"
@@ -40,6 +46,17 @@ module Package
40
46
 
41
47
  version || '0.0.0.0'
42
48
  end
49
+
50
+ def regex_pattern_for_package(dep_name, version)
51
+ # assume the package name is prefixed by a space, a quote or be the first thing on the line
52
+ # there can be multiple comma-separated versions on the same line with or without quotes
53
+ # Here are some examples of strings that would be matched:
54
+ # - aria-query@^5.0.0:
55
+ # - lodash@^4.17.15, lodash@^4.17.20:
56
+ # - "@adobe/css-tools@^4.0.1":
57
+ # - "@babel/runtime@^7.23.1", "@babel/runtime@^7.9.2":
58
+ /(?:^|[ "])#{Regexp.escape(dep_name)}@#{Regexp.escape(version)}.*?:.*?(\n\n|\z)/m
59
+ end
43
60
  end
44
61
  end
45
62
  end
@@ -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.definition
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
- @gem_hash[spec.name].update(groups: @gem_hash[spec.name].groups | [group]) if @gem_hash.key? spec.name
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
- @technologies.each do |technology|
28
- all_pkgs, ignored_pkgs = PackageFinder.new(@config, @dir, @report).run(technology)
29
- ignored_pkgs = [] if @options[Enum::Option::INCLUDE_IGNORED]
30
- cumulative_pkgs << all_pkgs
31
- print_results(technology, (all_pkgs || []) - (ignored_pkgs || []), ignored_pkgs || [])
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
- cumulative_pkgs.any?
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(report_fields)
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
- ignored_pkgs = filter_pkgs_based_on_config(all_pkgs)
23
- [all_pkgs, ignored_pkgs]
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::ALL).any?
35
+ return unless (fields - Const::Fields::DEFAULT).any?
36
36
 
37
37
  raise ArgumentError,
38
- "#{fields - Const::Fields::ALL} are not valid field names. " \
39
- "Available fields names are: #{Const::Fields::ALL}."
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::ALL) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
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::MEDIUM, risk.explanation)].min || Risk.new(Enum::RiskType::NONE)
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.orange('medium')} risk"
88
+ puts " - cap risk severity to\t -> #{Util::BashColor.yellow('low')} risk"
89
89
  end
90
90
  end
91
91
  end
@@ -1,5 +1,5 @@
1
1
  module Package
2
2
  module Audit
3
- VERSION = '0.4.0'
3
+ VERSION = '0.5.0'
4
4
  end
5
5
  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
- DEPRECATED: Array[Symbol]
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: Symbol
6
- DEV: Symbol
7
- PRODUCTION: Symbol
8
- STAGING: Symbol
9
- TEST: Symbol
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
@@ -5,6 +5,7 @@ module Package
5
5
  CONFIG: String
6
6
  CSV: String
7
7
  CSV_EXCLUDE_HEADERS: String
8
+ ENVIRONMENT: String
8
9
  INCLUDE_IGNORED: String
9
10
  TECHNOLOGY: String
10
11
  end
@@ -1,12 +1,12 @@
1
1
  module Package
2
2
  module Audit
3
3
  class Package
4
- @groups: Array[Symbol]
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[Symbol]
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
@@ -14,6 +14,8 @@ module Package
14
14
  def fetch_package_block: (Symbol, String) -> String
15
15
 
16
16
  def fetch_package_version: (Symbol, String) -> String
17
+
18
+ def regex_pattern_for_package: (Symbol, String) -> Regexp
17
19
  end
18
20
  end
19
21
  end
@@ -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: -> bool
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.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
- - Vadim Kononov
7
+ - Tactica Communications Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-11 00:00:00.000000000 Z
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.12
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.