license_finder 2.0.0.rc2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -1
  3. data/CHANGELOG.rdoc +16 -9
  4. data/CONTRIBUTING.md +3 -3
  5. data/README.md +4 -1
  6. data/TODO.md +6 -19
  7. data/bin/license_finder_pip.py +2 -2
  8. data/features/features/cli_spec.rb +18 -18
  9. data/features/features/configure/add_dependencies_spec.rb +16 -16
  10. data/features/features/configure/approve_dependencies_spec.rb +10 -9
  11. data/features/features/configure/assign_licenses_spec.rb +8 -8
  12. data/features/features/configure/ignore_dependencies_spec.rb +15 -15
  13. data/features/features/configure/ignore_groups_spec.rb +15 -15
  14. data/features/features/configure/name_project_spec.rb +15 -14
  15. data/features/features/configure/whitelist_licenses_spec.rb +21 -21
  16. data/features/features/package_managers/bower_spec.rb +3 -3
  17. data/features/features/package_managers/cocoapods_spec.rb +4 -4
  18. data/features/features/package_managers/gradle_spec.rb +3 -3
  19. data/features/features/package_managers/maven_spec.rb +3 -3
  20. data/features/features/package_managers/npm_spec.rb +3 -3
  21. data/features/features/package_managers/pip_spec.rb +3 -3
  22. data/features/features/report/csv_spec.rb +9 -8
  23. data/features/features/report/html_spec.rb +13 -12
  24. data/features/support/testing_dsl.rb +1 -1
  25. data/lib/license_finder.rb +1 -16
  26. data/lib/license_finder/cli/approvals.rb +3 -4
  27. data/lib/license_finder/cli/base.rb +40 -3
  28. data/lib/license_finder/cli/dependencies.rb +3 -3
  29. data/lib/license_finder/cli/main.rb +7 -25
  30. data/lib/license_finder/cli/makes_decisions.rb +2 -20
  31. data/lib/license_finder/cli/patched_thor.rb +0 -2
  32. data/lib/license_finder/cli/whitelist.rb +6 -8
  33. data/lib/license_finder/configuration.rb +1 -1
  34. data/lib/license_finder/core.rb +68 -0
  35. data/lib/license_finder/decision_applier.rb +10 -7
  36. data/lib/license_finder/license.rb +10 -10
  37. data/lib/license_finder/license/template.rb +3 -2
  38. data/lib/license_finder/logger.rb +2 -6
  39. data/lib/license_finder/package.rb +25 -44
  40. data/lib/license_finder/package_manager.rb +11 -13
  41. data/lib/license_finder/package_managers/bower.rb +1 -1
  42. data/lib/license_finder/package_managers/bundler.rb +1 -1
  43. data/lib/license_finder/package_managers/cocoa_pods.rb +3 -3
  44. data/lib/license_finder/package_managers/cocoa_pods_package.rb +3 -3
  45. data/lib/license_finder/package_managers/gradle.rb +2 -2
  46. data/lib/license_finder/package_managers/maven.rb +2 -2
  47. data/lib/license_finder/package_managers/npm.rb +1 -1
  48. data/lib/license_finder/package_managers/pip.rb +1 -1
  49. data/lib/license_finder/package_managers/pip_package.rb +6 -4
  50. data/lib/license_finder/packages/activation.rb +54 -0
  51. data/lib/license_finder/{possible_license_files.rb → packages/license_files.rb} +9 -7
  52. data/lib/license_finder/packages/licensing.rb +43 -0
  53. data/lib/license_finder/{package_managers → packages}/manual_package.rb +0 -0
  54. data/lib/license_finder/{possible_license_file.rb → packages/possible_license_file.rb} +0 -2
  55. data/lib/license_finder/version.rb +1 -1
  56. data/spec/fixtures/{license_directory/LICENSE/Apache.txt → all_pms/Gemfile} +0 -0
  57. data/spec/fixtures/all_pms/Podfile +0 -0
  58. data/spec/fixtures/all_pms/bower.json +0 -0
  59. data/spec/fixtures/all_pms/build.gradle +0 -0
  60. data/spec/fixtures/all_pms/package.json +0 -0
  61. data/spec/fixtures/all_pms/pom.xml +0 -0
  62. data/spec/fixtures/all_pms/requirements.txt +0 -0
  63. data/spec/fixtures/license_directory/COPYING +1 -0
  64. data/spec/fixtures/license_directory/LICENSE/MIT.txt +1 -0
  65. data/spec/fixtures/license_names/COPYING.txt +1 -0
  66. data/spec/fixtures/license_names/LICENSE +1 -0
  67. data/spec/fixtures/license_names/Licence.rdoc +1 -0
  68. data/spec/fixtures/license_names/Mit-License +1 -0
  69. data/spec/fixtures/license_names/README.rdoc +1 -0
  70. data/spec/fixtures/nested_gem/vendor/LICENSE +1 -0
  71. data/spec/lib/license_finder/cli/approvals_spec.rb +9 -3
  72. data/spec/lib/license_finder/cli/dependencies_spec.rb +5 -2
  73. data/spec/lib/license_finder/cli/main_spec.rb +20 -27
  74. data/spec/lib/license_finder/configuration_spec.rb +1 -3
  75. data/spec/lib/license_finder/decision_applier_spec.rb +15 -15
  76. data/spec/lib/license_finder/decisions_spec.rb +94 -95
  77. data/spec/lib/license_finder/license_spec.rb +5 -5
  78. data/spec/lib/license_finder/package_managers/bower_package_spec.rb +0 -4
  79. data/spec/lib/license_finder/package_managers/bower_spec.rb +6 -27
  80. data/spec/lib/license_finder/package_managers/bundler_package_spec.rb +0 -2
  81. data/spec/lib/license_finder/package_managers/bundler_spec.rb +0 -15
  82. data/spec/lib/license_finder/package_managers/cocoa_pods_package_spec.rb +5 -2
  83. data/spec/lib/license_finder/package_managers/cocoa_pods_spec.rb +13 -31
  84. data/spec/lib/license_finder/package_managers/gradle_package_spec.rb +0 -2
  85. data/spec/lib/license_finder/package_managers/gradle_spec.rb +11 -35
  86. data/spec/lib/license_finder/package_managers/maven_package_spec.rb +0 -2
  87. data/spec/lib/license_finder/package_managers/maven_spec.rb +18 -56
  88. data/spec/lib/license_finder/package_managers/npm_package_spec.rb +0 -2
  89. data/spec/lib/license_finder/package_managers/npm_spec.rb +0 -17
  90. data/spec/lib/license_finder/package_managers/pip_package_spec.rb +0 -2
  91. data/spec/lib/license_finder/package_managers/pip_spec.rb +8 -25
  92. data/spec/lib/license_finder/package_spec.rb +2 -4
  93. data/spec/lib/license_finder/packages/activation_spec.rb +47 -0
  94. data/spec/lib/license_finder/{possible_license_files_spec.rb → packages/license_files_spec.rb} +2 -6
  95. data/spec/lib/license_finder/packages/licensing_spec.rb +1 -0
  96. data/spec/lib/license_finder/{possible_license_file_spec.rb → packages/possible_license_file_spec.rb} +0 -0
  97. data/spec/spec_helper.rb +2 -0
  98. data/spec/support/shared_examples_for_package_manager.rb +14 -1
  99. data/spec/support/test_fixtures.rb +7 -0
  100. metadata +117 -12
  101. data/spec/support/shared_examples_for_package.rb +0 -35
