spandx 0.13.3 → 0.13.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b36f49bab527c52c6d3f6ddf1d70e022422f70c678bf865231921982460a4b4
4
- data.tar.gz: 5d31efbe54079dd42a07c46f9d47bbe508d712ebed5d7294537685112d170079
3
+ metadata.gz: ef9e117562bb153d2bf7a7aa8561244f50f7dcbca8a81300e10279efec45c674
4
+ data.tar.gz: '069f96ae764417f3b005ebd8e7fee919c66eee38a63649918f7dea3209a9bc34'
5
5
  SHA512:
6
- metadata.gz: abe3e8e231a35f5861b3e85502a7b5c415684ce351756b0d64c77cfcf417bfd099e25587714c9e88b9a3ddb7309154921e0b57b4601bbe9aa74de7f057165773
7
- data.tar.gz: 757dd76cebbd921d4034a69e794beffac0c9ff00ec846491b4037bf01a687d06aad5a8d258dccb59dc6cce6d94626dbb6df77eae53ccc8755982482a780bf65f
6
+ metadata.gz: 67ec66d00236b0c4a98bc770e0b33698ecabb6e868b4e1b309c735a0d3cf5288a49393280f0cff2829d8ab5d1005920b16a877bdabdb2a0b63c88ac9f7af7df9
7
+ data.tar.gz: 9260aeb08a495fb4f8bd1ba4c2b17fed8e34c2e60e96d5c826c79f7c51d83a8686b4194e060fa77e3b898f1beb17404006dd5370b727d2a7ce98d87ddce41507
@@ -1,4 +1,4 @@
1
- Version 0.13.3
1
+ Version 0.13.4
2
2
 
3
3
  # Changelog
4
4
 
@@ -9,6 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.13.4] - 2020-05-26
13
+ ### Added
14
+ - Add detected file path to report output.
15
+
16
+ ### Changed
17
+ - Use `Pathname` instead of `String` to represent file paths.
18
+ - Scan current directory when a path is not specified.
19
+
12
20
  ## [0.13.3] - 2020-05-19
13
21
  ### Fixed
14
22
  - Ignore invalid URLs during scan.
@@ -1,5 +1,7 @@
1
1
  #include "spandx.h"
2
2
 
3
+ #define NEWLINE 10
4
+
3
5
  VALUE rb_mSpandx;
4
6
  VALUE rb_mCore;
5
7
  VALUE rb_mCsvParser;
@@ -9,7 +11,7 @@ VALUE rb_mCsvParser;
9
11
  // "name","version","license"\r
10
12
  // "name","version","license"\r\n
11
13
  // "name","version",""\r\n
12
- static VALUE parse(VALUE self, VALUE line)
14
+ VALUE parse(VALUE self, VALUE line)
13
15
  {
14
16
  if (NIL_P(line)) return Qnil;
15
17
 
@@ -32,13 +34,13 @@ static VALUE parse(VALUE self, VALUE line)
32
34
  s = n;
33
35
  state = open;
34
36
  } else if (state == open) {
35
- if (!*n || n == p || *n == ',' || *n == 10) {
37
+ if (!*n || n == p || *n == ',' || *n == NEWLINE) {
36
38
  rb_ary_push(items, rb_str_new(s, p - s));
37
39
  state = closed;
38
40
  }
39
41
  }
40
42
  }
41
- *p++;
43
+ *(p++);
42
44
  }
43
45
 
44
46
  return items;
@@ -12,7 +12,7 @@ require 'parslet'
12
12
  require 'pathname'
13
13
  require 'yaml'
14
14
  require 'zeitwerk'
15
-
15
+ require 'terminal-table'
16
16
  require 'spandx/spandx'
17
17
 
18
18
  loader = Zeitwerk::Loader.for_gem
@@ -30,13 +30,12 @@ module Spandx
30
30
 
31
31
  def each_file
32
32
  Spandx::Core::PathTraversal
