license_matcher 0.2.0 → 0.3.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
  SHA1:
3
- metadata.gz: 75f4cc4338e87a4244875d5172770867b63588cb
4
- data.tar.gz: 3bb514e6e029140949ed3c78c1b32a1a04333a04
3
+ metadata.gz: bae726cf67cb9e615291d1da18e87f120fdb7ea6
4
+ data.tar.gz: d104b7310dc786821c56df1b3d984e9069dc1434
5
5
  SHA512:
6
- metadata.gz: 1b99befeaf51c94e2f85acdc991abd02486de41ea3f7506a2e7a6402f08e4c0765b322cb480db98703da01ef286bf9751bc6fc458356e1c93c4142f611a26457
7
- data.tar.gz: 67b3d8e0265f91ebd9d1818983dfea906f543dffcc08d41d3cb50aeb66d56fe76714409085e741513a36229cbaefef388e0ffe691e20e06ec558796eef6f4ac0
6
+ metadata.gz: 72c13e2a98ce021d8491063244f00c9ef56ec3ef7332d77448485d93d92cdcead16e20cb5dc0b01726970defed06dafa4bc2ac121a867df1393dace608a3e951
7
+ data.tar.gz: d11e26305040d796f072294f6bdb9c20e09e3fcaf25e2d519e0737bf1647a4ac65166795a030a35f4938b8fffbbf2cb66ae00f64edc9066b124f49aa93c090ed
data/Gemfile.lock CHANGED
@@ -1,11 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- license_matcher (0.2.0.pre.alpha)
5
- helix_runtime (~> 0.6.0)
4
+ license_matcher (0.3.0)
5
+ helix_runtime (~> 0.6)
6
+ msgpack (~> 1.1)
6
7
  narray (~> 0.6.1.2)
7
- nokogiri (~> 1.8.0)
8
- tf-idf-similarity (~> 0.1.6)
8
+ nokogiri (~> 1.8)
9
+ os (~> 1.0)
10
+ tf-idf-similarity (~> 0.1)
9
11
 
10
12
  GEM
11
13
  remote: https://rubygems.org/
@@ -16,11 +18,12 @@ GEM
16
18
  rake (>= 10.0)
17
19
  thor (~> 0.19.4)
18
20
  toml (~> 0.1.2)
19
- mini_portile2 (2.2.0)
21
+ mini_portile2 (2.3.0)
20
22
  msgpack (1.1.0)
21
23
  narray (0.6.1.2)
22
- nokogiri (1.8.0)
23
- mini_portile2 (~> 2.2.0)
24
+ nokogiri (1.8.1)
25
+ mini_portile2 (~> 2.3.0)
26
+ os (1.0.0)
24
27
  parslet (1.5.0)
25
28
  blankslate (~> 2.0)
26
29
  rake (10.5.0)
@@ -50,7 +53,6 @@ PLATFORMS
50
53
  DEPENDENCIES
51
54
  bundler (~> 1.15)
52
55
  license_matcher!
53
- msgpack (~> 1.1.0)
54
56
  rake (~> 10.0)
55
57
  rspec (~> 3.4)
56
58
 
data/README.md CHANGED
@@ -44,7 +44,7 @@ LicenseMatcher::IndexBuilder.build_index( "data/licenses", "data/index.msgpack")
44
44
  txt = File.read("fixtures/files/mit.txt");
45
45
 
46
46
  lm = LicenseMatcher::TFRubyMatcher.new("data/index.msgpack")
47
- m = lm.match_text(txt, 0.9)
47
+ m = lm.match_text(txt, 0.9)
48
48
  p "spdx id: #{m.get_label()}, confidence: #{m.get_score()}"
49
49
 
50
50
  ```
@@ -78,7 +78,7 @@ lm.match_rules "It is license under Apache 2.0 License."
78
78
  lm = LicenseMatcher::TFRubyMatcher.new
79
79
 
80
80
  txt = File.read "fixtures/files/mit.html"
81
- clean_txt = lm.preprocess_html txt # NB! it may help to increase accuracy
81
+ clean_txt = LicenseMatcher::Preprocess.preprocess_html txt # NB! it may help to increase accuracy
82
82
  lm.match_txt clean_txt
83
83
  ```
84
84
 
@@ -95,7 +95,7 @@ lm2.match_text txt
95
95
 
96
96
  ```
97
97
  lm3 = File.read "fixtures/files/mit.txt"
98
- lm3.match_text txt
98
+ lm3.match_text txt
99
99
  ```