@@ -1,5 +1,3 @@
1
- require 'thor'
2
-
3
1
  module LicenseFinder
4
2
  module CLI
5
3
  module Rootcommand
@@ -12,19 +12,17 @@ module LicenseFinder
12
12
 
13
13
  auditable
14
14
  desc "add LICENSE...", "Add one or more licenses to the whitelist"
15
- def add(license, *other_licenses)
16
- licenses = modify_each(license, *other_licenses) do |l|
17
- decisions.whitelist(l, txn)
18
- end
15
+ def add(*licenses)
16
+ assert_some licenses
17
+ modifying { licenses.each { |l| decisions.whitelist(l, txn) } }
19
18
  say "Added #{licenses.join(", ")} to the license whitelist"
20
19
  end
21
20
 
22
21
  auditable
23
22
  desc "remove LICENSE...", "Remove one or more licenses from the whitelist"
24
- def remove(license, *other_licenses)
25
- licenses = modify_each(license, *other_licenses) do |l|
26
- decisions.unwhitelist(l, txn)
27
- end
23
+ def remove(*licenses)
24
+ assert_some licenses
25
+ modifying { licenses.each { |l| decisions.unwhitelist(l, txn) } }
28
26
  say "Removed #{licenses.join(", ")} from the license whitelist"
