spandx 0.4.1 → 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: bd43f4534fd78176bb372673b73a3fcd135872f4b784ed84a6b9d518fbb7001d
4
- data.tar.gz: a66deaed24189e97e130258647b4c10f00554514ae508510169ec5ff54dee30f
3
+ metadata.gz: 440933f7b4b8706a0a4da8ed5c84c5db80f93e40e7db258715bb73b11c5cbb31
4
+ data.tar.gz: 182e055dea23b17d3bb67fc16ce84ce245aa2dbfd247d9eead1b33162bf05472
5
5
  SHA512:
6
- metadata.gz: e25407370b0ec723f948f128a80e7030e969da7744740f3d49d9293b473c68370a59615bf8638da168b1bf47f5ecaa682f74a4689c77e1f15bc30bd3dcfebfcc
7
- data.tar.gz: 89151e50569afac8e15e8fb4e882e6241c083939d30a7ffd4b15151d5420b9dba3953c7aa774006d51d2fde1df8e4eb0da550c6c05584d9a8f7b841529cb912c
6
+ metadata.gz: 26f4bc7516adf9f96c3725b15acc6ead6a2bdad6deaaf718a145106dcbec9f7c95c0f2053163f3c913a7466d2a8c3af860d4903a78bcb6eec8329f05a0cdb17f
7
+ data.tar.gz: 441abbd1f3cd090514627386e6f175ff5e53ba2909a2722f7e34e0f9a5e514532c431ffdd54e23d501dd20c6626c382b0fba215939989b7e0d32ba477bf86aa9
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- Version 0.4.1
1
+ Version 0.5.0
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.5.0] - 2020-02-13
13
+ ### Added
14
+ - Add jaro winkler string similarity support.
15
+ - Attempt to resolve rubygems dependencies via `spandx-rubygems` index.
16
+
17
+ ### Changed
18
+ - Make `text` and `jaro_winkler` gems a soft dependency.
19
+
12
20
  ## [0.4.1] - 2020-02-02
13
21
  ### Fixed
14
22
  - Save license expression as string instead of array.
@@ -65,7 +73,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
65
73
  ### Added
66
74
  - Provide ruby API to the latest SPDX catalogue.
67
75
 
68
- [Unreleased]: https://github.com/mokhan/spandx/compare/v0.4.1...HEAD
76
+ [Unreleased]: https://github.com/mokhan/spandx/compare/v0.5.0...HEAD
77
+ [0.5.0]: https://github.com/mokhan/spandx/compare/v0.4.1...v0.5.0
69
78
  [0.4.1]: https://github.com/mokhan/spandx/compare/v0.4.0...v0.4.1
70
79
  [0.4.0]: https://github.com/mokhan/spandx/compare/v0.3.0...v0.4.0
71
80
  [0.3.0]: https://github.com/mokhan/spandx/compare/v0.2.0...v0.3.0
@@ -36,7 +36,7 @@ module Spandx
36
36
  end
37
37
 
38
38
  def from_git
39
- from_json(Spandx.db.read('json/licenses.json'))
39
+ from_json(Spandx.spdx_db.read('json/licenses.json'))
40
40
  end
41
41
 
42
42
  def empty
@@ -2,10 +2,9 @@
2
2
 
3
3
  module Spandx
4
4
  class Content
5
- attr_reader :raw, :threshold
5
+ attr_reader :raw
6
6
 
7
- def initialize(raw, threshold: 89.0)
8
- @threshold = threshold
7
+ def initialize(raw)
9
8
  @raw = raw
10
9
  end
11
10
 
@@ -16,9 +15,11 @@ module Spandx
16
15
  def similar?(other, algorithm: :dice_coefficient)
17
16
  case algorithm
18
17
  when :dice_coefficient
19
- similarity_score(other) > threshold
18
+ similarity_score(other, algorithm: algorithm) > 89.0
20
19
  when :levenshtein