33
- .new(scan_path, recursive: @options['recursive'])
33
+ .new(scan_path, recursive: @options[:recursive])
34
34
  .each { |file| yield file }
35
35
  end
36
36
 
37
37
  def each_dependency_from(file)
38
38
  ::Spandx::Core::Parser
39
- .for(file)
40
39
  .parse(file)
41
40
  .map { |x| enhance(x) }
42
41
  .each { |dependency| yield dependency }
@@ -8,11 +8,11 @@ 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', default: 'table'
11
+ method_option :format, aliases: '-f', type: :string, desc: 'Format of report. (table, csv, json, hash)', 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
14
  method_option :show_progress, aliases: '-sp', type: :boolean, desc: 'Shows a progress bar', default: true
15
- def scan(lockfile)
15
+ def scan(lockfile = Pathname.pwd)
16
16
  if options[:help]
17
17
  invoke :help, ['scan']
18
18
  else
@@ -3,46 +3,80 @@
3
3
  module Spandx
4
4
  module Core
5
5
  class Dependency
6
- attr_reader :package_manager, :name, :version, :licenses, :meta
6
+ PACKAGE_MANAGERS = {
7
+ Spandx::Dotnet::Parsers::Csproj => :nuget,
8
+ Spandx::Dotnet::Parsers::PackagesConfig => :nuget,
9
+ Spandx::Dotnet::Parsers::Sln => :nuget,
10
+ Spandx::Java::Parsers::Maven => :maven,
11
+ Spandx::Js::Parsers::Npm => :npm,
12
+ Spandx::Js::Parsers::Yarn => :yarn,
13
+ Spandx::Php::Parsers::Composer => :composer,
14
+ Spandx::Python::Parsers::PipfileLock => :pypi,
15
+ Spandx::Ruby::Parsers::GemfileLock => :rubygems,
16
+ }.freeze
17
+ attr_reader :path, :name, :version, :licenses, :meta
7
18
 
8
- def initialize(package_manager:, name:, version:, licenses: [], meta: {})
9
- @package_manager = package_manager
10
- @name = name
11
- @version = version
12
- @licenses = licenses
19
+ def initialize(name:, version:, path:, meta: {})
20
+ @path = Pathname.new(path).realpath
21
+ @name = name || @path.basename.to_s
22
+ @version = version || @path.mtime.to_i.to_s
23
+ @licenses = []
13
24
  @meta = meta
14
25
  end
15
26
 
16
- def managed_by?(value)
17
- package_manager == value&.to_sym
27
+ def package_manager
28
+ PACKAGE_MANAGERS[Parser.for(path).class]
18
29
  end
19
30
 
20
31
  def <=>(other)
21
- to_s <=> other.to_s
32
+ return 1 if other.nil?
33
+
34
+ score = (name <=> other.name)
35
+ score = score.zero? ? (version <=> other&.version) : score
36
+ score.zero? ? (path.to_s <=> other&.path.to_s) : score
22
37
  end
23
38
 
24
39
  def hash
25
40
  to_s.hash
26
41
  end
27
42
 
43
+ def ==(other)
44
+ eql?(other)
45
+ end
46
+
28
47
  def eql?(other)
29
48
  to_s == other.to_s
30
49
  end
31
50
 
32
51
  def to_s
33
- @to_s ||= [name, version].compact.join(' ')
52
+ @to_s ||= [name, version, path].compact.join(' ')
34
53
  end
35
54
 
36
55
  def inspect
37
- "#<Spandx::Core::Dependency name=#{name}, version=#{version}>"
56
+ "#<#{self.class} name=#{name} version=#{version} path=#{relative_path}>"
38
57
  end
39
58
 
40
59
  def to_a
41
- [name, version, licenses.map(&:id)]
60
+ [name, version, license_expression, relative_path.to_s]
42
61
  end
43
62
 
44
63
  def to_h