100
100
 
101
101
  ## Benchmarks
@@ -138,7 +138,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
138
138
 
139
139
  ## Contributing
140
140
 
141
- Bug reports and pull requests are welcome on GitHub at https://github.com/fosslim/license_matcher.
141
+ Bug reports and pull requests are welcome on GitHub at https://github.com/fosslim/license_matcher.
142
142
 
143
143
  This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
144
144
 
Binary file
@@ -1,75 +1,77 @@
1
1
  require 'nokogiri'
2
2
 
3
- module Preprocess
4
- def preprocess_text(text)
5
- text = safe_encode(text)
3
+ module LicenseMatcher
4
+ class Preprocess
5
+ def self.preprocess_text(text)
6
+ text = safe_encode(text)
6
7
 
7
- #remove markdown url tags
8
- text = text.gsub(/\[.+?\]\(.+?\)/, ' ')
8
+ #remove markdown url tags
9
+ text = text.gsub(/\[.+?\]\(.+?\)/, ' ')
9
10
 
10
- #remove spam words
11
- text.gsub!(/\bTHE\b/i, '')
11
+ #remove spam words
12
+ text.gsub!(/\bTHE\b/i, '')
12
13
 
13
- #remove some XML grabage
14
- text = text.gsub(/\<\!\[CDATA.*?\]\]\>/, ' ').to_s
15
- text = text.gsub(/\<\!--.+?--\>/, ' ').to_s
16
- text = text.gsub(/<\!\[CDATA.+?\]>/, ' ').to_s
14
+ #remove some XML grabage
15
+ text = text.gsub(/\<\!\[CDATA.*?\]\]\>/, ' ').to_s
16
+ text = text.gsub(/\<\!--.+?--\>/, ' ').to_s
17
+ text = text.gsub(/<\!\[CDATA.+?\]>/, ' ').to_s
17
18
 
18
- return text.to_s.strip.gsub(/\s+/, ' ')
19
- end
19
+ return text.to_s.strip.gsub(/\s+/, ' ')
20
+ end
20
21
 
21
- def preprocess_html(html_text)
22
- # if text is HTML doc, then
23
- # extract text only from visible html tags
24
- text = ""
22
+ def self.preprocess_html(html_text)
23
+ # if text is HTML doc, then
24
+ # extract text only from visible html tags
25
+ text = ""
25
26
 
26
- html_doc = parse_html(html_text)
27
- if html_doc
28
- text = clean_html(html_doc)
29
- else
30
- p "match_html: failed to parse html document\n#{html_text}"
27
+ html_doc = parse_html(html_text)
28
+ if html_doc
29
+ text = clean_html(html_doc)
30
+ else
31
+ p "match_html: failed to parse html document\n#{html_text}"
32
+ end
33
+
34
+ return text
31
35
  end
32
36
 
33
- return text
34
- end
37
+ def self.clean_html(html_doc)
38
+ body_text = ""
39
+ body_elements = html_doc.xpath(
40
+ '//p | //h1 | //h2 | //h3 | //h4 | //h5 | //h6 | //em | //strong | //b | //td | //pre
41
+ | //li[not(@id) and not(@class) and not(a)] | //section//section[@class="project-info"]
42
+ | //blockquote | //textarea'
43
+ ).to_a
35
44
 
36
- def clean_html(html_doc)
37
- body_text = ""
38
- body_elements = html_doc.xpath(
39
- '//p | //h1 | //h2 | //h3 | //h4 | //h5 | //h6 | //em | //strong | //b | //td | //pre
40
- | //li[not(@id) and not(@class) and not(a)] | //section//section[@class="project-info"]
41
- | //blockquote | //textarea'
42
- ).to_a
45
+ #extract text from html tag and separate them by space
46
+ body_elements.each {|el| body_text += ' ' + el.text.to_s}
43
47
 
44
- #extract text from html tag and separate them by space
45
- body_elements.each {|el| body_text += ' ' + el.text.to_s}
48
+ #REMOVE XML CDATA like opensource.org pages has
49
+ body_text = body_text.to_s.strip
50
+ body_text.gsub!(/\<\!\[CDATA.+?\]\]\>/i, ' ')
46
51
 