29
27
  end
30
28
  end
@@ -1,6 +1,6 @@
1
1
  module LicenseFinder
2
2
  class Configuration
3
- def self.with_optional_saved_config(primary_config, project_path = Pathname.new('.'))
3
+ def self.with_optional_saved_config(primary_config, project_path)
4
4
  config_file = project_path.join('config', 'license_finder.yml')
5
5
  saved_config = config_file.exist? ? YAML.load(config_file.read) : {}
6
6
  new(primary_config, saved_config)
@@ -0,0 +1,68 @@
1
+ require 'license_finder/logger'
2
+
3
+ require 'license_finder/license'
4
+
5
+ require 'license_finder/configuration'
6
+ require 'license_finder/package_manager'
7
+ require 'license_finder/decisions'
8
+ require 'license_finder/decision_applier'
9
+
10
+ require 'forwardable'
11
+ module LicenseFinder
12
+ # Coordinates setup
13
+ class Core
14
+ def self.default_logger
15
+ Logger::Default.new
16
+ end
17
+
18
+ # +options+ look like:
19
+ # {
20
+ # logger: { quiet: true, debug: false },
21
+ # project_path: "./some/project/path/"
22
+ # gradle_command: "gradlew",
23
+ # decisions_file: "./some/path.yml",
24
+ # }
25
+ # +gradle_command+ and +decisions_file+ are optional, see Configuration
26
+ def initialize(options)
27
+ @logger = Logger.new(options.fetch(:logger))
28
+ @project_path = Pathname(options.fetch(:project_path))
29
+ @config = Configuration.with_optional_saved_config(options, project_path)
30
+ @decisions = Decisions.saved!(config.decisions_file)
31
+ end
32
+
33
+ def modifying
34
+ yield
35
+ decisions.save!(config.decisions_file)
36
+ end
37
+
38
+ extend Forwardable
39
+ def_delegators :decision_applier, :acknowledged, :unapproved
40
+ attr_reader :decisions
41
+
42
+ def project_name
43
+ decisions.project_name || project_path.basename.to_s
44
+ end
45
+
46
+ private
47
+
48
+ attr_reader :config, :logger, :project_path
49
+
50
+ # The core of the system. The saved decisions are applied to the current
51
+ # packages.
52
+ def decision_applier
53
+ # lazy, do not move to `initialize`
54
+ DecisionApplier.new(decisions: decisions, packages: current_packages)
55
+ end
56
+
57
+ def current_packages
58
+ # lazy, do not move to `initialize`
59
+ PackageManager.current_packages(
60
+ logger: logger,
61
+ project_path: project_path,
62
+ gradle_command: config.gradle_command,
63
+ ignore_groups: decisions.ignored_groups
64
+ )
65
+ end
66
+ end
67
+ end
68
+
@@ -2,7 +2,7 @@ module LicenseFinder
2
2
  class DecisionApplier
3
3
  def initialize(options)
4
4
  @decisions = options.fetch(:decisions)