45
- { name: name, version: version, licenses: licenses.map(&:id) }
64
+ {
65
+ name: name,
66
+ version: version,
67
+ licenses: license_expression,
68
+ path: relative_path.to_s
69
+ }
70
+ end
71
+
72
+ private
73
+
74
+ def relative_path(from: Pathname.pwd)
75
+ path.relative_path_from(from)
76
+ end
77
+
78
+ def license_expression
79
+ licenses.map(&:id).join(' AND ')
46
80
  end
47
81
  end
48
82
  end
@@ -8,7 +8,8 @@ module Spandx
8
8
  end
9
9
 
10
10
  def enhance(dependency)
11
- return dependency unless known?(dependency.package_manager)
11
+ package_manager = package_manager_for(dependency)
12
+ return dependency unless known?(package_manager)
12
13
  return enhance_from_metadata(dependency) if available_in?(dependency.meta)
13
14
 
14
15
  licenses_for(dependency).each do |text|
@@ -25,8 +26,9 @@ module Spandx
25
26
  end
26
27
 
27
28
  def cache_for(dependency, git: Spandx.git)
28
- git = git[dependency.package_manager.to_sym] || git[:cache]
29
- key = key_for(dependency.package_manager)
29
+ package_manager = package_manager_for(dependency)
30
+ git = git[package_manager.to_sym] || git[:cache]
31
+ key = key_for(package_manager)
30
32
  Spandx::Core::Cache.new(key, root: "#{git.root}/.index")
31
33
  end
32
34
 
@@ -54,6 +56,10 @@ module Spandx
54
56
  def key_for(package_manager)
55
57
  package_manager == :yarn ? :npm : package_manager
56
58
  end
59
+
60
+ def package_manager_for(dependency)
61
+ dependency.package_manager
62
+ end
57
63
  end
58
64
  end
59
65
  end
@@ -9,8 +9,8 @@ module Spandx
9
9
  end
10
10
  end
11
11
 
12
- def matches?(_filename)
13
- raise ::Spandx::Error, :matches?
12
+ def match?(_path)
13
+ raise ::Spandx::Error, :match?
14
14
  end
15
15
 
16
16
  def parse(_dependency)
@@ -20,10 +20,15 @@ module Spandx
20
20
  class << self
21
21
  include Registerable
22
22
 
23
+ def parse(path)
24
+ self.for(path).parse(path)
25
+ end
26
+
23
27
  def for(path)
24
- return UNKNOWN if !File.exist?(path) || File.size(path).zero?
28
+ path = Pathname.new(path)
29
+ return UNKNOWN if !path.exist? || path.zero?
25
30
 
26
- find { |x| x.matches?(File.basename(path)) } || UNKNOWN
31
+ find { |x| x.match?(path) } || UNKNOWN
27
32
  end
28
33
  end
29
34
  end
@@ -6,7 +6,7 @@ module Spandx
6
6
  attr_reader :root
7
7
 
8
8
  def initialize(root, recursive: true)
9
- @root = root
9
+ @root = Pathname.new(root)
10
10
  @recursive = recursive
11
11
  end
12
12
 
@@ -14,27 +14,18 @@ module Spandx
14
14
  each_file_in(root, &block)
15
15
  end
16
16
 
17
- def to_enum
18
- Enumerator.new do |yielder|
19
- each do |item|
20
- yielder.yield item
21
- end
22
- end
23
- end
24
-
25
17
  private
26
18
 
27
19
  def recursive?
28
20
  @recursive
29
21
  end
30
22
 
31
- def each_file_in(dir, &block)
32
- files = File.directory?(dir) ? Dir.glob(File.join(dir, '*')) : [dir]
23
+ def each_file_in(path, &block)
24
+ files = path.directory? ? path.children : [path]
33
25
  files.each do |file|
34
- if File.directory?(file)
26
+ if file.directory?
35
27
  each_file_in(file, &block) if recursive?
