license_finder 1.0.0.0-java → 1.1.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.force-build +0 -0
  3. data/.travis.yml +8 -7
  4. data/CHANGELOG.rdoc +29 -1
  5. data/Rakefile +2 -2
  6. data/db/migrate/201311192003_reassociate_manual_approval.rb +2 -3
  7. data/db/migrate/201403181732_rename_manual_fields.rb +10 -0
  8. data/db/migrate/201403190028_add_manual_approvals.rb +22 -0
  9. data/db/migrate/201403191419_add_timestamps_to_manual_approvals.rb +15 -0
  10. data/db/migrate/201403191645_remove_license_aliases.rb +23 -0
  11. data/features/cli.feature +21 -20
  12. data/features/cocoapods_dependencies.feature +10 -0
  13. data/features/configure_bundler_groups.feature +23 -0
  14. data/features/configure_ignore_dependencies.feature +16 -0
  15. data/features/{project_name.feature → configure_project_name.feature} +1 -1
  16. data/features/{whitelist.feature → configure_whitelist.feature} +6 -6
  17. data/features/manually_added.feature +19 -0
  18. data/features/{approve_dependencies.feature → manually_approved.feature} +2 -2
  19. data/features/manually_assigned_license.feature +16 -0
  20. data/features/{text_report.feature → report_csv.feature} +2 -2
  21. data/features/{html_report.feature → report_html.feature} +2 -2
  22. data/features/step_definitions/cli_steps.rb +22 -32
  23. data/features/step_definitions/cocoapod_steps.rb +8 -0
  24. data/features/step_definitions/configure_bundler_groups_steps.rb +30 -0
  25. data/features/step_definitions/configure_ignore_dependencies.rb +35 -0
  26. data/features/step_definitions/{project_name_steps.rb → configure_project_name_steps.rb} +0 -0
  27. data/features/step_definitions/configure_whitelist_steps.rb +45 -0
  28. data/features/step_definitions/gradle_steps.rb +2 -2
  29. data/features/step_definitions/manually_added_steps.rb +28 -0
  30. data/features/step_definitions/manually_approved_steps.rb +24 -0
  31. data/features/step_definitions/manually_assigned_license_steps.rb +34 -0
  32. data/features/step_definitions/maven_steps.rb +2 -2
  33. data/features/step_definitions/node_steps.rb +2 -2
  34. data/features/step_definitions/python_steps.rb +1 -1
  35. data/features/step_definitions/report_csv_steps.rb +20 -0
  36. data/features/step_definitions/report_html_steps.rb +60 -0
  37. data/features/step_definitions/shared_steps.rb +125 -104
  38. data/{files/license_finder.yml → lib/data/license_finder.example.yml} +3 -0
  39. data/lib/license_finder.rb +3 -2
  40. data/lib/license_finder/cli.rb +94 -49
  41. data/lib/license_finder/configuration.rb +21 -14
  42. data/lib/license_finder/dependency_manager.rb +27 -19
  43. data/lib/license_finder/license.rb +33 -19
  44. data/lib/license_finder/license/definitions.rb +153 -104
  45. data/lib/license_finder/license/matcher.rb +6 -1
  46. data/lib/license_finder/license/none_matcher.rb +9 -0
  47. data/lib/license_finder/license/text.rb +1 -0
  48. data/lib/license_finder/package.rb +30 -6
  49. data/lib/license_finder/package_managers/bower.rb +2 -2
  50. data/lib/license_finder/package_managers/bower_package.rb +2 -2
  51. data/lib/license_finder/package_managers/bundler.rb +9 -17
  52. data/lib/license_finder/package_managers/bundler_package.rb +1 -1
  53. data/lib/license_finder/package_managers/cocoa_pods.rb +35 -0
  54. data/lib/license_finder/package_managers/cocoa_pods_package.rb +19 -0
  55. data/lib/license_finder/package_managers/gradle.rb +9 -5
  56. data/lib/license_finder/package_managers/gradle_package.rb +4 -4
  57. data/lib/license_finder/package_managers/maven.rb +7 -3
  58. data/lib/license_finder/package_managers/maven_package.rb +5 -5
  59. data/lib/license_finder/package_managers/npm.rb +2 -2
  60. data/lib/license_finder/package_managers/npm_package.rb +2 -2
  61. data/lib/license_finder/package_managers/pip.rb +2 -2
  62. data/lib/license_finder/package_managers/pip_package.rb +7 -11
  63. data/lib/license_finder/package_saver.rb +12 -10
  64. data/lib/license_finder/possible_license_file.rb +1 -1
  65. data/lib/license_finder/possible_license_files.rb +11 -15
  66. data/lib/license_finder/reports/formatted_report.rb +25 -6
  67. data/lib/license_finder/reports/html_report.rb +2 -1
  68. data/lib/license_finder/reports/reporter.rb +3 -3
  69. data/lib/license_finder/tables.rb +6 -4
  70. data/lib/license_finder/tables/dependency.rb +36 -16
  71. data/lib/license_finder/tables/manual_approval.rb +13 -0
  72. data/lib/license_finder/yml_to_sql.rb +12 -9
  73. data/lib/templates/html_report.erb +68 -74
  74. data/lib/templates/markdown_report.erb +20 -21
  75. data/license_finder.gemspec +7 -7
  76. data/readme.md +76 -79
  77. data/spec/fixtures/Podfile +3 -0
  78. data/spec/lib/license_finder/cli_spec.rb +71 -23
  79. data/spec/lib/license_finder/configuration_spec.rb +61 -21
  80. data/spec/lib/license_finder/dependency_manager_spec.rb +52 -33
  81. data/spec/lib/license_finder/license/definitions_spec.rb +30 -14
  82. data/spec/lib/license_finder/license_spec.rb +55 -12
  83. data/spec/lib/license_finder/package_managers/bower_package_spec.rb +38 -19
  84. data/spec/lib/license_finder/package_managers/bower_spec.rb +10 -16
  85. data/spec/lib/license_finder/package_managers/bundler_package_spec.rb +39 -15
  86. data/spec/lib/license_finder/package_managers/bundler_spec.rb +10 -22
  87. data/spec/lib/license_finder/package_managers/cocoa_pods_package_spec.rb +44 -0
  88. data/spec/lib/license_finder/package_managers/cocoa_pods_spec.rb +79 -0
  89. data/spec/lib/license_finder/package_managers/gradle_package_spec.rb +4 -5
  90. data/spec/lib/license_finder/package_managers/gradle_spec.rb +26 -20
  91. data/spec/lib/license_finder/package_managers/maven_package_spec.rb +4 -5
  92. data/spec/lib/license_finder/package_managers/maven_spec.rb +16 -19
  93. data/spec/lib/license_finder/package_managers/npm_package_spec.rb +39 -19
  94. data/spec/lib/license_finder/package_managers/npm_spec.rb +10 -16
  95. data/spec/lib/license_finder/package_managers/pip_package_spec.rb +8 -8
  96. data/spec/lib/license_finder/package_managers/pip_spec.rb +10 -16
  97. data/spec/lib/license_finder/package_saver_spec.rb +27 -3
  98. data/spec/lib/license_finder/possible_license_file_spec.rb +25 -23
  99. data/spec/lib/license_finder/reports/detailed_text_report_spec.rb +6 -8
  100. data/spec/lib/license_finder/reports/html_report_spec.rb +45 -44
  101. data/spec/lib/license_finder/reports/markdown_report_spec.rb +8 -9
  102. data/spec/lib/license_finder/reports/reporter_spec.rb +1 -1
  103. data/spec/lib/license_finder/reports/text_report_spec.rb +6 -8
  104. data/spec/lib/license_finder/tables/dependency_spec.rb +57 -41
  105. data/spec/lib/license_finder/yml_to_sql_spec.rb +94 -92
  106. data/spec/spec_helper.rb +1 -0
  107. data/spec/support/stdout_helpers.rb +25 -0
  108. metadata +86 -69
  109. data/MIT.LICENSE +0 -20
  110. data/features/ignore_bundle_groups.feature +0 -23
  111. data/features/manually_managed_dependencies.feature +0 -19
  112. data/features/set_license.feature +0 -10
  113. data/features/step_definitions/approve_dependencies_steps.rb +0 -25
  114. data/features/step_definitions/html_report_steps.rb +0 -62
  115. data/features/step_definitions/ignore_bundle_groups_steps.rb +0 -29
  116. data/features/step_definitions/manually_managed_steps.rb +0 -33
  117. data/features/step_definitions/set_license_steps.rb +0 -20
  118. data/features/step_definitions/text_report_steps.rb +0 -19
  119. data/features/step_definitions/whitelist_steps.rb +0 -45
  120. data/files/dependency_breakdown.png +0 -0
  121. data/files/report_breakdown.png +0 -0
  122. data/lib/license_finder/license_url.rb +0 -9
  123. data/lib/license_finder/tables/license_alias.rb +0 -22
  124. data/spec/lib/license_finder/license_url_spec.rb +0 -16
  125. data/spec/lib/license_finder/tables/license_alias_spec.rb +0 -37
  126. 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
