licensed 2.10.0 → 2.12.2
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 +4 -4
- data/.github/workflows/test.yml +1 -1
- data/.gitignore +2 -0
- data/CHANGELOG.md +40 -2
- data/README.md +7 -5
- data/docs/commands.md +14 -0
- data/lib/licensed/cli.rb +20 -4
- data/lib/licensed/commands.rb +1 -0
- data/lib/licensed/commands/cache.rb +16 -9
- data/lib/licensed/commands/command.rb +12 -4
- data/lib/licensed/commands/list.rb +19 -0
- data/lib/licensed/commands/notices.rb +54 -0
- data/lib/licensed/commands/status.rb +19 -0
- data/lib/licensed/dependency.rb +1 -1
- data/lib/licensed/reporters.rb +1 -0
- data/lib/licensed/reporters/cache_reporter.rb +10 -10
- data/lib/licensed/reporters/list_reporter.rb +21 -5
- data/lib/licensed/reporters/notices_reporter.rb +99 -0
- data/lib/licensed/reporters/status_reporter.rb +24 -7
- data/lib/licensed/sources/cabal.rb +2 -2
- data/lib/licensed/sources/go.rb +1 -1
- data/lib/licensed/sources/nuget.rb +14 -8
- data/lib/licensed/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42da8bbc3e526abe154311e85c5dcb1ffaeba7a631e3b6eab6dbb976a94d9c4d
|
4
|
+
data.tar.gz: b0884fb5ae8a8c332c8ea8684075a57e3efe86c6026656279eb2ffe0ae50105a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5d14b32dffb12a412090348429a116f9732bb6413bc35fb677dbf248e8af415ca531d7980bafeaa5a81ed2f083e798821cd21be7fd8eed1037a6659f24d4693
|
7
|
+
data.tar.gz: 411785733af02c33cc0b239980558f79389b8bfdc144bf862530fde111dc3ad0c8fd64040b9fdecba022ae93158287b0f45e26a10719567dda3022024a60728b
|
data/.github/workflows/test.yml
CHANGED
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,44 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## 2.12.2
|
10
|
+
2020-07-07
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
- Cleaned up ruby 2.7 warnings (:tada: @jurre https://github.com/github/licensed/pull/292)
|
14
|
+
- Cleaned up additional warnings in tests (https://github.com/github/licensed/pull/293)
|
15
|
+
|
16
|
+
## 2.12.1
|
17
|
+
2020-06-30
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
- `licensed` no longer exits an error code when using the `--sources` CLI argument(https://github.com/github/licensed/pull/290)
|
21
|
+
|
22
|
+
## 2.12.0
|
23
|
+
2020-06-19
|
24
|
+
|
25
|
+
### Added
|
26
|
+
- `--sources` argument for cache, list, status and notices commands to filter running sources (https://github.com/github/licensed/pull/287)
|
27
|
+
|
28
|
+
### Fixed
|
29
|
+
- `cache` command will not remove files outside of enabled source cache paths (https://github.com/github/licensed/pull/287)
|
30
|
+
|
31
|
+
## 2.11.1
|
32
|
+
2020-06-09
|
33
|
+
|
34
|
+
### Fixed
|
35
|
+
- `notices` command properly reads cached dependency notices contents (https://github.com/github/licensed/pull/283)
|
36
|
+
|
37
|
+
## 2.11.0
|
38
|
+
2020-06-02
|
39
|
+
|
40
|
+
### Added
|
41
|
+
- `notices` command to create a `NOTICE` file for each configured app (https://github.com/github/licensed/pull/277)
|
42
|
+
|
43
|
+
### Fixed
|
44
|
+
- NuGet source no longer crashes on a non-existent dependency path (https://github.com/github/licensed/pull/280)
|
45
|
+
- Go source no longer crashes on a non-existent dependency package path (https://github.com/github/licensed/pull/274)
|
46
|
+
|
9
47
|
## 2.10.0
|
10
48
|
2020-05-15
|
11
49
|
|
@@ -13,7 +51,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
13
51
|
- NPM source ignores missing peer dependencies (https://github.com/github/licensed/pull/267)
|
14
52
|
|
15
53
|
### Added
|
16
|
-
-
|
54
|
+
- NuGet source (:tada: @zarenner https://github.com/github/licensed/pull/261)
|
17
55
|
- Multiple apps can share a single cache location (https://github.com/github/licensed/pull/263)
|
18
56
|
|
19
57
|
## 2.9.2
|
@@ -302,4 +340,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
302
340
|
|
303
341
|
Initial release :tada:
|
304
342
|
|
305
|
-
[Unreleased]: https://github.com/github/licensed/compare/2.
|
343
|
+
[Unreleased]: https://github.com/github/licensed/compare/2.12.2...HEAD
|
data/README.md
CHANGED
@@ -24,13 +24,13 @@ See the [migration documentation](./docs/migrating_to_newer_versions.md) for mor
|
|
24
24
|
### Dependencies
|
25
25
|
|
26
26
|
Licensed uses the `libgit2` bindings for Ruby provided by `rugged`. `rugged` requires `cmake` and `pkg-config` which you may need to install before you can install Licensed.
|
27
|
-
|
27
|
+
|
28
28
|
> Ubuntu
|
29
|
-
|
29
|
+
|
30
30
|
sudo apt-get install cmake pkg-config
|
31
|
-
|
31
|
+
|
32
32
|
> OS X
|
33
|
-
|
33
|
+
|
34
34
|
brew install cmake pkg-config
|
35
35
|
|
36
36
|
### With a Gemfile
|
@@ -64,8 +64,10 @@ For system wide usage, install licensed to a location on `$PATH`, e.g. `/usr/loc
|
|
64
64
|
|
65
65
|
- `licensed list`: Output enumerated dependencies only.
|
66
66
|
- `licensed cache`: Cache licenses and metadata.
|
67
|
-
- `licensed status`: Check status of dependencies' cached licenses.
|
67
|
+
- `licensed status`: Check status of dependencies' cached licenses.
|
68
|
+
- `licensed notices`: Write a `NOTICE` file for each application configuration.
|
68
69
|
- `licensed version`: Show current installed version of Licensed. Aliases: `-v|--version`
|
70
|
+
- `licensed env`: Output environment information from the licensed configuration.
|
69
71
|
|
70
72
|
See the [commands documentation](./docs/commands.md) for additional documentation, or run `licensed -h` to see all of the current available commands.
|
71
73
|
|
data/docs/commands.md
CHANGED
@@ -6,10 +6,14 @@ Run `licensed -h` to see help content for running licensed commands.
|
|
6
6
|
|
7
7
|
Running the list command finds the dependencies for all sources in all configured applications. No additional actions are taken on each dependency.
|
8
8
|
|
9
|
+
An optional `--sources` flag can be given to limit which dependency sources are run. This is a filter over sources that are enabled via the licensed configuration file and cannot be used to run licensed with a disabled source.
|
10
|
+
|
9
11
|
## `cache`
|
10
12
|
|
11
13
|
The cache command finds all dependencies and ensures that each dependency has an up-to-date cached record.
|
12
14
|
|
15
|
+
An optional `--sources` flag can be given to limit which dependency sources are run. This is a filter over sources that are enabled via the licensed configuration file and cannot be used to run licensed with a disabled source.
|
16
|
+
|
13
17
|
Dependency records will be saved if:
|
14
18
|
1. The `force` option is set
|
15
19
|
2. No cached record is found
|
@@ -22,6 +26,8 @@ After the cache command is run, any cached records that don't match up to a curr
|
|
22
26
|
|
23
27
|
The status command finds all dependencies and checks whether each dependency has a valid cached record.
|
24
28
|
|
29
|
+
An optional `--sources` flag can be given to limit which dependency sources are run. This is a filter over sources that are enabled via the licensed configuration file and cannot be used to run licensed with a disabled source.
|
30
|
+
|
25
31
|
A dependency will fail the status checks if:
|
26
32
|
1. No cached record is found
|
27
33
|
2. The cached record's version is different than the current dependency's version
|
@@ -31,6 +37,14 @@ A dependency will fail the status checks if:
|
|
31
37
|
5. The cached record is flagged for re-review.
|
32
38
|
- This occurs when the record's license text has changed since the record was reviewed.
|
33
39
|
|
40
|
+
## `notices`
|
41
|
+
|
42
|
+
Outputs license and notice text for all dependencies in each app into a `NOTICE` file in the app's `cache_path`. If an app uses a shared cache path, the file name will contain the app name as well, e.g. `NOTICE.my_app`.
|
43
|
+
|
44
|
+
An optional `--sources` flag can be given to limit which dependency sources are run. This is a filter over sources that are enabled via the licensed configuration file and cannot be used to run licensed with a disabled source.
|
45
|
+
|
46
|
+
The `NOTICE` file contents are retrieved from cached records, with the assumption that cached records have already been reviewed in a compliance workflow.
|
47
|
+
|
34
48
|
## `env`
|
35
49
|
|
36
50
|
Prints the runtime environment used by licensed after loading a configuration file. By default the output is in YAML format, but can be output in JSON using the `--json` flag.
|
data/lib/licensed/cli.rb
CHANGED
@@ -10,22 +10,38 @@ module Licensed
|
|
10
10
|
desc: "Overwrite licenses even if version has not changed."
|
11
11
|
method_option :config, aliases: "-c", type: :string,
|
12
12
|
desc: "Path to licensed configuration file"
|
13
|
+
method_option :sources, aliases: "-s", type: :array,
|
14
|
+
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
13
15
|
def cache
|
14
|
-
run Licensed::Commands::Cache.new(config: config),
|
16
|
+
run Licensed::Commands::Cache.new(config: config),
|
17
|
+
force: options[:force], sources: options[:sources]
|
15
18
|
end
|
16
19
|
|
17
20
|
desc "status", "Check status of dependencies' cached licenses"
|
18
21
|
method_option :config, aliases: "-c", type: :string,
|
19
22
|
desc: "Path to licensed configuration file"
|
23
|
+
method_option :sources, aliases: "-s", type: :array,
|
24
|
+
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
20
25
|
def status
|
21
|
-
run Licensed::Commands::Status.new(config: config)
|
26
|
+
run Licensed::Commands::Status.new(config: config), sources: options[:sources]
|
22
27
|
end
|
23
28
|
|
24
29
|
desc "list", "List dependencies"
|
25
30
|
method_option :config, aliases: "-c", type: :string,
|
26
31
|
desc: "Path to licensed configuration file"
|
32
|
+
method_option :sources, aliases: "-s", type: :array,
|
33
|
+
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
27
34
|
def list
|
28
|
-
run Licensed::Commands::List.new(config: config)
|
35
|
+
run Licensed::Commands::List.new(config: config), sources: options[:sources]
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "notices", "Generate a NOTICE file from cached records"
|
39
|
+
method_option :config, aliases: "-c", type: :string,
|
40
|
+
desc: "Path to licensed configuration file"
|
41
|
+
method_option :sources, aliases: "-s", type: :array,
|
42
|
+
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
43
|
+
def notices
|
44
|
+
run Licensed::Commands::Notices.new(config: config), sources: options[:sources]
|
29
45
|
end
|
30
46
|
|
31
47
|
map "-v" => :version
|
@@ -80,7 +96,7 @@ module Licensed
|
|
80
96
|
end
|
81
97
|
|
82
98
|
def run(command, **args)
|
83
|
-
exit command.run(args)
|
99
|
+
exit command.run(**args)
|
84
100
|
end
|
85
101
|
end
|
86
102
|
end
|
data/lib/licensed/commands.rb
CHANGED
@@ -32,19 +32,26 @@ module Licensed
|
|
32
32
|
|
33
33
|
protected
|
34
34
|
|
35
|
-
# Run the command for all
|
35
|
+
# Run the command for all enumerated dependencies found in a dependency source,
|
36
36
|
# recording results in a report.
|
37
|
+
# Enumerating dependencies in the source is skipped if a :sources option
|
38
|
+
# is provided and the evaluated `source.class.type` is not in the :sources values
|
37
39
|
#
|
38
|
-
# app -
|
40
|
+
# app - The application configuration for the source
|
41
|
+
# source - A dependency source enumerator
|
39
42
|
#
|
40
|
-
# Returns whether the command succeeded for the
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
# Returns whether the command succeeded for the dependency source enumerator
|
44
|
+
def run_source(app, source)
|
45
|
+
super do |report|
|
46
|
+
if Array(options[:sources]).any? && !options[:sources].include?(source.class.type)
|
47
|
+
report.warnings << "skipped source"
|
48
|
+
next :skip
|
49
|
+
end
|
46
50
|
|
47
|
-
|
51
|
+
# add the full cache path to the list of cache paths
|
52
|
+
# that should be cleaned up after the command run
|
53
|
+
cache_paths << app.cache_path.join(source.class.type)
|
54
|
+
end
|
48
55
|
end
|
49
56
|
|
50
57
|
# Cache dependency record data.
|
@@ -21,7 +21,9 @@ module Licensed
|
|
21
21
|
begin
|
22
22
|
result = reporter.report_run(self) do |report|
|
23
23
|
# allow additional report data to be given by commands
|
24
|
-
|
24
|
+
if block_given?
|
25
|
+
next true if (yield report) == :skip
|
26
|
+
end
|
25
27
|
|
26
28
|
config.apps.sort_by { |app| app["name"] }
|
27
29
|
.map { |app| run_app(app) }
|
@@ -57,7 +59,9 @@ module Licensed
|
|
57
59
|
Dir.chdir app.source_path do
|
58
60
|
begin
|
59
61
|
# allow additional report data to be given by commands
|
60
|
-
|
62
|
+
if block_given?
|
63
|
+
next true if (yield report) == :skip
|
64
|
+
end
|
61
65
|
|
62
66
|
app.sources.select(&:enabled?)
|
63
67
|
.sort_by { |source| source.class.type }
|
@@ -81,7 +85,9 @@ module Licensed
|
|
81
85
|
reporter.report_source(source) do |report|
|
82
86
|
begin
|
83
87
|
# allow additional report data to be given by commands
|
84
|
-
|
88
|
+
if block_given?
|
89
|
+
next true if (yield report) == :skip
|
90
|
+
end
|
85
91
|
|
86
92
|
source.dependencies.sort_by { |dependency| dependency.name }
|
87
93
|
.map { |dependency| run_dependency(app, source, dependency) }
|
@@ -114,7 +120,9 @@ module Licensed
|
|
114
120
|
|
115
121
|
begin
|
116
122
|
# allow additional report data to be given by commands
|
117
|
-
|
123
|
+
if block_given?
|
124
|
+
next true if (yield report) == :skip
|
125
|
+
end
|
118
126
|
|
119
127
|
evaluate_dependency(app, source, dependency, report)
|
120
128
|
rescue Licensed::Shell::Error => err
|
@@ -13,6 +13,25 @@ module Licensed
|
|
13
13
|
|
14
14
|
protected
|
15
15
|
|
16
|
+
# Run the command for all enumerated dependencies found in a dependency source,
|
17
|
+
# recording results in a report.
|
18
|
+
# Enumerating dependencies in the source is skipped if a :sources option
|
19
|
+
# is provided and the evaluated `source.class.type` is not in the :sources values
|
20
|
+
#
|
21
|
+
# app - The application configuration for the source
|
22
|
+
# source - A dependency source enumerator
|
23
|
+
#
|
24
|
+
# Returns whether the command succeeded for the dependency source enumerator
|
25
|
+
def run_source(app, source)
|
26
|
+
super do |report|
|
27
|
+
next if Array(options[:sources]).empty?
|
28
|
+
next if options[:sources].include?(source.class.type)
|
29
|
+
|
30
|
+
report.warnings << "skipped source"
|
31
|
+
:skip
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
16
35
|
# Listing dependencies requires no extra work.
|
17
36
|
#
|
18
37
|
# app - The application configuration for the dependency
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Licensed
|
3
|
+
module Commands
|
4
|
+
class Notices < Command
|
5
|
+
# Create a reporter to use during a command run
|
6
|
+
#
|
7
|
+
# options - The options the command was run with
|
8
|
+
#
|
9
|
+
# Raises a Licensed::Reporters::CacheReporter
|
10
|
+
def create_reporter(options)
|
11
|
+
Licensed::Reporters::NoticesReporter.new
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
# Run the command for all enumerated dependencies found in a dependency source,
|
17
|
+
# recording results in a report.
|
18
|
+
# Enumerating dependencies in the source is skipped if a :sources option
|
19
|
+
# is provided and the evaluated `source.class.type` is not in the :sources values
|
20
|
+
#
|
21
|
+
# app - The application configuration for the source
|
22
|
+
# source - A dependency source enumerator
|
23
|
+
#
|
24
|
+
# Returns whether the command succeeded for the dependency source enumerator
|
25
|
+
def run_source(app, source)
|
26
|
+
super do |report|
|
27
|
+
next if Array(options[:sources]).empty?
|
28
|
+
next if options[:sources].include?(source.class.type)
|
29
|
+
|
30
|
+
report.warnings << "skipped source"
|
31
|
+
:skip
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Load stored dependency record data to add to the notices report.
|
36
|
+
#
|
37
|
+
# app - The application configuration for the dependency
|
38
|
+
# source - The dependency source enumerator for the dependency
|
39
|
+
# dependency - An application dependency
|
40
|
+
# report - A report hash for the command to provide extra data for the report output.
|
41
|
+
#
|
42
|
+
# Returns true.
|
43
|
+
def evaluate_dependency(app, source, dependency, report)
|
44
|
+
filename = app.cache_path.join(source.class.type, "#{dependency.name}.#{DependencyRecord::EXTENSION}")
|
45
|
+
report["cached_record"] = Licensed::DependencyRecord.read(filename)
|
46
|
+
if !report["cached_record"]
|
47
|
+
report.warnings << "expected cached record not found at #{filename}"
|
48
|
+
end
|
49
|
+
|
50
|
+
true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -15,6 +15,25 @@ module Licensed
|
|
15
15
|
|
16
16
|
protected
|
17
17
|
|
18
|
+
# Run the command for all enumerated dependencies found in a dependency source,
|
19
|
+
# recording results in a report.
|
20
|
+
# Enumerating dependencies in the source is skipped if a :sources option
|
21
|
+
# is provided and the evaluated `source.class.type` is not in the :sources values
|
22
|
+
#
|
23
|
+
# app - The application configuration for the source
|
24
|
+
# source - A dependency source enumerator
|
25
|
+
#
|
26
|
+
# Returns whether the command succeeded for the dependency source enumerator
|
27
|
+
def run_source(app, source)
|
28
|
+
super do |report|
|
29
|
+
next if Array(options[:sources]).empty?
|
30
|
+
next if options[:sources].include?(source.class.type)
|
31
|
+
|
32
|
+
report.warnings << "skipped source"
|
33
|
+
:skip
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
18
37
|
# Verifies that a cached record exists, is up to date and
|
19
38
|
# has license data that complies with the licensed configuration.
|
20
39
|
#
|
data/lib/licensed/dependency.rb
CHANGED
@@ -74,7 +74,7 @@ module Licensed
|
|
74
74
|
def license_contents
|
75
75
|
files = matched_files.reject { |f| f == package_file }
|
76
76
|
.group_by(&:content)
|
77
|
-
.map { |content,
|
77
|
+
.map { |content, sources| { "sources" => license_content_sources(sources), "text" => content } }
|
78
78
|
|
79
79
|
files << generated_license_contents if files.empty?
|
80
80
|
files.compact
|
data/lib/licensed/reporters.rb
CHANGED
@@ -27,32 +27,32 @@ module Licensed
|
|
27
27
|
shell.info " #{source.class.type}"
|
28
28
|
result = yield report
|
29
29
|
|
30
|
-
warning_reports = report.all_reports.select { |
|
30
|
+
warning_reports = report.all_reports.select { |r| r.warnings.any? }.to_a
|
31
31
|
if warning_reports.any?
|
32
32
|
shell.newline
|
33
33
|
shell.warn " * Warnings:"
|
34
|
-
warning_reports.each do |
|
35
|
-
display_metadata =
|
34
|
+
warning_reports.each do |r|
|
35
|
+
display_metadata = r.map { |k, v| "#{k}: #{v}" }.join(", ")
|
36
36
|
|
37
|
-
shell.warn " * #{
|
37
|
+
shell.warn " * #{r.name}"
|
38
38
|
shell.warn " #{display_metadata}" unless display_metadata.empty?
|
39
|
-
|
39
|
+
r.warnings.each do |warning|
|
40
40
|
shell.warn " - #{warning}"
|
41
41
|
end
|
42
42
|
shell.newline
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
errored_reports = report.all_reports.select { |
|
46
|
+
errored_reports = report.all_reports.select { |r| r.errors.any? }.to_a
|
47
47
|
if errored_reports.any?
|
48
48
|
shell.newline
|
49
49
|
shell.error " * Errors:"
|
50
|
-
errored_reports.each do |
|
51
|
-
display_metadata =
|
50
|
+
errored_reports.each do |r|
|
51
|
+
display_metadata = r.map { |k, v| "#{k}: #{v}" }.join(", ")
|
52
52
|
|
53
|
-
shell.error " * #{
|
53
|
+
shell.error " * #{r.name}"
|
54
54
|
shell.error " #{display_metadata}" unless display_metadata.empty?
|
55
|
-
|
55
|
+
r.errors.each do |error|
|
56
56
|
shell.error " - #{error}"
|
57
57
|
end
|
58
58
|
shell.newline
|
@@ -28,16 +28,32 @@ module Licensed
|
|
28
28
|
shell.info " #{source.class.type}"
|
29
29
|
result = yield report
|
30
30
|
|
31
|
-
|
31
|
+
warning_reports = report.all_reports.select { |r| r.warnings.any? }.to_a
|
32
|
+
if warning_reports.any?
|
33
|
+
shell.newline
|
34
|
+
shell.warn " * Warnings:"
|
35
|
+
warning_reports.each do |r|
|
36
|
+
display_metadata = r.map { |k, v| "#{k}: #{v}" }.join(", ")
|
37
|
+
|
38
|
+
shell.warn " * #{r.name}"
|
39
|
+
shell.warn " #{display_metadata}" unless display_metadata.empty?
|
40
|
+
r.warnings.each do |warning|
|
41
|
+
shell.warn " - #{warning}"
|
42
|
+
end
|
43
|
+
shell.newline
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
errored_reports = report.all_reports.select { |r| r.errors.any? }.to_a
|
32
48
|
if errored_reports.any?
|
33
49
|
shell.newline
|
34
50
|
shell.error " * Errors:"
|
35
|
-
errored_reports.each do |
|
36
|
-
display_metadata =
|
51
|
+
errored_reports.each do |r|
|
52
|
+
display_metadata = r.map { |k, v| "#{k}: #{v}" }.join(", ")
|
37
53
|
|
38
|
-
shell.error " * #{
|
54
|
+
shell.error " * #{r.name}"
|
39
55
|
shell.error " #{display_metadata}" unless display_metadata.empty?
|
40
|
-
|
56
|
+
r.errors.each do |error|
|
41
57
|
shell.error " - #{error}"
|
42
58
|
end
|
43
59
|
shell.newline
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Licensed
|
4
|
+
module Reporters
|
5
|
+
class NoticesReporter < Reporter
|
6
|
+
TEXT_SEPARATOR = "\n\n#{("-" * 5)}\n\n".freeze
|
7
|
+
LICENSE_SEPARATOR = "\n#{("*" * 5)}\n".freeze
|
8
|
+
|
9
|
+
# Reports on an application configuration in a notices command run
|
10
|
+
#
|
11
|
+
# app - An application configuration
|
12
|
+
#
|
13
|
+
# Returns the result of the yielded method
|
14
|
+
# Note - must be called from inside the `report_run` scope
|
15
|
+
def report_app(app)
|
16
|
+
super do |report|
|
17
|
+
filename = app["shared_cache"] ? "NOTICE.#{app["name"]}" : "NOTICE"
|
18
|
+
path = app.cache_path.join(filename)
|
19
|
+
shell.info "Writing notices for #{app["name"]} to #{path}"
|
20
|
+
|
21
|
+
result = yield report
|
22
|
+
|
23
|
+
File.open(path, "w") do |file|
|
24
|
+
file << "THIRD PARTY NOTICES\n"
|
25
|
+
file << LICENSE_SEPARATOR
|
26
|
+
file << report.all_reports
|
27
|
+
.map { |r| notices(r) }
|
28
|
+
.compact
|
29
|
+
.join(LICENSE_SEPARATOR)
|
30
|
+
end
|
31
|
+
|
32
|
+
result
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# Reports on a dependency source enumerator in a notices command run.
|
38
|
+
# Shows warnings encountered during the run.
|
39
|
+
#
|
40
|
+
# source - A dependency source enumerator
|
41
|
+
#
|
42
|
+
# Returns the result of the yielded method
|
43
|
+
# Note - must be called from inside the `report_run` scope
|
44
|
+
def report_source(source)
|
45
|
+
super do |report|
|
46
|
+
result = yield report
|
47
|
+
|
48
|
+
report.warnings.each do |warning|
|
49
|
+
shell.warn "* #{report.name}: #{warning}"
|
50
|
+
end
|
51
|
+
|
52
|
+
result
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Reports on a dependency in a notices command run.
|
57
|
+
#
|
58
|
+
# dependency - An application dependency
|
59
|
+
#
|
60
|
+
# Returns the result of the yielded method
|
61
|
+
# Note - must be called from inside the `report_run` scope
|
62
|
+
def report_dependency(dependency)
|
63
|
+
super do |report|
|
64
|
+
result = yield report
|
65
|
+
report.warnings.each do |warning|
|
66
|
+
shell.warn "* #{report.name}: #{warning}"
|
67
|
+
end
|
68
|
+
result
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns notices information for a dependency report
|
73
|
+
def notices(report)
|
74
|
+
return unless report.target.is_a?(Licensed::Dependency)
|
75
|
+
|
76
|
+
cached_record = report["cached_record"]
|
77
|
+
return unless cached_record
|
78
|
+
|
79
|
+
texts = cached_record.licenses.map(&:text)
|
80
|
+
cached_record.notices.each do |notice|
|
81
|
+
case notice
|
82
|
+
when Hash
|
83
|
+
texts << notice["text"]
|
84
|
+
when String
|
85
|
+
texts << notice
|
86
|
+
else
|
87
|
+
shell.warn "* unable to parse notices for #{report.target.name}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
<<~NOTICE
|
92
|
+
#{cached_record["name"]}@#{cached_record["version"]}
|
93
|
+
|
94
|
+
#{texts.map(&:strip).reject(&:empty?).compact.join(TEXT_SEPARATOR)}
|
95
|
+
NOTICE
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -15,20 +15,37 @@ module Licensed
|
|
15
15
|
result = yield report
|
16
16
|
|
17
17
|
all_reports = report.all_reports
|
18
|
-
errored_reports = all_reports.select { |report| report.errors.any? }.to_a
|
19
18
|
|
20
|
-
|
21
|
-
|
19
|
+
warning_reports = all_reports.select { |r| r.warnings.any? }.to_a
|
20
|
+
if warning_reports.any?
|
21
|
+
shell.newline
|
22
|
+
shell.warn "Warnings:"
|
23
|
+
warning_reports.each do |r|
|
24
|
+
display_metadata = r.map { |k, v| "#{k}: #{v}" }.join(", ")
|
25
|
+
|
26
|
+
shell.warn "* #{r.name}"
|
27
|
+
shell.warn " #{display_metadata}" unless display_metadata.empty?
|
28
|
+
r.warnings.each do |warning|
|
29
|
+
shell.warn " - #{warning}"
|
30
|
+
end
|
31
|
+
shell.newline
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
errored_reports = all_reports.select { |r| r.errors.any? }.to_a
|
36
|
+
|
37
|
+
dependency_count = all_reports.select { |r| r.target.is_a?(Licensed::Dependency) }.size
|
38
|
+
error_count = errored_reports.sum { |r| r.errors.size }
|
22
39
|
|
23
40
|
if error_count > 0
|
24
41
|
shell.newline
|
25
42
|
shell.error "Errors:"
|
26
|
-
errored_reports.each do |
|
27
|
-
display_metadata =
|
43
|
+
errored_reports.each do |r|
|
44
|
+
display_metadata = r.map { |k, v| "#{k}: #{v}" }.join(", ")
|
28
45
|
|
29
|
-
shell.error "* #{
|
46
|
+
shell.error "* #{r.name}"
|
30
47
|
shell.error " #{display_metadata}" unless display_metadata.empty?
|
31
|
-
|
48
|
+
r.errors.each do |error|
|
32
49
|
shell.error " - #{error}"
|
33
50
|
end
|
34
51
|
shell.newline
|
@@ -111,11 +111,11 @@ module Licensed
|
|
111
111
|
info = package_info_command(id).strip
|
112
112
|
return missing_package(id) if info.empty?
|
113
113
|
|
114
|
-
info.lines.each_with_object({}) do |line,
|
114
|
+
info.lines.each_with_object({}) do |line, hsh|
|
115
115
|
key, value = line.split(":", 2).map(&:strip)
|
116
116
|
next unless key && value
|
117
117
|
|
118
|
-
|
118
|
+
hsh[key] = value
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
data/lib/licensed/sources/go.rb
CHANGED
@@ -120,7 +120,7 @@ module Licensed
|
|
120
120
|
return go_mod["Version"] if go_mod
|
121
121
|
|
122
122
|
package_directory = package["Dir"]
|
123
|
-
return unless package_directory
|
123
|
+
return unless package_directory && File.exist?(package_directory)
|
124
124
|
|
125
125
|
# find most recent git SHA for a package, or nil if SHA is
|
126
126
|
# not available
|
@@ -17,10 +17,13 @@ module Licensed
|
|
17
17
|
PROJECT_URL_REGEX = /<projectUrl>\s*(.*)\s*<\/projectUrl>/ix.freeze
|
18
18
|
PROJECT_DESC_REGEX = /<description>\s*(.*)\s*<\/description>/ix.freeze
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
# Returns the metadata that represents this dependency. This metadata
|
21
|
+
# is written to YAML in the dependencys cached text file
|
22
|
+
def license_metadata
|
23
|
+
super.tap do |record_metadata|
|
24
|
+
record_metadata["homepage"] = project_url if project_url
|
25
|
+
record_metadata["summary"] = description if description
|
26
|
+
end
|
24
27
|
end
|
25
28
|
|
26
29
|
def nuspec_path
|
@@ -29,14 +32,17 @@ module Licensed
|
|
29
32
|
end
|
30
33
|
|
31
34
|
def nuspec_contents
|
32
|
-
return
|
33
|
-
@nuspec_contents
|
35
|
+
return @nuspec_contents if defined?(@nuspec_contents)
|
36
|
+
@nuspec_contents = begin
|
37
|
+
return unless nuspec_path && File.exist?(nuspec_path)
|
38
|
+
File.read(nuspec_path)
|
39
|
+
end
|
34
40
|
end
|
35
41
|
|
36
42
|
def project_url
|
37
43
|
return @project_url if defined?(@project_url)
|
38
|
-
return unless nuspec_contents
|
39
44
|
@project_url = begin
|
45
|
+
return unless nuspec_contents
|
40
46
|
match = nuspec_contents.match PROJECT_URL_REGEX
|
41
47
|
match[1] if match && match[1]
|
42
48
|
end
|
@@ -44,8 +50,8 @@ module Licensed
|
|
44
50
|
|
45
51
|
def description
|
46
52
|
return @description if defined?(@description)
|
47
|
-
return unless nuspec_contents
|
48
53
|
@description = begin
|
54
|
+
return unless nuspec_contents
|
49
55
|
match = nuspec_contents.match PROJECT_DESC_REGEX
|
50
56
|
match[1] if match && match[1]
|
51
57
|
end
|
data/lib/licensed/version.rb
CHANGED
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: 2.
|
4
|
+
version: 2.12.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: licensee
|
@@ -284,6 +284,7 @@ files:
|
|
284
284
|
- lib/licensed/commands/command.rb
|
285
285
|
- lib/licensed/commands/environment.rb
|
286
286
|
- lib/licensed/commands/list.rb
|
287
|
+
- lib/licensed/commands/notices.rb
|
287
288
|
- lib/licensed/commands/status.rb
|
288
289
|
- lib/licensed/configuration.rb
|
289
290
|
- lib/licensed/dependency.rb
|
@@ -295,6 +296,7 @@ files:
|
|
295
296
|
- lib/licensed/reporters/cache_reporter.rb
|
296
297
|
- lib/licensed/reporters/json_reporter.rb
|
297
298
|
- lib/licensed/reporters/list_reporter.rb
|
299
|
+
- lib/licensed/reporters/notices_reporter.rb
|
298
300
|
- lib/licensed/reporters/reporter.rb
|
299
301
|
- lib/licensed/reporters/status_reporter.rb
|
300
302
|
- lib/licensed/reporters/yaml_reporter.rb
|