36
28
  else
37
- Spandx.logger.debug(file)
38
29
  block.call(file)
39
30
  end
40
31
  end
@@ -3,7 +3,7 @@
3
3
  module Spandx
4
4
  module Core
5
5
  class Report
6
- include Enumerable
6
+ attr_reader :dependencies
7
7
 
8
8
  FORMATS = {
9
9
  csv: :to_csv,
@@ -20,27 +20,21 @@ module Spandx
20
20
  @dependencies << dependency
21
21
  end
22
22
 
23
- def each
24
- @dependencies.each do |dependency|
25
- yield dependency
26
- end
27
- end
28
-
29
23
  def to(format, formats: FORMATS)
30
24
  public_send(formats.fetch(format&.to_sym, :to_json))
31
25
  end
32
26
 
33
27
  def to_table
34
- Table.new do |table|
35
- map do |dependency|
36
- table << dependency
28
+ Terminal::Table.new(headings: ['Name', 'Version', 'Licenses', 'Location']) do |t|
29
+ dependencies.each do |d|
30
+ t.add_row d.to_a
37
31
  end
38
32
  end
39
33
  end
40
34
 
41
35
  def to_h
42
36
  { version: '1.0', dependencies: [] }.tap do |report|
43
- each do |dependency|
37
+ dependencies.each do |dependency|
44
38
  report[:dependencies].push(dependency.to_h)
45
39
  end
46
40
  end
@@ -51,7 +45,7 @@ module Spandx
51
45
  end
52
46
 
53
47
  def to_csv
54
- map do |dependency|
48
+ dependencies.map do |dependency|
55
49
  CSV.generate_line(dependency.to_a)
56
50
  end
57
51
  end
@@ -4,22 +4,22 @@ module Spandx
4
4
  module Dotnet
5
5
  module Parsers
6
6
  class Csproj < ::Spandx::Core::Parser
7
- def matches?(filename)
8
- ['.csproj', '.props'].include?(File.extname(filename))
7
+ def match?(path)
8
+ ['.csproj', '.props'].include?(path.extname)
9
9
  end
10
10
 
11
- def parse(lockfile)
11
+ def parse(path)
12
12
  ProjectFile
13
- .new(lockfile)
13
+ .new(path)
14
14
  .package_references
15
- .map { |x| map_from(x) }
15
+ .map { |x| map_from(path, x) }
16
16
  end
17
17
 
18
18
  private
19
19
 
20
- def map_from(package_reference)
20
+ def map_from(path, package_reference)
21
21
  ::Spandx::Core::Dependency.new(
22
- package_manager: :nuget,
22
+ path: path,
23
23
  name: package_reference.name,
24
24
  version: package_reference.version,
25
25
  meta: package_reference
@@ -4,22 +4,22 @@ module Spandx
4
4
  module Dotnet
5
5
  module Parsers
6
6
  class PackagesConfig < ::Spandx::Core::Parser
7
- def matches?(filename)
8
- filename.match?(/packages\.config/)
7
+ def match?(path)
8
+ path.basename.fnmatch?('packages.config')
9
9
  end
10
10
 
11
- def parse(lockfile)
12
- Nokogiri::XML(IO.read(lockfile))
11
+ def parse(path)
12
+ Nokogiri::XML(path.read)
13
13
  .search('//package')
14
- .map { |node| map_from(node) }
14
+ .map { |node| map_from(path, node) }
15
15
  end
16
16
 
17
17
  private
18
18
 
19
- def map_from(node)
19
+ def map_from(path, node)
20
20
  name = attribute_for('id', node)
21
21
  version = attribute_for('version', node)
22
- ::Spandx::Core::Dependency.new(package_manager: :nuget, name: name, version: version)
22
+ ::Spandx::Core::Dependency.new(name: name, version: version, path: path)
23
23
  end
24
24
 
25
25
  def attribute_for(key, node)
@@ -4,29 +4,26 @@ module Spandx
4
4
  module Dotnet
5
5
  module Parsers
6
6
  class Sln < ::Spandx::Core::Parser
7
- def matches?(filename)
8
- filename.match?(/.*\.sln/)
7
+ def match?(path)
8
+ path.extname == '.sln'
9
9
  end
10
10
 
11
- def parse(file_path)
12
- project_paths_from(file_path).map do |path|
13
- ::Spandx::Core::Parser
14
- .for(path)
15
- .parse(path)
11
+ def parse(path)
12
+ project_paths_from(path).map do |project_path|
13
+ ::Spandx::Core::Parser.parse(project_path)
16
14
  end.flatten
17
15
  end
18
16
 
19
17
  private
20
18
 
21
- def project_paths_from(file_path)
22
- IO.readlines(file_path).map do |line|
19
+ def project_paths_from(path)
20
+ path.each_line.map do |line|
23
21
  next unless project_line?(line)
24
22
 
25
- path = project_path_from(line)
26
- next unless path
23
+ project_path = project_path_from(line)
24
+ next unless project_path
27
25
 
28
- path = File.join(File.dirname(file_path), path)
29
- Pathname.new(path).cleanpath.to_path
26
+ path.dirname.join(project_path).cleanpath.to_path
30
27
  end.compact
31
28
  end
32
29
 
@@ -6,9 +6,9 @@ module Spandx
6
6
  attr_reader :catalogue, :document, :nuget
7
7
 
8
8
  def initialize(path)
9
- @path = path
10
- @dir = File.dirname(path)
11
- @document = Nokogiri::XML(IO.read(path)).tap(&:remove_namespaces!)
9
+ @path = Pathname(path)
10
+ @dir = @path.dirname
11
+ @document = Nokogiri::XML(@path.read).tap(&:remove_namespaces!)
12
12
  end
13
13
 
14
14
  def package_references
@@ -4,26 +4,26 @@ module Spandx
4
4
  module Java
5
5
  module Parsers
6
6
  class Maven < ::Spandx::Core::Parser
7
- def matches?(filename)
8
- File.basename(filename) == 'pom.xml'
7
+ def match?(path)
8
+ path.basename.fnmatch?('pom.xml')
9
9
  end
10
10
 
11
- def parse(filename)
12
- document = Nokogiri.XML(IO.read(filename)).tap(&:remove_namespaces!)
11
+ def parse(path)
12
+ document = Nokogiri.XML(path.read).tap(&:remove_namespaces!)
13
13
  document.search('//project/dependencies/dependency').map do |node|
14
- map_from(node)
14
+ map_from(path, node)
15
15
  end
16
16
  end
17
17
 
18
18
  private
19
19
 
20
- def map_from(node)
20
+ def map_from(path, node)
21
21
  artifact_id = node.at_xpath('./artifactId').text
22
22
  group_id = node.at_xpath('./groupId').text
23
23
  version = node.at_xpath('./version').text
24
24
 
25
25
  ::Spandx::Core::Dependency.new(
26
- package_manager: :maven,
26
+ path: path,
27
27
  name: "#{group_id}:#{artifact_id}",
28
28
  version: version
29
29
  )
@@ -4,14 +4,14 @@ module Spandx
4
4
  module Js
5
5
  module Parsers
6
6
  class Npm < ::Spandx::Core::Parser
7
- def matches?(filename)
7
+ def match?(filename)
8
8
  File.basename(filename) == 'package-lock.json'
9
9
  end
10
10
 
11
- def parse(file_path)
11
+ def parse(path)
12
12
  items = Set.new
13
- each_metadata(file_path) do |metadata|
14
- items.add(map_from(metadata))
13
+ each_metadata(path) do |metadata|
14
+ items.add(map_from(path, metadata))
15
15
  end
16
16
  items
17
17
  end
@@ -25,9 +25,9 @@ module Spandx
25
25
  end
26
26
  end
27
27
 
28
- def map_from(metadata)
28
+ def map_from(path, metadata)
29
29
  Spandx::Core::Dependency.new(
30
- package_manager: :npm,
30
+ path: path,
31
31
  name: metadata['name'],
32
32
  version: metadata['version'],
33
33
  meta: metadata
@@ -4,21 +4,21 @@ module Spandx
4
4
  module Js
5
5
  module Parsers
6
6
  class Yarn < ::Spandx::Core::Parser
7
- def matches?(filename)
8
- File.basename(filename) == 'yarn.lock'
7
+ def match?(filename)
8
+ filename.basename.fnmatch?('yarn.lock')
9
9
  end
10
10
 
11
- def parse(file_path)
12
- YarnLock.new(file_path).each_with_object(Set.new) do |metadata, memo|
13
- memo << map_from(metadata)
11
+ def parse(path)
12
+ YarnLock.new(path).each_with_object(Set.new) do |metadata, memo|
13
+ memo << map_from(path, metadata)
14
14
  end
15
15
  end
16
16
 
17
17
  private
18
18
 
19
- def map_from(metadata)
19
+ def map_from(path, metadata)
20
20
  ::Spandx::Core::Dependency.new(
21
- package_manager: :yarn,
21
+ path: path,
22
22
  name: metadata['name'],
23
23
  version: metadata['version'],
24
24
  meta: metadata
@@ -4,24 +4,24 @@ module Spandx
4
4
  module Php
5
5
  module Parsers
6
6
  class Composer < ::Spandx::Core::Parser
7
- def matches?(filename)
8
- File.basename(filename) == 'composer.lock'
7
+ def match?(path)
8
+ path.basename.fnmatch? 'composer.lock'
9
9
  end
10
10
 
11
- def parse(file_path)
11
+ def parse(path)
12
12
  items = Set.new
13
- composer_lock = JSON.parse(IO.read(file_path))
13
+ composer_lock = JSON.parse(path.read)
14
14
  composer_lock['packages'].concat(composer_lock['packages-dev']).each do |dependency|
15
- items.add(map_from(dependency))
15
+ items.add(map_from(path, dependency))
16
16
  end
17
17
  items
18
18
  end
19
19
 
20
20
  private
21
21
 
22
- def map_from(dependency)
22
+ def map_from(path, dependency)
23
23
  Spandx::Core::Dependency.new(
24
- package_manager: :composer,
24
+ path: path,
25
25
  name: dependency['name'],
26
26
  version: dependency['version'],
27
27
  meta: dependency
@@ -4,8 +4,8 @@ module Spandx
4
4
  module Python
5
5
  module Parsers
6
6
  class PipfileLock < ::Spandx::Core::Parser
7
- def matches?(filename)
8
- filename.match?(/Pipfile.*\.lock/)
7
+ def match?(path)
8
+ path.basename.fnmatch?('Pipfile*.lock')
9
9
  end
10
10
 
11
11
  def parse(lockfile)
@@ -19,10 +19,10 @@ module Spandx
19
19
  private
20
20
 
21
21
  def dependencies_from(lockfile)
22
- json = JSON.parse(IO.read(lockfile))
22
+ json = JSON.parse(lockfile.read)
23
23
  each_dependency(json) do |name, version|
24
24
  yield ::Spandx::Core::Dependency.new(
25
- package_manager: :pypi,
25
+ path: lockfile,
26
26
  name: name,
27
27
  version: version,
28
28
  meta: json
@@ -6,31 +6,32 @@ module Spandx
6
6
  class GemfileLock < ::Spandx::Core::Parser
7
7
  STRIP_BUNDLED_WITH = /^BUNDLED WITH$(\r?\n) (?<major>\d+)\.\d+\.\d+/m.freeze
8
8
 
9
- def matches?(filename)
10
- filename.match?(/Gemfile.*\.lock/) ||
11
- filename.match?(/gems.*\.lock/)
9
+ def match?(pathname)
10
+ basename = pathname.basename
11
+ basename.fnmatch?('Gemfile*.lock') ||
12
+ basename.fnmatch?('gems*.lock')
12
13
  end
13
14
 
14
15
  def parse(lockfile)
15
16
  dependencies_from(lockfile).map do |specification|
16
- map_from(specification)
17
+ map_from(lockfile, specification)
17
18
  end
18
19
  end
19
20
 
20
21
  private
21
22
 
22
23
  def dependencies_from(filepath)
23
- content = IO.read(filepath)
24
- Dir.chdir(File.dirname(filepath)) do
24
+ content = filepath.read.sub(STRIP_BUNDLED_WITH, '')
25
+ Dir.chdir(filepath.dirname) do
25
26
  ::Bundler::LockfileParser
26
- .new(content.sub(STRIP_BUNDLED_WITH, ''))
27
+ .new(content)
27
28
  .specs
28
29
  end
29
30
  end
30
31
 
31
- def map_from(specification)
32
+ def map_from(lockfile, specification)
32
33
  ::Spandx::Core::Dependency.new(
33
- package_manager: :rubygems,
34
+ path: lockfile,
34
35
  name: specification.name,
35
36
  version: specification.version.to_s,
36
37
  meta: {
@@ -33,7 +33,7 @@ module Spandx
33
33
  end
34
34
 
35
35
  def from_file(path)
36
- from_json(IO.read(path))
36
+ from_json(Pathname.new(path).read)
37
37
  end
38
38
 
39
39
  def from_git
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spandx
4
- VERSION = '0.13.3'
4
+ VERSION = '0.13.4'
5
5
  end
@@ -38,6 +38,7 @@ Gem::Specification.new do |spec|
38
38
  spec.add_dependency 'net-hippie', '~> 0.3'
39
39
  spec.add_dependency 'nokogiri', '~> 1.10'
40
40
  spec.add_dependency 'parslet', '~> 2.0'
41
+ spec.add_dependency 'terminal-table', '~> 1.8'
41
42
  spec.add_dependency 'thor'
42
43
  spec.add_dependency 'tty-screen', '~> 0.7'
43
44
  spec.add_dependency 'zeitwerk', '~> 2.3'
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.3
4
+ version: 0.13.4
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-05-21 00:00:00.000000000 Z
12
+ date: 2020-05-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable
@@ -101,6 +101,20 @@ dependencies:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: '2.0'
104
+ - !ruby/object:Gem::Dependency
105
+ name: terminal-table
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.8'
111
+ type: :runtime
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.8'
104
118
  - !ruby/object:Gem::Dependency
105
119
  name: thor
106
120
  requirement: !ruby/object:Gem::Requirement
@@ -372,7 +386,6 @@ files:
372
386
  - lib/spandx/core/report.rb
373
387
  - lib/spandx/core/score.rb
374
388
  - lib/spandx/core/spinner.rb
375
- - lib/spandx/core/table.rb
376
389
  - lib/spandx/dotnet/index.rb
377
390
  - lib/spandx/dotnet/nuget_gateway.rb
378
391
  - lib/spandx/dotnet/package_reference.rb
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spandx
4
- module Core
5
- class Table
6
- def initialize
7
- @rows = []
8
- @max_justification = 0
9
- yield self
10
- end
11
-
12
- def <<(item)
13
- row = item.to_a
14
- new_max = row[0].size
15
- @max_justification = new_max + 1 if new_max > @max_justification
16
- @rows << row
17
- end
18
-
19
- def to_s
20
- @rows.map do |row|
21
- row.each.with_index.map do |cell, index|
22
- justification = index.zero? ? @max_justification : 15
23
- Array(cell).join(', ').ljust(justification, ' ')
24
- end.join
25
- end
26
- end
27
- end
28
- end
29
- end