21
- similarity_score(other) < threshold
20
+ similarity_score(other, algorithm: algorithm) < 3
21
+ when :jaro_winkler
22
+ similarity_score(other, algorithm: algorithm) > 89.0
22
23
  end
23
24
  end
24
25
 
@@ -27,7 +28,13 @@ module Spandx
27
28
  when :dice_coefficient
28
29
  dice_coefficient(other)
29
30
  when :levenshtein
31
+ require 'text'
32
+
30
33
  Text::Levenshtein.distance(raw, other.raw, 100)
34
+ when :jaro_winkler
35
+ require 'jaro_winkler'
36
+
37
+ JaroWinkler.distance(raw, other.raw) * 100.0
31
38
  end
32
39
  end
33
40
 
@@ -16,13 +16,13 @@ module Spandx
16
16
  end
17
17
 
18
18
  def update!(index, limit: nil)
19
- counter = Concurrent::AtomicFixnum.new(0)
19
+ counter = 0
20
20
  each do |spec|
21
21
  upsert_into!(index, spec)
22
22
 
23
23
  if limit
24
- counter.increment
25
- break if counter.value > limit
24
+ counter += 1
25
+ break if counter > limit
26
26
  end
27
27
  end
28
28
  end
@@ -104,10 +104,9 @@ module Spandx
104
104
  key = [host, spec['id'], spec['version']]
105
105
  return if index.indexed?(key)
106
106
 
107
- if (license = spec['licenseExpression'])
108
- index.write(key, license)
109
- end
110
- puts [license, key].inspect
107
+ return unless spec['licenseExpression']
108
+
109
+ index.write(key, spec['licenseExpression'])
111
110
  end
112
111
  end
113
112
  end
@@ -9,13 +9,18 @@ module Spandx
9
9
  end
10
10
 
11
11
  def licenses_for(name, version)
12
- details_on(name, version)['licenses'] || []
12
+ found = index.licenses_for(name: name, version: version)
13
+ found.any? ? found : details_on(name, version)['licenses'] || []
13
14
  end
14
15
 
15
16
  private
16
17
 
17
18
  attr_reader :http
18
19
 
20
+ def index
21
+ @index ||= Spandx::Rubygems::Index.new
22
+ end
23
+
19
24
  def details_on(name, version)
20
25
  url = "https://rubygems.org/api/v2/rubygems/#{name}/versions/#{version}.json"
21
26
  response = http.get(url, default: {})
data/lib/spandx/guess.rb CHANGED
@@ -8,10 +8,18 @@ module Spandx
8
8
  attr_reader :score, :item
9
9
 
10
10
  def initialize(score, item)
11
+ update(score || 0.0, item)
12
+ end
13
+
14
+ def update(score, item)
11
15
  @score = score
12
16
  @item = item
13
17
  end
14
18
 
19
+ def empty?
20
+ score.nil? || item.nil?
21
+ end
22
+
15
23
  def <=>(other)
16
24
  score <=> other.score
17
25
  end
@@ -29,33 +37,40 @@ module Spandx
29
37
 
30
38
  def license_for(raw_content, algorithm: :dice_coefficient)
31
39
  content = Content.new(raw_content)
32
- score = nil
33
- catalogue.each do |license|
34
- next if license.deprecated_license_id?
40
+ score = Score.new(nil, nil)
41
+ threshold = threshold_for(algorithm)
42
+ direction = algorithm == :levenshtein ? method(:min) : method(:max)
35
43
 
36
- score = algorithm == :levenshtein ? levenshtein(content, license, score) : dice(content, license, score)
44
+ catalogue.each do |license|
45
+ direction.call(content, license, score, threshold, algorithm) unless license.deprecated_license_id?
37
46
  end
38
47
  score&.item&.id
39
48
  end
40
49
 
41
50
  private
42
51
 
43
- def levenshtein(target, other, score)
44
- percentage = target.similarity_score(other.content, algorithm: :levenshtein)
45
- if score.nil? || percentage < score.score
46
- return Score.new(percentage, other)
47
- end
52
+ def threshold_for(algorithm)
53
+ {
54
+ dice_coefficient: 89.0,
55
+ jaro_winkler: 80.0,
56
+ levenshtein: 80.0,
57
+ }[algorithm.to_sym]
58
+ end
48
59
 
