spandx 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -2
- data/lib/spandx/cli.rb +16 -1
- data/lib/spandx/commands/build.rb +33 -0
- data/lib/spandx/gateways/http.rb +1 -1
- data/lib/spandx/gateways/nuget.rb +59 -3
- data/lib/spandx/gateways/pypi.rb +1 -1
- data/lib/spandx/index.rb +49 -0
- data/lib/spandx/version.rb +1 -1
- data/lib/spandx.rb +3 -0
- data/spandx.gemspec +2 -0
- metadata +32 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 60e89d9935bbf82bb28b848858df9b48a736613600808721b6feddf511ed2f8a
|
|
4
|
+
data.tar.gz: a3e0396a012747f80b97376c1afbccb646f4e8a7bc379998fb89fed35d1a188b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c27a27d68f51fcecd579edbcfd2a1ce591f2d2ca9d647df94280c78aa78e0b5a4af7dfc2b08ca0cccb93d3f512a3989dfc6d11846540d69bd814974df2e55d44
|
|
7
|
+
data.tar.gz: b01f6403eff92f6438f707806b4b976e651c0765d3b9dae5beb46fd801aeab982e7ca1c3e7315102660006f023fb67b8a66e8984533c58678408613c8fd5c051
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Version 0.
|
|
1
|
+
Version 0.4.0
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
@@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.4.0] - 2020-02-02
|
|
13
|
+
### Added
|
|
14
|
+
- Add command to build offline index of nuget packages and their licenses.
|
|
15
|
+
|
|
12
16
|
## [0.3.0] - 2020-01-29
|
|
13
17
|
### Added
|
|
14
18
|
- Add `pom.xml` parser
|
|
@@ -57,7 +61,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
57
61
|
### Added
|
|
58
62
|
- Provide ruby API to the latest SPDX catalogue.
|
|
59
63
|
|
|
60
|
-
[Unreleased]: https://github.com/mokhan/spandx/compare/v0.
|
|
64
|
+
[Unreleased]: https://github.com/mokhan/spandx/compare/v0.4.0...HEAD
|
|
65
|
+
[0.4.0]: https://github.com/mokhan/spandx/compare/v0.3.0...v0.4.0
|
|
61
66
|
[0.3.0]: https://github.com/mokhan/spandx/compare/v0.2.0...v0.3.0
|
|
62
67
|
[0.2.0]: https://github.com/mokhan/spandx/compare/v0.1.7...v0.2.0
|
|
63
68
|
[0.1.7]: https://github.com/mokhan/spandx/compare/v0.1.6...v0.1.7
|
data/lib/spandx/cli.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'thor'
|
|
|
4
4
|
|
|
5
5
|
require 'spandx'
|
|
6
6
|
require 'spandx/command'
|
|
7
|
+
require 'spandx/commands/build'
|
|
7
8
|
require 'spandx/commands/scan'
|
|
8
9
|
|
|
9
10
|
module Spandx
|
|
@@ -16,7 +17,21 @@ module Spandx
|
|
|
16
17
|
end
|
|
17
18
|
map %w[--version -v] => :version
|
|
18
19
|
|
|
19
|
-
desc '
|
|
20
|
+
desc 'build', 'Build a package index'
|
|
21
|
+
method_option :help, aliases: '-h', type: :boolean,
|
|
22
|
+
desc: 'Display usage information'
|
|
23
|
+
method_option :directory, aliases: '-d', type: :string,
|
|
24
|
+
desc: 'Directory to build index in'
|
|
25
|
+
def build(*)
|
|
26
|
+
if options[:help]
|
|
27
|
+
invoke :help, ['build']
|
|
28
|
+
else
|
|
29
|
+
require_relative 'commands/build'
|
|
30
|
+
Spandx::Commands::Build.new(options).execute
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc 'scan LOCKFILE', 'Scan a lockfile and list dependencies/licenses'
|
|
20
35
|
method_option :help, aliases: '-h', type: :boolean,
|
|
21
36
|
desc: 'Display usage information'
|
|
22
37
|
def scan(lockfile = nil)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../command'
|
|
4
|
+
|
|
5
|
+
module Spandx
|
|
6
|
+
module Commands
|
|
7
|
+
class Build < Spandx::Command
|
|
8
|
+
def initialize(options)
|
|
9
|
+
@options = options
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def execute(output: $stdout)
|
|
13
|
+
index = Spandx::Index.new(directory: @options[:directory])
|
|
14
|
+
gateways.each do |gateway|
|
|
15
|
+
gateway.update!(index)
|
|
16
|
+
end
|
|
17
|
+
output.puts 'OK'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def catalogue
|
|
23
|
+
Spandx::Catalogue.from_git
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def gateways
|
|
27
|
+
[
|
|
28
|
+
Spandx::Gateways::Nuget.new(catalogue: catalogue)
|
|
29
|
+
]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/spandx/gateways/http.rb
CHANGED
|
@@ -6,10 +6,25 @@ module Spandx
|
|
|
6
6
|
# https://api.nuget.org/v3-flatcontainer/#{package.name}/index.json
|
|
7
7
|
# https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource
|
|
8
8
|
class Nuget
|
|
9
|
+
attr_reader :host
|
|
10
|
+
|
|
9
11
|
def initialize(http: Spandx.http, catalogue:)
|
|
10
12
|
@http = http
|
|
11
13
|
@catalogue = catalogue
|
|
12
14
|
@guess = Guess.new(catalogue)
|
|
15
|
+
@host = 'api.nuget.org'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def update!(index, limit: nil)
|
|
19
|
+
counter = Concurrent::AtomicFixnum.new(0)
|
|
20
|
+
each do |spec|
|
|
21
|
+
upsert_into!(index, spec)
|
|
22
|
+
|
|
23
|
+
if limit
|
|
24
|
+
counter.increment
|
|
25
|
+
break if counter.value > limit
|
|
26
|
+
end
|
|
27
|
+
end
|
|
13
28
|
end
|
|
14
29
|
|
|
15
30
|
def licenses_for(name, version)
|
|
@@ -23,19 +38,34 @@ module Spandx
|
|
|
23
38
|
|
|
24
39
|
attr_reader :http, :catalogue, :guess
|
|
25
40
|
|
|
41
|
+
def each
|
|
42
|
+
each_page do |page|
|
|
43
|
+
items_from(page).each do |item|
|
|
44
|
+
yield fetch_json(item['@id'])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def each_page
|
|
50
|
+
url = "https://#{host}/v3/catalog0/index.json"
|
|
51
|
+
items_from(fetch_json(url)).each do |page|
|
|
52
|
+
yield fetch_json(page['@id'])
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
26
56
|
def nuspec_url_for(name, version)
|
|
27
|
-
"https
|
|
57
|
+
"https://#{host}/v3-flatcontainer/#{name}/#{version}/#{name}.nuspec"
|
|
28
58
|
end
|
|
29
59
|
|
|
30
60
|
def nuspec_for(name, version)
|
|
31
|
-
|
|
32
|
-
from_xml(response.body) if http.ok?(response)
|
|
61
|
+
fetch_xml(nuspec_url_for(name, version))
|
|
33
62
|
end
|
|
34
63
|
|
|
35
64
|
def from_xml(xml)
|
|
36
65
|
Nokogiri::XML(xml).tap(&:remove_namespaces!)
|
|
37
66
|
end
|
|
38
67
|
|
|
68
|
+
# TODO: Fix parsing https://github.com/NuGet/Home/wiki/Packaging-License-within-the-nupkg#license
|
|
39
69
|
def extract_licenses_from(document)
|
|
40
70
|
licenses = document.search('//package/metadata/license')
|
|
41
71
|
licenses.map(&:text) if licenses.any?
|
|
@@ -53,6 +83,32 @@ module Spandx
|
|
|
53
83
|
|
|
54
84
|
guess.license_for(response.body) if http.ok?(response)
|
|
55
85
|
end
|
|
86
|
+
|
|
87
|
+
def fetch_json(url)
|
|
88
|
+
response = http.get(url)
|
|
89
|
+
http.ok?(response) ? JSON.parse(response.body) : {}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def fetch_xml(url)
|
|
93
|
+
response = http.get(url)
|
|
94
|
+
http.ok?(response) ? from_xml(response.body) : from_xml('<empty />')
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def items_from(page)
|
|
98
|
+
page['items']
|
|
99
|
+
.sort_by { |x| x['commitTimeStamp'] }
|
|
100
|
+
.reverse
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def upsert_into!(index, spec)
|
|
104
|
+
key = [host, spec['id'], spec['version']]
|
|
105
|
+
return if index.indexed?(key)
|
|
106
|
+
|
|
107
|
+
if (license = spec['licenseExpression'])
|
|
108
|
+
index.write(key, [license])
|
|
109
|
+
end
|
|
110
|
+
puts [license, key].inspect
|
|
111
|
+
end
|
|
56
112
|
end
|
|
57
113
|
end
|
|
58
114
|
end
|
data/lib/spandx/gateways/pypi.rb
CHANGED
data/lib/spandx/index.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spandx
|
|
4
|
+
class Index
|
|
5
|
+
DEFAULT_DIR = File.expand_path(File.join(Dir.home, '.local', 'share', 'spandx'))
|
|
6
|
+
attr_reader :directory
|
|
7
|
+
|
|
8
|
+
def initialize(directory: DEFAULT_DIR)
|
|
9
|
+
@directory = directory ? File.expand_path(directory) : DEFAULT_DIR
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def indexed?(key)
|
|
13
|
+
File.exist?(data_file_for(digest_for(key)))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def read(key)
|
|
17
|
+
open_data(digest_for(key), mode: 'r', &:read)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def write(key, data)
|
|
21
|
+
return if data.nil? || data.empty?
|
|
22
|
+
|
|
23
|
+
open_data(digest_for(key)) do |x|
|
|
24
|
+
x.write(data)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def digest_for(components)
|
|
31
|
+
Digest::SHA1.hexdigest(Array(components).join('/'))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def open_data(key, mode: 'w')
|
|
35
|
+
FileUtils.mkdir_p(data_dir_for(key))
|
|
36
|
+
File.open(data_file_for(key), mode) do |file|
|
|
37
|
+
yield file
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def data_dir_for(index_key)
|
|
42
|
+
File.join(directory, *index_key.scan(/../))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def data_file_for(key)
|
|
46
|
+
File.join(data_dir_for(key), 'data')
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/lib/spandx/version.rb
CHANGED
data/lib/spandx.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'addressable/uri'
|
|
3
4
|
require 'bundler'
|
|
5
|
+
require 'concurrent'
|
|
4
6
|
require 'forwardable'
|
|
5
7
|
require 'json'
|
|
6
8
|
require 'net/hippie'
|
|
@@ -18,6 +20,7 @@ require 'spandx/gateways/pypi'
|
|
|
18
20
|
require 'spandx/gateways/rubygems'
|
|
19
21
|
require 'spandx/gateways/spdx'
|
|
20
22
|
require 'spandx/guess'
|
|
23
|
+
require 'spandx/index'
|
|
21
24
|
require 'spandx/license'
|
|
22
25
|
require 'spandx/parsers'
|
|
23
26
|
require 'spandx/report'
|
data/spandx.gemspec
CHANGED
|
@@ -30,7 +30,9 @@ Gem::Specification.new do |spec|
|
|
|
30
30
|
spec.require_paths = ['lib']
|
|
31
31
|
|
|
32
32
|
spec.required_ruby_version = '>= 2.4.0'
|
|
33
|
+
spec.add_dependency 'addressable', '~> 2.7'
|
|
33
34
|
spec.add_dependency 'bundler', '>= 1.16', '< 3.0.0'
|
|
35
|
+
spec.add_dependency 'concurrent-ruby-ext', '~> 1.1'
|
|
34
36
|
spec.add_dependency 'net-hippie', '~> 0.3'
|
|
35
37
|
spec.add_dependency 'nokogiri', '~> 1.10'
|
|
36
38
|
spec.add_dependency 'text', '~> 1.3'
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spandx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- mo khan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-02-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: addressable
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.7'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.7'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: bundler
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -30,6 +44,20 @@ dependencies:
|
|
|
30
44
|
- - "<"
|
|
31
45
|
- !ruby/object:Gem::Version
|
|
32
46
|
version: 3.0.0
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: concurrent-ruby-ext
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.1'
|
|
54
|
+
type: :runtime
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '1.1'
|
|
33
61
|
- !ruby/object:Gem::Dependency
|
|
34
62
|
name: net-hippie
|
|
35
63
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -214,6 +242,7 @@ files:
|
|
|
214
242
|
- lib/spandx/catalogue.rb
|
|
215
243
|
- lib/spandx/cli.rb
|
|
216
244
|
- lib/spandx/command.rb
|
|
245
|
+
- lib/spandx/commands/build.rb
|
|
217
246
|
- lib/spandx/commands/scan.rb
|
|
218
247
|
- lib/spandx/content.rb
|
|
219
248
|
- lib/spandx/database.rb
|
|
@@ -224,6 +253,7 @@ files:
|
|
|
224
253
|
- lib/spandx/gateways/rubygems.rb
|
|
225
254
|
- lib/spandx/gateways/spdx.rb
|
|
226
255
|
- lib/spandx/guess.rb
|
|
256
|
+
- lib/spandx/index.rb
|
|
227
257
|
- lib/spandx/license.rb
|
|
228
258
|
- lib/spandx/parsers.rb
|
|
229
259
|
- lib/spandx/parsers/base.rb
|