5
- @packages = options.fetch(:packages)
5
+ @system_packages = options.fetch(:packages)
6
6
  end
7
7
 
8
8
  def unapproved
@@ -10,16 +10,19 @@ module LicenseFinder
10
10
  end
11
11
 
12
12
  def acknowledged
13
- base_packages = decisions.packages + packages
14
- base_packages.
15
- reject { |package| ignored?(package) }.
16
- map { |package| with_decided_licenses(package) }.
17
- map { |package| with_approval(package) }
13
+ packages.reject { |package| ignored?(package) }
18
14
  end
19
15
 
20
16
  private
21
17
 
22
- attr_reader :packages, :decisions
18
+ attr_reader :system_packages, :decisions
19
+
20
+ def packages
21
+ result = decisions.packages + system_packages
22
+ result
23
+ .map { |package| with_decided_licenses(package) }
24
+ .map { |package| with_approval(package) }
25
+ end
23
26
 
24
27
  def ignored?(package)
25
28
  decisions.ignored?(package.name) ||
@@ -1,3 +1,13 @@
1
+ require "license_finder/license/text"
2
+ require "license_finder/license/template"
3
+
4
+ require "license_finder/license/matcher"
5
+ require "license_finder/license/header_matcher"
6
+ require "license_finder/license/any_matcher"
7
+ require "license_finder/license/none_matcher"
8
+
9
+ require "license_finder/license/definitions"
10
+
1
11
  module LicenseFinder
2
12
  class License
3
13
  class << self
@@ -55,13 +65,3 @@ module LicenseFinder
55
65
  end
56
66
  end
57
67
  end
58
-
59
- require "license_finder/license/text"
60
- require "license_finder/license/template"
61
-
62
- require "license_finder/license/matcher"
63
- require "license_finder/license/header_matcher"
64
- require "license_finder/license/any_matcher"
65
- require "license_finder/license/none_matcher"
66
-
67
- require "license_finder/license/definitions"
@@ -1,9 +1,10 @@
1
1
  module LicenseFinder
2
2
  class License
3
3
  class Template
4
+ TEMPLATE_PATH = ROOT_PATH.join("license", "templates")
5
+
4
6
  def self.named(name)
5
- path = ROOT_PATH.join("license", "templates", "#{name}.txt")
6
- new(path.read)
7
+ new TEMPLATE_PATH.join("#{name}.txt").read
7
8
  end
8
9
 
9
10
  attr_reader :content
@@ -28,10 +28,6 @@ module LicenseFinder
28
28
  end
29
29
  end
30
30
 
31
- def license package, package_name, license, how
32
- log package, sprintf("package %s: found license '%s' %s", package_name, license, how)
33
- end
34
-
35
31
  def log prefix, string
36
32
  raise NotImplementedError, "#log must be implemented"
37
33
  end
@@ -44,13 +40,13 @@ module LicenseFinder
44
40
 
45
41
  class Progress < Base
46
42
  def log prefix, string
47
- STDOUT.print(".") && STDOUT.flush
43
+ print(".") && $stdout.flush
48
44
  end
49
45
  end
50
46
 
51
47
  class Verbose < Base
52
48
  def log prefix, string
53
- STDOUT.printf("%s: %s\n", prefix, string)
49
+ printf("%s: %s\n", prefix, string)
54
50
  end
55
51
  end
56
52
 
@@ -1,21 +1,19 @@
1
+ require 'license_finder/packages/licensing'
2
+ require 'license_finder/packages/license_files'
3
+
1
4
  module LicenseFinder
2
5
  # Super-class that adapts data from different package management
3
6
  # systems (gems, npm, pip, etc.) to a common interface.
4
7
  #
5
- # For guidance on adding a new system use the shared behavior
6
- #
7
- # it_behaves_like "a Package"
8
- #
9
- # Additional guidelines are:
10
- #
11
- # - if you're going to use Package#licenses ...
12
- # - and the package spec will report licenses,
13
- # pass :spec_licenses in the constructor options
14
- # - and the package's files can be searched for licenses
15
- # pass :install_path in the constructor options
16
- # - else
17
- # - implement #licenses
8
+ # Guidance on adding a new system
18
9
  #
