license_finder 1.0.0.0-java → 1.1.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.force-build +0 -0
- data/.travis.yml +8 -7
- data/CHANGELOG.rdoc +29 -1
- data/Rakefile +2 -2
- data/db/migrate/201311192003_reassociate_manual_approval.rb +2 -3
- data/db/migrate/201403181732_rename_manual_fields.rb +10 -0
- data/db/migrate/201403190028_add_manual_approvals.rb +22 -0
- data/db/migrate/201403191419_add_timestamps_to_manual_approvals.rb +15 -0
- data/db/migrate/201403191645_remove_license_aliases.rb +23 -0
- data/features/cli.feature +21 -20
- data/features/cocoapods_dependencies.feature +10 -0
- data/features/configure_bundler_groups.feature +23 -0
- data/features/configure_ignore_dependencies.feature +16 -0
- data/features/{project_name.feature → configure_project_name.feature} +1 -1
- data/features/{whitelist.feature → configure_whitelist.feature} +6 -6
- data/features/manually_added.feature +19 -0
- data/features/{approve_dependencies.feature → manually_approved.feature} +2 -2
- data/features/manually_assigned_license.feature +16 -0
- data/features/{text_report.feature → report_csv.feature} +2 -2
- data/features/{html_report.feature → report_html.feature} +2 -2
- data/features/step_definitions/cli_steps.rb +22 -32
- data/features/step_definitions/cocoapod_steps.rb +8 -0
- data/features/step_definitions/configure_bundler_groups_steps.rb +30 -0
- data/features/step_definitions/configure_ignore_dependencies.rb +35 -0
- data/features/step_definitions/{project_name_steps.rb → configure_project_name_steps.rb} +0 -0
- data/features/step_definitions/configure_whitelist_steps.rb +45 -0
- data/features/step_definitions/gradle_steps.rb +2 -2
- data/features/step_definitions/manually_added_steps.rb +28 -0
- data/features/step_definitions/manually_approved_steps.rb +24 -0
- data/features/step_definitions/manually_assigned_license_steps.rb +34 -0
- data/features/step_definitions/maven_steps.rb +2 -2
- data/features/step_definitions/node_steps.rb +2 -2
- data/features/step_definitions/python_steps.rb +1 -1
- data/features/step_definitions/report_csv_steps.rb +20 -0
- data/features/step_definitions/report_html_steps.rb +60 -0
- data/features/step_definitions/shared_steps.rb +125 -104
- data/{files/license_finder.yml → lib/data/license_finder.example.yml} +3 -0
- data/lib/license_finder.rb +3 -2
- data/lib/license_finder/cli.rb +94 -49
- data/lib/license_finder/configuration.rb +21 -14
- data/lib/license_finder/dependency_manager.rb +27 -19
- data/lib/license_finder/license.rb +33 -19
- data/lib/license_finder/license/definitions.rb +153 -104
- data/lib/license_finder/license/matcher.rb +6 -1
- data/lib/license_finder/license/none_matcher.rb +9 -0
- data/lib/license_finder/license/text.rb +1 -0
- data/lib/license_finder/package.rb +30 -6
- data/lib/license_finder/package_managers/bower.rb +2 -2
- data/lib/license_finder/package_managers/bower_package.rb +2 -2
- data/lib/license_finder/package_managers/bundler.rb +9 -17
- data/lib/license_finder/package_managers/bundler_package.rb +1 -1
- data/lib/license_finder/package_managers/cocoa_pods.rb +35 -0
- data/lib/license_finder/package_managers/cocoa_pods_package.rb +19 -0
- data/lib/license_finder/package_managers/gradle.rb +9 -5
- data/lib/license_finder/package_managers/gradle_package.rb +4 -4
- data/lib/license_finder/package_managers/maven.rb +7 -3
- data/lib/license_finder/package_managers/maven_package.rb +5 -5
- data/lib/license_finder/package_managers/npm.rb +2 -2
- data/lib/license_finder/package_managers/npm_package.rb +2 -2
- data/lib/license_finder/package_managers/pip.rb +2 -2
- data/lib/license_finder/package_managers/pip_package.rb +7 -11
- data/lib/license_finder/package_saver.rb +12 -10
- data/lib/license_finder/possible_license_file.rb +1 -1
- data/lib/license_finder/possible_license_files.rb +11 -15
- data/lib/license_finder/reports/formatted_report.rb +25 -6
- data/lib/license_finder/reports/html_report.rb +2 -1
- data/lib/license_finder/reports/reporter.rb +3 -3
- data/lib/license_finder/tables.rb +6 -4
- data/lib/license_finder/tables/dependency.rb +36 -16
- data/lib/license_finder/tables/manual_approval.rb +13 -0
- data/lib/license_finder/yml_to_sql.rb +12 -9
- data/lib/templates/html_report.erb +68 -74
- data/lib/templates/markdown_report.erb +20 -21
- data/license_finder.gemspec +7 -7
- data/readme.md +76 -79
- data/spec/fixtures/Podfile +3 -0
- data/spec/lib/license_finder/cli_spec.rb +71 -23
- data/spec/lib/license_finder/configuration_spec.rb +61 -21
- data/spec/lib/license_finder/dependency_manager_spec.rb +52 -33
- data/spec/lib/license_finder/license/definitions_spec.rb +30 -14
- data/spec/lib/license_finder/license_spec.rb +55 -12
- data/spec/lib/license_finder/package_managers/bower_package_spec.rb +38 -19
- data/spec/lib/license_finder/package_managers/bower_spec.rb +10 -16
- data/spec/lib/license_finder/package_managers/bundler_package_spec.rb +39 -15
- data/spec/lib/license_finder/package_managers/bundler_spec.rb +10 -22
- data/spec/lib/license_finder/package_managers/cocoa_pods_package_spec.rb +44 -0
- data/spec/lib/license_finder/package_managers/cocoa_pods_spec.rb +79 -0
- data/spec/lib/license_finder/package_managers/gradle_package_spec.rb +4 -5
- data/spec/lib/license_finder/package_managers/gradle_spec.rb +26 -20
- data/spec/lib/license_finder/package_managers/maven_package_spec.rb +4 -5
- data/spec/lib/license_finder/package_managers/maven_spec.rb +16 -19
- data/spec/lib/license_finder/package_managers/npm_package_spec.rb +39 -19
- data/spec/lib/license_finder/package_managers/npm_spec.rb +10 -16
- data/spec/lib/license_finder/package_managers/pip_package_spec.rb +8 -8
- data/spec/lib/license_finder/package_managers/pip_spec.rb +10 -16
- data/spec/lib/license_finder/package_saver_spec.rb +27 -3
- data/spec/lib/license_finder/possible_license_file_spec.rb +25 -23
- data/spec/lib/license_finder/reports/detailed_text_report_spec.rb +6 -8
- data/spec/lib/license_finder/reports/html_report_spec.rb +45 -44
- data/spec/lib/license_finder/reports/markdown_report_spec.rb +8 -9
- data/spec/lib/license_finder/reports/reporter_spec.rb +1 -1
- data/spec/lib/license_finder/reports/text_report_spec.rb +6 -8
- data/spec/lib/license_finder/tables/dependency_spec.rb +57 -41
- data/spec/lib/license_finder/yml_to_sql_spec.rb +94 -92
- data/spec/spec_helper.rb +1 -0
- data/spec/support/stdout_helpers.rb +25 -0
- metadata +86 -69
- data/MIT.LICENSE +0 -20
- data/features/ignore_bundle_groups.feature +0 -23
- data/features/manually_managed_dependencies.feature +0 -19
- data/features/set_license.feature +0 -10
- data/features/step_definitions/approve_dependencies_steps.rb +0 -25
- data/features/step_definitions/html_report_steps.rb +0 -62
- data/features/step_definitions/ignore_bundle_groups_steps.rb +0 -29
- data/features/step_definitions/manually_managed_steps.rb +0 -33
- data/features/step_definitions/set_license_steps.rb +0 -20
- data/features/step_definitions/text_report_steps.rb +0 -19
- data/features/step_definitions/whitelist_steps.rb +0 -45
- data/files/dependency_breakdown.png +0 -0
- data/files/report_breakdown.png +0 -0
- data/lib/license_finder/license_url.rb +0 -9
- data/lib/license_finder/tables/license_alias.rb +0 -22
- data/spec/lib/license_finder/license_url_spec.rb +0 -16
- data/spec/lib/license_finder/tables/license_alias_spec.rb +0 -37
- data/spec/support/silence_stdout.rb +0 -13
@@ -0,0 +1,35 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
class CocoaPods
|
5
|
+
|
6
|
+
def self.current_packages
|
7
|
+
podfile = YAML.load_file(lockfile_path)
|
8
|
+
|
9
|
+
acknowledgements = JSON.parse(`plutil -convert json -o - #{Pathname.new('Pods/Pods-acknowledgements.plist').expand_path}`)["PreferenceSpecifiers"]
|
10
|
+
|
11
|
+
podfile["PODS"].map do |pod|
|
12
|
+
pod = pod.keys.first if pod.is_a?(Hash)
|
13
|
+
|
14
|
+
pod_name, pod_version = pod.scan(/(.*)\s\((.*)\)/).flatten
|
15
|
+
pod_acknowledgment = acknowledgements.detect { |hash| hash["Title"] == pod_name } || {}
|
16
|
+
CocoaPodsPackage.new(pod_name, pod_version, pod_acknowledgment["FooterText"])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.active?
|
21
|
+
package_path.exist?
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def self.package_path
|
27
|
+
Pathname.new("Podfile")
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.lockfile_path
|
31
|
+
Pathname.new("Podfile.lock")
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module LicenseFinder
|
2
|
+
class CocoaPodsPackage < Package
|
3
|
+
attr_reader :name, :version
|
4
|
+
attr_reader :summary, :description, :homepage
|
5
|
+
|
6
|
+
def initialize(name, version, license_text)
|
7
|
+
@name = name
|
8
|
+
@version = version
|
9
|
+
@license_text = license_text
|
10
|
+
end
|
11
|
+
|
12
|
+
def groups; []; end
|
13
|
+
def children; []; end
|
14
|
+
|
15
|
+
def license
|
16
|
+
License.find_by_text(@license_text.to_s) || default_license
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -3,27 +3,31 @@ require "xmlsimple"
|
|
3
3
|
module LicenseFinder
|
4
4
|
class Gradle
|
5
5
|
def self.current_packages
|
6
|
-
|
6
|
+
`#{LicenseFinder.config.gradle_command} downloadLicenses`
|
7
7
|
|
8
|
-
xml =
|
8
|
+
xml = license_report.read
|
9
9
|
|
10
10
|
options = {
|
11
11
|
'GroupTags' => { 'dependencies' => 'dependency' }
|
12
12
|
}
|
13
|
-
XmlSimple.xml_in(xml, options)[
|
13
|
+
XmlSimple.xml_in(xml, options).fetch('dependency', []).map do |d|
|
14
14
|
d["license"].reject! { |l| l["name"] == "No license found" }
|
15
15
|
GradlePackage.new(d)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.active?
|
20
|
-
|
20
|
+
package_path.exist?
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
|
+
def self.license_report
|
26
|
+
Pathname.new('build/reports/license/dependency-license.xml')
|
27
|
+
end
|
28
|
+
|
25
29
|
def self.package_path
|
26
|
-
Pathname.new('build.gradle')
|
30
|
+
Pathname.new('build.gradle')
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
@@ -28,13 +28,13 @@ module LicenseFinder
|
|
28
28
|
[]
|
29
29
|
end
|
30
30
|
|
31
|
-
|
31
|
+
private
|
32
|
+
|
33
|
+
def licenses_from_files
|
32
34
|
[]
|
33
35
|
end
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
def licenses_from_spec
|
37
|
+
def license_names_from_spec
|
38
38
|
@gradle_dependency["license"].map { |l| l["name"] }
|
39
39
|
end
|
40
40
|
end
|
@@ -5,7 +5,7 @@ module LicenseFinder
|
|
5
5
|
def self.current_packages
|
6
6
|
`mvn license:download-licenses`
|
7
7
|
|
8
|
-
xml =
|
8
|
+
xml = license_report.read
|
9
9
|
|
10
10
|
options = {
|
11
11
|
'GroupTags' => { 'licenses' => 'license', 'dependencies' => 'dependency' },
|
@@ -19,13 +19,17 @@ module LicenseFinder
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.active?
|
22
|
-
|
22
|
+
package_path.exist?
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
+
def self.license_report
|
28
|
+
Pathname.new('target/generated-resources/licenses.xml')
|
29
|
+
end
|
30
|
+
|
27
31
|
def self.package_path
|
28
|
-
Pathname.new('pom.xml')
|
32
|
+
Pathname.new('pom.xml')
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
@@ -32,14 +32,14 @@ module LicenseFinder
|
|
32
32
|
[]
|
33
33
|
end
|
34
34
|
|
35
|
-
def license_from_files
|
36
|
-
[]
|
37
|
-
end
|
38
|
-
|
39
35
|
private
|
40
36
|
attr_reader :mvn_dependency
|
41
37
|
|
42
|
-
def
|
38
|
+
def licenses_from_files
|
39
|
+
[]
|
40
|
+
end
|
41
|
+
|
42
|
+
def license_names_from_spec
|
43
43
|
mvn_dependency["licenses"].map { |l| l["name"] }
|
44
44
|
end
|
45
45
|
end
|
@@ -14,7 +14,7 @@ module LicenseFinder
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.active?
|
17
|
-
|
17
|
+
package_path.exist?
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
@@ -40,7 +40,7 @@ module LicenseFinder
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def self.package_path
|
43
|
-
Pathname.new('package.json')
|
43
|
+
Pathname.new('package.json')
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -26,13 +26,13 @@ print "[" + ",".join(dists) + "]"
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.active?
|
29
|
-
|
29
|
+
requirements_path.exist?
|
30
30
|
end
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
34
|
def self.requirements_path
|
35
|
-
Pathname.new('requirements.txt')
|
35
|
+
Pathname.new('requirements.txt')
|
36
36
|
end
|
37
37
|
|
38
38
|
def self.pypi_def(name, version)
|
@@ -33,19 +33,15 @@ module LicenseFinder
|
|
33
33
|
|
34
34
|
attr_reader :install_path, :pypi_def
|
35
35
|
|
36
|
-
def
|
36
|
+
def license_names_from_spec
|
37
37
|
license = pypi_def["license"]
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
c.gsub(/^License.*::\s*(.*)$/, '\1')
|
46
|
-
end
|
47
|
-
end.compact
|
48
|
-
end
|
39
|
+
return [license] if license && license != "UNKNOWN"
|
40
|
+
|
41
|
+
pypi_def.
|
42
|
+
fetch("classifiers", []).
|
43
|
+
select { |c| c.start_with?("License") }.
|
44
|
+
map { |c| c.gsub(/^License.*::\s*(.*)$/, '\1') }
|
49
45
|
end
|
50
46
|
end
|
51
47
|
end
|
@@ -19,16 +19,18 @@ module LicenseFinder
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def save
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
dependency.version = version.to_s
|
23
|
+
dependency.summary = summary
|
24
|
+
dependency.description = description
|
25
|
+
dependency.homepage = homepage
|
26
|
+
dependency.bundler_group_names = groups.map(&:to_s)
|
27
|
+
dependency.children_names = children
|
28
|
+
dependency.apply_better_license license
|
29
|
+
|
30
|
+
# Only save *changed* dependencies. This ensures re-running
|
31
|
+
# `license_finder` won't always update the DB, and therefore won't always
|
32
|
+
# update the HTML/markdown reports with a new timestamp.
|
33
|
+
dependency.save_changes
|
32
34
|
dependency
|
33
35
|
end
|
34
36
|
|
@@ -1,18 +1,19 @@
|
|
1
1
|
module LicenseFinder
|
2
2
|
class PossibleLicenseFiles
|
3
|
-
|
3
|
+
CANDIDATE_FILE_NAMES = %w(LICENSE License Licence COPYING README Readme ReadMe)
|
4
|
+
CANDIDATE_PATH_WILDCARD = "*{#{CANDIDATE_FILE_NAMES.join(',')}}*"
|
4
5
|
|
5
6
|
def self.find(install_path)
|
6
7
|
new(install_path).find
|
7
8
|
end
|
8
9
|
|
9
10
|
def initialize(install_path)
|
10
|
-
@install_path = install_path
|
11
|
+
@install_path = Pathname(install_path)
|
11
12
|
end
|
12
13
|
|
13
14
|
def find
|
14
|
-
|
15
|
-
|
15
|
+
paths_of_candidate_files.map do |path|
|
16
|
+
file_at_path(path)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -20,22 +21,17 @@ module LicenseFinder
|
|
20
21
|
|
21
22
|
attr_reader :install_path
|
22
23
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
24
|
+
def paths_of_candidate_files
|
25
|
+
candidate_files_and_dirs.map do |path|
|
26
|
+
path.directory? ? path.children : path
|
26
27
|
end.flatten.uniq
|
27
28
|
end
|
28
29
|
|
29
|
-
def
|
30
|
-
|
30
|
+
def candidate_files_and_dirs
|
31
|
+
Pathname.glob(install_path.join('**', CANDIDATE_PATH_WILDCARD))
|
31
32
|
end
|
32
33
|
|
33
|
-
def
|
34
|
-
entries_in_directory = Dir::entries(path).reject { |p| p.match(/^(\.){1,2}$/) }
|
35
|
-
entries_in_directory.map { |entry_name| File.join(path, entry_name) }
|
36
|
-
end
|
37
|
-
|
38
|
-
def get_file_for_path(path)
|
34
|
+
def file_at_path(path)
|
39
35
|
PossibleLicenseFile.new(install_path, path)
|
40
36
|
end
|
41
37
|
end
|
@@ -7,15 +7,34 @@ module LicenseFinder
|
|
7
7
|
|
8
8
|
def grouped_dependencies
|
9
9
|
find_name = lambda do |dep|
|
10
|
-
|
11
|
-
if license
|
12
|
-
license.pretty_name
|
13
|
-
else
|
14
|
-
dep.license.name
|
15
|
-
end
|
10
|
+
dep.license.name
|
16
11
|
end
|
17
12
|
|
18
13
|
dependencies.group_by(&find_name).sort_by { |_, group| group.size }.reverse
|
19
14
|
end
|
15
|
+
|
16
|
+
def link_to_license(license)
|
17
|
+
link_to_maybe license.name, license.url
|
18
|
+
end
|
19
|
+
|
20
|
+
def link_to_dependency(dependency)
|
21
|
+
link_to_maybe dependency.name, dependency.homepage
|
22
|
+
end
|
23
|
+
|
24
|
+
def link_to_maybe(text, link)
|
25
|
+
if link && !link.empty?
|
26
|
+
%{<a href="#{link}">#{text}</a>}
|
27
|
+
else
|
28
|
+
text
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def version_groups(dependency)
|
33
|
+
result = "v#{dependency.version}"
|
34
|
+
if dependency.bundler_groups.any?
|
35
|
+
result += " (#{dependency.bundler_groups.map(&:name).join(", ")})"
|
36
|
+
end
|
37
|
+
result
|
38
|
+
end
|
20
39
|
end
|
21
40
|
end
|
@@ -3,7 +3,7 @@ module LicenseFinder
|
|
3
3
|
extend self
|
4
4
|
|
5
5
|
def write_reports
|
6
|
-
dependencies = Dependency.
|
6
|
+
dependencies = Dependency.acknowledged
|
7
7
|
artifacts = LicenseFinder.config.artifacts
|
8
8
|
|
9
9
|
write_file artifacts.text_file, TextReport.of(dependencies)
|
@@ -11,8 +11,8 @@ module LicenseFinder
|
|
11
11
|
write_file artifacts.html_file, HtmlReport.of(dependencies)
|
12
12
|
write_file artifacts.markdown_file, MarkdownReport.of(dependencies)
|
13
13
|
|
14
|
-
if
|
15
|
-
|
14
|
+
if artifacts.legacy_text_file.exist?
|
15
|
+
artifacts.legacy_text_file.delete
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -1,7 +1,9 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'sequel'
|
3
2
|
require LicenseFinder::Platform.sqlite_load_path
|
4
3
|
|
5
|
-
|
6
|
-
Sequel.
|
7
|
-
|
4
|
+
module LicenseFinder
|
5
|
+
DB = Sequel.connect(Platform.sqlite_adapter + "://" + config.artifacts.database_uri)
|
6
|
+
|
7
|
+
Sequel.extension :migration, :core_extensions
|
8
|
+
Sequel::Migrator.run(DB, ROOT_PATH.join('../db/migrate'))
|
9
|
+
end
|
@@ -1,18 +1,23 @@
|
|
1
1
|
module LicenseFinder
|
2
2
|
class Dependency < Sequel::Model
|
3
3
|
plugin :boolean_readers
|
4
|
-
|
4
|
+
plugin :composition
|
5
|
+
composition :license,
|
6
|
+
composer: ->(d) { License.find_by_name(d.license_name) },
|
7
|
+
decomposer: ->(d) { self.license_name = license.name }
|
8
|
+
|
9
|
+
one_to_one :manual_approval
|
5
10
|
many_to_many :children, join_table: :ancestries, left_key: :parent_dependency_id, right_key: :child_dependency_id, class: self
|
6
11
|
many_to_many :parents, join_table: :ancestries, left_key: :child_dependency_id, right_key: :parent_dependency_id, class: self
|
7
12
|
many_to_many :bundler_groups
|
8
13
|
|
9
14
|
dataset_module do
|
10
|
-
def
|
11
|
-
|
15
|
+
def added_automatically
|
16
|
+
added_manually.invert
|
12
17
|
end
|
13
18
|
|
14
|
-
def
|
15
|
-
where(
|
19
|
+
def added_manually
|
20
|
+
where(added_manually: true)
|
16
21
|
end
|
17
22
|
|
18
23
|
def obsolete(current)
|
@@ -21,7 +26,14 @@ module LicenseFinder
|
|
21
26
|
end
|
22
27
|
|
23
28
|
def self.unapproved
|
24
|
-
|
29
|
+
acknowledged.reject(&:approved?)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.acknowledged
|
33
|
+
ignored_dependencies = LicenseFinder.config.ignore_dependencies
|
34
|
+
all.reject do |dependency|
|
35
|
+
ignored_dependencies.include? dependency.name
|
36
|
+
end
|
25
37
|
end
|
26
38
|
|
27
39
|
def self.named(name)
|
@@ -36,25 +48,33 @@ module LicenseFinder
|
|
36
48
|
update_association_collection(:children, names)
|
37
49
|
end
|
38
50
|
|
39
|
-
def approve!
|
40
|
-
self.
|
51
|
+
def approve!(approver = nil, notes = nil)
|
52
|
+
self.manual_approval = ManualApproval.new(approver: approver, notes: notes)
|
41
53
|
save
|
42
54
|
end
|
43
55
|
|
44
56
|
def approved?
|
45
|
-
|
57
|
+
whitelisted? || approved_manually?
|
58
|
+
end
|
59
|
+
|
60
|
+
def whitelisted?
|
61
|
+
license.whitelisted?
|
62
|
+
end
|
63
|
+
|
64
|
+
def approved_manually?
|
65
|
+
!!manual_approval
|
46
66
|
end
|
47
67
|
|
48
|
-
def set_license_manually!(
|
49
|
-
self.license =
|
50
|
-
self.
|
68
|
+
def set_license_manually!(license)
|
69
|
+
self.license = license
|
70
|
+
self.license_assigned_manually = true
|
51
71
|
save
|
52
72
|
end
|
53
73
|
|
54
|
-
def apply_better_license(
|
55
|
-
return if
|
56
|
-
if license.
|
57
|
-
self.license =
|
74
|
+
def apply_better_license(other_license)
|
75
|
+
return if license_assigned_manually?
|
76
|
+
if license.name != other_license.name
|
77
|
+
self.license = other_license
|
58
78
|
end
|
59
79
|
end
|
60
80
|
|