require 'rugged' module Licensee class Project attr_reader :detect_readme, :detect_packages alias detect_readme? detect_readme alias detect_packages? detect_packages def initialize(detect_packages: false, detect_readme: false) @detect_packages = detect_packages @detect_readme = detect_readme end # Returns the matching License instance if a license can be detected def license @license ||= matched_file && matched_file.license end def matched_file @matched_file ||= begin [license_file, readme, package_file].compact.find(&:license) end end def license_file return @license_file if defined? @license_file @license_file = begin license_file = license_from_file { |n| LicenseFile.name_score(n) } return license_file unless license_file && license_file.license # Special case LGPL, which actually 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 def readme_file return unless detect_readme? return @readme if defined? @readme @readme = begin content, name = find_file { |n| Readme.name_score(n) } content = Readme.license_content(content) Readme.new(content, name) if content && name end end alias readme readme_file def package_file return unless detect_packages? return @package_file if defined? @package_file @package_file = begin content, name = find_file { |n| PackageInfo.name_score(n) } 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