10
+ # - subclass Package, and initialize based on the data you receive from the
11
+ # package manager
12
+ # - if the package specs will report license names, pass :spec_licenses in the
13
+ # constructor options
14
+ # - if the package's files can be searched for licenses pass :install_path in
15
+ # the constructor options
16
+ # - otherwise, override #licenses_from_spec or #license_files
19
17
  class Package
20
18
  attr_reader :logger
21
19
 
@@ -32,7 +30,7 @@ module LicenseFinder
32
30
  end
33
31
 
34
32
  def initialize(name, version = nil, options={})
35
- @logger = options[:logger] || LicenseFinder::Logger::Default.new
33
+ @logger = options[:logger] || Core.default_logger
36
34
 
37
35
  @name = name
38
36
  @version = version
@@ -88,20 +86,17 @@ module LicenseFinder
88
86
  attr_reader :install_path # checked in tests, otherwise private
89
87
 
90
88
  def licenses
91
- @licenses ||= determine_licenses.to_set
89
+ @licenses ||= activations.map(&:license).to_set
92
90
  end
93
91
 
94
- def determine_licenses
95
- dl = @decided_licenses
96
- return dl if dl.any?
97
-
98
- lfs = licenses_from_spec
99
- return lfs if lfs.any?
100
-
101
- lff = licenses_from_files
102
- return lff if lff.any?
92
+ def activations
93
+ licensing.activations.tap do |activations|
94
+ activations.each { |activation| activation.log(logger) }
95
+ end
96
+ end
103
97
 
104
- [default_license].to_set
98
+ def licensing
99
+ Licensing.new(self, @decided_licenses, licenses_from_spec, license_files)
105
100
  end
106
101
 
107
102
  def decide_on_license(license)
@@ -109,27 +104,13 @@ module LicenseFinder
109
104
  end
110
105
 
111
106
  def licenses_from_spec
112
- license_names_from_spec.map do |name|
113
- License.find_by_name(name).tap do |license|
114
- logger.license self.class, self.name, license.name, "from spec" if license
115
- end
116
- end.compact.to_set
117
- end
118
-
119
- def licenses_from_files
120
- license_files.map do |license_file|
121
- license_file.license.tap do |license|
122
- logger.license self.class, self.name, license.name, "from file '#{license_file.path}'" if license
123
- end
124
- end.compact.to_set
107
+ license_names_from_spec
108
+ .map { |name| License.find_by_name(name) }
109
+ .to_set
125
110
  end
126
111
 
127
112
  def license_files
128
- PossibleLicenseFiles.find(install_path)
129
- end
130
-
131
- def default_license
132
- License.find_by_name nil
113
+ LicenseFiles.find(install_path)
133
114
  end
134
115
 
135
116
  def missing?
@@ -138,7 +119,7 @@ module LicenseFinder
138
119
  end
139
120
  end
140
121
 
141
- require 'license_finder/package_managers/manual_package'
122
+ require 'license_finder/packages/manual_package'
142
123
  require 'license_finder/package_managers/bower_package'
143
124
  require 'license_finder/package_managers/bundler_package'
144
125
  require 'license_finder/package_managers/pip_package'
@@ -17,22 +17,20 @@ module LicenseFinder
17
17
  end
18
18
 
19
19
  def self.current_packages(options)
20
- package_managers.
21
- map { |pm| pm.new(options) }.
22
- select(&:active?).
23
- map(&:current_packages_with_relations).
24
- flatten
20
+ package_managers
21
+ .map { |pm| pm.new(options) }
22
+ .select(&:active?)
23
+ .flat_map(&:current_packages_with_relations)
25
24
  end
26
25
 
27
- attr_reader :logger
28
-
29
26
  def initialize options={}
