From d57e616015f96681f8c3cf2ce36bdd85a24e2163 Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 15 Aug 2019 10:54:48 -0600 Subject: insert shim to generate report via ruby API --- lib/license/management.rb | 20 +++++++++ lib/license/management/json_report.rb | 28 +++++++++++++ lib/license/management/loggable.rb | 15 +++++++ lib/license/management/repository.rb | 46 +++++++++++++++++++++ lib/license/management/verifiable.rb | 15 +++++++ lib/license/management/version.rb | 7 ++++ lib/license/management/versions/base.rb | 34 ++++++++++++++++ lib/license/management/versions/v1.rb | 72 +++++++++++++++++++++++++++++++++ 8 files changed, 237 insertions(+) create mode 100644 lib/license/management.rb create mode 100644 lib/license/management/json_report.rb create mode 100644 lib/license/management/loggable.rb create mode 100644 lib/license/management/repository.rb create mode 100644 lib/license/management/verifiable.rb create mode 100644 lib/license/management/version.rb create mode 100644 lib/license/management/versions/base.rb create mode 100644 lib/license/management/versions/v1.rb (limited to 'lib') diff --git a/lib/license/management.rb b/lib/license/management.rb new file mode 100644 index 0000000..3b41843 --- /dev/null +++ b/lib/license/management.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'pathname' +require 'yaml' +require 'license_finder' +require 'license/management/loggable' +require 'license/management/verifiable' +require 'license/management/repository' +require 'license/management/versions/base' +require 'license/management/versions/v1' +require 'license/management/json_report' +require 'license/management/version' + +module License + module Management + def self.root + Pathname.new(File.dirname(__FILE__)).join('../..') + end + end +end diff --git a/lib/license/management/json_report.rb b/lib/license/management/json_report.rb new file mode 100644 index 0000000..19a44c4 --- /dev/null +++ b/lib/license/management/json_report.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +# This is a monkey patch of the JsonReport found in `license_finder` +module LicenseFinder + class JsonReport < CsvReport + DEFAULT_VERSION = '1' + VERSIONS = { + nil => ::License::Management::Versions::V1, + '' => ::License::Management::Versions::V1, + '1' => ::License::Management::Versions::V1, + '1.0' => ::License::Management::Versions::V1 + }.freeze + + def to_s + JSON.pretty_generate(version_for(report_version).to_h) + "\n" + end + + private + + def report_version + ENV.fetch('LM_REPORT_VERSION', DEFAULT_VERSION) + end + + def version_for(version) + VERSIONS.fetch(version.to_s).new(dependencies) + end + end +end diff --git a/lib/license/management/loggable.rb b/lib/license/management/loggable.rb new file mode 100644 index 0000000..a44d45d --- /dev/null +++ b/lib/license/management/loggable.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module License + module Management + module Loggable + def logger + ::LicenseFinder::Core.default_logger + end + + def log_info(message) + logger.info(self.class, message) + end + end + end +end diff --git a/lib/license/management/repository.rb b/lib/license/management/repository.rb new file mode 100644 index 0000000..707d9f0 --- /dev/null +++ b/lib/license/management/repository.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module License + module Management + class Repository + include Loggable + include Verifiable + + def initialize( + compatibility_path: License::Management.root.join('licenses.yml') + ) + @compatibility_data = YAML.safe_load(IO.read(compatibility_path)) + end + + def item_for(license) + id = id_for(license) + item = id ? compatibility_data['items'][id] : nil + item ? { 'id' => id }.merge(item) : generate_item_for(license) + end + + private + + attr_reader :compatibility_data + + def id_for(license) + ids = compatibility_data['ids'] + ids[license.send(:short_name)] || ids[license.url] + end + + def take_first_line_from(content) + return '' if blank?(content) + + content.split(/[\r\n]+/)[0] + end + + def generate_item_for(license) + log_info("detected unknown license named `#{license.send(:short_name)}`") + { + 'id' => 'unknown', + 'name' => take_first_line_from(license.name), + 'url' => present?(license.url) ? license.url : '' + } + end + end + end +end diff --git a/lib/license/management/verifiable.rb b/lib/license/management/verifiable.rb new file mode 100644 index 0000000..72667fb --- /dev/null +++ b/lib/license/management/verifiable.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module License + module Management + module Verifiable + def blank?(item) + item.nil? || item.empty? + end + + def present?(item) + !blank?(item) + end + end + end +end diff --git a/lib/license/management/version.rb b/lib/license/management/version.rb new file mode 100644 index 0000000..d679b3f --- /dev/null +++ b/lib/license/management/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module License + module Management + VERSION = '1.6.0' + end +end diff --git a/lib/license/management/versions/base.rb b/lib/license/management/versions/base.rb new file mode 100644 index 0000000..6e30e20 --- /dev/null +++ b/lib/license/management/versions/base.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module License + module Management + module Versions + class Base + include Loggable + include Verifiable + + attr_reader :dependencies, :repository + + def initialize(dependencies) + @dependencies = dependencies + @repository = License::Management::Repository.new + end + + private + + def paths_from(dependency) + return [] unless dependency.respond_to?(:aggregate_paths) + + paths = dependency.aggregate_paths + return [] if blank?(paths) + + paths.map { |x| x.gsub(Dir.pwd, '.') } + end + + def description_for(dependency) + present?(dependency.summary) ? dependency.summary : dependency.description + end + end + end + end +end diff --git a/lib/license/management/versions/v1.rb b/lib/license/management/versions/v1.rb new file mode 100644 index 0000000..d448397 --- /dev/null +++ b/lib/license/management/versions/v1.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module License + module Management + module Versions + class V1 < Base + def to_h + { + licenses: license_summary, + dependencies: formatted_dependencies(dependencies) + } + end + + private + + # when a dependency has multiple licenses, this will join the licenses into a single name + # this defect was backported from the htmltojson version of this script. + def license_summary + dependencies + .map { |x| x.licenses.map { |y| best_name_for(y) }.sort.reverse.join(', ') } + .flatten + .group_by { |name| name } + .map { |(license, items)| { count: items.count, name: license } } + .sort_by { |x| [-x[:count], x[:name]] } + end + + # when a dependency has more than one license + # this method chooses one of the urls. + # to maintain backwards compatibility this bug has been carried forward. + def license_for(dependency) + name = join_license_names(dependency.licenses) + urls = dependency.licenses.map(&:url).reject { |x| blank?(x) }.uniq.sort + log_info("multiple urls detected: #{urls.inspect}") if urls.size > 1 + url = urls[0] || data_for(dependency.licenses.first)['url'] + blank?(url) ? { name: name } : { name: name, url: url } + end + + def join_license_names(licenses) + licenses.map { |x| best_name_for(x) }.join(', ') + end + + def map_from_dependency(dependency) + result = { + license: license_for(dependency), + dependency: { + name: dependency.name, + url: dependency.homepage, + description: description_for(dependency), + pathes: paths_from(dependency) + } + } + result[:dependency].delete(:url) if blank?(dependency.homepage) + result + end + + def formatted_dependencies(dependencies) + dependencies + .sort_by(&:name) + .map { |x| map_from_dependency(x) } + end + + def best_name_for(license) + data_for(license)['name'] + end + + def data_for(license) + repository.item_for(license) + end + end + end + end +end -- cgit v1.2.3 From 97b0618b6a8953343a97036862df3ed977167d72 Mon Sep 17 00:00:00 2001 From: mo khan Date: Mon, 19 Aug 2019 14:55:16 -0600 Subject: Apply changes from https://gitlab.com/gitlab-org/security-products/license-management/merge_requests/50 --- lib/license/management.rb | 3 ++ lib/license/management/json_report.rb | 41 ++++++++++-------- lib/license/management/repository.rb | 7 ++- licenses.yml | 82 ----------------------------------- normalized-licenses.yml | 82 +++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 103 deletions(-) delete mode 100644 licenses.yml create mode 100644 normalized-licenses.yml (limited to 'lib') diff --git a/lib/license/management.rb b/lib/license/management.rb index 3b41843..2fdb6b5 100644 --- a/lib/license/management.rb +++ b/lib/license/management.rb @@ -11,6 +11,9 @@ require 'license/management/versions/v1' require 'license/management/json_report' require 'license/management/version' +# This applies a monkey patch to the JsonReport found in the `license_finder` gem. +LicenseFinder::JsonReport.prepend(License::Management::JsonReport) + module License module Management def self.root diff --git a/lib/license/management/json_report.rb b/lib/license/management/json_report.rb index 19a44c4..fde30ef 100644 --- a/lib/license/management/json_report.rb +++ b/lib/license/management/json_report.rb @@ -1,28 +1,31 @@ # frozen_string_literal: true -# This is a monkey patch of the JsonReport found in `license_finder` -module LicenseFinder - class JsonReport < CsvReport - DEFAULT_VERSION = '1' - VERSIONS = { - nil => ::License::Management::Versions::V1, - '' => ::License::Management::Versions::V1, - '1' => ::License::Management::Versions::V1, - '1.0' => ::License::Management::Versions::V1 - }.freeze +module License + module Management + module JsonReport + DEFAULT_VERSION = '1' + VERSIONS = { + nil => ::License::Management::Versions::V1, + '' => ::License::Management::Versions::V1, + '1' => ::License::Management::Versions::V1, + '1.0' => ::License::Management::Versions::V1 + }.freeze - def to_s - JSON.pretty_generate(version_for(report_version).to_h) + "\n" - end + # This method overrides the method defined in `License::Management::JsonReport` to + # allow us to generate a custom json report. + def to_s + JSON.pretty_generate(version_for(report_version).to_h) + "\n" + end - private + private - def report_version - ENV.fetch('LM_REPORT_VERSION', DEFAULT_VERSION) - end + def report_version + ENV.fetch('LM_REPORT_VERSION', DEFAULT_VERSION) + end - def version_for(version) - VERSIONS.fetch(version.to_s).new(dependencies) + def version_for(version) + VERSIONS.fetch(version.to_s).new(dependencies) + end end end end diff --git a/lib/license/management/repository.rb b/lib/license/management/repository.rb index 707d9f0..2eee1b6 100644 --- a/lib/license/management/repository.rb +++ b/lib/license/management/repository.rb @@ -7,14 +7,14 @@ module License include Verifiable def initialize( - compatibility_path: License::Management.root.join('licenses.yml') + compatibility_path: License::Management.root.join('normalized-licenses.yml') ) @compatibility_data = YAML.safe_load(IO.read(compatibility_path)) end def item_for(license) id = id_for(license) - item = id ? compatibility_data['items'][id] : nil + item = id ? compatibility_data['licenses'][id] : nil item ? { 'id' => id }.merge(item) : generate_item_for(license) end @@ -27,6 +27,9 @@ module License ids[license.send(:short_name)] || ids[license.url] end + # When `license_finder` is unable to determine the license it will use the full + # content of the file as the name of the license. This method shrinks that name + # down to just take the first line of the file. def take_first_line_from(content) return '' if blank?(content) diff --git a/licenses.yml b/licenses.yml deleted file mode 100644 index 8ed24b2..0000000 --- a/licenses.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- -ids: - ASL, version 2: Apache-2.0 - Apache1_1: Apache-1.1 - Apache2: Apache-2.0 - Apache 2.0: Apache-2.0 - BSD: BSD-4-Clause - CC01: CC0-1.0 - EPL1: EPL-1.0 - GPLv2: GPL-2.0 - GPLv3: GPL-3.0 - ISC: ISC - LGPL 2.1: LGPL-2.1 - LGPL, version 2.1: LGPL-2.1 - LGPL2_1: LGPL-2.1 - LGPL: LGPL-3.0-only - MIT: MIT - MPL 1.1: MPL-1.1 - MPL1_1: MPL-1.1 - MPL2: MPL-2.0 - New BSD License: BSD-3-Clause - NewBSD: BSD-3-Clause - Python: Python-2.0 - Ruby: Ruby - SimplifiedBSD: BSD-2-Clause - http://www.apache.org/licenses/LICENSE-2.0: Apache-2.0 - unknown: unknown -items: - GPL-3.0: - name: GPL 3.0 - url: https://www.gnu.org/licenses/gpl-3.0.txt - BSD-2-Clause: - name: Simplified BSD - url: https://opensource.org/licenses/bsd-license - ISC: - name: ISC - url: https://en.wikipedia.org/wiki/ISC_license - Apache-1.1: - name: Apache 1.1 - url: https://www.apache.org/licenses/LICENSE-1.1.txt - MPL-2.0: - name: Mozilla Public License 2.0 - url: https://www.mozilla.org/media/MPL/2.0/index.815ca599c9df.txt - LGPL-3.0-only: - name: LGPL - url: https://www.gnu.org/licenses/lgpl.txt - CC0-1.0: - name: CC0 1.0 - url: https://creativecommons.org/publicdomain/zero/1.0/ - unknown: - name: unknown - url: '' - GPL-2.0: - name: GPL 2.0 - url: https://www.gnu.org/licenses/gpl-2.0.txt - EPL-1.0: - name: EPL 1.0 - url: https://www.eclipse.org/legal/epl-v10.html - Python-2.0: - name: Python Software Foundation License - url: https://hg.python.org/cpython/raw-file/89ce323357db/LICENSE - BSD-3-Clause: - name: New BSD License - url: https://opensource.org/licenses/BSD-3-Clause - MIT: - name: MIT - url: https://opensource.org/licenses/mit-license - LGPL-2.1: - name: LGPL 2.1 - url: https://opensource.org/licenses/LGPL-2.1 - Ruby: - name: Ruby - url: https://www.ruby-lang.org/en/about/license.txt - Apache-2.0: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0.txt - MPL-1.1: - name: MPL 1.1 - url: https://www.mozilla.org/en-US/MPL/1.1/ - BSD-4-Clause: - name: BSD - url: https://en.wikipedia.org/wiki/BSD_licenses#4-clause_license_.28original_.22BSD_License.22.29 diff --git a/normalized-licenses.yml b/normalized-licenses.yml new file mode 100644 index 0000000..e26df4f --- /dev/null +++ b/normalized-licenses.yml @@ -0,0 +1,82 @@ +--- +ids: + ASL, version 2: Apache-2.0 + Apache1_1: Apache-1.1 + Apache2: Apache-2.0 + Apache 2.0: Apache-2.0 + BSD: BSD-4-Clause + CC01: CC0-1.0 + EPL1: EPL-1.0 + GPLv2: GPL-2.0 + GPLv3: GPL-3.0 + ISC: ISC + LGPL 2.1: LGPL-2.1 + LGPL, version 2.1: LGPL-2.1 + LGPL2_1: LGPL-2.1 + LGPL: LGPL-3.0-only + MIT: MIT + MPL 1.1: MPL-1.1 + MPL1_1: MPL-1.1 + MPL2: MPL-2.0 + New BSD License: BSD-3-Clause + NewBSD: BSD-3-Clause + Python: Python-2.0 + Ruby: Ruby + SimplifiedBSD: BSD-2-Clause + http://www.apache.org/licenses/LICENSE-2.0: Apache-2.0 + unknown: unknown +licenses: + GPL-3.0: + name: GPL 3.0 + url: https://www.gnu.org/licenses/gpl-3.0.txt + BSD-2-Clause: + name: Simplified BSD + url: https://opensource.org/licenses/bsd-license + ISC: + name: ISC + url: https://en.wikipedia.org/wiki/ISC_license + Apache-1.1: + name: Apache 1.1 + url: https://www.apache.org/licenses/LICENSE-1.1.txt + MPL-2.0: + name: Mozilla Public License 2.0 + url: https://www.mozilla.org/media/MPL/2.0/index.815ca599c9df.txt + LGPL-3.0-only: + name: LGPL + url: https://www.gnu.org/licenses/lgpl.txt + CC0-1.0: + name: CC0 1.0 + url: https://creativecommons.org/publicdomain/zero/1.0/ + unknown: + name: unknown + url: '' + GPL-2.0: + name: GPL 2.0 + url: https://www.gnu.org/licenses/gpl-2.0.txt + EPL-1.0: + name: EPL 1.0 + url: https://www.eclipse.org/legal/epl-v10.html + Python-2.0: + name: Python Software Foundation License + url: https://hg.python.org/cpython/raw-file/89ce323357db/LICENSE + BSD-3-Clause: + name: New BSD License + url: https://opensource.org/licenses/BSD-3-Clause + MIT: + name: MIT + url: https://opensource.org/licenses/mit-license + LGPL-2.1: + name: LGPL 2.1 + url: https://opensource.org/licenses/LGPL-2.1 + Ruby: + name: Ruby + url: https://www.ruby-lang.org/en/about/license.txt + Apache-2.0: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.txt + MPL-1.1: + name: MPL 1.1 + url: https://www.mozilla.org/en-US/MPL/1.1/ + BSD-4-Clause: + name: BSD + url: https://en.wikipedia.org/wiki/BSD_licenses#4-clause_license_.28original_.22BSD_License.22.29 -- cgit v1.2.3 From ced12c2b14be4db7c05dd5d24df5eb5038d933d2 Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 20 Aug 2019 12:00:37 -0600 Subject: remove unnecessary parentheses --- lib/license/management/versions/v1.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/license/management/versions/v1.rb b/lib/license/management/versions/v1.rb index d448397..abaa1d8 100644 --- a/lib/license/management/versions/v1.rb +++ b/lib/license/management/versions/v1.rb @@ -20,7 +20,7 @@ module License .map { |x| x.licenses.map { |y| best_name_for(y) }.sort.reverse.join(', ') } .flatten .group_by { |name| name } - .map { |(license, items)| { count: items.count, name: license } } + .map { |license, items| { count: items.count, name: license } } .sort_by { |x| [-x[:count], x[:name]] } end -- cgit v1.2.3 From 033e0908666c1b67e9958ee22c2a18459cb2db99 Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 20 Aug 2019 12:03:57 -0600 Subject: replace ternary with hash initialization --- lib/license/management/versions/v1.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/license/management/versions/v1.rb b/lib/license/management/versions/v1.rb index abaa1d8..6eb3f36 100644 --- a/lib/license/management/versions/v1.rb +++ b/lib/license/management/versions/v1.rb @@ -28,11 +28,14 @@ module License # this method chooses one of the urls. # to maintain backwards compatibility this bug has been carried forward. def license_for(dependency) - name = join_license_names(dependency.licenses) + license = { name: join_license_names(dependency.licenses) } + urls = dependency.licenses.map(&:url).reject { |x| blank?(x) }.uniq.sort log_info("multiple urls detected: #{urls.inspect}") if urls.size > 1 url = urls[0] || data_for(dependency.licenses.first)['url'] - blank?(url) ? { name: name } : { name: name, url: url } + + license.merge(url: url) if present?(url) + license end def join_license_names(licenses) -- cgit v1.2.3 From 5100c31f3b8befd24c40a95d957122084f90f08c Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 20 Aug 2019 12:38:13 -0600 Subject: use better intention revealing names --- lib/license/management/versions/v1.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/license/management/versions/v1.rb b/lib/license/management/versions/v1.rb index 6eb3f36..f7de2e6 100644 --- a/lib/license/management/versions/v1.rb +++ b/lib/license/management/versions/v1.rb @@ -14,14 +14,14 @@ module License private # when a dependency has multiple licenses, this will join the licenses into a single name - # this defect was backported from the htmltojson version of this script. + # this defect was backported from the html2json version of this script. def license_summary dependencies - .map { |x| x.licenses.map { |y| best_name_for(y) }.sort.reverse.join(', ') } + .map { |dependency| join_license_names(dependency.licenses) } .flatten .group_by { |name| name } .map { |license, items| { count: items.count, name: license } } - .sort_by { |x| [-x[:count], x[:name]] } + .sort_by { |hash| [-hash[:count], hash[:name]] } end # when a dependency has more than one license @@ -32,14 +32,14 @@ module License urls = dependency.licenses.map(&:url).reject { |x| blank?(x) }.uniq.sort log_info("multiple urls detected: #{urls.inspect}") if urls.size > 1 - url = urls[0] || data_for(dependency.licenses.first)['url'] + url = urls[0] || license_data(dependency.licenses.first)['url'] license.merge(url: url) if present?(url) license end def join_license_names(licenses) - licenses.map { |x| best_name_for(x) }.join(', ') + licenses.map { |x| best_name_for(x) }.sort.reverse.join(', ') end def map_from_dependency(dependency) @@ -63,10 +63,10 @@ module License end def best_name_for(license) - data_for(license)['name'] + license_data(license)['name'] end - def data_for(license) + def license_data(license) repository.item_for(license) end end -- cgit v1.2.3 From 4614246f0edf72ebcdf2e45aa05d1736cd3358f1 Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 20 Aug 2019 12:40:03 -0600 Subject: provide default implementation of template method and use safe navigation operator --- lib/license/management/versions/base.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/license/management/versions/base.rb b/lib/license/management/versions/base.rb index 6e30e20..2345a50 100644 --- a/lib/license/management/versions/base.rb +++ b/lib/license/management/versions/base.rb @@ -14,10 +14,15 @@ module License @repository = License::Management::Repository.new end + def to_h + raise NotImplementedError + end + private + def paths_from(dependency) - return [] unless dependency.respond_to?(:aggregate_paths) + return [] unless dependency&.respond_to?(:aggregate_paths) paths = dependency.aggregate_paths return [] if blank?(paths) -- cgit v1.2.3 From 026959fcbe2fb0fa7b37a8b64a54d7672a065eac Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 20 Aug 2019 15:18:43 -0600 Subject: update gem version # to match CHANGELOG entry --- lib/license/management/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/license/management/version.rb b/lib/license/management/version.rb index d679b3f..7fec52d 100644 --- a/lib/license/management/version.rb +++ b/lib/license/management/version.rb @@ -2,6 +2,6 @@ module License module Management - VERSION = '1.6.0' + VERSION = '1.7.0' end end -- cgit v1.2.3 From d6c503e2347cb75df398f8cd88bb2623b34273a4 Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 20 Aug 2019 17:02:22 -0600 Subject: assign to current hash instead of new one --- lib/license/management/versions/v1.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/license/management/versions/v1.rb b/lib/license/management/versions/v1.rb index f7de2e6..1ef81c0 100644 --- a/lib/license/management/versions/v1.rb +++ b/lib/license/management/versions/v1.rb @@ -34,7 +34,7 @@ module License log_info("multiple urls detected: #{urls.inspect}") if urls.size > 1 url = urls[0] || license_data(dependency.licenses.first)['url'] - license.merge(url: url) if present?(url) + license[:url] = url if present?(url) license end -- cgit v1.2.3 From 170f3bee921b24f9ee12191662afe68aea2e8788 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 21 Aug 2019 10:21:58 -0600 Subject: remove unnecessary usage of safe navigation operator --- lib/license/management/versions/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/license/management/versions/base.rb b/lib/license/management/versions/base.rb index 2345a50..a087520 100644 --- a/lib/license/management/versions/base.rb +++ b/lib/license/management/versions/base.rb @@ -22,7 +22,7 @@ module License def paths_from(dependency) - return [] unless dependency&.respond_to?(:aggregate_paths) + return [] unless dependency.respond_to?(:aggregate_paths) paths = dependency.aggregate_paths return [] if blank?(paths) -- cgit v1.2.3 From 27888daf19c84e646ffdae7a635f38db8bc05cdb Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 21 Aug 2019 10:31:01 -0600 Subject: Move version classes to Report namespace --- lib/license/management.rb | 6 +- lib/license/management/json_report.rb | 31 ----------- lib/license/management/report.rb | 34 ++++++++++++ lib/license/management/report/versions/base.rb | 40 +++++++++++++ lib/license/management/report/versions/v1.rb | 77 ++++++++++++++++++++++++++ lib/license/management/versions/base.rb | 39 ------------- lib/license/management/versions/v1.rb | 75 ------------------------- 7 files changed, 153 insertions(+), 149 deletions(-) delete mode 100644 lib/license/management/json_report.rb create mode 100644 lib/license/management/report.rb create mode 100644 lib/license/management/report/versions/base.rb create mode 100644 lib/license/management/report/versions/v1.rb delete mode 100644 lib/license/management/versions/base.rb delete mode 100644 lib/license/management/versions/v1.rb (limited to 'lib') diff --git a/lib/license/management.rb b/lib/license/management.rb index 2fdb6b5..64fd4e8 100644 --- a/lib/license/management.rb +++ b/lib/license/management.rb @@ -6,13 +6,11 @@ require 'license_finder' require 'license/management/loggable' require 'license/management/verifiable' require 'license/management/repository' -require 'license/management/versions/base' -require 'license/management/versions/v1' -require 'license/management/json_report' +require 'license/management/report' require 'license/management/version' # This applies a monkey patch to the JsonReport found in the `license_finder` gem. -LicenseFinder::JsonReport.prepend(License::Management::JsonReport) +LicenseFinder::JsonReport.prepend(License::Management::Report) module License module Management diff --git a/lib/license/management/json_report.rb b/lib/license/management/json_report.rb deleted file mode 100644 index fde30ef..0000000 --- a/lib/license/management/json_report.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -module License - module Management - module JsonReport - DEFAULT_VERSION = '1' - VERSIONS = { - nil => ::License::Management::Versions::V1, - '' => ::License::Management::Versions::V1, - '1' => ::License::Management::Versions::V1, - '1.0' => ::License::Management::Versions::V1 - }.freeze - - # This method overrides the method defined in `License::Management::JsonReport` to - # allow us to generate a custom json report. - def to_s - JSON.pretty_generate(version_for(report_version).to_h) + "\n" - end - - private - - def report_version - ENV.fetch('LM_REPORT_VERSION', DEFAULT_VERSION) - end - - def version_for(version) - VERSIONS.fetch(version.to_s).new(dependencies) - end - end - end -end diff --git a/lib/license/management/report.rb b/lib/license/management/report.rb new file mode 100644 index 0000000..40fa854 --- /dev/null +++ b/lib/license/management/report.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'license/management/report/versions/base' +require 'license/management/report/versions/v1' + +module License + module Management + module Report + DEFAULT_VERSION = '1' + VERSIONS = { + nil => Versions::V1, + '' => Versions::V1, + '1' => Versions::V1, + '1.0' => Versions::V1 + }.freeze + + # This method overrides the method defined in `LicenseFinder::JsonReport` to + # allow us to generate a custom json report. + def to_s + JSON.pretty_generate(version_for(report_version).to_h) + "\n" + end + + private + + def report_version + ENV.fetch('LM_REPORT_VERSION', DEFAULT_VERSION) + end + + def version_for(version) + VERSIONS.fetch(version.to_s).new(dependencies) + end + end + end +end diff --git a/lib/license/management/report/versions/base.rb b/lib/license/management/report/versions/base.rb new file mode 100644 index 0000000..68bd41f --- /dev/null +++ b/lib/license/management/report/versions/base.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module License + module Management + module Report + module Versions + class Base + include Loggable + include Verifiable + + attr_reader :dependencies, :repository + + def initialize(dependencies) + @dependencies = dependencies + @repository = License::Management::Repository.new + end + + def to_h + raise NotImplementedError + end + + private + + def paths_from(dependency) + return [] unless dependency.respond_to?(:aggregate_paths) + + paths = dependency.aggregate_paths + return [] if blank?(paths) + + paths.map { |x| x.gsub(Dir.pwd, '.') } + end + + def description_for(dependency) + present?(dependency.summary) ? dependency.summary : dependency.description + end + end + end + end + end +end diff --git a/lib/license/management/report/versions/v1.rb b/lib/license/management/report/versions/v1.rb new file mode 100644 index 0000000..c14864b --- /dev/null +++ b/lib/license/management/report/versions/v1.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module License + module Management + module Report + module Versions + class V1 < Base + def to_h + { + licenses: license_summary, + dependencies: formatted_dependencies(dependencies) + } + end + + private + + # when a dependency has multiple licenses, this will join the licenses into a single name + # this defect was backported from the html2json version of this script. + def license_summary + dependencies + .map { |dependency| join_license_names(dependency.licenses) } + .flatten + .group_by { |name| name } + .map { |license, items| { count: items.count, name: license } } + .sort_by { |hash| [-hash[:count], hash[:name]] } + end + + # when a dependency has more than one license + # this method chooses one of the urls. + # to maintain backwards compatibility this bug has been carried forward. + def license_for(dependency) + license = { name: join_license_names(dependency.licenses) } + + urls = dependency.licenses.map(&:url).reject { |x| blank?(x) }.uniq.sort + log_info("multiple urls detected: #{urls.inspect}") if urls.size > 1 + url = urls[0] || license_data(dependency.licenses.first)['url'] + + license[:url] = url if present?(url) + license + end + + def join_license_names(licenses) + licenses.map { |x| best_name_for(x) }.sort.reverse.join(', ') + end + + def map_from_dependency(dependency) + result = { + license: license_for(dependency), + dependency: { + name: dependency.name, + url: dependency.homepage, + description: description_for(dependency), + pathes: paths_from(dependency) + } + } + result[:dependency].delete(:url) if blank?(dependency.homepage) + result + end + + def formatted_dependencies(dependencies) + dependencies + .sort_by(&:name) + .map { |x| map_from_dependency(x) } + end + + def best_name_for(license) + license_data(license)['name'] + end + + def license_data(license) + repository.item_for(license) + end + end + end + end + end +end diff --git a/lib/license/management/versions/base.rb b/lib/license/management/versions/base.rb deleted file mode 100644 index a087520..0000000 --- a/lib/license/management/versions/base.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -module License - module Management - module Versions - class Base - include Loggable - include Verifiable - - attr_reader :dependencies, :repository - - def initialize(dependencies) - @dependencies = dependencies - @repository = License::Management::Repository.new - end - - def to_h - raise NotImplementedError - end - - private - - - def paths_from(dependency) - return [] unless dependency.respond_to?(:aggregate_paths) - - paths = dependency.aggregate_paths - return [] if blank?(paths) - - paths.map { |x| x.gsub(Dir.pwd, '.') } - end - - def description_for(dependency) - present?(dependency.summary) ? dependency.summary : dependency.description - end - end - end - end -end diff --git a/lib/license/management/versions/v1.rb b/lib/license/management/versions/v1.rb deleted file mode 100644 index 1ef81c0..0000000 --- a/lib/license/management/versions/v1.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -module License - module Management - module Versions - class V1 < Base - def to_h - { - licenses: license_summary, - dependencies: formatted_dependencies(dependencies) - } - end - - private - - # when a dependency has multiple licenses, this will join the licenses into a single name - # this defect was backported from the html2json version of this script. - def license_summary - dependencies - .map { |dependency| join_license_names(dependency.licenses) } - .flatten - .group_by { |name| name } - .map { |license, items| { count: items.count, name: license } } - .sort_by { |hash| [-hash[:count], hash[:name]] } - end - - # when a dependency has more than one license - # this method chooses one of the urls. - # to maintain backwards compatibility this bug has been carried forward. - def license_for(dependency) - license = { name: join_license_names(dependency.licenses) } - - urls = dependency.licenses.map(&:url).reject { |x| blank?(x) }.uniq.sort - log_info("multiple urls detected: #{urls.inspect}") if urls.size > 1 - url = urls[0] || license_data(dependency.licenses.first)['url'] - - license[:url] = url if present?(url) - license - end - - def join_license_names(licenses) - licenses.map { |x| best_name_for(x) }.sort.reverse.join(', ') - end - - def map_from_dependency(dependency) - result = { - license: license_for(dependency), - dependency: { - name: dependency.name, - url: dependency.homepage, - description: description_for(dependency), - pathes: paths_from(dependency) - } - } - result[:dependency].delete(:url) if blank?(dependency.homepage) - result - end - - def formatted_dependencies(dependencies) - dependencies - .sort_by(&:name) - .map { |x| map_from_dependency(x) } - end - - def best_name_for(license) - license_data(license)['name'] - end - - def license_data(license) - repository.item_for(license) - end - end - end - end -end -- cgit v1.2.3 From 450d9b983df6c616f74759c59a7e1ae1098a2dff Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 21 Aug 2019 13:58:21 -0600 Subject: add way to choose canonical or non canonical form in v1 reports --- lib/license/management/report/versions/v1.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/license/management/report/versions/v1.rb b/lib/license/management/report/versions/v1.rb index c14864b..e897960 100644 --- a/lib/license/management/report/versions/v1.rb +++ b/lib/license/management/report/versions/v1.rb @@ -68,7 +68,16 @@ module License end def license_data(license) - repository.item_for(license) + return repository.item_for(license) if canonicalize? + + { + 'name' => license.name.split(/[\r\n]+/)[0], + 'url' => license.url + } + end + + def canonicalize? + ENV.fetch('LM_V1_CANONICALIZE', 'false') == 'true' end end end -- cgit v1.2.3 From 47d34c5b04ccb0018329cb35cb587911510d7f3e Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 21 Aug 2019 14:05:52 -0600 Subject: collapse versions namespace --- lib/license/management/report.rb | 12 ++-- lib/license/management/report/base.rb | 38 ++++++++++++ lib/license/management/report/v1.rb | 84 +++++++++++++++++++++++++ lib/license/management/report/versions/base.rb | 40 ------------ lib/license/management/report/versions/v1.rb | 86 -------------------------- 5 files changed, 128 insertions(+), 132 deletions(-) create mode 100644 lib/license/management/report/base.rb create mode 100644 lib/license/management/report/v1.rb delete mode 100644 lib/license/management/report/versions/base.rb delete mode 100644 lib/license/management/report/versions/v1.rb (limited to 'lib') diff --git a/lib/license/management/report.rb b/lib/license/management/report.rb index 40fa854..5ac41bb 100644 --- a/lib/license/management/report.rb +++ b/lib/license/management/report.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true -require 'license/management/report/versions/base' -require 'license/management/report/versions/v1' +require 'license/management/report/base' +require 'license/management/report/v1' module License module Management module Report DEFAULT_VERSION = '1' VERSIONS = { - nil => Versions::V1, - '' => Versions::V1, - '1' => Versions::V1, - '1.0' => Versions::V1 + nil => V1, + '' => V1, + '1' => V1, + '1.0' => V1 }.freeze # This method overrides the method defined in `LicenseFinder::JsonReport` to diff --git a/lib/license/management/report/base.rb b/lib/license/management/report/base.rb new file mode 100644 index 0000000..ab9b6a1 --- /dev/null +++ b/lib/license/management/report/base.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module License + module Management + module Report + class Base + include Loggable + include Verifiable + + attr_reader :dependencies, :repository + + def initialize(dependencies) + @dependencies = dependencies + @repository = License::Management::Repository.new + end + + def to_h + raise NotImplementedError + end + + private + + def paths_from(dependency) + return [] unless dependency.respond_to?(:aggregate_paths) + + paths = dependency.aggregate_paths + return [] if blank?(paths) + + paths.map { |x| x.gsub(Dir.pwd, '.') } + end + + def description_for(dependency) + present?(dependency.summary) ? dependency.summary : dependency.description + end + end + end + end +end diff --git a/lib/license/management/report/v1.rb b/lib/license/management/report/v1.rb new file mode 100644 index 0000000..5882f72 --- /dev/null +++ b/lib/license/management/report/v1.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +module License + module Management + module Report + class V1 < Base + def to_h + { + licenses: license_summary, + dependencies: formatted_dependencies(dependencies) + } + end + + private + + # when a dependency has multiple licenses, this will join the licenses into a single name + # this defect was backported from the html2json version of this script. + def license_summary + dependencies + .map { |dependency| join_license_names(dependency.licenses) } + .flatten + .group_by { |name| name } + .map { |license, items| { count: items.count, name: license } } + .sort_by { |hash| [-hash[:count], hash[:name]] } + end + + # when a dependency has more than one license + # this method chooses one of the urls. + # to maintain backwards compatibility this bug has been carried forward. + def license_for(dependency) + license = { name: join_license_names(dependency.licenses) } + + urls = dependency.licenses.map(&:url).reject { |x| blank?(x) }.uniq.sort + log_info("multiple urls detected: #{urls.inspect}") if urls.size > 1 + url = urls[0] || license_data(dependency.licenses.first)['url'] + + license[:url] = url if present?(url) + license + end + + def join_license_names(licenses) + licenses.map { |x| best_name_for(x) }.sort.reverse.join(', ') + end + + def map_from_dependency(dependency) + result = { + license: license_for(dependency), + dependency: { + name: dependency.name, + url: dependency.homepage, + description: description_for(dependency), + pathes: paths_from(dependency) + } + } + result[:dependency].delete(:url) if blank?(dependency.homepage) + result + end + + def formatted_dependencies(dependencies) + dependencies + .sort_by(&:name) + .map { |x| map_from_dependency(x) } + end + + def best_name_for(license) + license_data(license)['name'] + end + + def license_data(license) + return repository.item_for(license) if canonicalize? + + { + 'name' => license.name.split(/[\r\n]+/)[0], + 'url' => license.url + } + end + + def canonicalize? + ENV.fetch('LM_V1_CANONICALIZE', 'false') == 'true' + end + end + end + end +end diff --git a/lib/license/management/report/versions/base.rb b/lib/license/management/report/versions/base.rb deleted file mode 100644 index 68bd41f..0000000 --- a/lib/license/management/report/versions/base.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -module License - module Management - module Report - module Versions - class Base - include Loggable - include Verifiable - - attr_reader :dependencies, :repository - - def initialize(dependencies) - @dependencies = dependencies - @repository = License::Management::Repository.new - end - - def to_h - raise NotImplementedError - end - - private - - def paths_from(dependency) - return [] unless dependency.respond_to?(:aggregate_paths) - - paths = dependency.aggregate_paths - return [] if blank?(paths) - - paths.map { |x| x.gsub(Dir.pwd, '.') } - end - - def description_for(dependency) - present?(dependency.summary) ? dependency.summary : dependency.description - end - end - end - end - end -end diff --git a/lib/license/management/report/versions/v1.rb b/lib/license/management/report/versions/v1.rb deleted file mode 100644 index e897960..0000000 --- a/lib/license/management/report/versions/v1.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -module License - module Management - module Report - module Versions - class V1 < Base - def to_h - { - licenses: license_summary, - dependencies: formatted_dependencies(dependencies) - } - end - - private - - # when a dependency has multiple licenses, this will join the licenses into a single name - # this defect was backported from the html2json version of this script. - def license_summary - dependencies - .map { |dependency| join_license_names(dependency.licenses) } - .flatten - .group_by { |name| name } - .map { |license, items| { count: items.count, name: license } } - .sort_by { |hash| [-hash[:count], hash[:name]] } - end - - # when a dependency has more than one license - # this method chooses one of the urls. - # to maintain backwards compatibility this bug has been carried forward. - def license_for(dependency) - license = { name: join_license_names(dependency.licenses) } - - urls = dependency.licenses.map(&:url).reject { |x| blank?(x) }.uniq.sort - log_info("multiple urls detected: #{urls.inspect}") if urls.size > 1 - url = urls[0] || license_data(dependency.licenses.first)['url'] - - license[:url] = url if present?(url) - license - end - - def join_license_names(licenses) - licenses.map { |x| best_name_for(x) }.sort.reverse.join(', ') - end - - def map_from_dependency(dependency) - result = { - license: license_for(dependency), - dependency: { - name: dependency.name, - url: dependency.homepage, - description: description_for(dependency), - pathes: paths_from(dependency) - } - } - result[:dependency].delete(:url) if blank?(dependency.homepage) - result - end - - def formatted_dependencies(dependencies) - dependencies - .sort_by(&:name) - .map { |x| map_from_dependency(x) } - end - - def best_name_for(license) - license_data(license)['name'] - end - - def license_data(license) - return repository.item_for(license) if canonicalize? - - { - 'name' => license.name.split(/[\r\n]+/)[0], - 'url' => license.url - } - end - - def canonicalize? - ENV.fetch('LM_V1_CANONICALIZE', 'false') == 'true' - end - end - end - end - end -end -- cgit v1.2.3