47
- #REMOVE XML CDATA like opensource.org pages has
48
- body_text = body_text.to_s.strip
49
- body_text.gsub!(/\<\!\[CDATA.+?\]\]\>/i, ' ')
52
+ if body_text.empty?
53
+ p "match_html: document didnt pass noise filter, will use whole body content"
54
+ body_text = html_doc.xpath('//body').text.to_s.strip
55
+ end
50
56
 
51
- if body_text.empty?
52
- p "match_html: document didnt pass noise filter, will use whole body content"
53
- body_text = html_doc.xpath('//body').text.to_s.strip
57
+ return body_text
54
58
  end
55
59
 
56
- return body_text
57
- end
60
+ def self.parse_html(html_text)
61
+ begin
62
+ return Nokogiri.HTML(safe_encode(html_text))
63
+ rescue Exception => e
64
+ p "failed to parse html doc: \n #{html_text} - #{e.message}"
65
+ return nil
66
+ end
67
+ end
58
68
 
59
- def parse_html(html_text)
60
- begin
61
- return Nokogiri.HTML(safe_encode(html_text))
62
- rescue Exception => e
63
- log.error "failed to parse html doc: \n #{html_text}"
64
- return nil
69
+ def self.safe_encode(txt)
70
+ txt.to_s.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
71
+ rescue
72
+ p "Failed to encode text:\n #{txt}i"
73
+ return ""
65
74
  end
66
- end
67
75
 
68
- def safe_encode(txt)
69
- txt.to_s.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
70
- rescue
71
- p "Failed to encode text:\n #{txt}i"
72
- return ""
73
76
  end
74
-
75
- end
77
+ end
@@ -1,14 +1,11 @@
1
1
  require 'json'
2
2
 
3
3
  module LicenseMatcher
4
-
5
- class RuleMatcher
6
- include Preprocess
7
4
 
5
+ class RuleMatcher
8
6
  attr_reader :licenses, :rules, :id_spdx_idx
9
7
 
10
- DEFAULT_LICENSE_JSON = 'data/spdx_licenses/licenses.json'
11
-
8
+ DEFAULT_LICENSE_JSON = 'data/licenses.json'
12
9
 
13
10
  def initialize(license_json_file = DEFAULT_LICENSE_JSON)
14
11
 
@@ -31,6 +28,16 @@ module LicenseMatcher
31
28
  idx
32
29
  end
33
30
 
31
+ def match_text(text, min_confidence = 0.0)
32
+ res = match_rules(text, true)
33
+ if res.empty?
34
+ Match.new("", 0.0)
35
+ else
36
+ spdx_id, score = res.first
37
+ Match.new(spdx_id, score.to_f)
38
+ end
39
+ end
40
+
34
41
  # finds matching regex rules in the text and sorts matches by length of match
35
42
  # ps: not very efficient, but good enough to handle special cases;
36
43
  # @args:
@@ -39,7 +46,7 @@ module LicenseMatcher
39
46
  # [[spdx_id, score, matching_rule, matching_length],...]
40
47
  def match_rules(text, early_exit = false)
41
48
  matches = []
42
- text = preprocess_text(text)
49
+ text = LicenseMatcher::Preprocess.preprocess_text(text)
43
50
 
44
51
  #if text is already spdx_id, then shortcut matching
45
52
  if @rules.has_key?(text.downcase)
@@ -90,7 +97,6 @@ module LicenseMatcher
90
97
  def read_json_file(file_path)
91
98
  JSON.parse(File.read(file_path), {symbolize_names: true})
92
99
  rescue
93
- log.info "Failed to read json file `#{file_path}`"
94
100
  nil
95
101
  end
96
102
 
@@ -144,7 +150,7 @@ module LicenseMatcher
144
150
  end
145
151
 
146
152
 
147
- spdx_name = preprocess_text(spdx_item[:name])
153
+ spdx_name = LicenseMatcher::Preprocess.preprocess_text(spdx_item[:name])
148
154
  spdx_name.gsub!(/\(.+?\)/, '') #remove SPDX ids in the license names
149
155
  spdx_name.gsub!(/\./, '\\.') #mark version dots as not regex selector
150
156
  spdx_name.gsub!(/[\*|\?|\+]/, '.') #replace regex selector with whatever mark ~> WTFPL name
@@ -598,4 +604,4 @@ module LicenseMatcher
598
604
  end
599
605
 
600
606
  end
601
- end
607
+ end
@@ -5,7 +5,6 @@ require 'msgpack'
5
5
  module LicenseMatcher
6
6
 
7
7
  class TFRubyMatcher
8
- include Preprocess
9
8
 