49
- score
60
+ def min(target, other, score, threshold, algorithm)
61
+ percentage = target.similarity_score(other.content, algorithm: algorithm)
62
+ return if percentage > threshold
63
+ return if score.score > 0.0 && score.score < percentage
64
+
65
+ score.update(percentage, other)
50
66
  end
51
67
 
52
- def dice(target, other, score)
53
- percentage = target.similarity_score(other.content, algorithm: :dice_coefficient)
54
- if (percentage > 89.0) && (score.nil? || percentage > score.score)
55
- return Score.new(percentage, other)
56
- end
68
+ def max(target, other, score, threshold, algorithm)
69
+ percentage = target.similarity_score(other.content, algorithm: algorithm)
70
+ return if percentage < threshold
71
+ return if score.score >= percentage
57
72
 
58
- score
73
+ score.update(percentage, other)
59
74
  end
60
75
  end
61
76
  end
@@ -65,7 +65,7 @@ module Spandx
65
65
  end
66
66
 
67
67
  def raw_content
68
- @raw_content ||= (Spandx.db.read("text/#{id}.txt") || '')
68
+ @raw_content ||= (Spandx.spdx_db.read("text/#{id}.txt") || '')
69
69
  end
70
70
 
71
71
  def <=>(other)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spandx
4
- VERSION = '0.4.1'
4
+ VERSION = '0.5.0'
5
5
  end
data/lib/spandx.rb CHANGED
@@ -2,13 +2,11 @@
2
2
 
3
3
  require 'addressable/uri'
4
4
  require 'bundler'
5
- require 'concurrent'
6
5
  require 'forwardable'
7
6
  require 'json'
8
7
  require 'net/hippie'
9
8
  require 'nokogiri'
10
9
  require 'pathname'
11
- require 'text'
12
10
 
13
11
  require 'spandx/catalogue'
14
12
  require 'spandx/content'
@@ -24,6 +22,7 @@ require 'spandx/index'
24
22
  require 'spandx/license'
25
23
  require 'spandx/parsers'
26
24
  require 'spandx/report'
25
+ require 'spandx/rubygems'
27
26
  require 'spandx/version'
28
27
 
29
28
  module Spandx
@@ -38,8 +37,8 @@ module Spandx
38
37
  @http ||= Spandx::Gateways::Http.new
39
38
  end
40
39
 
41
- def db
42
- @db ||= Spandx::Database.new(url: 'https://github.com/spdx/license-list-data.git').tap(&:update!)
40
+ def spdx_db
41
+ @spdx_db ||= Spandx::Database.new(url: 'https://github.com/spdx/license-list-data.git').tap(&:update!)
43
42
  end
44
43
  end
45
44
  end
data/spandx.gemspec CHANGED
@@ -14,6 +14,7 @@ Gem::Specification.new do |spec|
14
14
  spec.description = 'A ruby interface to the SPDX catalogue.'
15
15
  spec.homepage = 'https://github.com/mokhan/spandx'
16
16
  spec.license = 'MIT'
17
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
17
18
 
18
19
  spec.metadata['homepage_uri'] = spec.homepage
19
20
  spec.metadata['source_code_uri'] = 'https://github.com/mokhan/spandx'
@@ -29,20 +30,21 @@ Gem::Specification.new do |spec|
29
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
31
  spec.require_paths = ['lib']
31
32
 
32
- spec.required_ruby_version = '>= 2.4.0'
33
33
  spec.add_dependency 'addressable', '~> 2.7'
34
34
  spec.add_dependency 'bundler', '>= 1.16', '< 3.0.0'
35
- spec.add_dependency 'concurrent-ruby-ext', '~> 1.1'
36
35
  spec.add_dependency 'net-hippie', '~> 0.3'
37
36
  spec.add_dependency 'nokogiri', '~> 1.10'
