licensed 3.1.0 → 3.2.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 +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
|