10
9
  attr_reader :corpus, :model, :spdx_ids
11
10
 
@@ -26,10 +25,9 @@ module LicenseMatcher
26
25
  # matches given text with SPDX licenses and returns Match object
27
26
  # returns:
28
27
  # match - Match {label: String, score: float}
29
- def match_text(text, min_confidence = DEFAULT_MIN_CONFIDENCE, is_processed_text = false)
28
+ def match_text(text, min_confidence = DEFAULT_MIN_CONFIDENCE)
30
29
  return [] if text.to_s.empty?
31
30
 
32
- text = preprocess_text(text) if is_processed_text == false
33
31
  test_doc = TfIdfSimilarity::Document.new(text, {:id => "test"})
34
32
 
35
33
  mat1 = @model.instance_variable_get(:@matrix)
@@ -52,7 +50,8 @@ module LicenseMatcher
52
50
  end
53
51
 
54
52
  def match_html(html_text, min_confidence = DEFAULT_MIN_CONFIDENCE)
55
- match_text(preprocess_html(html_text), min_confidence)
53
+ clean_text = LicenseMatcher::Preprocess.preprocess_html(html_text)
54
+ match_text(clean_text, min_confidence)
56
55
  end
57
56
 
58
57
  #-- helpers
@@ -89,7 +88,7 @@ module LicenseMatcher
89
88
 
90
89
  idx[A_DOC_ROW].to_a.each do |doc_row|
91
90
  _, spdx_id, content, _ = doc_row
92
- txt = preprocess_text content
91
+ txt = LicenseMatcher::Preprocess.preprocess_text content
93
92
  if txt
94
93
  spdx_ids << spdx_id
95
94
  docs << TfIdfSimilarity::Document.new(txt, :id => spdx_id)
@@ -1,10 +1,9 @@
1
1
 
2
2
  module LicenseMatcher
3
-
4
3
  class UrlMatcher
5
4
  attr_reader :url_index
6
5
 
7
- DEFAULT_LICENSE_JSON = 'data/spdx_licenses/licenses.json'
6
+ DEFAULT_LICENSE_JSON = 'data/licenses.json'
8
7
 
9
8
  def initialize(license_json_file = DEFAULT_LICENSE_JSON)
10
9
  licenses_json_doc = read_json_file license_json_file
@@ -13,33 +12,42 @@ module LicenseMatcher
13
12
  @url_index = read_license_url_index(licenses_json_doc)
14
13
  end
15
14
 
16
- # Matches License.url with urls in Licenses.json and returns tuple [spdx_id, score]
15
+ def match_text(url_txt, min_confidence = 0.0)
16
+ spdx_id, score = match_url
17
+ if spdx_idx
18
+ Match.new(spdx_id, score.to_f)
19
+ else
20
+ Match.new("", 0.0)
21
+ end
22
+ end
23
+
24
+ # Matches License.url with urls in Licenses.json and returns tuple [spdx_id, score]
17
25
  def match_url(the_url)
18
26
  the_url = the_url.to_s.strip
19
27
  spdx_id = nil
20
28
 
21
29
  case the_url
22
- when 'http://jquery.org/license'
30
+ when /jquery\.org\/license/i
23
31
  return ['mit', 1.0] #Jquery license page doesnt include any license text
24
- when 'https://www.mozilla.org/en-US/MPL/'
32
+ when /mozilla\.org\/en-US\/MPL/i
25
33
  return ['mpl-2.0', 1.0]
26
- when 'http://fairlicense.org'
34
+ when /fairlicense\.org/i
27
35
  return ['fair', 1.0]
28
- when 'http://www.aforgenet.com/framework/license.html'
36
+ when /aforgenet\.com\/framework\/license/i
29
37
  return ['lgpl-3.0', 1.0]
30
- when 'http://www.apache.org/licenses/'
38
+ when /apache\.org\/licenses/i
31
39
  return ['apache-2.0', 1.0]
32
- when 'http://aws.amazon.com/apache2.0/'
40
+ when /aws\.amazon\.com\/apache2\.0/i
33
41
  return ['apache-2.0', 1.0]
34
- when 'http://aws.amazon.com/asl/'
42
+ when /aws\.amazon\.com\/asl/i
35
43
  return ['amazon', 1.0]
36
- when 'https://choosealicense.com/no-license/'
44
+ when /choosealicense\.com\/no-license/i
37
45
  return ['no-license', 1.0]
