spandx 0.1.1 → 0.1.2
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/.github/workflows/ci.yml +13 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +8 -46
- data/CHANGELOG.md +25 -0
- data/Gemfile.lock +24 -23
- data/README.md +14 -3
- data/exe/spandx +15 -1
- data/lib/spandx/catalogue.rb +25 -3
- data/lib/spandx/cli.rb +30 -0
- data/lib/spandx/command.rb +119 -0
- data/lib/spandx/commands/.gitkeep +0 -0
- data/lib/spandx/commands/scan.rb +23 -0
- data/lib/spandx/gateways/http.rb +32 -0
- data/lib/spandx/gateways/pypi.rb +59 -0
- data/lib/spandx/gateways/spdx.rb +20 -0
- data/lib/spandx/parsers/base.rb +31 -0
- data/lib/spandx/parsers/gemfile_lock.rb +34 -0
- data/lib/spandx/parsers/pipfile_lock.rb +51 -0
- data/lib/spandx/parsers.rb +19 -0
- data/lib/spandx/report.rb +25 -0
- data/lib/spandx/templates/.gitkeep +0 -0
- data/lib/spandx/templates/scan/.gitkeep +1 -0
- data/lib/spandx/version.rb +1 -1
- data/lib/spandx.rb +18 -1
- data/spandx.gemspec +6 -5
- metadata +41 -13
- data/.travis.yml +0 -7
- data/lib/spandx/catalogue_gateway.rb +0 -43
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a8c7d63af4cdd331e0f9ab51eb895797567278365cc1029dbbe07744158cb5f4
|
|
4
|
+
data.tar.gz: d8cb97dfc05729a577a95c358d2a8397b43bd4628925bf3bcb55b282d6042ee8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 252c70cd5862c795eede663242f22b4be188c35a950fa55f41f1b324f9e6ee73b8a1a4bebf3d875fbd68b640359db6e20d5c0bbdd42e90dc640470a5fa91d7ad
|
|
7
|
+
data.tar.gz: 14a5bc5fe4ad89de5288df9ea6425d234d25daced1c6429e17563809ec666109c9b8ba668881cf32b5528c480b44a0fa32b3f57c33bb2608f123c2fd3c62d498
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -3,46 +3,24 @@ require:
|
|
|
3
3
|
|
|
4
4
|
AllCops:
|
|
5
5
|
Exclude:
|
|
6
|
-
- 'coverage/**/*'
|
|
7
6
|
- 'pkg/**/*'
|
|
8
7
|
- 'spec/fixtures/**/*'
|
|
9
|
-
- 'tmp/**/*'
|
|
10
|
-
- 'vendor/**/*'
|
|
11
8
|
TargetRubyVersion: 2.6
|
|
12
9
|
|
|
13
|
-
Layout/
|
|
10
|
+
Layout/ArgumentAlignment:
|
|
14
11
|
EnforcedStyle: with_fixed_indentation
|
|
15
12
|
|
|
16
|
-
Layout/
|
|
13
|
+
Layout/ParameterAlignment:
|
|
17
14
|
Enabled: true
|
|
18
15
|
EnforcedStyle: with_fixed_indentation
|
|
19
16
|
IndentationWidth: 2
|
|
20
17
|
|
|
21
|
-
Layout/ClassStructure:
|
|
22
|
-
Enabled: true
|
|
23
|
-
Categories:
|
|
24
|
-
module_inclusion:
|
|
25
|
-
- include
|
|
26
|
-
- prepend
|
|
27
|
-
- extend
|
|
28
|
-
ExpectedOrder:
|
|
29
|
-
- module_inclusion
|
|
30
|
-
- constants
|
|
31
|
-
- public_class_methods
|
|
32
|
-
- initializer
|
|
33
|
-
- instance_methods
|
|
34
|
-
- protected_methods
|
|
35
|
-
- private_methods
|
|
36
|
-
|
|
37
18
|
Layout/EndOfLine:
|
|
38
19
|
EnforcedStyle: lf
|
|
39
20
|
|
|
40
|
-
Layout/
|
|
21
|
+
Layout/FirstArrayElementIndentation:
|
|
41
22
|
EnforcedStyle: consistent
|
|
42
23
|
|
|
43
|
-
Layout/IndentHeredoc:
|
|
44
|
-
EnforcedStyle: active_support
|
|
45
|
-
|
|
46
24
|
Layout/MultilineMethodCallIndentation:
|
|
47
25
|
Enabled: true
|
|
48
26
|
EnforcedStyle: indented
|
|
@@ -51,14 +29,8 @@ Lint/AmbiguousBlockAssociation:
|
|
|
51
29
|
Exclude:
|
|
52
30
|
- 'spec/**/*.rb'
|
|
53
31
|
|
|
54
|
-
Lint/InterpolationCheck:
|
|
55
|
-
Exclude:
|
|
56
|
-
- 'spec/**/*.rb'
|
|
57
|
-
|
|
58
32
|
Metrics/BlockLength:
|
|
59
33
|
Exclude:
|
|
60
|
-
- '**/**/*.builder'
|
|
61
|
-
- '**/*.rake'
|
|
62
34
|
- '*.gemspec'
|
|
63
35
|
- 'Rakefile'
|
|
64
36
|
- 'spec/**/*.rb'
|
|
@@ -69,24 +41,16 @@ Metrics/ModuleLength:
|
|
|
69
41
|
|
|
70
42
|
Metrics/LineLength:
|
|
71
43
|
Exclude:
|
|
72
|
-
- 'lib/saml/kit/builders/templates/*.builder'
|
|
73
44
|
- 'spec/**/*.rb'
|
|
74
45
|
IgnoredPatterns:
|
|
75
46
|
- '^#*'
|
|
76
47
|
|
|
77
|
-
Naming/FileName:
|
|
78
|
-
Exclude:
|
|
79
|
-
- 'lib/saml-kit.rb'
|
|
80
|
-
|
|
81
48
|
Naming/RescuedExceptionsVariableName:
|
|
82
49
|
PreferredName: error
|
|
83
50
|
|
|
84
51
|
Style/Documentation:
|
|
85
52
|
Enabled: false
|
|
86
53
|
|
|
87
|
-
Style/EachWithObject:
|
|
88
|
-
Enabled: false
|
|
89
|
-
|
|
90
54
|
Style/StringLiterals:
|
|
91
55
|
EnforcedStyle: 'single_quotes'
|
|
92
56
|
|
|
@@ -99,14 +63,12 @@ Style/TrailingCommaInHashLiteral:
|
|
|
99
63
|
RSpec/ExampleLength:
|
|
100
64
|
Max: 80
|
|
101
65
|
|
|
102
|
-
RSpec/MultipleExpectations:
|
|
103
|
-
Enabled: false
|
|
104
|
-
|
|
105
66
|
RSpec/NamedSubject:
|
|
106
67
|
Enabled: false
|
|
107
68
|
|
|
108
|
-
RSpec/
|
|
109
|
-
Max: 7
|
|
110
|
-
|
|
111
|
-
RSpec/SubjectStub:
|
|
69
|
+
RSpec/FilePath:
|
|
112
70
|
Enabled: false
|
|
71
|
+
|
|
72
|
+
RSpec/DescribeClass:
|
|
73
|
+
Exclude:
|
|
74
|
+
- 'spec/integration/**/*'
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Version 0.1.2
|
|
2
|
+
|
|
3
|
+
# Changelog
|
|
4
|
+
All notable changes to this project will be documented in this file.
|
|
5
|
+
|
|
6
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
7
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
- nil
|
|
11
|
+
|
|
12
|
+
## [0.1.2] - 2020-01-16
|
|
13
|
+
### Added
|
|
14
|
+
- Add CLI for `spandx scan <LOCKER>`
|
|
15
|
+
- Parse Gemfile.lock for dependencies.
|
|
16
|
+
- Parse Pipfile.lock for dependencies.
|
|
17
|
+
- Allow lookup for a specific license by id
|
|
18
|
+
|
|
19
|
+
## [0.1.1] - 2019-10-05
|
|
20
|
+
### Added
|
|
21
|
+
- Provide ruby API to the latest SPDX catalogue.
|
|
22
|
+
|
|
23
|
+
[Unreleased]: https://github.com/mokhan/spandx/compare/v0.1.2...HEAD
|
|
24
|
+
[0.1.2]: https://github.com/mokhan/spandx/compare/v0.1.1...v0.1.2
|
|
25
|
+
[0.1.1]: https://github.com/mokhan/spandx/compare/v0.1.0...v0.1.1
|
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
spandx (0.1.
|
|
5
|
-
net-hippie (~> 0.
|
|
4
|
+
spandx (0.1.2)
|
|
5
|
+
net-hippie (~> 0.3)
|
|
6
|
+
thor (~> 0.1)
|
|
6
7
|
|
|
7
8
|
GEM
|
|
8
9
|
remote: https://rubygems.org/
|
|
@@ -17,35 +18,35 @@ GEM
|
|
|
17
18
|
safe_yaml (~> 1.0.0)
|
|
18
19
|
diff-lcs (1.3)
|
|
19
20
|
hashdiff (1.0.0)
|
|
20
|
-
jaro_winkler (1.5.
|
|
21
|
-
net-hippie (0.
|
|
22
|
-
parallel (1.
|
|
23
|
-
parser (2.
|
|
21
|
+
jaro_winkler (1.5.4)
|
|
22
|
+
net-hippie (0.3.1)
|
|
23
|
+
parallel (1.19.1)
|
|
24
|
+
parser (2.7.0.0)
|
|
24
25
|
ast (~> 2.4.0)
|
|
25
|
-
public_suffix (4.0.
|
|
26
|
+
public_suffix (4.0.2)
|
|
26
27
|
rainbow (3.0.0)
|
|
27
|
-
rake (
|
|
28
|
-
rspec (3.
|
|
29
|
-
rspec-core (~> 3.
|
|
30
|
-
rspec-expectations (~> 3.
|
|
31
|
-
rspec-mocks (~> 3.
|
|
32
|
-
rspec-core (3.
|
|
33
|
-
rspec-support (~> 3.
|
|
34
|
-
rspec-expectations (3.
|
|
28
|
+
rake (13.0.1)
|
|
29
|
+
rspec (3.9.0)
|
|
30
|
+
rspec-core (~> 3.9.0)
|
|
31
|
+
rspec-expectations (~> 3.9.0)
|
|
32
|
+
rspec-mocks (~> 3.9.0)
|
|
33
|
+
rspec-core (3.9.0)
|
|
34
|
+
rspec-support (~> 3.9.0)
|
|
35
|
+
rspec-expectations (3.9.0)
|
|
35
36
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
36
|
-
rspec-support (~> 3.
|
|
37
|
-
rspec-mocks (3.
|
|
37
|
+
rspec-support (~> 3.9.0)
|
|
38
|
+
rspec-mocks (3.9.0)
|
|
38
39
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
39
|
-
rspec-support (~> 3.
|
|
40
|
-
rspec-support (3.
|
|
41
|
-
rubocop (0.
|
|
40
|
+
rspec-support (~> 3.9.0)
|
|
41
|
+
rspec-support (3.9.0)
|
|
42
|
+
rubocop (0.78.0)
|
|
42
43
|
jaro_winkler (~> 1.5.1)
|
|
43
44
|
parallel (~> 1.10)
|
|
44
45
|
parser (>= 2.6)
|
|
45
46
|
rainbow (>= 2.2.2, < 4.0)
|
|
46
47
|
ruby-progressbar (~> 1.7)
|
|
47
48
|
unicode-display_width (>= 1.4.0, < 1.7)
|
|
48
|
-
rubocop-rspec (1.
|
|
49
|
+
rubocop-rspec (1.37.1)
|
|
49
50
|
rubocop (>= 0.68.1)
|
|
50
51
|
ruby-progressbar (1.10.1)
|
|
51
52
|
safe_yaml (1.0.5)
|
|
@@ -62,7 +63,7 @@ PLATFORMS
|
|
|
62
63
|
DEPENDENCIES
|
|
63
64
|
bundler (~> 2.0)
|
|
64
65
|
bundler-audit (~> 0.6)
|
|
65
|
-
rake (~>
|
|
66
|
+
rake (~> 13.0)
|
|
66
67
|
rspec (~> 3.0)
|
|
67
68
|
rubocop (~> 0.52)
|
|
68
69
|
rubocop-rspec (~> 1.22)
|
|
@@ -70,4 +71,4 @@ DEPENDENCIES
|
|
|
70
71
|
webmock (~> 3.7)
|
|
71
72
|
|
|
72
73
|
BUNDLED WITH
|
|
73
|
-
2.
|
|
74
|
+
2.1.2
|
data/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Spandx
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A ruby API for interacting with the https://spdx.org software license catalogue.
|
|
4
4
|
|
|
5
|
+

|
|
5
6
|
|
|
6
7
|
## Installation
|
|
7
8
|
|
|
@@ -21,7 +22,7 @@ Or install it yourself as:
|
|
|
21
22
|
|
|
22
23
|
## Usage
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
To fetch the latest version of the catalogue data from [SPDX](https://spdx.org/licenses/licenses.json).
|
|
25
26
|
|
|
26
27
|
```ruby
|
|
27
28
|
catalogue = Spandx::Catalogue.latest
|
|
@@ -30,6 +31,16 @@ catalogue.each do |license|
|
|
|
30
31
|
end
|
|
31
32
|
```
|
|
32
33
|
|
|
34
|
+
To load an offline copy of the data.
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
path = File.join(Dir.pwd, 'licenses.json')
|
|
38
|
+
catalogue = Spandx::Catalogue.from_file(path)
|
|
39
|
+
catalogue.each do |license|
|
|
40
|
+
puts license.inspect
|
|
41
|
+
end
|
|
42
|
+
```
|
|
43
|
+
|
|
33
44
|
## Development
|
|
34
45
|
|
|
35
46
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/cibuild` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -38,7 +49,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
|
38
49
|
|
|
39
50
|
## Contributing
|
|
40
51
|
|
|
41
|
-
Bug reports and pull requests are welcome on
|
|
52
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/mokhan/spandx.
|
|
42
53
|
|
|
43
54
|
## License
|
|
44
55
|
|
data/exe/spandx
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
lib_path = File.expand_path('../lib', __dir__)
|
|
5
|
+
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
|
|
6
|
+
require 'spandx/cli'
|
|
7
|
+
|
|
8
|
+
Signal.trap('INT') do
|
|
9
|
+
warn("\n#{caller.join("\n")}: interrupted")
|
|
10
|
+
exit(1)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
begin
|
|
14
|
+
Spandx::CLI.start
|
|
15
|
+
rescue Spandx::CLI::Error => error
|
|
16
|
+
puts "ERROR: #{error.message}"
|
|
17
|
+
exit 1
|
|
18
|
+
end
|
data/lib/spandx/catalogue.rb
CHANGED
|
@@ -8,6 +8,10 @@ module Spandx
|
|
|
8
8
|
@catalogue = catalogue
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
def [](id)
|
|
12
|
+
identity_map[id]
|
|
13
|
+
end
|
|
14
|
+
|
|
11
15
|
def version
|
|
12
16
|
catalogue[:licenseListVersion]
|
|
13
17
|
end
|
|
@@ -18,8 +22,18 @@ module Spandx
|
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
class << self
|
|
26
|
+
def latest(gateway: ::Spandx::Gateways::Spdx.new)
|
|
27
|
+
gateway.fetch
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def from_file(path)
|
|
31
|
+
new(JSON.parse(IO.read(path), symbolize_names: true))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def empty
|
|
35
|
+
@empty ||= new(licenses: [])
|
|
36
|
+
end
|
|
23
37
|
end
|
|
24
38
|
|
|
25
39
|
private
|
|
@@ -27,7 +41,7 @@ module Spandx
|
|
|
27
41
|
attr_reader :catalogue
|
|
28
42
|
|
|
29
43
|
def licenses
|
|
30
|
-
@licenses ||=
|
|
44
|
+
@licenses ||= identity_map.values
|
|
31
45
|
end
|
|
32
46
|
|
|
33
47
|
def map_from(license_hash)
|
|
@@ -37,5 +51,13 @@ module Spandx
|
|
|
37
51
|
def present?(item)
|
|
38
52
|
item && !item.empty?
|
|
39
53
|
end
|
|
54
|
+
|
|
55
|
+
def identity_map
|
|
56
|
+
@identity_map ||=
|
|
57
|
+
catalogue.fetch(:licenses, []).each_with_object({}) do |hash, memo|
|
|
58
|
+
license = map_from(hash)
|
|
59
|
+
memo[license.id] = license if present?(license.id)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
40
62
|
end
|
|
41
63
|
end
|
data/lib/spandx/cli.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'thor'
|
|
4
|
+
|
|
5
|
+
require 'spandx'
|
|
6
|
+
require 'spandx/command'
|
|
7
|
+
require 'spandx/commands/scan'
|
|
8
|
+
|
|
9
|
+
module Spandx
|
|
10
|
+
class CLI < Thor
|
|
11
|
+
Error = Class.new(StandardError)
|
|
12
|
+
|
|
13
|
+
desc 'version', 'spandx version'
|
|
14
|
+
def version
|
|
15
|
+
puts "v#{Spandx::VERSION}"
|
|
16
|
+
end
|
|
17
|
+
map %w[--version -v] => :version
|
|
18
|
+
|
|
19
|
+
desc 'scan LOCKFILE', 'Command description...'
|
|
20
|
+
method_option :help, aliases: '-h', type: :boolean,
|
|
21
|
+
desc: 'Display usage information'
|
|
22
|
+
def scan(lockfile = nil)
|
|
23
|
+
if options[:help]
|
|
24
|
+
invoke :help, ['scan']
|
|
25
|
+
else
|
|
26
|
+
Spandx::Commands::Scan.new(lockfile, options).execute
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
class Command
|
|
5
|
+
extend Forwardable
|
|
6
|
+
|
|
7
|
+
def_delegators :command, :run
|
|
8
|
+
|
|
9
|
+
# Execute this command
|
|
10
|
+
#
|
|
11
|
+
# @api public
|
|
12
|
+
def execute(*)
|
|
13
|
+
raise(
|
|
14
|
+
NotImplementedError,
|
|
15
|
+
"#{self.class}##{__method__} must be implemented"
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The external commands runner
|
|
20
|
+
#
|
|
21
|
+
# @see http://www.rubydoc.info/gems/tty-command
|
|
22
|
+
#
|
|
23
|
+
# @api public
|
|
24
|
+
def command(**options)
|
|
25
|
+
require 'tty-command'
|
|
26
|
+
TTY::Command.new(options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# The cursor movement
|
|
30
|
+
#
|
|
31
|
+
# @see http://www.rubydoc.info/gems/tty-cursor
|
|
32
|
+
#
|
|
33
|
+
# @api public
|
|
34
|
+
def cursor
|
|
35
|
+
require 'tty-cursor'
|
|
36
|
+
TTY::Cursor
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Open a file or text in the user's preferred editor
|
|
40
|
+
#
|
|
41
|
+
# @see http://www.rubydoc.info/gems/tty-editor
|
|
42
|
+
#
|
|
43
|
+
# @api public
|
|
44
|
+
def editor
|
|
45
|
+
require 'tty-editor'
|
|
46
|
+
TTY::Editor
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# File manipulation utility methods
|
|
50
|
+
#
|
|
51
|
+
# @see http://www.rubydoc.info/gems/tty-file
|
|
52
|
+
#
|
|
53
|
+
# @api public
|
|
54
|
+
def generator
|
|
55
|
+
require 'tty-file'
|
|
56
|
+
TTY::File
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Terminal output paging
|
|
60
|
+
#
|
|
61
|
+
# @see http://www.rubydoc.info/gems/tty-pager
|
|
62
|
+
#
|
|
63
|
+
# @api public
|
|
64
|
+
def pager(**options)
|
|
65
|
+
require 'tty-pager'
|
|
66
|
+
TTY::Pager.new(options)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Terminal platform and OS properties
|
|
70
|
+
#
|
|
71
|
+
# @see http://www.rubydoc.info/gems/tty-pager
|
|
72
|
+
#
|
|
73
|
+
# @api public
|
|
74
|
+
def platform
|
|
75
|
+
require 'tty-platform'
|
|
76
|
+
TTY::Platform.new
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# The interactive prompt
|
|
80
|
+
#
|
|
81
|
+
# @see http://www.rubydoc.info/gems/tty-prompt
|
|
82
|
+
#
|
|
83
|
+
# @api public
|
|
84
|
+
def prompt(**options)
|
|
85
|
+
require 'tty-prompt'
|
|
86
|
+
TTY::Prompt.new(options)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Get terminal screen properties
|
|
90
|
+
#
|
|
91
|
+
# @see http://www.rubydoc.info/gems/tty-screen
|
|
92
|
+
#
|
|
93
|
+
# @api public
|
|
94
|
+
def screen
|
|
95
|
+
require 'tty-screen'
|
|
96
|
+
TTY::Screen
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# The unix which utility
|
|
100
|
+
#
|
|
101
|
+
# @see http://www.rubydoc.info/gems/tty-which
|
|
102
|
+
#
|
|
103
|
+
# @api public
|
|
104
|
+
def which(*args)
|
|
105
|
+
require 'tty-which'
|
|
106
|
+
TTY::Which.which(*args)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Check if executable exists
|
|
110
|
+
#
|
|
111
|
+
# @see http://www.rubydoc.info/gems/tty-which
|
|
112
|
+
#
|
|
113
|
+
# @api public
|
|
114
|
+
def exec_exist?(*args)
|
|
115
|
+
require 'tty-which'
|
|
116
|
+
TTY::Which.exist?(*args)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
module Commands
|
|
5
|
+
class Scan < Spandx::Command
|
|
6
|
+
attr_reader :lockfile
|
|
7
|
+
|
|
8
|
+
def initialize(lockfile, options)
|
|
9
|
+
@lockfile = lockfile ? Pathname.new(File.expand_path(lockfile)) : nil
|
|
10
|
+
@options = options
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def execute(output: $stdout)
|
|
14
|
+
if lockfile.nil?
|
|
15
|
+
output.puts 'OK'
|
|
16
|
+
else
|
|
17
|
+
report = Parsers.for(lockfile).parse(lockfile)
|
|
18
|
+
output.puts report.to_json
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
module Gateways
|
|
5
|
+
class Http
|
|
6
|
+
attr_reader :driver
|
|
7
|
+
|
|
8
|
+
def initialize(driver: Http.default_driver)
|
|
9
|
+
@driver = driver
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get(uri, default: nil)
|
|
13
|
+
driver.with_retry do |client|
|
|
14
|
+
client.get(uri)
|
|
15
|
+
end
|
|
16
|
+
rescue *Net::Hippie::CONNECTION_ERRORS
|
|
17
|
+
default
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def ok?(response)
|
|
21
|
+
response.is_a?(Net::HTTPSuccess)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.default_driver
|
|
25
|
+
@default_driver ||= Net::Hippie::Client.new.tap do |client|
|
|
26
|
+
client.logger = ::Logger.new('http.log')
|
|
27
|
+
client.follow_redirects = 3
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
module Gateways
|
|
5
|
+
class PyPI
|
|
6
|
+
class Source
|
|
7
|
+
attr_reader :name, :uri, :verify_ssl
|
|
8
|
+
|
|
9
|
+
def initialize(source)
|
|
10
|
+
@name = source['name']
|
|
11
|
+
@uri = URI.parse(source['url'])
|
|
12
|
+
@verify_ssl = source['verify_ssl']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def host
|
|
16
|
+
@uri.host
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def uri_for(name, version)
|
|
20
|
+
URI.parse("https://#{host}/pypi/#{name}/#{version}/json")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def lookup(name, version, http: Spandx.http)
|
|
24
|
+
response = http.get(uri_for(name, version))
|
|
25
|
+
response if http.ok?(response)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
def sources_from(json)
|
|
30
|
+
meta = json['_meta']
|
|
31
|
+
meta['sources'].map do |hash|
|
|
32
|
+
Gateways::PyPI::Source.new(hash)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def default
|
|
37
|
+
new(
|
|
38
|
+
'name' => 'pypi',
|
|
39
|
+
'url' => 'https://pypi.org/simple',
|
|
40
|
+
'verify_ssl' => true
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def initialize(sources: [Source.default])
|
|
47
|
+
@sources = sources
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def definition_for(name, version)
|
|
51
|
+
@sources.each do |source|
|
|
52
|
+
response = source.lookup(name, version)
|
|
53
|
+
return JSON.parse(response.body).fetch('info', {}) if response
|
|
54
|
+
end
|
|
55
|
+
{}
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
module Gateways
|
|
5
|
+
class Spdx
|
|
6
|
+
URL = 'https://spdx.org/licenses/licenses.json'
|
|
7
|
+
|
|
8
|
+
def fetch(url: URL, http: Spandx.http, default: Catalogue.empty)
|
|
9
|
+
response = http.get(url, default: default)
|
|
10
|
+
http.ok?(response) ? parse(response.body) : default
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def parse(json)
|
|
16
|
+
Catalogue.new(JSON.parse(json, symbolize_names: true))
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
module Parsers
|
|
5
|
+
class Base
|
|
6
|
+
attr_reader :catalogue
|
|
7
|
+
|
|
8
|
+
def initialize(catalogue:)
|
|
9
|
+
@catalogue = catalogue
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
include Enumerable
|
|
14
|
+
|
|
15
|
+
def each(&block)
|
|
16
|
+
registry.each do |x|
|
|
17
|
+
block.call(x)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def inherited(subclass)
|
|
22
|
+
registry.push(subclass)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def registry
|
|
26
|
+
@registry ||= []
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
module Parsers
|
|
5
|
+
class GemfileLock < Base
|
|
6
|
+
def self.matches?(filename)
|
|
7
|
+
filename.match?(/Gemfile.*\.lock/)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def parse(lockfile)
|
|
11
|
+
report = Report.new
|
|
12
|
+
dependencies_from(lockfile) do |dependency|
|
|
13
|
+
spec = dependency.to_spec
|
|
14
|
+
report.add(
|
|
15
|
+
name: dependency.name,
|
|
16
|
+
version: spec.version.to_s,
|
|
17
|
+
licenses: [catalogue[spec.license]]
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
report
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def dependencies_from(lockfile)
|
|
26
|
+
::Bundler::LockfileParser
|
|
27
|
+
.new(IO.read(lockfile))
|
|
28
|
+
.dependencies.each do |_key, dependency|
|
|
29
|
+
yield dependency
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
module Parsers
|
|
5
|
+
class PipfileLock < Base
|
|
6
|
+
def self.matches?(filename)
|
|
7
|
+
filename.match?(/Pipfile.*\.lock/)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def parse(lockfile)
|
|
11
|
+
report = Report.new
|
|
12
|
+
dependencies_from(lockfile) do |x|
|
|
13
|
+
report.add(
|
|
14
|
+
name: x[:name],
|
|
15
|
+
version: x[:version],
|
|
16
|
+
licenses: x[:licenses]
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
report
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def dependencies_from(lockfile)
|
|
25
|
+
json = JSON.parse(IO.read(lockfile))
|
|
26
|
+
each_dependency(pypi_for(json), json) do |name, version, definition|
|
|
27
|
+
yield({ name: name, version: version, licenses: [catalogue[definition['license']]] })
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def each_dependency(pypi, json, groups: %w[default develop])
|
|
32
|
+
groups.each do |group|
|
|
33
|
+
json[group].each do |name, value|
|
|
34
|
+
version = canonicalize(value['version'])
|
|
35
|
+
yield name, version, pypi.definition_for(name, version)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def canonicalize(version)
|
|
41
|
+
version.gsub(/==/, '')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def pypi_for(json)
|
|
45
|
+
Gateways::PyPI.new(
|
|
46
|
+
sources: Gateways::PyPI::Source.sources_from(json)
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spandx/parsers/base'
|
|
4
|
+
require 'spandx/parsers/gemfile_lock'
|
|
5
|
+
require 'spandx/parsers/pipfile_lock'
|
|
6
|
+
|
|
7
|
+
module Spandx
|
|
8
|
+
module Parsers
|
|
9
|
+
class << self
|
|
10
|
+
def for(path, catalogue: Spandx::Catalogue.latest)
|
|
11
|
+
result = ::Spandx::Parsers::Base.find do |x|
|
|
12
|
+
x.matches?(File.basename(path))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
result&.new(catalogue: catalogue)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
class Report
|
|
5
|
+
def initialize(report: { version: '1.0', packages: [] })
|
|
6
|
+
@report = report
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def add(name:, version:, licenses: [])
|
|
10
|
+
@report[:packages].push(
|
|
11
|
+
name: name,
|
|
12
|
+
version: version,
|
|
13
|
+
licenses: licenses.map(&:id)
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_h
|
|
18
|
+
@report
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_json(*_args)
|
|
22
|
+
JSON.pretty_generate(to_h)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#
|
data/lib/spandx/version.rb
CHANGED
data/lib/spandx.rb
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
require 'json'
|
|
3
5
|
require 'net/hippie'
|
|
6
|
+
|
|
4
7
|
require 'spandx/catalogue'
|
|
5
|
-
require 'spandx/
|
|
8
|
+
require 'spandx/gateways/http'
|
|
9
|
+
require 'spandx/gateways/pypi'
|
|
10
|
+
require 'spandx/gateways/spdx'
|
|
6
11
|
require 'spandx/license'
|
|
12
|
+
require 'spandx/parsers'
|
|
13
|
+
require 'spandx/report'
|
|
7
14
|
require 'spandx/version'
|
|
8
15
|
|
|
9
16
|
module Spandx
|
|
10
17
|
class Error < StandardError; end
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
def root
|
|
21
|
+
Pathname.new(File.dirname(__FILE__)).join('../..')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def http
|
|
25
|
+
@http ||= Spandx::Gateways::Http.new
|
|
26
|
+
end
|
|
27
|
+
end
|
|
11
28
|
end
|
data/spandx.gemspec
CHANGED
|
@@ -12,12 +12,12 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
|
|
13
13
|
spec.summary = 'A ruby interface to the SPDX catalogue.'
|
|
14
14
|
spec.description = 'A ruby interface to the SPDX catalogue.'
|
|
15
|
-
spec.homepage = 'https://
|
|
15
|
+
spec.homepage = 'https://github.com/mokhan/spandx'
|
|
16
16
|
spec.license = 'MIT'
|
|
17
17
|
|
|
18
18
|
spec.metadata['homepage_uri'] = spec.homepage
|
|
19
|
-
spec.metadata['source_code_uri'] = 'https://
|
|
20
|
-
spec.metadata['changelog_uri'] = 'https://
|
|
19
|
+
spec.metadata['source_code_uri'] = 'https://github.com/mokhan/spandx'
|
|
20
|
+
spec.metadata['changelog_uri'] = 'https://github.com/mokhan/spandx/blob/master/CHANGELOG.md'
|
|
21
21
|
|
|
22
22
|
# Specify which files should be added to the gem when it is released.
|
|
23
23
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
@@ -28,10 +28,11 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
29
29
|
spec.require_paths = ['lib']
|
|
30
30
|
|
|
31
|
-
spec.add_dependency 'net-hippie', '~> 0.
|
|
31
|
+
spec.add_dependency 'net-hippie', '~> 0.3'
|
|
32
|
+
spec.add_dependency 'thor', '~> 0.1'
|
|
32
33
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
|
33
34
|
spec.add_development_dependency 'bundler-audit', '~> 0.6'
|
|
34
|
-
spec.add_development_dependency 'rake', '~>
|
|
35
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
35
36
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
36
37
|
spec.add_development_dependency 'rubocop', '~> 0.52'
|
|
37
38
|
spec.add_development_dependency 'rubocop-rspec', '~> 1.22'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spandx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- mo khan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-01-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: net-hippie
|
|
@@ -16,14 +16,28 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0.
|
|
19
|
+
version: '0.3'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0.
|
|
26
|
+
version: '0.3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: thor
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.1'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.1'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: bundler
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -58,14 +72,14 @@ dependencies:
|
|
|
58
72
|
requirements:
|
|
59
73
|
- - "~>"
|
|
60
74
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
75
|
+
version: '13.0'
|
|
62
76
|
type: :development
|
|
63
77
|
prerelease: false
|
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
79
|
requirements:
|
|
66
80
|
- - "~>"
|
|
67
81
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
82
|
+
version: '13.0'
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
84
|
name: rspec
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -130,11 +144,12 @@ executables:
|
|
|
130
144
|
extensions: []
|
|
131
145
|
extra_rdoc_files: []
|
|
132
146
|
files:
|
|
147
|
+
- ".github/workflows/ci.yml"
|
|
133
148
|
- ".gitignore"
|
|
134
149
|
- ".gitlab-ci.yml"
|
|
135
150
|
- ".rspec"
|
|
136
151
|
- ".rubocop.yml"
|
|
137
|
-
-
|
|
152
|
+
- CHANGELOG.md
|
|
138
153
|
- Gemfile
|
|
139
154
|
- Gemfile.lock
|
|
140
155
|
- LICENSE.txt
|
|
@@ -149,17 +164,30 @@ files:
|
|
|
149
164
|
- exe/spandx
|
|
150
165
|
- lib/spandx.rb
|
|
151
166
|
- lib/spandx/catalogue.rb
|
|
152
|
-
- lib/spandx/
|
|
167
|
+
- lib/spandx/cli.rb
|
|
168
|
+
- lib/spandx/command.rb
|
|
169
|
+
- lib/spandx/commands/.gitkeep
|
|
170
|
+
- lib/spandx/commands/scan.rb
|
|
171
|
+
- lib/spandx/gateways/http.rb
|
|
172
|
+
- lib/spandx/gateways/pypi.rb
|
|
173
|
+
- lib/spandx/gateways/spdx.rb
|
|
153
174
|
- lib/spandx/license.rb
|
|
175
|
+
- lib/spandx/parsers.rb
|
|
176
|
+
- lib/spandx/parsers/base.rb
|
|
177
|
+
- lib/spandx/parsers/gemfile_lock.rb
|
|
178
|
+
- lib/spandx/parsers/pipfile_lock.rb
|
|
179
|
+
- lib/spandx/report.rb
|
|
180
|
+
- lib/spandx/templates/.gitkeep
|
|
181
|
+
- lib/spandx/templates/scan/.gitkeep
|
|
154
182
|
- lib/spandx/version.rb
|
|
155
183
|
- spandx.gemspec
|
|
156
|
-
homepage: https://
|
|
184
|
+
homepage: https://github.com/mokhan/spandx
|
|
157
185
|
licenses:
|
|
158
186
|
- MIT
|
|
159
187
|
metadata:
|
|
160
|
-
homepage_uri: https://
|
|
161
|
-
source_code_uri: https://
|
|
162
|
-
changelog_uri: https://
|
|
188
|
+
homepage_uri: https://github.com/mokhan/spandx
|
|
189
|
+
source_code_uri: https://github.com/mokhan/spandx
|
|
190
|
+
changelog_uri: https://github.com/mokhan/spandx/blob/master/CHANGELOG.md
|
|
163
191
|
post_install_message:
|
|
164
192
|
rdoc_options: []
|
|
165
193
|
require_paths:
|
|
@@ -175,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
175
203
|
- !ruby/object:Gem::Version
|
|
176
204
|
version: '0'
|
|
177
205
|
requirements: []
|
|
178
|
-
rubygems_version: 3.
|
|
206
|
+
rubygems_version: 3.1.2
|
|
179
207
|
signing_key:
|
|
180
208
|
specification_version: 4
|
|
181
209
|
summary: A ruby interface to the SPDX catalogue.
|
data/.travis.yml
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Spandx
|
|
4
|
-
class CatalogueGateway
|
|
5
|
-
URL = 'https://spdx.org/licenses/licenses.json'
|
|
6
|
-
|
|
7
|
-
def initialize(http: default_client)
|
|
8
|
-
@http = http
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def fetch(url: URL)
|
|
12
|
-
response = http.get(url)
|
|
13
|
-
|
|
14
|
-
if response.code == '200'
|
|
15
|
-
parse(response.body)
|
|
16
|
-
else
|
|
17
|
-
empty_catalogue
|
|
18
|
-
end
|
|
19
|
-
rescue *::Net::Hippie::CONNECTION_ERRORS
|
|
20
|
-
empty_catalogue
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
private
|
|
24
|
-
|
|
25
|
-
attr_reader :http
|
|
26
|
-
|
|
27
|
-
def parse(json)
|
|
28
|
-
build_catalogue(JSON.parse(json, symbolize_names: true))
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def empty_catalogue
|
|
32
|
-
build_catalogue(licenses: [])
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def build_catalogue(hash)
|
|
36
|
-
Catalogue.new(hash)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def default_client
|
|
40
|
-
Net::Hippie::Client.new
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|