Add support for filesystem-based projects

This commit is contained in:
Vicent Marti 2015-09-24 11:46:19 -07:00
parent 91b7a0f63f
commit aca09c73cc
5 changed files with 79 additions and 32 deletions

View File

@ -3,7 +3,7 @@ require_relative "../lib/licensee"
path = ARGV[0] || Dir.pwd
project = Licensee::Project.new(path, detect_packages: true)
project = Licensee::GitProject.new(path, detect_packages: true)
file = project.matched_file
if project.license_file

View File

@ -26,9 +26,13 @@ class Licensee
Licensee::License.all(options)
end
# Returns the license for a given git repo
# Returns the license for a given path
def license(path)
Licensee::Project.new(path).license
begin
Licensee::GitProject.new(path).license
rescue Licensee::GitProject::InvalidRepository
Licensee::FSProject.new(path).license
end
end
def confidence_threshold

View File

@ -1,23 +1,9 @@
require 'rugged'
class Licensee
private
class Project
MAX_LICENSE_SIZE = 64 * 1024
attr_reader :repository, :revision
# Initializes a new project
#
# path_or_repo path to git repo or Rugged::Repository instance
# revsion - revision ref, if any
def initialize(repo, revision: nil, detect_packages: false)
if repo.kind_of? Rugged::Repository
@repository = repo
else
@repository = Rugged::Repository.new(repo)
end
@revision = revision
def initialize(detect_packages)
@detect_packages = detect_packages
end
@ -37,9 +23,9 @@ class Licensee
def license_file
return @license_file if defined? @license_file
@license_file = begin
if file = find_blob { |name| LicenseFile.name_score(name) }
data = load_blob_data(file[:oid])
LicenseFile.new(data, file[:name])
content, name = find_file { |name| LicenseFile.name_score(name) }
if content && name
LicenseFile.new(content, name)
end
end
end
@ -48,30 +34,88 @@ class Licensee
return unless detect_packages?
return @package_file if defined? @package_file
@package_file = begin
if file = find_blob { |name| PackageInfo.name_score(name) }
data = load_blob_data(file[:oid])
PackageInfo.new(data, file[:name])
content, name = find_file { |name| PackageInfo.name_score(name) }
if content && name
PackageInfo.new(content, name)
end
end
end
end
public
# Git-based project
#
# analyze a given git repository for license information
class GitProject < Project
attr_reader :repository, :revision
class InvalidRepository < ArgumentError; end
def initialize(repo, revision: nil, detect_packages: false)
if repo.kind_of? Rugged::Repository
@repository = repo
else
@repository = Rugged::Repository.new(repo)
end
@revision = revision
super(detect_packages)
rescue Rugged::RepositoryError
raise InvalidRepository
end
private
def commit
@commit ||= revision ? repository.lookup(revision) : repository.last_commit
end
MAX_LICENSE_SIZE = 64 * 1024
def load_blob_data(oid)
data, _ = Rugged::Blob.to_buffer(repository, oid, MAX_LICENSE_SIZE)
data
end
def find_blob
commit.tree.map do |entry|
def find_file
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
end.compact.sort { |a, b| b[:score] <=> a[:score] }.first
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
# Filesystem-based project
#
# Analyze a folder on the filesystem for license information
class FSProject < Project
def initialize(path, detect_packages: false)
@path = path
super(detect_packages)
end
private
def find_file
files = Dir.foreach(path) do |file|
next unless ::File.file?(::File.join(path, file))
if (score = yield file) > 0
{ :name => file, :score => score }
end
end.compact
return if files.empty?
files.sort! { |a, b| b[:score] <=> a[:score] }
f = files.first
[::File.read(::File.join(path, f[:name])), f[:name]]
end
end
end

View File

@ -3,7 +3,7 @@ require 'helper'
class TestLicenseeGemspecMatchers < Minitest::Test
should "detect its own license" do
root = File.expand_path "../", File.dirname(__FILE__)
project = Licensee::Project.new(root, detect_packages: true)
project = Licensee::GitProject.new(root, detect_packages: true)
matcher = Licensee::Matchers::Gemspec.new(project.package_file)
assert_equal "mit", matcher.send(:license_property)
assert_equal "mit", matcher.match.key

View File

@ -5,7 +5,7 @@ class TestLicenseeProject < Minitest::Test
describe("git repository project") do
def make_project(fixture_name)
fixture = fixture_path fixture_name
Licensee::Project.new fixture
Licensee::GitProject.new(fixture)
end
should "detect the license file" do
@ -59,10 +59,9 @@ class TestLicenseeProject < Minitest::Test
end
end
describe "packages" do
should "detect a package file" do
project = Licensee::Project.new(fixture_path("npm.git"), detect_packages: true)
project = Licensee::GitProject.new(fixture_path("npm.git"), detect_packages: true)
assert_equal "package.json", project.package_file.filename
assert_equal "mit", project.license.key
end