30
- @logger = options[:logger] || LicenseFinder::Logger::Default.new
31
- @package_path = options[:package_path] # dependency injection for tests
27
+ @logger = options[:logger] || Core.default_logger
28
+ @project_path = options[:project_path]
32
29
  end
33
30
 
34
31
  def active?
35
- injected_package_path.exist?.tap { |is_active| logger.active self.class, is_active }
32
+ package_path.exist?
33
+ .tap { |is_active| logger.active self.class, is_active }
36
34
  end
37
35
 
38
36
  def current_packages_with_relations
@@ -48,9 +46,7 @@ module LicenseFinder
48
46
 
49
47
  private
50
48
 
51
- def injected_package_path
52
- @package_path || package_path
53
- end
49
+ attr_reader :logger, :project_path
54
50
  end
55
51
  end
56
52
 
@@ -61,3 +57,5 @@ require 'license_finder/package_managers/pip'
61
57
  require 'license_finder/package_managers/maven'
62
58
  require 'license_finder/package_managers/cocoa_pods'
63
59
  require 'license_finder/package_managers/gradle'
60
+
61
+ require 'license_finder/package'
@@ -15,7 +15,7 @@ module LicenseFinder
15
15
  private
16
16
 
17
17
  def package_path
18
- Pathname.new('bower.json')
18
+ project_path.join('bower.json')
19
19
  end
20
20
  end
21
21
  end
@@ -28,7 +28,7 @@ module LicenseFinder
28
28
  end
29
29
 
30
30
  def package_path
31
- Pathname.new("Gemfile")
31
+ project_path.join("Gemfile")
32
32
  end
33
33
 
34
34
  def bundler_defs
@@ -19,11 +19,11 @@ module LicenseFinder
19
19
  private
20
20
 
21
21
  def package_path
22
- Pathname.new("Podfile")
22
+ project_path.join("Podfile")
23
23
  end
24
24
 
25
25
  def lockfile_path
26
- Pathname.new("Podfile.lock")
26
+ project_path.join("Podfile.lock")
27
27
  end
28
28
 
29
29
  def acknowledgements_path
@@ -33,7 +33,7 @@ module LicenseFinder
33
33
  'Pods/Target Support Files/Pods' # cocoapods >= 0.34
34
34
  ]
35
35
 
36
- directories.map { |dir| Pathname.new(dir).join(filename) }.find(&:exist?)
36
+ directories.map { |dir| project_path.join(dir, filename) }.find(&:exist?)
37
37
  end
38
38
 
39
39
  def read_plist pathname
@@ -2,11 +2,11 @@ module LicenseFinder
2
2
  class CocoaPodsPackage < Package
3
3
  def initialize(name, version, license_text)
4
4
  super(name, version)
5
- @license_text = license_text
5
+ @license = License.find_by_text(license_text.to_s)
6
6
  end
7
7
 
8
- def licenses
9
- [License.find_by_text(@license_text.to_s) || default_license].to_set
8
+ def licenses_from_spec
9
+ [@license].compact
10
10
  end
11
11
  end
12
12
  end
@@ -23,11 +23,11 @@ module LicenseFinder
23
23
  private
24
24
 
25
25
  def license_report
26
- Pathname.new('build/reports/license/dependency-license.xml')
26
+ project_path.join('build/reports/license/dependency-license.xml')
27
27
  end
28
28
 
29
29
  def package_path
30
- Pathname.new('build.gradle')
30
+ project_path.join('build.gradle')
31
31
  end
32
32
  end
33
33
  end
@@ -21,11 +21,11 @@ module LicenseFinder
21
21
  private
22
22
 
23
23
  def license_report
24
- Pathname.new('target/generated-resources/licenses.xml')
24
+ project_path.join('target/generated-resources/licenses.xml')
25
25
  end
26
26
 
27
27
  def package_path
28
- Pathname.new('pom.xml')
28
+ project_path.join('pom.xml')
29
29
  end
30
30
  end
31
31
  end