38
- spec.add_dependency 'text', '~> 1.3'
39
- spec.add_dependency 'thor', '~> 0.1'
37
+ spec.add_dependency 'spandx-rubygems', '~> 0.1'
38
+ spec.add_dependency 'thor'
39
+
40
40
  spec.add_development_dependency 'bundler-audit', '~> 0.6'
41
+ spec.add_development_dependency 'jaro_winkler', '~> 1.5'
41
42
  spec.add_development_dependency 'rake', '~> 13.0'
42
43
  spec.add_development_dependency 'rspec', '~> 3.0'
43
44
  spec.add_development_dependency 'rspec-benchmark', '~> 0.5'
44
45
  spec.add_development_dependency 'rubocop', '~> 0.52'
45
46
  spec.add_development_dependency 'rubocop-rspec', '~> 1.22'
47
+ spec.add_development_dependency 'text', '~> 1.3'
46
48
  spec.add_development_dependency 'vcr', '~> 5.0'
47
49
  spec.add_development_dependency 'webmock', '~> 3.7'
48
50
  end
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.4.1
4
+ version: 0.5.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-02-02 00:00:00.000000000 Z
11
+ date: 2020-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -44,20 +44,6 @@ dependencies:
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
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'
61
47
  - !ruby/object:Gem::Dependency
62
48
  name: net-hippie
63
49
  requirement: !ruby/object:Gem::Requirement
@@ -87,33 +73,33 @@ dependencies:
87
73
  - !ruby/object:Gem::Version
88
74
  version: '1.10'
89
75
  - !ruby/object:Gem::Dependency
90
- name: text
76
+ name: spandx-rubygems
91
77
  requirement: !ruby/object:Gem::Requirement
92
78
  requirements:
93
79
  - - "~>"
94
80
  - !ruby/object:Gem::Version
95
- version: '1.3'
81
+ version: '0.1'
96
82
  type: :runtime
97
83
  prerelease: false
98
84
  version_requirements: !ruby/object:Gem::Requirement
99
85
  requirements:
100
86
  - - "~>"
101
87
  - !ruby/object:Gem::Version
102
- version: '1.3'
88
+ version: '0.1'
103
89
  - !ruby/object:Gem::Dependency
104
90
  name: thor
105
91
  requirement: !ruby/object:Gem::Requirement
106
92
  requirements:
107
- - - "~>"
93
+ - - ">="
108
94
  - !ruby/object:Gem::Version
109
- version: '0.1'
95
+ version: '0'
110
96
  type: :runtime
111
97
  prerelease: false
112
98
  version_requirements: !ruby/object:Gem::Requirement
113
99
  requirements:
114
- - - "~>"
100
+ - - ">="
115
101
  - !ruby/object:Gem::Version
116
- version: '0.1'
102
+ version: '0'
117
103
  - !ruby/object:Gem::Dependency
118
104
  name: bundler-audit
119
105
  requirement: !ruby/object:Gem::Requirement
@@ -128,6 +114,20 @@ dependencies:
128
114
  - - "~>"
129
115
  - !ruby/object:Gem::Version
130
116
  version: '0.6'
117
+ - !ruby/object:Gem::Dependency
118
+ name: jaro_winkler
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '1.5'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '1.5'
131
131
  - !ruby/object:Gem::Dependency
132
132
  name: rake
133
133
  requirement: !ruby/object:Gem::Requirement
@@ -198,6 +198,20 @@ dependencies:
198
198
  - - "~>"
199
199
  - !ruby/object:Gem::Version
200
200
  version: '1.22'
201
+ - !ruby/object:Gem::Dependency
202
+ name: text
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - "~>"
206
+ - !ruby/object:Gem::Version
207
+ version: '1.3'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - "~>"
213
+ - !ruby/object:Gem::Version
214
+ version: '1.3'
201
215
  - !ruby/object:Gem::Dependency
202
216
  name: vcr
203
217
  requirement: !ruby/object:Gem::Requirement