diff --git a/lib/omnibus.rb b/lib/omnibus.rb index 2bfef912b3bf6e201c711a81e1bc7756e31fbced..680e102db6a9b43e77c8cc2ba47fe00732014de0 100644 --- a/lib/omnibus.rb +++ b/lib/omnibus.rb @@ -81,6 +81,8 @@ module Omnibus autoload :SemanticVersion, 'omnibus/semantic_version' + autoload :DependencyInformation, 'omnibus/dependency_information' + module Command autoload :Base, 'omnibus/cli/base' autoload :Cache, 'omnibus/cli/cache' diff --git a/lib/omnibus/dependency_information.rb b/lib/omnibus/dependency_information.rb new file mode 100644 index 0000000000000000000000000000000000000000..34644f5de0e505ec40397790eca64301a34d0332 --- /dev/null +++ b/lib/omnibus/dependency_information.rb @@ -0,0 +1,52 @@ +require 'json' + +module Omnibus + class DependencyInformation + + JSON_FILE = "dependency_licenses.json".freeze + + class << self + def process!(project) + new(project).process! + end + end + + attr_reader :project + + def initialize(project) + @project = project + end + + def json_location + File.expand_path(JSON_FILE, project.install_dir) + end + + def process! + csv_output = "" + output = {} + + project.library.each do |component| + csv_output += "#{component.name},#{component.version},#{component.license}\n" + end + + # Concatenating contents of CSV files from individual components with the + # one generate above. + csv_dir = File.expand_path("licenses", project.install_dir) + Dir.glob(File.expand_path("*.csv", csv_dir)).each do |csv_file| + csv_output += File.open(csv_file).read + "\n" + end + FileUtils.rm_rf(csv_dir) + + # Creating JSON output + csv_output.each_line do |line| + line = line.strip + next if line.empty? + components = line.split(",") + output[components[0]] = {"version": components[1], "license": components[2]} + end + File.open(json_location, "w") do |f| + f.write(JSON.pretty_generate(output)) + end + end + end +end diff --git a/lib/omnibus/project.rb b/lib/omnibus/project.rb index 251fef8bcaf222f549007c2ec6cf9c73096cfd10..3bb99fbab7aaa53100c52dc0a1d3b9964f50e0f9 100644 --- a/lib/omnibus/project.rb +++ b/lib/omnibus/project.rb @@ -1088,6 +1088,7 @@ module Omnibus write_json_manifest write_text_manifest Licensing.create!(self) + DependencyInformation.process!(self) HealthCheck.run!(self) package_me compress_me diff --git a/spec/functional/dependency_information_spec.rb b/spec/functional/dependency_information_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..5227062ae3d8cb8f2ac6b1765ef66c4f2c461a54 --- /dev/null +++ b/spec/functional/dependency_information_spec.rb @@ -0,0 +1,134 @@ +require "spec_helper" +require "json" + +module Omnibus + describe DependencyInformation do + + let(:install_dir) { File.join(tmp_path, "install_dir")} + let(:output_location) { File.join(install_dir, "dependency_licenses.json") } + + let(:project) do + Project.new.tap do |project| + project.name('test-project') + project.install_dir(install_dir) + end + end + + let(:private_code) do + Software.new(project, 'private_code.rb').evaluate do + name 'private_code' + default_version '1.7.2' + end + end + + let(:zlib) do + Software.new(project, 'zlib.rb').evaluate do + name 'zlib' + default_version '1.7.2' + license "Zlib" + license_file "LICENSE" + end + end + + let(:snoopy) do + Software.new(project, 'snoopy.rb').evaluate do + name 'snoopy' + default_version '1.0.0' + license "GPL v2" + license_file "http://dev.perl.org/licenses/artistic.html" + license_file "NOTICE" + end + end + + before do + FileUtils.mkdir_p(install_dir) + + end + + def generate_information + project.library.component_added(snoopy) + project.library.component_added(zlib) + project.library.component_added(private_code) + + DependencyInformation.process!(project) + end + + describe "without explicit csv files" do + + it "creates depdendency_licenses.json file" do + generate_information + expect(File).to exist(output_location) + end + + it "dependency_licenses.json file has correct contents" do + content = { + "snoopy": { + "version": "1.0.0", + "license": "GPL v2" + }, + "zlib": { + "version": "1.7.2", + "license": "Zlib" + }, + "private_code": { + "version": "1.7.2", + "license": "Unspecified" + } + } + generate_information + json_output = JSON.parse(File.open(output_location).read, :symbolize_names => true) + expect(json_output).to eq(content) + end + end + + describe "with explicit csv files" do + let(:csv_file) { double(File, read: "RedCloth,4.3.2,MIT\nyauzl,2.4.1,MIT\nyargs-parser,4.2.1,ISC") } + let(:csv_file2) { double(File, read: "virtus,1.0.5,MIT\nyauzl,2.4.1,MIT") } + + it "creates depdendency_licenses.json file" do + generate_information + expect(File).to exist(output_location) + end + + it "dependency_licenses.json file has contents from csv files also" do + allow(Dir).to receive(:glob).and_return(["gitlab-rails.csv", "some-other-dependency.csv"]) + allow(File).to receive(:open).and_call_original + allow(File).to receive(:open).with("gitlab-rails.csv").and_return(csv_file) + allow(File).to receive(:open).with("some-other-dependency.csv").and_return(csv_file2) + content = { + "snoopy": { + "version": "1.0.0", + "license": "GPL v2" + }, + "zlib": { + "version": "1.7.2", + "license": "Zlib" + }, + "private_code": { + "version": "1.7.2", + "license": "Unspecified" + }, + "RedCloth": { + "version": "4.3.2", + "license": "MIT" + }, + "yauzl": { + "version": "2.4.1", + "license": "MIT" + }, + "yargs-parser": { + "version": "4.2.1", + "license": "ISC" + }, + "virtus": { + "version": "1.0.5", + "license": "MIT" + } + } + generate_information + json_output = JSON.parse(File.open(output_location).read, :symbolize_names => true) + expect(json_output).to eq(content) + end + end + end +end