licensed 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +28 -11
- data/CHANGELOG.md +19 -0
- data/README.md +25 -80
- data/docs/adding_a_new_source.md +11 -8
- data/docs/commands/README.md +59 -0
- data/docs/commands/cache.md +35 -0
- data/docs/commands/env.md +10 -0
- data/docs/commands/list.md +23 -0
- data/docs/commands/migrate.md +10 -0
- data/docs/commands/notices.md +12 -0
- data/docs/commands/status.md +73 -0
- data/docs/commands/version.md +3 -0
- data/docs/configuration.md +9 -173
- data/docs/configuration/README.md +11 -0
- data/docs/configuration/allowed_licenses.md +17 -0
- data/docs/configuration/application_name.md +63 -0
- data/docs/configuration/application_source.md +64 -0
- data/docs/configuration/configuration_root.md +27 -0
- data/docs/configuration/configuring_multiple_apps.md +58 -0
- data/docs/configuration/dependency_source_enumerators.md +28 -0
- data/docs/configuration/ignoring_dependencies.md +19 -0
- data/docs/configuration/metadata_cache.md +106 -0
- data/docs/configuration/reviewing_dependencies.md +18 -0
- data/lib/licensed.rb +1 -0
- data/lib/licensed/cli.rb +2 -2
- data/lib/licensed/commands/cache.rb +19 -20
- data/lib/licensed/commands/command.rb +104 -72
- data/lib/licensed/commands/environment.rb +12 -11
- data/lib/licensed/commands/list.rb +0 -19
- data/lib/licensed/commands/notices.rb +0 -19
- data/lib/licensed/commands/status.rb +13 -15
- data/lib/licensed/configuration.rb +77 -7
- data/lib/licensed/report.rb +44 -0
- data/lib/licensed/reporters/cache_reporter.rb +48 -64
- data/lib/licensed/reporters/json_reporter.rb +19 -21
- data/lib/licensed/reporters/list_reporter.rb +45 -58
- data/lib/licensed/reporters/notices_reporter.rb +33 -46
- data/lib/licensed/reporters/reporter.rb +37 -104
- data/lib/licensed/reporters/status_reporter.rb +58 -56
- data/lib/licensed/reporters/yaml_reporter.rb +19 -21
- data/lib/licensed/sources/bundler.rb +1 -1
- data/lib/licensed/sources/gradle.rb +2 -2
- data/lib/licensed/sources/npm.rb +4 -3
- data/lib/licensed/version.rb +1 -1
- data/script/source-setup/go +1 -1
- metadata +21 -3
- data/docs/commands.md +0 -95
@@ -0,0 +1,27 @@
|
|
1
|
+
# Configuration root
|
2
|
+
|
3
|
+
**Key**: root
|
4
|
+
**Default value**:
|
5
|
+
|
6
|
+
1. the root of the local git repository, if run inside a git repository
|
7
|
+
1. the directory that `licensed` is run from
|
8
|
+
|
9
|
+
An application's root path is used as the base for any relative configuration paths in the application.
|
10
|
+
|
11
|
+
From a configuration file, the root value can be specified as one of the following. Path string values can contain special path characters.
|
12
|
+
|
13
|
+
- a relative path from the configuration file location
|
14
|
+
- an absolute path
|
15
|
+
- `true` to use the configuration file's directory as the root
|
16
|
+
|
17
|
+
When creating a `Licensed::AppConfiguration` manually with a `root` property, the property must be an absolute path - no path expansion will occur.
|
18
|
+
|
19
|
+
```yml
|
20
|
+
root: path/from/configuration
|
21
|
+
# or
|
22
|
+
root: /absolute/path/to/root
|
23
|
+
# or
|
24
|
+
root: ~/path/from/home/to/root
|
25
|
+
# or
|
26
|
+
root: true
|
27
|
+
```
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Configuring multiple application definitions
|
2
|
+
|
3
|
+
**Key**: apps
|
4
|
+
**Required**: false
|
5
|
+
|
6
|
+
The configuration file can specify multiple source paths to enumerate metadata, each with their own configuration by using the `apps` key.
|
7
|
+
Each source path and any additional configuration make up an "application". Root configuration settings are inherited into each application,
|
8
|
+
allowing applications to share a common configuration and reducing the overall size of the configuration file.
|
9
|
+
|
10
|
+
When the apps key is not given, the root configuration is treated as a single application.
|
11
|
+
|
12
|
+
```yml
|
13
|
+
apps:
|
14
|
+
# application definition for "go-application"
|
15
|
+
- source_path: path/to/go-application
|
16
|
+
sources:
|
17
|
+
go: true
|
18
|
+
allowed:
|
19
|
+
- mit
|
20
|
+
|
21
|
+
# application definition for "ruby-application"
|
22
|
+
- source_path: path/to/ruby-application
|
23
|
+
sources:
|
24
|
+
bundler: true
|
25
|
+
allowed:
|
26
|
+
- bsd-3-clause
|
27
|
+
```
|
28
|
+
|
29
|
+
## Inheriting configuration
|
30
|
+
|
31
|
+
Applications inherit all root configuration settings. Inherited settings will be overridden by any configuration set directly on the application definition.
|
32
|
+
|
33
|
+
In this example, two apps have been declared. The first app, with `source_path: path/to/application1`, inherits all configuration settings from the root configuration. The second app, with `source_path: path/to/application2`, overrides the `sources` configuration and inherits all other settings.
|
34
|
+
|
35
|
+
```yml
|
36
|
+
sources:
|
37
|
+
go: true
|
38
|
+
bundler: false
|
39
|
+
|
40
|
+
ignored:
|
41
|
+
bundler:
|
42
|
+
- some-internal-gem
|
43
|
+
|
44
|
+
reviewed:
|
45
|
+
bundler:
|
46
|
+
- bcrypt-ruby
|
47
|
+
|
48
|
+
cache_path: 'path/to/cache'
|
49
|
+
apps:
|
50
|
+
# inherits all settings from the root configuration
|
51
|
+
- source_path: 'path/to/application1'
|
52
|
+
|
53
|
+
# inherits all settings except for "sources" from the root configuration
|
54
|
+
- source_path: 'path/to/application2'
|
55
|
+
sources:
|
56
|
+
bundler: true
|
57
|
+
go: false
|
58
|
+
```
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Specifying dependency sources to use in an application
|
2
|
+
|
3
|
+
**Key**: sources
|
4
|
+
**Required**: false
|
5
|
+
**Default value**: All sources enabled
|
6
|
+
|
7
|
+
The sources configuration property specifies which sources `licensed` will use to enumerate dependencies.
|
8
|
+
By default, `licensed` will try to enumerate dependencies from all sources. As a result,
|
9
|
+
the configuration property should be used to explicitly disable sources rather than to enable a particular source.
|
10
|
+
|
11
|
+
This configuration value does not guarantee that a source will enumerate dependencies. Each
|
12
|
+
configured source's `enabled?` method must return true for licensed to pull dependency information.
|
13
|
+
|
14
|
+
`licensed` determines which sources will try to enumerate dependencies based on the following rules:
|
15
|
+
|
16
|
+
1. If no sources are configured, all sources are enabled
|
17
|
+
2. If no sources are set to true, any unconfigured sources are enabled
|
18
|
+
3. If any sources are set to true, any unconfigured sources are disabled
|
19
|
+
|
20
|
+
```yml
|
21
|
+
# all other sources are enabled by default since there are no sources set to true
|
22
|
+
sources:
|
23
|
+
bower: false
|
24
|
+
|
25
|
+
# all other sources are disabled by default because a source was set to true
|
26
|
+
sources:
|
27
|
+
bower: true
|
28
|
+
```
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Ignoring dependencies
|
2
|
+
|
3
|
+
**Key**: ignored
|
4
|
+
**Default value**: none
|
5
|
+
|
6
|
+
This configuration property is used to fully ignore a dependency during all `licensed` commands. Any dependency on this list will not
|
7
|
+
be enumerated, or have its metadata cached or checked for compliance. This is intended for dependencies that do not require attribution
|
8
|
+
or compliance checking - internal or 1st party dependencies, or dependencies that do not ship with the product such as test frameworks.
|
9
|
+
|
10
|
+
The ignored dependency list is organized based on the dependency source type - `bundler`, `go`, etc. Add a dependency's metadata identifier to the appropriate source type sub-property to cause `licensed` to no longer take action on the dependency. Glob patterns can be used to identify multiple internal dependencies without having to manage a large list.
|
11
|
+
|
12
|
+
```yml
|
13
|
+
ignored:
|
14
|
+
bundler:
|
15
|
+
- my-internal-gem
|
16
|
+
- my-first-party-gem
|
17
|
+
go:
|
18
|
+
- github.com/me/my-repo/**/*
|
19
|
+
```
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# Dependency metadata cache
|
2
|
+
|
3
|
+
**Key**: cache_path
|
4
|
+
**Default value**: .licenses
|
5
|
+
|
6
|
+
The cache path is the root directory where `licensed` will write cached metadata files for each dependency.
|
7
|
+
By default, files will be written to a folder under the cache path in a structure like:
|
8
|
+
|
9
|
+
```text
|
10
|
+
<cache path>
|
11
|
+
|_<source name>
|
12
|
+
|_<dependency identifier>.dep.yml
|
13
|
+
```
|
14
|
+
|
15
|
+
Cache paths can be given as an absolute or relative path and can contain special path characters
|
16
|
+
|
17
|
+
```yml
|
18
|
+
cache_path: relative/path/to/cache
|
19
|
+
# or
|
20
|
+
cache_path: /absolute/path/to/cache
|
21
|
+
# or
|
22
|
+
cache_path: ~/path/from/home/to/cache
|
23
|
+
```
|
24
|
+
|
25
|
+
## Configuring caches for multiple applications
|
26
|
+
|
27
|
+
When multiple applications are specified in a configuration file caches can be shared, inherited and explicitly configured.
|
28
|
+
Unless otherwise specified, preference is given based on the locality and intention of the configuration options.
|
29
|
+
|
30
|
+
1. explicitly configured cache paths are preferred to inherited or shared cache paths
|
31
|
+
2. shared cache paths are preferred to inherited cache paths
|
32
|
+
3. cache paths that are not otherwise set by an application will be inherited from the root configuration
|
33
|
+
|
34
|
+
### Explicit cache usage for multiple applications
|
35
|
+
|
36
|
+
Individual applications in a multi-application configuration can explicitly set cache paths.
|
37
|
+
|
38
|
+
```yml
|
39
|
+
apps:
|
40
|
+
- source_path: path/to/application1
|
41
|
+
cache_path: path/to/application1/.licenses
|
42
|
+
- source_path: path/to/application2
|
43
|
+
cache_path: path/to/application2/.licenses
|
44
|
+
```
|
45
|
+
|
46
|
+
### Sharing a single cache for multiple applications
|
47
|
+
|
48
|
+
Sharing a cache across multiple applications is possible by setting `cache_path: <path>` and `shared_cache: true` at the root level.
|
49
|
+
Individual applications can opt out of sharing a cache by explicitly setting a cache path.
|
50
|
+
|
51
|
+
```yml
|
52
|
+
shared_cache: true
|
53
|
+
cache_path: .cache/shared
|
54
|
+
apps:
|
55
|
+
# application1 and application2 will share a cache at .cache/shared
|
56
|
+
- source_path: path/to/application1
|
57
|
+
- source_path: path/to/application2
|
58
|
+
# application3 will use a separate cache at .cache/application3
|
59
|
+
- source_path: path/to/application3
|
60
|
+
cache_path: .cache/application3
|
61
|
+
```
|
62
|
+
|
63
|
+
This is equivalent to explicitly configuring the same cache for many applications
|
64
|
+
|
65
|
+
```yaml
|
66
|
+
apps:
|
67
|
+
- source_path: "path/to/application1"
|
68
|
+
cache_path: ".cache/shared"
|
69
|
+
- source_path: "path/to/application2"
|
70
|
+
cache_path: ".cache/shared"
|
71
|
+
```
|
72
|
+
|
73
|
+
Using the `shared_cache` key is primarily useful when specifying `source_path` as a glob pattern.
|
74
|
+
|
75
|
+
```yml
|
76
|
+
shared_cache: true
|
77
|
+
cache_path: .cache/shared
|
78
|
+
source_path: path/to/*
|
79
|
+
```
|
80
|
+
|
81
|
+
### Inheriting cache usage from the root configuration
|
82
|
+
|
83
|
+
When not otherwise specified, applications will inherit a cache path from the root configuration.
|
84
|
+
If the root configuration does not explicitly set a cache path value, the default cache path value is used.
|
85
|
+
|
86
|
+
Inherited cache paths are treated as the root location for each application's metadata cache. Each application
|
87
|
+
will store metadata in a named subdirectory of the root location to avoid file path clashes between
|
88
|
+
applications.
|
89
|
+
|
90
|
+
```yml
|
91
|
+
# optional. if not specified, the default value `.licenses` will be used
|
92
|
+
cache_path: .cache
|
93
|
+
apps:
|
94
|
+
- source_path: path/to/application1
|
95
|
+
- source_path: path/to/application2
|
96
|
+
```
|
97
|
+
|
98
|
+
```text
|
99
|
+
.cache
|
100
|
+
|_application1
|
101
|
+
|_<source type>
|
102
|
+
|_<dependency identifier>.dep.yml
|
103
|
+
|_application2
|
104
|
+
|_<source type>
|
105
|
+
|_<dependency identifier>.dep.yml
|
106
|
+
```
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Reviewing dependencies
|
2
|
+
|
3
|
+
**Key**: reviewed
|
4
|
+
**Default value**: none
|
5
|
+
|
6
|
+
Sometimes your projects will use a dependency with an OSS license that you don't want to globally allow but can use with individual review.
|
7
|
+
The list of reviewed dependencies is meant to cover this scenario and will prevent the status command from raising an error for
|
8
|
+
a dependency with a license not on the allowed list.
|
9
|
+
|
10
|
+
The reviewed dependency list is organized based on the dependency source type - `bundler`, `go`, etc. Add a dependency's metadata identifier to the appropriate source type sub-property to cause `licensed` to ignore license compliance failures. Glob patterns can be used to identify multiple internal dependencies without having to manage a large list.
|
11
|
+
|
12
|
+
_NOTE: marking a dependency as reviewed will not prevent licensed from raising an error on missing license information._
|
13
|
+
|
14
|
+
```yml
|
15
|
+
reviewed:
|
16
|
+
bundler:
|
17
|
+
- gem-using-unallowed-license
|
18
|
+
```
|
data/lib/licensed.rb
CHANGED
data/lib/licensed/cli.rb
CHANGED
@@ -20,12 +20,12 @@ module Licensed
|
|
20
20
|
end
|
21
21
|
|
22
22
|
desc "status", "Check status of dependencies' cached licenses"
|
23
|
-
method_option :format, enum: ["yaml", "json"],
|
24
|
-
desc: "Output format"
|
25
23
|
method_option :config, aliases: "-c", type: :string,
|
26
24
|
desc: "Path to licensed configuration file"
|
27
25
|
method_option :sources, aliases: "-s", type: :array,
|
28
26
|
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
27
|
+
method_option :format, aliases: "-f", enum: ["yaml", "json"],
|
28
|
+
desc: "Output format"
|
29
29
|
def status
|
30
30
|
run Licensed::Commands::Status.new(config: config), sources: options[:sources], reporter: options[:format]
|
31
31
|
end
|
@@ -11,6 +11,8 @@ module Licensed
|
|
11
11
|
Licensed::Reporters::CacheReporter.new
|
12
12
|
end
|
13
13
|
|
14
|
+
protected
|
15
|
+
|
14
16
|
# Run the command.
|
15
17
|
# Removes any cached records that don't match a current application
|
16
18
|
# dependency.
|
@@ -18,20 +20,15 @@ module Licensed
|
|
18
20
|
# options - Options to run the command with
|
19
21
|
#
|
20
22
|
# Returns whether the command was a success
|
21
|
-
def
|
22
|
-
|
23
|
-
result = super
|
23
|
+
def run_command(report)
|
24
|
+
super do |result|
|
24
25
|
clear_stale_cached_records if result
|
25
|
-
|
26
|
-
result
|
27
|
-
ensure
|
28
|
-
cache_paths.clear
|
29
|
-
files.clear
|
30
26
|
end
|
27
|
+
ensure
|
28
|
+
cache_paths.clear
|
29
|
+
files.clear
|
31
30
|
end
|
32
31
|
|
33
|
-
protected
|
34
|
-
|
35
32
|
# Run the command for all enumerated dependencies found in a dependency source,
|
36
33
|
# recording results in a report.
|
37
34
|
# Enumerating dependencies in the source is skipped if a :sources option
|
@@ -41,17 +38,12 @@ module Licensed
|
|
41
38
|
# source - A dependency source enumerator
|
42
39
|
#
|
43
40
|
# Returns whether the command succeeded for the dependency source enumerator
|
44
|
-
def run_source(app, source)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
next :skip
|
49
|
-
end
|
41
|
+
def run_source(app, source, report)
|
42
|
+
# add the full cache path to the list of cache paths
|
43
|
+
# that should be cleaned up after the command run
|
44
|
+
cache_paths << app.cache_path.join(source.class.type)
|
50
45
|
|
51
|
-
|
52
|
-
# that should be cleaned up after the command run
|
53
|
-
cache_paths << app.cache_path.join(source.class.type)
|
54
|
-
end
|
46
|
+
super
|
55
47
|
end
|
56
48
|
|
57
49
|
# Cache dependency record data.
|
@@ -70,6 +62,12 @@ module Licensed
|
|
70
62
|
|
71
63
|
filename = app.cache_path.join(source.class.type, "#{dependency.name}.#{DependencyRecord::EXTENSION}")
|
72
64
|
cached_record = Licensed::DependencyRecord.read(filename)
|
65
|
+
|
66
|
+
report["cached"] = false
|
67
|
+
report["license"] = cached_record["license"] if cached_record
|
68
|
+
report["filename"] = filename.to_s
|
69
|
+
report["version"] = dependency.version
|
70
|
+
|
73
71
|
if options[:force] || save_dependency_record?(dependency, cached_record)
|
74
72
|
if dependency.record.matches?(cached_record)
|
75
73
|
# use the cached license value if the license text wasn't updated
|
@@ -82,6 +80,7 @@ module Licensed
|
|
82
80
|
|
83
81
|
dependency.record.save(filename)
|
84
82
|
report["cached"] = true
|
83
|
+
report["license"] = dependency.record["license"]
|
85
84
|
end
|
86
85
|
|
87
86
|
if !dependency.exist?
|
@@ -18,23 +18,12 @@ module Licensed
|
|
18
18
|
def run(**options)
|
19
19
|
@options = options
|
20
20
|
@reporter = create_reporter(options)
|
21
|
-
begin
|
22
|
-
result = reporter.report_run(self) do |report|
|
23
|
-
# allow additional report data to be given by commands
|
24
|
-
if block_given?
|
25
|
-
next true if (yield report) == :skip
|
26
|
-
end
|
27
|
-
|
28
|
-
config.apps.sort_by { |app| app["name"] }
|
29
|
-
.map { |app| run_app(app) }
|
30
|
-
.all?
|
31
|
-
end
|
32
|
-
ensure
|
33
|
-
@options = nil
|
34
|
-
@reporter = nil
|
35
|
-
end
|
36
21
|
|
37
|
-
|
22
|
+
command_report = Licensed::Report.new(name: nil, target: self)
|
23
|
+
run_command(command_report)
|
24
|
+
ensure
|
25
|
+
@options = nil
|
26
|
+
@reporter = nil
|
38
27
|
end
|
39
28
|
|
40
29
|
# Creates a reporter to use during a command run
|
@@ -64,36 +53,65 @@ module Licensed
|
|
64
53
|
|
65
54
|
protected
|
66
55
|
|
56
|
+
# Run the command for all application configurations
|
57
|
+
#
|
58
|
+
# report - A Licensed::Report object for this command
|
59
|
+
#
|
60
|
+
# Returns whether the command succeeded
|
61
|
+
def run_command(report)
|
62
|
+
reporter.begin_report_command(self, report)
|
63
|
+
apps = config.apps.sort_by { |app| app["name"] }
|
64
|
+
results = apps.map do |app|
|
65
|
+
app_report = Licensed::Report.new(name: app["name"], target: app)
|
66
|
+
report.reports << app_report
|
67
|
+
run_app(app, app_report)
|
68
|
+
end
|
69
|
+
|
70
|
+
result = results.all?
|
71
|
+
|
72
|
+
yield(result) if block_given?
|
73
|
+
|
74
|
+
result
|
75
|
+
ensure
|
76
|
+
reporter.end_report_command(self, report)
|
77
|
+
end
|
78
|
+
|
67
79
|
# Run the command for all enabled sources for an application configuration,
|
68
80
|
# recording results in a report.
|
69
81
|
#
|
70
82
|
# app - An application configuration
|
83
|
+
# report - A report object for this application
|
71
84
|
#
|
72
85
|
# Returns whether the command succeeded for the application.
|
73
|
-
def run_app(app)
|
74
|
-
reporter.
|
75
|
-
# ensure the app source path exists before evaluation
|
76
|
-
if !Dir.exist?(app.source_path)
|
77
|
-
report.errors << "No such directory #{app.source_path}"
|
78
|
-
next false
|
79
|
-
end
|
86
|
+
def run_app(app, report)
|
87
|
+
reporter.begin_report_app(app, report)
|
80
88
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
89
|
+
# ensure the app source path exists before evaluation
|
90
|
+
if !Dir.exist?(app.source_path)
|
91
|
+
report.errors << "No such directory #{app.source_path}"
|
92
|
+
return false
|
93
|
+
end
|
94
|
+
|
95
|
+
Dir.chdir app.source_path do
|
96
|
+
sources = app.sources.select(&:enabled?)
|
97
|
+
.sort_by { |source| source.class.type }
|
98
|
+
results = sources.map do |source|
|
99
|
+
source_report = Licensed::Report.new(name: [report.name, source.class.type].join("."), target: source)
|
100
|
+
report.reports << source_report
|
101
|
+
run_source(app, source, source_report)
|
95
102
|
end
|
103
|
+
|
104
|
+
result = results.all?
|
105
|
+
|
106
|
+
yield(result) if block_given?
|
107
|
+
|
108
|
+
result
|
96
109
|
end
|
110
|
+
rescue Licensed::Shell::Error => err
|
111
|
+
report.errors << err.message
|
112
|
+
false
|
113
|
+
ensure
|
114
|
+
reporter.end_report_app(app, report)
|
97
115
|
end
|
98
116
|
|
99
117
|
# Run the command for all enumerated dependencies found in a dependency source,
|
@@ -101,27 +119,37 @@ module Licensed
|
|
101
119
|
#
|
102
120
|
# app - The application configuration for the source
|
103
121
|
# source - A dependency source enumerator
|
122
|
+
# report - A report object for this source
|
104
123
|
#
|
105
124
|
# Returns whether the command succeeded for the dependency source enumerator
|
106
|
-
def run_source(app, source)
|
107
|
-
reporter.
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
source.dependencies.sort_by { |dependency| dependency.name }
|
115
|
-
.map { |dependency| run_dependency(app, source, dependency) }
|
116
|
-
.all?
|
117
|
-
rescue Licensed::Shell::Error => err
|
118
|
-
report.errors << err.message
|
119
|
-
false
|
120
|
-
rescue Licensed::Sources::Source::Error => err
|
121
|
-
report.errors << err.message
|
122
|
-
false
|
123
|
-
end
|
125
|
+
def run_source(app, source, report)
|
126
|
+
reporter.begin_report_source(source, report)
|
127
|
+
|
128
|
+
if !sources_overrides.empty? && !sources_overrides.include?(source.class.type)
|
129
|
+
report.warnings << "skipped source"
|
130
|
+
return true
|
124
131
|
end
|
132
|
+
|
133
|
+
dependencies = source.dependencies.sort_by { |dependency| dependency.name }
|
134
|
+
results = dependencies.map do |dependency|
|
135
|
+
dependency_report = Licensed::Report.new(name: [report.name, dependency.name].join("."), target: dependency)
|
136
|
+
report.reports << dependency_report
|
137
|
+
run_dependency(app, source, dependency, dependency_report)
|
138
|
+
end
|
139
|
+
|
140
|
+
result = results.all?
|
141
|
+
|
142
|
+
yield(result) if block_given?
|
143
|
+
|
144
|
+
result
|
145
|
+
rescue Licensed::Shell::Error => err
|
146
|
+
report.errors << err.message
|
147
|
+
false
|
148
|
+
rescue Licensed::Sources::Source::Error => err
|
149
|
+
report.errors << err.message
|
150
|
+
false
|
151
|
+
ensure
|
152
|
+
reporter.end_report_source(source, report)
|
125
153
|
end
|
126
154
|
|
127
155
|
# Run the command for a dependency, evaluating the dependency and
|
@@ -131,27 +159,27 @@ module Licensed
|
|
131
159
|
# app - The application configuration for the dependency
|
132
160
|
# source - The dependency source enumerator for the dependency
|
133
161
|
# dependency - An application dependency
|
162
|
+
# report - A report object for this dependency
|
134
163
|
#
|
135
164
|
# Returns whether the command succeeded for the dependency
|
136
|
-
def run_dependency(app, source, dependency)
|
137
|
-
reporter.
|
138
|
-
if dependency.errors?
|
139
|
-
report.errors.concat(dependency.errors)
|
140
|
-
return false
|
141
|
-
end
|
165
|
+
def run_dependency(app, source, dependency, report)
|
166
|
+
reporter.begin_report_dependency(dependency, report)
|
142
167
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
next true if (yield report) == :skip
|
147
|
-
end
|
148
|
-
|
149
|
-
evaluate_dependency(app, source, dependency, report)
|
150
|
-
rescue Licensed::DependencyRecord::Error, Licensed::Shell::Error => err
|
151
|
-
report.errors << err.message
|
152
|
-
false
|
153
|
-
end
|
168
|
+
if dependency.errors?
|
169
|
+
report.errors.concat(dependency.errors)
|
170
|
+
return false
|
154
171
|
end
|
172
|
+
|
173
|
+
result = evaluate_dependency(app, source, dependency, report)
|
174
|
+
|
175
|
+
yield(result) if block_given?
|
176
|
+
|
177
|
+
result
|
178
|
+
rescue Licensed::DependencyRecord::Error, Licensed::Shell::Error => err
|
179
|
+
report.errors << err.message
|
180
|
+
false
|
181
|
+
ensure
|
182
|
+
reporter.end_report_dependency(dependency, report)
|
155
183
|
end
|
156
184
|
|
157
185
|
# Evaluate a dependency for the command. Must be implemented by a command implementation.
|
@@ -165,6 +193,10 @@ module Licensed
|
|
165
193
|
def evaluate_dependency(app, source, dependency, report)
|
166
194
|
raise "`evaluate_dependency` must be implemented by a command"
|
167
195
|
end
|
196
|
+
|
197
|
+
def sources_overrides
|
198
|
+
@sources_overrides = Array(options[:sources])
|
199
|
+
end
|
168
200
|
end
|
169
201
|
end
|
170
202
|
end
|