mirror of https://github.com/licensee/licensee.git
Merge pull request #113 from benbalter/lgpl
Special case LICENSE.lesser to handle LGPL implementation instructions
This commit is contained in:
commit
62b37a8b43
|
@ -111,6 +111,10 @@ module Licensee
|
|||
meta['hidden']
|
||||
end
|
||||
|
||||
def gpl?
|
||||
key == 'gpl-2.0' || key == 'gpl-3.0'
|
||||
end
|
||||
|
||||
# The license body (e.g., contents - frontmatter)
|
||||
def content
|
||||
@content ||= parts[2] if parts && parts[2]
|
||||
|
|
|
@ -23,8 +23,16 @@ module Licensee
|
|||
def license_file
|
||||
return @license_file if defined? @license_file
|
||||
@license_file = begin
|
||||
content, name = find_file { |n| LicenseFile.name_score(n) }
|
||||
LicenseFile.new(content, name) if content && name
|
||||
license_file = license_from_file { |n| LicenseFile.name_score(n) }
|
||||
return license_file unless license_file && license_file.license
|
||||
|
||||
# Special case LGPL, which actuall lives in LICENSE.lesser, per the
|
||||
# license instructions. See https://git.io/viwyK
|
||||
lesser = if license_file.license.gpl?
|
||||
license_from_file { |file| LicenseFile.lesser_gpl_score(file) }
|
||||
end
|
||||
|
||||
lesser || license_file
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -46,5 +54,31 @@ module Licensee
|
|||
PackageInfo.new(content, name) if content && name
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Given a block, passes each filename to that block, and expects a numeric
|
||||
# score in response. Returns an array of all files with a score > 0,
|
||||
# sorted by file score descending
|
||||
def find_files
|
||||
return [] if files.empty? || files.nil?
|
||||
found = files.each { |file| file[:score] = yield(file[:name]) }
|
||||
found.select! { |file| file[:score] > 0 }
|
||||
found.sort { |a, b| b[:score] <=> a[:score] }
|
||||
end
|
||||
|
||||
# Given a block, passes each filename to that block, and expects a numeric
|
||||
# score in response. Returns a hash representing the top scoring file
|
||||
# or nil, if no file scored > 0
|
||||
def find_file(&block)
|
||||
return if files.empty? || files.nil?
|
||||
file = find_files(&block).first
|
||||
[load_file(file), file[:name]] if file
|
||||
end
|
||||
|
||||
def license_from_file(&block)
|
||||
content, name = find_file(&block)
|
||||
LicenseFile.new(content, name) if content && name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,6 +20,11 @@ module Licensee
|
|||
return 0.5 if filename =~ /licen[sc]e/i
|
||||
0.0
|
||||
end
|
||||
|
||||
# case-insensitive block to determine if the given file is LICENSE.lesser
|
||||
def self.lesser_gpl_score(filename)
|
||||
filename.casecmp('copying.lesser').zero? ? 1 : 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,9 @@ module Licensee
|
|||
|
||||
private
|
||||
|
||||
def find_file
|
||||
# Returns an array of hashes representing the project's files.
|
||||
# Hashes will have the :name key, with the relative path to the file
|
||||
def files
|
||||
files = []
|
||||
|
||||
if ::File.file?(path)
|
||||
|
@ -24,17 +26,20 @@ module Licensee
|
|||
|
||||
Dir.glob(::File.join(path, pattern)) do |file|
|
||||
next unless ::File.file?(file)
|
||||
file = ::File.basename(file)
|
||||
if (score = yield file) > 0
|
||||
files.push(name: file, score: score)
|
||||
end
|
||||
files.push(name: ::File.basename(file))
|
||||
end
|
||||
|
||||
return if files.empty?
|
||||
files.sort! { |a, b| b[:score] <=> a[:score] }
|
||||
files
|
||||
end
|
||||
|
||||
f = files.first
|
||||
[::File.read(::File.join(path, f[:name])), f[:name]]
|
||||
# Retrieve a file's content from disk
|
||||
#
|
||||
# file - the file hash, with the :name key as the file's relative path
|
||||
# path - the base path to the project
|
||||
#
|
||||
# Returns the fiel contents as a string
|
||||
def load_file(file)
|
||||
::File.read(::File.join(path, file[:name]))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,24 +36,25 @@ module Licensee
|
|||
|
||||
MAX_LICENSE_SIZE = 64 * 1024
|
||||
|
||||
def load_blob_data(oid)
|
||||
data, = Rugged::Blob.to_buffer(repository, oid, MAX_LICENSE_SIZE)
|
||||
# Retrieve a file's content from the Git database
|
||||
#
|
||||
# file - the file hash, including the file's OID
|
||||
#
|
||||
# Returns a string representing the file's contents
|
||||
def load_file(file)
|
||||
data, = Rugged::Blob.to_buffer(repository, file[:oid], MAX_LICENSE_SIZE)
|
||||
data
|
||||
end
|
||||
|
||||
def find_file
|
||||
files = commit.tree.map do |entry|
|
||||
# Returns an array of hashes representing the project's files.
|
||||
# Hashes will have the the following keys:
|
||||
# :name - the file's path relative to the repo root
|
||||
# :oid - the file's OID
|
||||
def files
|
||||
commit.tree.map do |entry|
|
||||
next unless entry[:type] == :blob
|
||||
if (score = yield entry[:name]) > 0
|
||||
{ name: entry[:name], oid: entry[:oid], score: score }
|
||||
end
|
||||
{ name: entry[:name], oid: entry[:oid] }
|
||||
end.compact
|
||||
|
||||
return if files.empty?
|
||||
files.sort! { |a, b| b[:score] <=> a[:score] }
|
||||
|
||||
f = files.first
|
||||
[load_blob_data(f[:oid]), f[:name]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ref: refs/heads/master
|
|
@ -0,0 +1,5 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = true
|
||||
ignorecase = true
|
|
@ -0,0 +1,2 @@
|
|||
x<01>ŽQjÃ0DûSìb${åHPJñMVë‘c°å`+…Ü>Né ú7oà
£ÛºÎ•ZŽuHX³p›4À<34>ܵY‚wê•Ñå6r¶Öç±3wÙQ*qr9uˆ>õ#<23>›¬¸Þfï9!^á%CaäQoÛN
|
||||
²Tìô™Pšô›¿§¹Þ©Ñmý"Ç×.„>„HËÖš³=?¾•ÿØfý¡eV”Í‚ã8gt»?ç2ý¡yÊ5Q}
|
|
@ -0,0 +1,2 @@
|
|||
x<01><>[
|
||||
Â0EýÎ*f–ÉC“BéNfš‰
4
„tÿVÝ<56>‡çž¥–’;è`/½‰@ŒµgÍÉŽFº¹dÅhFòBAXÐ*:úZ̲ÃL[—Ë>𗟯Ü׃‡¥–hçmÎß\Ñ!ªs=›å[å=÷LünÔ7®<<3C>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
1acd060ebbbeac294200008657d9502130f93465
|
|
@ -55,4 +55,19 @@ class TestLicenseeLicenseFile < Minitest::Test
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'LGPL scoring' do
|
||||
{
|
||||
'COPYING.lesser' => 1,
|
||||
'copying.lesser' => 1,
|
||||
'license.lesser' => 0,
|
||||
'LICENSE.md' => 0,
|
||||
'FOO.md' => 0
|
||||
}.each do |filename, expected|
|
||||
should "score a license named `#{filename}` as `#{expected}`" do
|
||||
score = Licensee::Project::LicenseFile.lesser_gpl_score(filename)
|
||||
assert_equal expected, score
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -117,6 +117,17 @@ class TestLicenseeLicense < Minitest::Test
|
|||
assert_equal '750260c322080bab4c19fd55eb78bc73e1ae8f11', @license.hash
|
||||
end
|
||||
|
||||
should "recognize GPL'd licenses" do
|
||||
license = Licensee::License.new 'gpl-2.0'
|
||||
assert license.gpl?
|
||||
|
||||
license = Licensee::License.new 'gpl-3.0'
|
||||
assert license.gpl?
|
||||
|
||||
license = Licensee::License.new 'mit'
|
||||
refute license.gpl?
|
||||
end
|
||||
|
||||
describe 'name without version' do
|
||||
should 'strip the version from the license name' do
|
||||
expected = 'GNU Affero General Public License'
|
||||
|
|
|
@ -72,6 +72,11 @@ class TestLicenseeProject < Minitest::Test
|
|||
project = make_project 'no-license.git'
|
||||
assert_equal nil, project.license
|
||||
end
|
||||
|
||||
should 'detect an LGPL licensed project with LICENSE.lesser' do
|
||||
project = make_project 'lgpl.git'
|
||||
assert_equal 'lgpl-3.0', project.license.key
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue