lib/licensed/dependency_record.rb (66 lines of code) (raw):
# frozen_string_literal: true
require "fileutils"
require "forwardable"
require "licensee"
module Licensed
class DependencyRecord
class Error < StandardError; end
class License
attr_reader :text, :sources
def initialize(content)
@sources = []
if content.is_a?(String)
@text = content.to_s
elsif content.respond_to?(:[])
@sources.concat content["sources"].to_s.split(", ")
@text = content["text"]
end
end
def to_cache
return text if sources.empty?
{
"sources" => sources.join(", "),
"text" => text
}
end
end
include Licensee::ContentHelper
extend Forwardable
EXTENSION = "dep.yml".freeze
# Read an existing record file
#
# filename - A String path to the file
#
# Returns a Licensed::DependencyRecord
def self.read(filename)
return unless File.exist?(filename)
data = YAML.load_file(filename)
return if data.nil? || data.empty?
new(
licenses: data.delete("licenses"),
notices: data.delete("notices"),
metadata: data
)
rescue Psych::SyntaxError => e
raise Licensed::DependencyRecord::Error.new(e.message)
end
def_delegators :@metadata, :[], :[]=
attr_reader :licenses
attr_reader :notices
# Construct a new record
#
# licenses - a string, or array of strings, representing the content of each license
# notices - a string, or array of strings, representing the content of each legal notice
# metadata - a Hash of the metadata for the package
def initialize(licenses: [], notices: [], metadata: {})
@licenses = [licenses].flatten.compact.map { |l| DependencyRecord::License.new(l) }
@notices = [notices].flatten.compact
@metadata = metadata
end
# Save the metadata and text to a file
#
# filename - The destination file to save record contents at
def save(filename)
data_to_save = @metadata.merge({
"licenses" => licenses.map(&:to_cache),
"notices" => notices
})
FileUtils.mkdir_p(File.dirname(filename))
File.write(filename, data_to_save.to_yaml)
end
# Returns the content used to compare two licenses using normalization from
# `Licensee::CotentHelper`
def content
return if licenses.nil? || licenses.empty?
licenses.map(&:text).compact.join
end
# Returns whether two records match based on their contents
def matches?(other)
return false unless other.is_a?(DependencyRecord)
self.content_normalized == other.content_normalized
end
end
end