licensed 4.0.4 → 4.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4862d2463055e895e3aac366c32821ee047360646946860d0cd6eb86ef9701f
4
- data.tar.gz: b75cf3b200090387ef2f104295bb90fc8874668bd895797335f02a23c9357296
3
+ metadata.gz: 7606d0b5e5f3755ee329a1963cda970c021deab08680c619731ed6fb3ba547da
4
+ data.tar.gz: 668a2d87d8019284b6ce02bccdda851ad186f03cc7d389fbdd659473affc08cf
5
5
  SHA512:
6
- metadata.gz: 766f5196aea9b41034c0a76e11ebe7e7272ce1554661d552ad88895dd45cc43544cb737f7c36173ab612fc71f352d14ac30d2449f7414f8b7813174e294828c5
7
- data.tar.gz: 0c6a31ae81db6abe8744d4a64b07e695b86b18536ce7308f7757c0c69183684e6d39d91082c87edd5a693617f30884a6c322ec3aa0e017a87bc137bf1e0793b7
6
+ metadata.gz: '064129baadae7345b5c05e2635cc1850b8ce8321f1e2df803b5fc6d6704556a1337c7d1561024775801cf5cb4158b6c25657b06a0a9baf5ccac7a7453f35fa53'
7
+ data.tar.gz: b3c6ba7179d7b777665f29b5cace4536181a428a5995c5e7d1d168b4ba6012fd333d191eb6ce23ab7b971a9cb8231dbfb999743c72bf91a1efe78ddec78223b7
data/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## 4.1.0
10
+
11
+ ### Added
12
+
13
+ - Custom license terms can be added to dependencies via new configuration options (https://github.com/github/licensed/pull/624)
14
+ - Licensed is now integrated with pnpm to enumerate dependencies (https://github.com/github/licensed/pull/626)
15
+
9
16
  ## 4.0.4
10
17
 
11
18
  ### Changed
@@ -706,4 +713,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
706
713
 
707
714
  Initial release :tada:
708
715
 
709
- [Unreleased]: https://github.com/github/licensed/compare/4.0.4...HEAD
716
+ [Unreleased]: https://github.com/github/licensed/compare/4.1.0...HEAD
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- licensed (4.0.4)
4
+ licensed (4.1.0)
5
5
  json (~> 2.6)
6
6
  licensee (~> 9.16)
7
7
  parallel (~> 1.22)
@@ -9,3 +9,4 @@
9
9
  1. [Allowed licenses](./allowed_licenses.md)
10
10
  1. [Ignoring dependencies](./ignoring_dependencies.md)
11
11
  1. [Reviewing dependencies](./reviewing_dependencies.md)
12
+ 1. [Additional license terms](./additional_terms.md)
@@ -0,0 +1,41 @@
1
+ # Additional terms
2
+
3
+ The `additional_terms` configuration option is used to specify paths to files containing extra licensing terms that do not ship with the dependency package. All files specified are expected to be plain text.
4
+
5
+ Files containing additional content can be located anywhere on disk that is accessible to licensed. File paths can be specified as a string or array and can contain glob values to simplify configuration inputs. All file paths are evaluated from the [configuration root](./configuration_root.md).
6
+
7
+ ## Examples
8
+
9
+ **Note** The examples below specify paths to additional files under the `.licenses` folder. This is a logical place to store files containing license terms, but be careful not to store files under paths managed by licensed like `.licenses/<source type>/...`. Running `licensed cache` in the future will delete any files under licensed managed paths that licensed did not create. This is why the below examples use paths like `.licenses/amendments/bundler/...` instead of not `.licenses/bundler/amendments/...`.
10
+
11
+ ### With a string
12
+
13
+ ```yaml
14
+ additional_terms:
15
+ # specify the type of dependency
16
+ bundler:
17
+ # specify the dependency name and path to an additional file
18
+ <gem-name>: .licenses/amendments/bundler/<gem-name>/terms.txt
19
+ ```
20
+
21
+ ### With a glob string
22
+
23
+ ```yaml
24
+ additional_terms:
25
+ # specify the type of dependency
26
+ bundler:
27
+ # specify the dependency name and one or more additional files with a glob pattern
28
+ <gem-name>: .licenses/amendments/bundler/<gem-name>/*.txt
29
+ ```
30
+
31
+ ### With an array of strings
32
+
33
+ ```yaml
34
+ additional_terms:
35
+ # specify the type of dependency
36
+ bundler:
37
+ # specify the dependency name and array of paths to additional files
38
+ <gem-name>:
39
+ - .licenses/amendments/bundler/<gem-name>/terms-1.txt
40
+ - .licenses/amendments/bundler/<gem-name>/terms-2.txt
41
+ ```
@@ -67,6 +67,13 @@ reviewed:
67
67
  - classlist # public domain
68
68
  - octicons
69
69
 
70
+ # Specify additional license terms that have been obtained from a dependency's owner
71
+ # which apply to the dependency's license
72
+ additional_terms:
73
+ bundler:
74
+ bcrypt-ruby:
75
+ - .licenses/amendments/bundler/bcrypt-ruby/amendment.txt
76
+
70
77
  # A single configuration file can be used to enumerate dependencies for multiple
71
78
  # projects. Each configuration is referred to as an "application" and must include
72
79
  # a source path, at a minimum
@@ -0,0 +1,18 @@
1
+ # pnpm
2
+
3
+ The npm source will detect dependencies when `pnpm-lock.yaml` is found at an apps `source_path`. It uses `pnpm licenses list` to enumerate dependencies and metadata.
4
+
5
+ **NOTE** [pnpm licenses list](https://pnpm.io/cli/licenses) is an experimental CLI command and subject to change. If changes to pnpm result in unexpected or broken behavior in licensed please open an [issue](https://github.com/github/licensed/issues/new).
6
+
7
+ ## Including development dependencies
8
+
9
+ By default, the npm source will exclude all development dependencies. To include development or test dependencies, set `production_only: false` in the licensed configuration.
10
+
11
+ ```yml
12
+ pnpm:
13
+ production_only: false
14
+ ```
15
+
16
+ ## Using licensed with pnpm workspaces
17
+
18
+ Licensed will locate all dependencies from all pnpm workspaces and cannot enumerate dependencies from individual project workspaces. This is a limitation from the pnpm CLI.
@@ -109,6 +109,12 @@ module Licensed
109
109
  self["allowed"] << license
110
110
  end
111
111
 
112
+ # Returns an array of paths to files containing additional license terms.
113
+ def additional_terms_for_dependency(dependency)
114
+ amendment_paths = Array(self.dig("additional_terms", dependency["type"], dependency["name"]))
115
+ amendment_paths.flat_map { |path| Dir.glob(self.root.join(path)) }
116
+ end
117
+
112
118
  private
113
119
 
114
120
  def any_list_pattern_matched?(list, dependency, match_version: false)
@@ -9,6 +9,7 @@ module Licensed
9
9
  attr_reader :version
10
10
  attr_reader :errors
11
11
  attr_reader :path
12
+ attr_reader :additional_terms
12
13
 
13
14
  # Create a new project dependency
14
15
  #
@@ -28,6 +29,7 @@ module Licensed
28
29
  @errors = errors
29
30
  path = path.to_s
30
31
  @path = path
32
+ @additional_terms = []
31
33
 
32
34
  # enforcing absolute paths makes life much easier when determining
33
35
  # an absolute file path in #notices
@@ -80,6 +82,13 @@ module Licensed
80
82
  files.compact
81
83
  end
82
84
 
85
+
86
+ # Override the behavior of Licensee::Projects::FSProject#project_files to include
87
+ # additional license terms
88
+ def project_files
89
+ super + additional_license_terms_files
90
+ end
91
+
83
92
  # Returns legal notices found at the dependency path
84
93
  def notice_contents
85
94
  Dir.glob(dir_path.join("*"))
@@ -102,6 +111,7 @@ module Licensed
102
111
  def license_content_sources(files)
103
112
  paths = Array(files).map do |file|
104
113
  next file[:uri] if file[:uri]
114
+ next file[:source] if file[:source]
105
115
 
106
116
  path = dir_path.join(file[:dir], file[:name])
107
117
  normalize_source_path(path)
@@ -157,5 +167,22 @@ module Licensed
157
167
  "text" => text
158
168
  }
159
169
  end
170
+
171
+ # Returns an array of Licensee::ProjectFiles::LicenseFile created from
172
+ # this dependency's additional license terms
173
+ def additional_license_terms_files
174
+ @additional_license_terms_files ||= begin
175
+ files = additional_terms.map do |path|
176
+ next unless File.file?(path)
177
+
178
+ metadata = { dir: File.dirname(path), name: File.basename(path) }
179
+ Licensee::ProjectFiles::LicenseFile.new(
180
+ load_file(metadata),
181
+ { source: "License terms loaded from #{metadata[:name]}" }
182
+ )
183
+ end
184
+ files.compact
185
+ end
186
+ end
160
187
  end
161
188
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+ require "json"
3
+
4
+ module Licensed
5
+ module Sources
6
+ class PNPM < Source
7
+ # Returns true when pnpm is installed and a pnpm-lock.yaml file is found,
8
+ # otherwise false
9
+ def enabled?
10
+ return false unless Licensed::Shell.tool_available?("pnpm")
11
+ File.exist?(File.join(config.pwd, "pnpm-lock.yaml"))
12
+ end
13
+
14
+ def enumerate_dependencies
15
+ packages.map do |package|
16
+ name_with_version = "#{package["name"]}@#{package["version"]}"
17
+ Dependency.new(
18
+ name: name_with_version,
19
+ version: package["version"],
20
+ path: package["path"],
21
+ metadata: {
22
+ "type" => PNPM.type,
23
+ "name" => package["name"],
24
+ "summary" => package["description"],
25
+ "homepage" => package["homepage"]
26
+ }
27
+ )
28
+ end
29
+ end
30
+
31
+ # Returns package metadata returned from `pnpm licensed list`
32
+ def packages
33
+ JSON.parse(package_metadata_command).values.flatten
34
+ rescue JSON::ParserError => e
35
+ message = "Licensed was unable to parse the output from 'pnpm licenses list'. JSON Error: #{e.message}"
36
+ raise Licensed::Sources::Source::Error, message
37
+ end
38
+
39
+ # Returns the output from running `pnpm licenses list` to get package metadata
40
+ def package_metadata_command
41
+ args = %w(--json --long)
42
+ args << "--prod" unless include_non_production?
43
+ Licensed::Shell.execute("pnpm", "licenses", "list", *args, allow_failure: true)
44
+ end
45
+
46
+ # Returns whether to include non production dependencies based on the licensed configuration settings
47
+ def include_non_production?
48
+ config.dig("pnpm", "production_only") == false
49
+ end
50
+ end
51
+ end
52
+ end
@@ -69,7 +69,9 @@ module Licensed
69
69
  # Returns all dependencies that should be evaluated.
70
70
  # Excludes ignored dependencies.
71
71
  def dependencies
72
- cached_dependencies.reject { |d| ignored?(d) }
72
+ cached_dependencies
73
+ .reject { |d| ignored?(d) }
74
+ .each { |d| add_additional_terms_from_configuration(d) }
73
75
  end
74
76
 
75
77
  # Enumerate all source dependencies. Must be implemented by each source class.
@@ -88,6 +90,11 @@ module Licensed
88
90
  def cached_dependencies
89
91
  @dependencies ||= enumerate_dependencies.compact
90
92
  end
93
+
94
+ # Add any additional_terms for this dependency that have been added to the configuration
95
+ def add_additional_terms_from_configuration(dependency)
96
+ dependency.additional_terms.concat config.additional_terms_for_dependency("type" => self.class.type, "name" => dependency.name)
97
+ end
91
98
  end
92
99
  end
93
100
  end
@@ -6,19 +6,20 @@ module Licensed
6
6
  require "licensed/sources/bundler"
7
7
  require "licensed/sources/cabal"
8
8
  require "licensed/sources/cargo"
9
+ require "licensed/sources/cocoapods"
9
10
  require "licensed/sources/composer"
10
11
  require "licensed/sources/dep"
11
12
  require "licensed/sources/git_submodule"
12
13
  require "licensed/sources/go"
14
+ require "licensed/sources/gradle"
13
15
  require "licensed/sources/manifest"
16
+ require "licensed/sources/mix"
14
17
  require "licensed/sources/npm"
15
18
  require "licensed/sources/nuget"
16
19
  require "licensed/sources/pip"
17
20
  require "licensed/sources/pipenv"
21
+ require "licensed/sources/pnpm"
18
22
  require "licensed/sources/swift"
19
- require "licensed/sources/gradle"
20
- require "licensed/sources/mix"
21
23
  require "licensed/sources/yarn"
22
- require "licensed/sources/cocoapods"
23
24
  end
24
25
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Licensed
3
- VERSION = "4.0.4".freeze
3
+ VERSION = "4.1.0".freeze
4
4
 
5
5
  def self.previous_major_versions
6
6
  major_version = Gem::Version.new(Licensed::VERSION).segments.first
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: licensed
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.4
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-26 00:00:00.000000000 Z
11
+ date: 2023-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: licensee
@@ -219,6 +219,7 @@ files:
219
219
  - docs/commands/version.md
220
220
  - docs/configuration.md
221
221
  - docs/configuration/README.md
222
+ - docs/configuration/additional_terms.md
222
223
  - docs/configuration/allowed_licenses.md
223
224
  - docs/configuration/application_name.md
224
225
  - docs/configuration/application_source.md
@@ -249,6 +250,7 @@ files:
249
250
  - docs/sources/nuget.md
250
251
  - docs/sources/pip.md
251
252
  - docs/sources/pipenv.md
253
+ - docs/sources/pnpm.md
252
254
  - docs/sources/stack.md
253
255
  - docs/sources/swift.md
254
256
  - docs/sources/yarn.md
@@ -298,6 +300,7 @@ files:
298
300
  - lib/licensed/sources/nuget.rb
299
301
  - lib/licensed/sources/pip.rb
300
302
  - lib/licensed/sources/pipenv.rb
303
+ - lib/licensed/sources/pnpm.rb
301
304
  - lib/licensed/sources/source.rb
302
305
  - lib/licensed/sources/swift.rb
303
306
  - lib/licensed/sources/yarn.rb