spdx file matcher

This commit is contained in:
Mike Linksvayer 2017-11-22 16:13:16 -08:00
parent 00489bb3bf
commit c310aed48d
7 changed files with 71 additions and 11 deletions

View File

@ -11,5 +11,6 @@ module Licensee
autoload :NpmBower, 'licensee/matchers/npm_bower'
autoload :Package, 'licensee/matchers/package'
autoload :Reference, 'licensee/matchers/reference'
autoload :Spdx, 'licensee/matchers/spdx'
end
end

View File

@ -0,0 +1,16 @@
module Licensee
module Matchers
class Spdx < Licensee::Matchers::Package
# While we could parse the LICENSE.spdx file, prefer
# a lenient regex for speed and security. Moar parsing moar problems.
LICENSE_REGEX = /PackageLicenseDeclared:\s*([a-z\-0-9\. +()]+)\s*/i
private
def license_property
match = @file.content.match LICENSE_REGEX
match[1].downcase if match && match[1]
end
end
end
end

View File

@ -7,8 +7,8 @@ module Licensee
PREFERRED_EXT = %w[md markdown txt].freeze
PREFERRED_EXT_REGEX = /\.#{Regexp.union(PREFERRED_EXT)}\z/
# Regex to match any extension
ANY_EXT_REGEX = %r{\.[^./]+\z}
# Regex to match any extension except .spdx
NONSPDX_EXT_REGEX = %r{\.(?!spdx)[^./]+\z}
# Regex to match, LICENSE, LICENCE, unlicense, etc.
LICENSE_REGEX = /(un)?licen[sc]e/i
@ -28,17 +28,17 @@ module Licensee
/\A#{LICENSE_REGEX}#{PREFERRED_EXT_REGEX}\z/ => 0.95, # LICENSE.md
/\A#{COPYING_REGEX}\z/ => 0.90, # COPYING
/\A#{COPYING_REGEX}#{PREFERRED_EXT_REGEX}\z/ => 0.85, # COPYING.md
/\A#{LICENSE_REGEX}#{ANY_EXT_REGEX}\z/ => 0.80, # LICENSE.textile
/\A#{COPYING_REGEX}#{ANY_EXT_REGEX}\z/ => 0.75, # COPYING.textile
/\A#{LICENSE_REGEX}#{NONSPDX_EXT_REGEX}\z/ => 0.80, # LICENSE.textile
/\A#{COPYING_REGEX}#{NONSPDX_EXT_REGEX}\z/ => 0.75, # COPYING.textile
/\A#{LICENSE_REGEX}[-_]/ => 0.70, # LICENSE-MIT
/\A#{COPYING_REGEX}[-_]/ => 0.65, # COPYING-MIT
/[-_]#{LICENSE_REGEX}/ => 0.60, # MIT-LICENSE-MIT
/[-_]#{COPYING_REGEX}/ => 0.55, # MIT-COPYING
/\A#{OFL_REGEX}#{PREFERRED_EXT_REGEX}/ => 0.50, # OFL.md
/\A#{OFL_REGEX}#{ANY_EXT_REGEX}/ => 0.45, # OFL.textile
/\A#{OFL_REGEX}#{NONSPDX_EXT_REGEX}/ => 0.45, # OFL.textile
/\A#{OFL_REGEX}\z/ => 0.40, # OFL
/\A#{PATENTS_REGEX}\z/ => 0.35, # PATENTS
/\A#{PATENTS_REGEX}#{ANY_EXT_REGEX}\z/ => 0.30, # PATENTS.txt
/\A#{PATENTS_REGEX}#{NONSPDX_EXT_REGEX}\z/ => 0.30, # PATENTS.txt
// => 0.00 # Catch all
}.freeze

View File

@ -10,8 +10,9 @@ module Licensee
# Hash of Filename => [possible matchers]
FILENAMES_EXTENSIONS = {
'DESCRIPTION' => [Matchers::Cran],
'dist.ini' => [Matchers::DistZilla]
'DESCRIPTION' => [Matchers::Cran],
'dist.ini' => [Matchers::DistZilla],
'LICENSE.spdx' => [Matchers::Spdx]
}.freeze
def possible_matchers
@ -21,6 +22,7 @@ module Licensee
def self.name_score(filename)
return 1.0 if ['.gemspec', '.cabal'].include?(File.extname(filename))
return 1.0 if filename == 'package.json'
return 1.0 if filename == 'LICENSE.spdx'
return 0.8 if filename == 'dist.ini'
return 0.9 if filename == 'DESCRIPTION'
return 0.75 if filename == 'bower.json'

View File

@ -66,7 +66,7 @@ module Licensee
def copyright?
return false unless is_a?(LicenseFile)
return false unless matcher.is_a?(Matchers::Copyright)
filename =~ /\Acopyright(?:#{LicenseFile::ANY_EXT_REGEX})?\z/i
filename =~ /\Acopyright(?:#{LicenseFile::NONSPDX_EXT_REGEX})?\z/i
end
end
end

View File

@ -0,0 +1,41 @@
RSpec.describe Licensee::Matchers::Spdx do
let(:content) { 'PackageLicenseDeclared: MIT' }
let(:file) do
Licensee::ProjectFiles::LicenseFile.new(content, 'LICENSE.spdx')
end
let(:mit) { Licensee::License.find('mit') }
let(:other) { Licensee::License.find('other') }
subject { described_class.new(file) }
it 'matches' do
expect(subject.match).to eql(mit)
end
it 'has a confidence' do
expect(subject.confidence).to eql(90)
end
context 'no license field' do
let(:content) { 'foo: bar' }
it 'returns nil' do
expect(subject.match).to be_nil
end
end
context 'an unknown license' do
let(:content) { 'PackageLicenseDeclared: xyz' }
it 'returns other' do
expect(subject.match).to eql(other)
end
end
context 'a license expression' do
let(:content) { 'PackageLicenseDeclared: (MIT OR Apache-2.0)' }
it 'returns other' do
expect(subject.match).to eql(other)
end
end
end

View File

@ -109,11 +109,11 @@ RSpec.describe Licensee::ProjectFiles::LicenseFile do
context 'any extension regex' do
it 'matches .foo' do
expect(described_class::ANY_EXT_REGEX).to match('.foo')
expect(described_class::NONSPDX_EXT_REGEX).to match('.foo')
end
it 'does not match .md/foo' do
expect(described_class::ANY_EXT_REGEX).to_not match('.md/foo')
expect(described_class::NONSPDX_EXT_REGEX).to_not match('.md/foo')
end
end