- `gradle downloadLicenses`
6
+ `#{LicenseFinder.config.gradle_command} downloadLicenses`
7
7
 
8
- xml = File.read('build/reports/license/dependency-license.xml')
8
+ xml = license_report.read
9
9
 
10
10
  options = {
11
11
  'GroupTags' => { 'dependencies' => 'dependency' }
12
12
  }
13
- XmlSimple.xml_in(xml, options)["dependency"].map do |d|
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
- File.exists?(package_path)
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').expand_path
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
- def license_from_files
31
+ private
32
+
33
+ def licenses_from_files
32
34
  []
33
35
  end
34
36
 
35
- private
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 = File.read('target/generated-resources/licenses.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
- File.exists?(package_path)
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').expand_path
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 licenses_from_spec
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
- File.exists?(package_path)
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').expand_path
43
+ Pathname.new('package.json')
44
44
  end
45
45
  end
46
46
  end
@@ -40,8 +40,8 @@ module LicenseFinder
40
40
  node_module["path"]
41
41
  end
42
42
 
43
- def licenses_from_spec
44
- Package.extract_licenses_from_standard_spec(node_module)
43
+ def license_names_from_spec
44
+ Package.license_names_from_standard_spec(node_module)
45
45
  end
46
46
  end
47
47
  end
@@ -26,13 +26,13 @@ print "[" + ",".join(dists) + "]"
26
26
  end
27
27
 
28
28
  def self.active?
29
- File.exists?(requirements_path)
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').expand_path
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 licenses_from_spec
36
+ def license_names_from_spec
37
37
  license = pypi_def["license"]
38
38
 
39
- if pypi_def["license"] && pypi_def["license"] != "UNKNOWN"
40
- return [license]
41
- else
42
- classifiers = pypi_def.fetch("classifiers", [])
43
- classifiers.map do |c|
44
- if c.start_with?("License")
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
- DB.transaction do
23
- dependency.version = version.to_s
24
- dependency.summary = summary
25
- dependency.description = description
26
- dependency.homepage = homepage
27
- dependency.bundler_group_names = groups.map(&:to_s)
28
- dependency.children_names = children
29
- dependency.apply_better_license license
30
- dependency.save_changes
31
- end
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
 
@@ -16,7 +16,7 @@ module LicenseFinder
16
16
  end
17
17
 
18
18
  def license
19
- License.find_by_text(text).pretty_name
19
+ License.find_by_text(text)
20
20
  end
21
21
  end
22
22
  end
@@ -1,18 +1,19 @@
1
1
  module LicenseFinder
2
2
  class PossibleLicenseFiles
3
- LICENSE_FILE_NAMES = %w(LICENSE License Licence COPYING README Readme ReadMe)
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
- paths_for_license_files.map do |path|
15
- get_file_for_path(path)
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 paths_for_license_files
24
- find_matching_files.map do |path|
25
- File.directory?(path) ? paths_for_files_in_license_directory(path) : path
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 find_matching_files
30
- Dir.glob(File.join(install_path, '**', "*{#{LICENSE_FILE_NAMES.join(',')}}*"))
30
+ def candidate_files_and_dirs
31
+ Pathname.glob(install_path.join('**', CANDIDATE_PATH_WILDCARD))
31
32
  end
32
33
 
33
- def paths_for_files_in_license_directory(path)
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
- license = License.find_by_name(dep.license.name)
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
@@ -1,3 +1,4 @@
1
1
  module LicenseFinder
2
- class HtmlReport < FormattedReport; end
2
+ class HtmlReport < FormattedReport
3
+ end
3
4
  end
@@ -3,7 +3,7 @@ module LicenseFinder
3
3
  extend self
4
4
 
5
5
  def write_reports
6
- dependencies = Dependency.all
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 LicenseFinder.config.artifacts.legacy_text_file.exist?
15
- LicenseFinder.config.artifacts.legacy_text_file.delete
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
- LicenseFinder::DB = Sequel.connect("#{LicenseFinder::Platform.sqlite_adapter}://#{LicenseFinder.config.artifacts.database_uri}")
6
- Sequel.extension :migration, :core_extensions
7
- Sequel::Migrator.run(LicenseFinder::DB, LicenseFinder::ROOT_PATH.join('../db/migrate'))
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
- many_to_one :license, class: LicenseAlias
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 managed
11
- manually_managed.invert
15
+ def added_automatically
16
+ added_manually.invert
12
17
  end
13
18
 
14
- def manually_managed
15
- where(manual: true)
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
- all.reject(&:approved?)
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.manually_approved = true
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
- (license && license.whitelisted?) || manually_approved?
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!(license_name)
49
- self.license = LicenseAlias.named(license_name)
50
- self.license_manual = true
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(license_name)
55
- return if license_manual
56
- if license.nil? || license.name != license_name
57
- self.license = LicenseAlias.named(license_name)
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