38
- when 'http://www.gzip.org/zlib/zlib_license.html'
46
+ when /gzip\.org\/zlib\/zlib?license/i
39
47
  return ['zlib', 1.0]
40
- when 'http://zlib.net/zlib-license.html'
48
+ when /zlib\.net\/zlib?license/i
41
49
  return ['zlib', 1.0]
42
- when 'http://www.wtfpl.net/about/'
50
+ when /wtfpl\.net\/about/i
43
51
  return ['wtfpl', 1.0]
44
52
  end
45
53
 
@@ -1,9 +1,21 @@
1
+ require 'os'
1
2
  require "helix_runtime"
2
3
 
3
- begin
4
+
5
+ if OS.mac?
6
+ begin
4
7
  require "license_matcher/native"
5
- rescue LoadError
6
- warn "Unable to load license_matcher/native. Please run `rake build`"
8
+ rescue LoadError
9
+ warn "Failed to load native extensions for OSx. Please run `rake build`"
10
+ end
11
+ elsif OS.posix?
12
+ begin
13
+ require "license_matcher/native.so"
14
+ rescue LoadError
15
+ warn "Failed to load native extensions for Posix. Please run `rake build`"
16
+ end
17
+ else
18
+ warn "Unsupported platform - you are not able to use some models;"
7
19
  end
8
20
 
9
21
  require 'license_matcher/preprocess'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: license_matcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Timo Sulg
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-09-27 00:00:00.000000000 Z
12
+ date: 2017-09-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: helix_runtime
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: 0.6.0
20
+ version: '0.6'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: 0.6.0
27
+ version: '0.6'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: narray
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -45,84 +45,98 @@ dependencies:
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: 0.1.6
48
+ version: '0.1'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: 0.1.6
55
+ version: '0.1'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: nokogiri
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: 1.8.0
62
+ version: '1.8'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: 1.8.0
69
+ version: '1.8'
70
70
  - !ruby/object:Gem::Dependency
71
- name: bundler
71
+ name: msgpack
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '1.15'
77
- type: :development
76
+ version: '1.1'
77
+ type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '1.15'
83
+ version: '1.1'
84
84
  - !ruby/object:Gem::Dependency
85
- name: rake
85
+ name: os
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: '10.0'
90
+ version: '1.0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: bundler
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '1.15'
91
105
  type: :development
92
106
  prerelease: false
93
107
  version_requirements: !ruby/object:Gem::Requirement
94
108
  requirements:
95
109
  - - "~>"
96
110
  - !ruby/object:Gem::Version
97
- version: '10.0'
111
+ version: '1.15'
98
112
  - !ruby/object:Gem::Dependency
99
- name: rspec
113
+ name: rake
100
114
  requirement: !ruby/object:Gem::Requirement
101
115
  requirements:
102
116
  - - "~>"
103
117
  - !ruby/object:Gem::Version
104
- version: '3.4'
118
+ version: '10.0'
105
119
  type: :development
106
120
  prerelease: false
107
121
  version_requirements: !ruby/object:Gem::Requirement
108
122
  requirements:
109
123
  - - "~>"
110
124
  - !ruby/object:Gem::Version
111
- version: '3.4'
125
+ version: '10.0'
112
126
  - !ruby/object:Gem::Dependency
113
- name: msgpack
127
+ name: rspec
114
128
  requirement: !ruby/object:Gem::Requirement
115
129
  requirements:
116
130
  - - "~>"
117
131
  - !ruby/object:Gem::Version
118
- version: 1.1.0
132
+ version: '3.4'
119
133
  type: :development
120
134
  prerelease: false
121
135
  version_requirements: !ruby/object:Gem::Requirement
122
136
  requirements:
123
137
  - - "~>"
124
138
  - !ruby/object:Gem::Version
125
- version: 1.1.0
139
+ version: '3.4'
126
140
  description: "\n LicenseMatcher is rubygem, which uses Fosslim to match various
127
141
  OSS license\n with correct SPDX-id or EULA label.\n "
128
142
  email:
@@ -142,6 +156,7 @@ files:
142
156
  - Rakefile
143
157
  - lib/license_matcher.rb
144
158
  - lib/license_matcher/native.bundle
159
+ - lib/license_matcher/native.so
145
160
  - lib/license_matcher/preprocess.rb
146
161
  - lib/license_matcher/rule_matcher.rb
147
162
  - lib/license_matcher/tf_ruby_matcher.rb