licensed 3.9.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8fc5dda597e72ea3231515620aa042c3daaa07ae652d78328000048fb476386e
4
- data.tar.gz: a772502d860cefdd4a6710432a3a5406abc2c81bd99dd82307b9ddbaf47d40cd
3
+ metadata.gz: 4c0f6c78059b52e669e7febd8a0a146c7d2bc1d2ff9c7a4e962941470a13845c
4
+ data.tar.gz: 14c6ff763c08e1317b430704fe8ec4552373f9ab24df80838f114fdb4d1fe906
5
5
  SHA512:
6
- metadata.gz: f5dd491826706986ac7503340ab6dddd122653f394b313e96f3cf0652502cedfc0e201b660ac657591e3e4fde507e6c60237680118e90ca053ab27effa35b0f6
7
- data.tar.gz: aed36ca1cf19673579fa8ffdf0e196e3e8edff5111515dcd0b3c0afcdf90d1b2e79ba558366f548ede7d6a86bdc1f37218967ed28943f9c05151d5a5450fbefb
6
+ metadata.gz: 7c7af4fe377c93becf816adab3b549452dba206aaf03080f18c42f944991f3572e4822ba768c6cc0ef1f320a81b9643738313097637f6da548b5285180a89ae2
7
+ data.tar.gz: be4466294a92d6cdb807fb6ace47b2ff0231430b118e60c7059dbfed92379a4e827e75f9df276e916c034f8f9a7226a95ef621239f1dbd0baecb942a30427a1a
data/CHANGELOG.md CHANGED
@@ -6,6 +6,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## 4.0.0
10
+
11
+ ### Added
12
+
13
+ - Licensed supports Cocoapods as a dependency source (:tada: @LouisBoudreau https://github.com/github/licensed/pull/584)
14
+ - Licensed supports Gradle multi-project builds (:tada: @LouisBoudreau https://github.com/github/licensed/pull/583)
15
+
16
+ ### Fixed
17
+
18
+ - Licensed no longer crashes when run with Bundler >= 2.4.0 (:tada: @JoshReedSchramm https://github.com/github/licensed/pull/597)
19
+
20
+ ### Changed
21
+
22
+ - BREAKING: Licensed no longer ships executables with releases (https://github.com/github/licensed/pull/586)
23
+ - BREAKING: Licensed no longer includes support for Go <= 1.11 (https://github.com/github/licensed/pull/602)
24
+
9
25
  ## 3.9.1
10
26
 
11
27
  ### Fixed
@@ -661,4 +677,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
661
677
 
662
678
  Initial release :tada:
663
679
 
664
- [Unreleased]: https://github.com/github/licensed/compare/3.9.1...HEAD
680
+ [Unreleased]: https://github.com/github/licensed/compare/4.0.0...HEAD
data/CONTRIBUTING.md CHANGED
@@ -59,8 +59,6 @@ The following steps will happen automatically from a GitHub Actions workflow
59
59
  after creating the release. In case that fails, the following steps can be performed manually
60
60
 
61
61
  11. Push the gem from (7) to rubygems.org -- `gem push licensed-x.xx.xx.gem`
62
- 12. Build packages for new tag: `VERSION=x.xx.xx bundle exec rake package`
63
- 13. Upload packages from (12) to release from (10)
64
62
 
65
63
  ## Resources
66
64
 
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # Licensed
2
2
 
3
- Licensed caches the licenses of dependencies and checks their status.
4
-
5
- Licensed is available as a Ruby gem for Ruby environments, and as a self-contained executable for non-Ruby environments.
3
+ Licensed caches the licenses of dependencies and checks their status, and is available as a Ruby gem.
6
4
 
7
5
  Licensed is **not** a complete open source license compliance solution. Please understand the important [disclaimer](#disclaimer) below to make appropriate use of Licensed.
8
6
 
@@ -12,6 +10,10 @@ Licensed is **not** a complete open source license compliance solution. Please u
12
10
 
13
11
  Licensed is in active development and currently used at GitHub. See the [open issues](https://github.com/github/licensed/issues) for a list of potential work.
14
12
 
13
+ ## Licensed v4 - **Removed support for non-Ruby environments**
14
+
15
+ Licensed v4 no longer provides a self-contained executable build of licensed. Please see [the deprecation notice](https://github.com/github/licensed/issues/585) for more context.
16
+
15
17
  ## Licensed v3
16
18
 
17
19
  Licensed v3 includes a breaking change if both of the following are true:
@@ -59,19 +61,12 @@ And then execute:
59
61
  $> bundle
60
62
  ```
61
63
 
62
- ### As an executable
63
-
64
- Download a package from GitHub and extract the executable. Executable packages are available for each release starting with version 1.2.0.
64
+ ### With a Homebrew (on macOS)
65
65
 
66
66
  ```bash
67
- $> curl -sSL https://github.com/github/licensed/releases/download/<version>/licensed-<version>-<os>-x64.tar.gz > licensed.tar.gz
68
- $> tar -xzf licensed.tar.gz
69
- $> rm -f licensed.tar.gz
70
- $> ./licensed list
67
+ brew install licensed
71
68
  ```
72
69
 
73
- For system wide usage, install licensed to a location on `$PATH`, e.g. `/usr/local/bin`.
74
-
75
70
  ## Usage
76
71
 
77
72
  See [getting started](./docs/getting_started.md) for guidance using Licensed as part of your developer workflow.
data/Rakefile CHANGED
@@ -72,32 +72,6 @@ Rake::TestTask.new(:test) do |t|
72
72
  t.test_files = FileList["test/**/*_test.rb"].exclude("test/fixtures/**/*_test.rb")
73
73
  end
74
74
 
75
- packages_search = File.expand_path("script/packages/*", __dir__)
76
- platforms = Dir[packages_search].map { |f| File.basename(f, ".*") }
77
- .reject { |f| f == "build" }
78
-
79
- namespace :package do
80
- platforms.each do |platform|
81
- desc "Package licensed for #{platform}"
82
- task platform.to_sym do
83
- puts "Packaging licensed for #{platform}"
84
-
85
- if Bundler.with_original_env { system("script/packages/#{platform}") }
86
- # green
87
- puts "\033[32mCompleted packaging for #{platform}.\e[0m"
88
- else
89
- # red
90
- puts "\033[31mEncountered an error packaging for #{platform}.\e[0m"
91
- end
92
-
93
- puts
94
- end
95
- end
96
- end
97
-
98
- desc "Package licensed for all platforms"
99
- task package: platforms.map { |platform| "package:#{platform}" }
100
-
101
75
  # add rubocop task
102
76
  # -S adds styleguide urls to offense messages
103
77
  RuboCop::RakeTask.new do |t|
@@ -2,8 +2,6 @@
2
2
 
3
3
  The bundler source will detect dependencies `Gemfile` and `Gemfile.lock` files are found at an apps `source_path`. The source uses the `Bundler` API to enumerate dependencies from `Gemfile` and `Gemfile.lock`.
4
4
 
5
- **Note** The bundler source cannot be used when running the [packaged licensed executable](../packaging.md)
6
-
7
5
  ### Excluding gem groups
8
6
 
9
7
  The bundler source determines which gem groups to include or exclude with the following logic, in order of precedence.
@@ -0,0 +1,15 @@
1
+ # CocoaPods
2
+
3
+ The cocoapods source will detect dependencies when `Podfile` and `Podfile.lock` are found at an app's `source_path`.
4
+
5
+ It uses the `pod` CLI commands to enumerate dependencies and gather metadata on each package.
6
+
7
+ ### Evaluating dependencies from a specific target
8
+
9
+ The `cocoapods.targets` property is used to specify which targets to analyze dependencies from. By default, dependencies from all targets will be analyzed.
10
+
11
+ ```yml
12
+ cocoapods:
13
+ targets:
14
+ - ios
15
+ ```
@@ -14,3 +14,11 @@ gradle:
14
14
  - runtime
15
15
  - runtimeClassPath
16
16
  ```
17
+ ### Multi-build projects
18
+
19
+ To run `licensed` for specific projects in a [multi-build project](https://docs.gradle.org/current/userguide/multi_project_builds.html) you must specify the [apps](../configuration/application_source.md) configuration key.
20
+
21
+ ```yml
22
+ apps:
23
+ - source_path: ./path/to/subproject
24
+ ```
@@ -355,7 +355,6 @@ module Licensed
355
355
  def default_options
356
356
  # manually set a cache path without additional name
357
357
  {
358
- "source_path" => Dir.pwd,
359
358
  "cache_path" => AppConfiguration::DEFAULT_CACHE_PATH
360
359
  }
361
360
  end
@@ -18,7 +18,7 @@ module Licensed
18
18
 
19
19
  all_dependencies = requested_dependencies.concat(specs.flat_map(&:dependencies))
20
20
  if all_dependencies.any? { |d| d.name == "bundler" } && !specs["bundler"].any?
21
- bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", ::Bundler::VERSION)).last
21
+ bundler = sources.metadata_source.specs.search(bundler_query).last
22
22
  specs["bundler"] = bundler
23
23
  end
24
24
 
@@ -26,6 +26,14 @@ module Licensed
26
26
  end
27
27
  end
28
28
 
29
+ def bundler_query
30
+ if Gem::Version.new(::Bundler::VERSION) >= Gem::Version.new("2.4.0")
31
+ ["bundler", ::Bundler.gem_version]
32
+ else
33
+ Gem::Dependency.new("bundler", ::Bundler::VERSION)
34
+ end
35
+ end
36
+
29
37
  # Override requested_groups to also exclude any groups that are
30
38
  # in the "bundler.without" section of the licensed configuration file.
31
39
  def requested_groups
@@ -39,13 +39,8 @@ module Licensed
39
39
  end
40
40
 
41
41
  DEFAULT_WITHOUT_GROUPS = %i{development test}
42
- RUBY_PACKER_ERROR = "The bundler source cannot be used from the executable built with ruby-packer. Please install licensed using `gem install` or using bundler."
43
42
 
44
43
  def enabled?
45
- # running a ruby-packer-built licensed exe when ruby isn't available
46
- # could lead to errors if the host ruby doesn't exist
47
- return false if ruby_packer? && !Licensed::Shell.tool_available?("ruby")
48
-
49
44
  # if Bundler isn't loaded, this enumerator won't work!
50
45
  return false unless defined?(::Bundler)
51
46
 
@@ -55,8 +50,6 @@ module Licensed
55
50
  end
56
51
 
57
52
  def enumerate_dependencies
58
- raise Licensed::Sources::Source::Error.new(RUBY_PACKER_ERROR) if ruby_packer?
59
-
60
53
  with_application_environment do
61
54
  definition.specs.map do |spec|
62
55
  next if spec.name == config["name"]
@@ -126,11 +119,6 @@ module Licensed
126
119
  # reload the bundler environment after enumeration
127
120
  ::Bundler.load
128
121
  end
129
-
130
- # Returns whether the current licensed execution is running ruby-packer
131
- def ruby_packer?
132
- @ruby_packer ||= RbConfig::TOPDIR =~ /__enclose_io_memfs__/
133
- end
134
122
  end
135
123
  end
136
124
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ require "json"
3
+ require "pathname"
4
+ require "uri"
5
+ require "cocoapods-core"
6
+
7
+ module Licensed
8
+ module Sources
9
+ class Cocoapods < Source
10
+ def enabled?
11
+ return unless Licensed::Shell.tool_available?("pod")
12
+
13
+ config.pwd.join("Podfile").exist? && config.pwd.join("Podfile.lock").exist?
14
+ end
15
+
16
+ def enumerate_dependencies
17
+ pods.map do |pod|
18
+ name = pod.name
19
+ path = dependency_path(pod.root_name)
20
+ version = lockfile.version(name).version
21
+
22
+ Dependency.new(
23
+ path: path,
24
+ name: name,
25
+ version: version,
26
+ metadata: { "type" => Cocoapods.type }
27
+ )
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def pods
34
+ return lockfile.dependencies if targets.nil?
35
+
36
+ targets_to_validate = podfile.target_definition_list.filter { |t| targets.include?(t.label) }
37
+ if targets_to_validate.any?
38
+ targets_to_validate.map(&:dependencies).flatten
39
+ else
40
+ raise Licensed::Sources::Source::Error, "Unable to find any target in the Podfile matching the ones provided in the config."
41
+ end
42
+ end
43
+
44
+ def targets
45
+ @targets ||= config.dig("cocoapods", "targets")&.map { |t| "Pods-#{t}" }
46
+ end
47
+
48
+ def lockfile
49
+ @lockfile ||= Pod::Lockfile.from_file(config.pwd.join("Podfile.lock"))
50
+ end
51
+
52
+ def podfile
53
+ @podfile ||= Pod::Podfile.from_file(config.pwd.join("Podfile"))
54
+ end
55
+
56
+ def dependency_path(name)
57
+ config.pwd.join("Pods/#{name}")
58
+ end
59
+ end
60
+ end
61
+ end
@@ -36,27 +36,13 @@ module Licensed
36
36
 
37
37
  # Returns an array of dependency package import paths
38
38
  def packages
39
- dependency_packages =
40
- if go_version < Gem::Version.new("1.11.0")
41
- root_package_deps
42
- else
43
- go_list_deps
44
- end
45
-
46
39
  # don't include go std packages
47
40
  # don't include packages under the root project that aren't vendored
48
- dependency_packages
41
+ go_list_deps
49
42
  .reject { |pkg| go_std_package?(pkg) }
50
43
  .reject { |pkg| local_package?(pkg) }
51
44
  end
52
45
 
53
- # Returns non-ignored packages found from the root packages "Deps" property
54
- def root_package_deps
55
- # check for ignored packages to avoid raising errors calling `go list`
56
- # when ignored package is not found
57
- Parallel.map(Array(root_package["Deps"])) { |name| package_info(name) }
58
- end
59
-
60
46
  # Returns the list of dependencies as returned by "go list -json -deps"
61
47
  # available in go 1.11
62
48
  def go_list_deps
@@ -188,13 +174,6 @@ module Licensed
188
174
  package["ImportPath"]
189
175
  end
190
176
 
191
- # Returns a hash of information about the package with a given import path
192
- #
193
- # import_path - Go package import path
194
- def package_info(import_path)
195
- JSON.parse(package_info_command(import_path))
196
- end
197
-
198
177
  # Returns package information as a JSON string
199
178
  #
200
179
  # args - additional arguments to `go list`, e.g. Go package import path
@@ -202,11 +181,6 @@ module Licensed
202
181
  Licensed::Shell.execute("go", "list", "-e", "-json", *Array(args)).strip
203
182
  end
204
183
 
205
- # Returns the info for the package under test
206
- def root_package
207
- @root_package ||= package_info(".")
208
- end
209
-
210
184
  # Returns whether go source is found
211
185
  def go_source?
212
186
  with_configured_gopath { Licensed::Shell.success?("go", "doc") }
@@ -230,15 +204,6 @@ module Licensed
230
204
  end
231
205
  end
232
206
 
233
- # Returns the current version of go available, as a Gem::Version
234
- def go_version
235
- @go_version ||= begin
236
- full_version = Licensed::Shell.execute("go", "version").strip
237
- version_string = full_version.gsub(%r{.*go(\d+\.\d+(\.\d+)?).*}, "\\1")
238
- Gem::Version.new(version_string)
239
- end
240
- end
241
-
242
207
  private
243
208
 
244
209
  # Execute a block with ENV["GOPATH"] set to the value of #gopath.
@@ -9,53 +9,19 @@ require "fileutils"
9
9
  module Licensed
10
10
  module Sources
11
11
  class Gradle < Source
12
-
13
12
  DEFAULT_CONFIGURATIONS = ["runtime", "runtimeClasspath"].freeze
14
13
  GRADLE_LICENSES_PATH = ".gradle-licenses".freeze
15
-
14
+ GRADLE_LICENSES_CSV_NAME = "licenses.csv".freeze
16
15
  class Dependency < Licensed::Dependency
17
- GRADLE_LICENSES_CSV_NAME = "licenses.csv".freeze
18
-
19
16
  class << self
20
- # Returns a key to uniquely identify a name and version in the obtained CSV content
21
- def csv_key(name:, version:)
22
- "#{name}-#{version}"
23
- end
24
-
25
- # Loads and caches license report CSV data as a hash of :name-:version => :url pairs
26
- #
27
- # executable - The gradle executable to run to generate the license report
28
- # configurations - The gradle configurations to generate license report for
29
- #
30
- # Returns a hash of dependency identifiers to their license content URL
31
- def load_csv(path, executable, configurations)
32
- @csv ||= begin
33
- gradle_licenses_dir = File.join(path, GRADLE_LICENSES_PATH)
34
- Licensed::Sources::Gradle.gradle_command("generateLicenseReport", path: path, executable: executable, configurations: configurations)
35
- CSV.foreach(File.join(gradle_licenses_dir, GRADLE_LICENSES_CSV_NAME), headers: true).each_with_object({}) do |row, hsh|
36
- name, _, version = row["artifact"].rpartition(":")
37
- key = csv_key(name: name, version: version)
38
- hsh[key] = row["moduleLicenseUrl"]
39
- end
40
- ensure
41
- FileUtils.rm_rf(gradle_licenses_dir)
42
- end
43
- end
44
-
45
- # Returns the cached url for the given dependency
46
- def url_for(dependency)
47
- @csv[csv_key(name: dependency.name, version: dependency.version)]
48
- end
49
-
50
17
  # Cache and return the results of getting the license content.
51
18
  def retrieve_license(url)
52
19
  (@licenses ||= {})[url] ||= Net::HTTP.get(URI(url))
53
20
  end
54
21
  end
55
22
 
56
- def initialize(name:, version:, path:, executable:, configurations:, metadata: {})
57
- @configurations = configurations
58
- @executable = executable
23
+ def initialize(name:, version:, path:, url:, metadata: {})
24
+ @url = url
59
25
  super(name: name, version: version, path: path, metadata: metadata)
60
26
  end
61
27
 
@@ -68,32 +34,27 @@ module Licensed
68
34
 
69
35
  # Returns a Licensee::ProjectFiles::LicenseFile for the dependency
70
36
  def project_files
71
- self.class.load_csv(path, @executable, @configurations)
72
- url = self.class.url_for(self)
37
+ return [] if @url.nil?
73
38
 
74
- return [] if url.nil?
75
-
76
- license_data = self.class.retrieve_license(url)
77
-
78
- Array(Licensee::ProjectFiles::LicenseFile.new(license_data, { uri: url }))
39
+ license_data = self.class.retrieve_license(@url)
40
+ Array(Licensee::ProjectFiles::LicenseFile.new(license_data, { uri: @url }))
79
41
  end
80
42
  end
81
43
 
82
44
  def enabled?
83
- !gradle_executable.to_s.empty? && File.exist?(config.pwd.join("build.gradle"))
45
+ gradle_runner.enabled? && File.exist?(config.pwd.join("build.gradle"))
84
46
  end
85
47
 
86
48
  def enumerate_dependencies
87
- JSON.parse(self.class.gradle_command("printDependencies", path: config.pwd, executable: gradle_executable, configurations: configurations)).map do |package|
88
- name = "#{package["group"]}:#{package["name"]}"
49
+ JSON.parse(gradle_runner.run("printDependencies", config.source_path)).map do |package|
50
+ name = "#{package['group']}:#{package['name']}"
89
51
  Dependency.new(
90
52
  name: name,
91
53
  version: package["version"],
92
54
  path: config.pwd,
93
- executable: gradle_executable,
94
- configurations: configurations,
55
+ url: package_url(name: name, version: package["version"]),
95
56
  metadata: {
96
- "type" => Gradle.type
57
+ "type" => Gradle.type,
97
58
  }
98
59
  )
99
60
  end
@@ -101,13 +62,8 @@ module Licensed
101
62
 
102
63
  private
103
64
 
104
- def gradle_executable
105
- return @gradle_executable if defined?(@gradle_executable)
106
- @gradle_executable = begin
107
- gradlew = File.join(config.pwd, "gradlew")
108
- return gradlew if File.executable?(gradlew)
109
- "gradle" if Licensed::Shell.tool_available?("gradle")
110
- end
65
+ def gradle_runner
66
+ @gradle_runner ||= Runner.new(config.pwd, configurations)
111
67
  end
112
68
 
113
69
  # Returns the configurations to include in license generation.
@@ -122,61 +78,134 @@ module Licensed
122
78
  end
123
79
  end
124
80
 
125
- def self.add_gradle_license_report_plugins_block(gradle_build_file)
81
+ # Returns a key to uniquely identify a name and version in the obtained CSV content
82
+ def csv_key(name:, version:)
83
+ "#{name}-#{version}"
84
+ end
126
85
 
127
- if gradle_build_file.include? "plugins"
128
- gradle_build_file.gsub(/(?<=plugins)\s+{/, " { id 'com.github.jk1.dependency-license-report' version '1.16'")
129
- else
86
+ def package_url(name:, version:)
87
+ # load and memoize the license report CSV
88
+ @urls ||= load_csv
130
89
 
131
- gradle_build_file = " plugins { id 'com.github.jk1.dependency-license-report' version '1.16' }" + gradle_build_file
90
+ # uniquely identify a name and version in the obtained CSV content
91
+ @urls["#{name}-#{version}"]
92
+ end
93
+
94
+ def load_csv
95
+ begin
96
+ # create the CSV file including dependency license urls using the gradle plugin
97
+ gradle_licenses_dir = File.join(config.root, GRADLE_LICENSES_PATH)
98
+ gradle_runner.run("generateLicenseReport", config.source_path)
99
+
100
+ # parse the CSV report for dependency license urls
101
+ CSV.foreach(File.join(gradle_licenses_dir, GRADLE_LICENSES_CSV_NAME), headers: true).each_with_object({}) do |row, hsh|
102
+ name, _, version = row["artifact"].rpartition(":")
103
+ key = csv_key(name: name, version: version)
104
+ hsh[key] = row["moduleLicenseUrl"]
105
+ end
106
+ ensure
107
+ FileUtils.rm_rf(gradle_licenses_dir)
132
108
  end
133
109
  end
134
110
 
135
- def self.gradle_command(*args, path:, executable:, configurations:)
136
- gradle_build_file = File.read("build.gradle")
111
+ # Returns the cached url for the given dependency
112
+ def url_for(dependency)
113
+ @csv[csv_key(name: dependency.name, version: dependency.version)]
114
+ end
137
115
 
138
- if !gradle_build_file.include? "dependency-license-report"
139
- gradle_build_file = Licensed::Sources::Gradle.add_gradle_license_report_plugins_block(gradle_build_file)
116
+ # The Gradle::Runner class is a wrapper which provides
117
+ # an interface to run gradle commands with the init script initialized
118
+ class Runner
119
+ def initialize(root_path, configurations)
120
+ @root_path = root_path
121
+ @init_script = create_init_script(root_path, configurations)
140
122
  end
141
123
 
142
- Dir.chdir(path) do
143
- Tempfile.create(["license-", ".gradle"], path) do |f|
144
- f.write(gradle_build_file)
145
- f.write gradle_file(configurations)
146
- f.close
147
- Licensed::Shell.execute(executable, "-q", "-b", f.path, *args)
148
- end
124
+ def run(command, source_path)
125
+ args = [format_command(command, source_path)]
126
+ # The configuration cache is an incubating feature that can be activated manually.
127
+ # The gradle plugin for licenses does not support it so we prevent it to run for gradle version supporting it.
128
+ args << "--no-configuration-cache" if gradle_version >= "6.6"
129
+ Licensed::Shell.execute(executable, "-q", "--init-script", @init_script.path, *args)
149
130
  end
150
- end
151
131
 
152
- def self.gradle_file(configurations)
153
- <<~EOF
132
+ def enabled?
133
+ !executable.to_s.empty?
134
+ end
154
135
 
155
- import com.github.jk1.license.render.CsvReportRenderer
156
- import com.github.jk1.license.filter.LicenseBundleNormalizer
136
+ private
137
+
138
+ def gradle_version
139
+ @gradle_version ||= Licensed::Shell.execute(executable, "--version").scan(/Gradle [\d+]\.[\d+]/).last.split(" ").last
140
+ end
157
141
 
158
- final configs = #{configurations.inspect}
142
+ def executable
143
+ return @executable if defined?(@executable)
159
144
 
160
- licenseReport {
161
- configurations = configs
162
- outputDir = "$projectDir/#{GRADLE_LICENSES_PATH}"
163
- renderers = [new CsvReportRenderer()]
164
- filters = [new LicenseBundleNormalizer()]
165
- }
145
+ @executable = begin
146
+ gradlew = File.join(@root_path, "gradlew")
147
+ return gradlew if File.executable?(gradlew)
166
148
 
167
- task printDependencies {
168
- doLast {
169
- def dependencies = []
170
- configs.each {
171
- configurations[it].resolvedConfiguration.resolvedArtifacts.each { artifact ->
172
- def id = artifact.moduleVersion.id
173
- dependencies << " { \\"group\\": \\"${id.group}\\", \\"name\\": \\"${id.name}\\", \\"version\\": \\"${id.version}\\" }"
149
+ "gradle" if Licensed::Shell.tool_available?("gradle")
150
+ end
151
+ end
152
+
153
+ def create_init_script(path, configurations)
154
+ Dir.chdir(path) do
155
+ f = Tempfile.new(["init", ".gradle"], @root_path)
156
+ f.write(
157
+ <<~EOF
158
+ import com.github.jk1.license.render.CsvReportRenderer
159
+ import com.github.jk1.license.filter.LicenseBundleNormalizer
160
+ final configs = #{configurations.inspect}
161
+
162
+ initscript {
163
+ repositories {
164
+ maven {
165
+ url "https://plugins.gradle.org/m2/"
174
166
  }
167
+ }
168
+ dependencies {
169
+ classpath "com.github.jk1:gradle-license-report:#{gradle_version >= "7.0" ? "2.0" : "1.17"}"
170
+ }
175
171
  }
176
- println "[\\n${dependencies.join(", ")}\\n]"
177
- }
178
- }
179
- EOF
172
+
173
+ allprojects {
174
+ apply plugin: com.github.jk1.license.LicenseReportPlugin
175
+ licenseReport {
176
+ outputDir = "$rootDir/.gradle-licenses"
177
+ configurations = configs
178
+ renderers = [new CsvReportRenderer()]
179
+ filters = [new LicenseBundleNormalizer()]
180
+ }
181
+
182
+ task printDependencies {
183
+ doLast {
184
+ def dependencies = []
185
+ configs.each {
186
+ configurations[it].resolvedConfiguration.resolvedArtifacts.each { artifact ->
187
+ def id = artifact.moduleVersion.id
188
+ dependencies << "{ \\"group\\": \\"${id.group}\\", \\"name\\": \\"${id.name}\\", \\"version\\": \\"${id.version}\\" }"
189
+ }
190
+ }
191
+ println "[${dependencies.join(", ")}]"
192
+ }
193
+ }
194
+ }
195
+ EOF
196
+ )
197
+ f.close
198
+ f
199
+ end
200
+ end
201
+
202
+ # Prefixes the gradle command with the project name for multi-build projects.
203
+ def format_command(command, source_path)
204
+ Dir.chdir(source_path) do
205
+ path = Licensed::Shell.execute(executable, "properties", "-Dorg.gradle.logging.level=quiet").scan(/path:.*/).last.split(" ").last
206
+ path == ":" ? command : "#{path}:#{command}"
207
+ end
208
+ end
180
209
  end
181
210
  end
182
211
  end
@@ -19,5 +19,6 @@ module Licensed
19
19
  require "licensed/sources/gradle"
20
20
  require "licensed/sources/mix"
21
21
  require "licensed/sources/yarn"
22
+ require "licensed/sources/cocoapods"
22
23
  end
23
24
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Licensed
3
- VERSION = "3.9.1".freeze
3
+ VERSION = "4.0.0".freeze
4
4
 
5
5
  def self.previous_major_versions
6
6
  major_version = Gem::Version.new(Licensed::VERSION).segments.first
data/licensed.gemspec CHANGED
@@ -21,21 +21,21 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.required_ruby_version = ">= 2.3.0"
24
+ spec.required_ruby_version = ">= 2.6.0"
25
25
 
26
- spec.add_dependency "licensee", ">= 9.15.2", "< 10.0.0"
27
- spec.add_dependency "thor", ">= 0.19"
28
- spec.add_dependency "pathname-common_prefix", "~> 0.0.1"
29
- spec.add_dependency "tomlrb", ">= 1.2", "< 3.0"
30
- spec.add_dependency "bundler", ">= 1.10"
31
- spec.add_dependency "ruby-xxHash", "~> 0.4"
32
- spec.add_dependency "parallel", ">= 0.18.0"
33
- spec.add_dependency "reverse_markdown", ">= 1", "< 3"
34
- spec.add_dependency "json", ">= 2.6.2"
26
+ spec.add_dependency "licensee", "9.16.0"
27
+ spec.add_dependency "thor", "1.2.1"
28
+ spec.add_dependency "pathname-common_prefix", "0.0.1"
29
+ spec.add_dependency "tomlrb", "2.0.3"
30
+ spec.add_dependency "ruby-xxHash", "0.4.0.2"
31
+ spec.add_dependency "parallel", "1.22.1"
32
+ spec.add_dependency "reverse_markdown", "2.1.1"
33
+ spec.add_dependency "json", "2.6.3"
34
+ spec.add_dependency "cocoapods-core", "1.11.3"
35
35
 
36
- spec.add_development_dependency "rake", ">= 12.3.3"
37
- spec.add_development_dependency "minitest", "~> 5.8"
38
- spec.add_development_dependency "mocha", "~> 2.0"
39
- spec.add_development_dependency "rubocop-github", "~> 0.6"
40
- spec.add_development_dependency "byebug", "~> 11.1.3"
36
+ spec.add_development_dependency "rake", "13.0.6"
37
+ spec.add_development_dependency "minitest", "5.17.0"
38
+ spec.add_development_dependency "mocha", "2.0.2"
39
+ spec.add_development_dependency "rubocop-github", "0.20.0"
40
+ spec.add_development_dependency "byebug", "11.1.3"
41
41
  end
metadata CHANGED
@@ -1,227 +1,209 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: licensed
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.9.1
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-25 00:00:00.000000000 Z
11
+ date: 2023-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: licensee
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 9.15.2
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: 10.0.0
19
+ version: 9.16.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 9.15.2
30
- - - "<"
24
+ - - '='
31
25
  - !ruby/object:Gem::Version
32
- version: 10.0.0
26
+ version: 9.16.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: thor
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
- - - ">="
31
+ - - '='
38
32
  - !ruby/object:Gem::Version
39
- version: '0.19'
33
+ version: 1.2.1
40
34
  type: :runtime
41
35
  prerelease: false
42
36
  version_requirements: !ruby/object:Gem::Requirement
43
37
  requirements:
44
- - - ">="
38
+ - - '='
45
39
  - !ruby/object:Gem::Version
46
- version: '0.19'
40
+ version: 1.2.1
47
41
  - !ruby/object:Gem::Dependency
48
42
  name: pathname-common_prefix
49
43
  requirement: !ruby/object:Gem::Requirement
50
44
  requirements:
51
- - - "~>"
45
+ - - '='
52
46
  - !ruby/object:Gem::Version
53
47
  version: 0.0.1
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
51
  requirements:
58
- - - "~>"
52
+ - - '='
59
53
  - !ruby/object:Gem::Version
60
54
  version: 0.0.1
61
55
  - !ruby/object:Gem::Dependency
62
56
  name: tomlrb
63
57
  requirement: !ruby/object:Gem::Requirement
64
58
  requirements:
65
- - - ">="
59
+ - - '='
66
60
  - !ruby/object:Gem::Version
67
- version: '1.2'
68
- - - "<"
69
- - !ruby/object:Gem::Version
70
- version: '3.0'
61
+ version: 2.0.3
71
62
  type: :runtime
72
63
  prerelease: false
73
64
  version_requirements: !ruby/object:Gem::Requirement
74
65
  requirements:
75
- - - ">="
76
- - !ruby/object:Gem::Version
77
- version: '1.2'
78
- - - "<"
66
+ - - '='
79
67
  - !ruby/object:Gem::Version
80
- version: '3.0'
68
+ version: 2.0.3
81
69
  - !ruby/object:Gem::Dependency
82
- name: bundler
70
+ name: ruby-xxHash
83
71
  requirement: !ruby/object:Gem::Requirement
84
72
  requirements:
85
- - - ">="
73
+ - - '='
86
74
  - !ruby/object:Gem::Version
87
- version: '1.10'
75
+ version: 0.4.0.2
88
76
  type: :runtime
89
77
  prerelease: false
90
78
  version_requirements: !ruby/object:Gem::Requirement
91
79
  requirements:
92
- - - ">="
80
+ - - '='
93
81
  - !ruby/object:Gem::Version
94
- version: '1.10'
82
+ version: 0.4.0.2
95
83
  - !ruby/object:Gem::Dependency
96
- name: ruby-xxHash
84
+ name: parallel
97
85
  requirement: !ruby/object:Gem::Requirement
98
86
  requirements:
99
- - - "~>"
87
+ - - '='
100
88
  - !ruby/object:Gem::Version
101
- version: '0.4'
89
+ version: 1.22.1
102
90
  type: :runtime
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
93
  requirements:
106
- - - "~>"
94
+ - - '='
107
95
  - !ruby/object:Gem::Version
108
- version: '0.4'
96
+ version: 1.22.1
109
97
  - !ruby/object:Gem::Dependency
110
- name: parallel
98
+ name: reverse_markdown
111
99
  requirement: !ruby/object:Gem::Requirement
112
100
  requirements:
113
- - - ">="
101
+ - - '='
114
102
  - !ruby/object:Gem::Version
115
- version: 0.18.0
103
+ version: 2.1.1
116
104
  type: :runtime
117
105
  prerelease: false
118
106
  version_requirements: !ruby/object:Gem::Requirement
119
107
  requirements:
120
- - - ">="
108
+ - - '='
121
109
  - !ruby/object:Gem::Version
122
- version: 0.18.0
110
+ version: 2.1.1
123
111
  - !ruby/object:Gem::Dependency
124
- name: reverse_markdown
112
+ name: json
125
113
  requirement: !ruby/object:Gem::Requirement
126
114
  requirements:
127
- - - ">="
115
+ - - '='
128
116
  - !ruby/object:Gem::Version
129
- version: '1'
130
- - - "<"
131
- - !ruby/object:Gem::Version
132
- version: '3'
117
+ version: 2.6.3
133
118
  type: :runtime
134
119
  prerelease: false
135
120
  version_requirements: !ruby/object:Gem::Requirement
136
121
  requirements:
137
- - - ">="
138
- - !ruby/object:Gem::Version
139
- version: '1'
140
- - - "<"
122
+ - - '='
141
123
  - !ruby/object:Gem::Version
142
- version: '3'
124
+ version: 2.6.3
143
125
  - !ruby/object:Gem::Dependency
144
- name: json
126
+ name: cocoapods-core
145
127
  requirement: !ruby/object:Gem::Requirement
146
128
  requirements:
147
- - - ">="
129
+ - - '='
148
130
  - !ruby/object:Gem::Version
149
- version: 2.6.2
131
+ version: 1.11.3
150
132
  type: :runtime
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
135
  requirements:
154
- - - ">="
136
+ - - '='
155
137
  - !ruby/object:Gem::Version
156
- version: 2.6.2
138
+ version: 1.11.3
157
139
  - !ruby/object:Gem::Dependency
158
140
  name: rake
159
141
  requirement: !ruby/object:Gem::Requirement
160
142
  requirements:
161
- - - ">="
143
+ - - '='
162
144
  - !ruby/object:Gem::Version
163
- version: 12.3.3
145
+ version: 13.0.6
164
146
  type: :development
165
147
  prerelease: false
166
148
  version_requirements: !ruby/object:Gem::Requirement
167
149
  requirements:
168
- - - ">="
150
+ - - '='
169
151
  - !ruby/object:Gem::Version
170
- version: 12.3.3
152
+ version: 13.0.6
171
153
  - !ruby/object:Gem::Dependency
172
154
  name: minitest
173
155
  requirement: !ruby/object:Gem::Requirement
174
156
  requirements:
175
- - - "~>"
157
+ - - '='
176
158
  - !ruby/object:Gem::Version
177
- version: '5.8'
159
+ version: 5.17.0
178
160
  type: :development
179
161
  prerelease: false
180
162
  version_requirements: !ruby/object:Gem::Requirement
181
163
  requirements:
182
- - - "~>"
164
+ - - '='
183
165
  - !ruby/object:Gem::Version
184
- version: '5.8'
166
+ version: 5.17.0
185
167
  - !ruby/object:Gem::Dependency
186
168
  name: mocha
187
169
  requirement: !ruby/object:Gem::Requirement
188
170
  requirements:
189
- - - "~>"
171
+ - - '='
190
172
  - !ruby/object:Gem::Version
191
- version: '2.0'
173
+ version: 2.0.2
192
174
  type: :development
193
175
  prerelease: false
194
176
  version_requirements: !ruby/object:Gem::Requirement
195
177
  requirements:
196
- - - "~>"
178
+ - - '='
197
179
  - !ruby/object:Gem::Version
198
- version: '2.0'
180
+ version: 2.0.2
199
181
  - !ruby/object:Gem::Dependency
200
182
  name: rubocop-github
201
183
  requirement: !ruby/object:Gem::Requirement
202
184
  requirements:
203
- - - "~>"
185
+ - - '='
204
186
  - !ruby/object:Gem::Version
205
- version: '0.6'
187
+ version: 0.20.0
206
188
  type: :development
207
189
  prerelease: false
208
190
  version_requirements: !ruby/object:Gem::Requirement
209
191
  requirements:
210
- - - "~>"
192
+ - - '='
211
193
  - !ruby/object:Gem::Version
212
- version: '0.6'
194
+ version: 0.20.0
213
195
  - !ruby/object:Gem::Dependency
214
196
  name: byebug
215
197
  requirement: !ruby/object:Gem::Requirement
216
198
  requirements:
217
- - - "~>"
199
+ - - '='
218
200
  - !ruby/object:Gem::Version
219
201
  version: 11.1.3
220
202
  type: :development
221
203
  prerelease: false
222
204
  version_requirements: !ruby/object:Gem::Requirement
223
205
  requirements:
224
- - - "~>"
206
+ - - '='
225
207
  - !ruby/object:Gem::Version
226
208
  version: 11.1.3
227
209
  description: Licensed automates extracting and validating the licenses of dependencies.
@@ -263,12 +245,12 @@ files:
263
245
  - docs/getting_started.md
264
246
  - docs/migrations/v2.md
265
247
  - docs/migrations/v3.md
266
- - docs/packaging.md
267
248
  - docs/reporters.md
268
249
  - docs/sources/bower.md
269
250
  - docs/sources/bundler.md
270
251
  - docs/sources/cabal.md
271
252
  - docs/sources/cargo.md
253
+ - docs/sources/cocoapods.md
272
254
  - docs/sources/composer.md
273
255
  - docs/sources/dep.md
274
256
  - docs/sources/git_submodule.md
@@ -316,6 +298,7 @@ files:
316
298
  - lib/licensed/sources/bundler/missing_specification.rb
317
299
  - lib/licensed/sources/cabal.rb
318
300
  - lib/licensed/sources/cargo.rb
301
+ - lib/licensed/sources/cocoapods.rb
319
302
  - lib/licensed/sources/composer.rb
320
303
  - lib/licensed/sources/dep.rb
321
304
  - lib/licensed/sources/git_submodule.rb
@@ -348,14 +331,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
348
331
  requirements:
349
332
  - - ">="
350
333
  - !ruby/object:Gem::Version
351
- version: 2.3.0
334
+ version: 2.6.0
352
335
  required_rubygems_version: !ruby/object:Gem::Requirement
353
336
  requirements:
354
337
  - - ">="
355
338
  - !ruby/object:Gem::Version
356
339
  version: '0'
357
340
  requirements: []
358
- rubygems_version: 3.0.3.1
341
+ rubygems_version: 3.3.26
359
342
  signing_key:
360
343
  specification_version: 4
361
344
  summary: Extract and validate the licenses of dependencies.
data/docs/packaging.md DELETED
@@ -1,53 +0,0 @@
1
- # Packaging licensed for distribution
2
-
3
- Licensed is built into executables and packaged for distribution using [ruby-packer][ruby-packer].
4
-
5
- Executable packages are currently supported for:
6
- 1. Linux
7
- 2. MacOS / Darwin
8
-
9
- The packaged executables contain a self-expanding file system containing ruby, licensed and all of it's runtime dependencies. Licensed is run inside the contained file system, allowing usage in scenarios where ruby is not available on the host system.
10
-
11
- ### Building packages
12
-
13
- Packages are built as `licensed-$VERSION-$PLATFORM-x64.tar.gz` tarballs that contain a single `./licensed` executable. After building a package through the available scripting, it will be available in the `pkg` directory.
14
-
15
- By default an exe is built for the current licensed git `HEAD`. The
16
- `$VERSION` in the package name will be set to the current branch name if
17
- available, otherwise the current SHA. To use a specific licensed version,
18
- set a `VERSION` environment variable when calling the packaging scripts. `VERSION` can be set to any value that works with `git checkout`.
19
-
20
- #### Building all packages
21
- ```bash
22
- # build all packages
23
- $ script/package
24
- ```
25
- or
26
- ```bash
27
- # build all packages
28
- $ bundle exec rake package
29
- ```
30
-
31
- #### Building packages for a single platform
32
- ```bash
33
- # build package for linux
34
- $ script/package linux
35
- ```
36
- or
37
- ```bash
38
- # build package for linux
39
- $ bundle exec rake package:linux
40
- ```
41
-
42
- #### Building packages for a specific version
43
- ```bash
44
- # VERSION can be set to anything that works with git checkout - tag, branch, SHA1
45
- $ VERSION="1.1.0" script/package
46
- ```
47
- or
48
- ```bash
49
- # VERSION can be set to anything that works with git checkout - tag, branch, SHA1
50
- $ VERSION="1.1.0" bundle exec rake package
51
- ```
52
-
53
- [ruby-packer]: https://github.com/pmq20/ruby-packer