licensed 3.0.0 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +19 -0
- data/.github/workflows/release.yml +4 -4
- data/.github/workflows/test.yml +180 -47
- data/.ruby-version +1 -1
- data/CHANGELOG.md +60 -1
- data/README.md +25 -79
- data/docker/Dockerfile.build-linux +1 -1
- 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 +74 -0
- data/docs/commands/version.md +3 -0
- 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/docs/configuration.md +9 -161
- data/docs/sources/swift.md +4 -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 +105 -12
- 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/definition.rb +36 -0
- data/lib/licensed/sources/bundler/missing_specification.rb +1 -1
- data/lib/licensed/sources/bundler.rb +38 -86
- data/lib/licensed/sources/dep.rb +2 -2
- data/lib/licensed/sources/go.rb +3 -3
- data/lib/licensed/sources/gradle.rb +2 -2
- data/lib/licensed/sources/helpers/content_versioning.rb +2 -1
- data/lib/licensed/sources/npm.rb +4 -3
- data/lib/licensed/sources/nuget.rb +56 -27
- data/lib/licensed/sources/swift.rb +69 -0
- data/lib/licensed/sources.rb +1 -0
- data/lib/licensed/version.rb +1 -1
- data/lib/licensed.rb +1 -0
- data/licensed.gemspec +4 -4
- data/script/source-setup/go +1 -1
- data/script/source-setup/swift +22 -0
- metadata +48 -13
- data/docs/commands.md +0 -95
@@ -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/docs/configuration.md
CHANGED
@@ -2,75 +2,12 @@
|
|
2
2
|
|
3
3
|
A configuration file specifies the details of enumerating and operating on license metadata for apps.
|
4
4
|
|
5
|
-
Configuration can be specified in either YML or JSON formats
|
5
|
+
Configuration can be specified in either YML or JSON formats, with examples given in YML. The example
|
6
|
+
below describes common configuration values and their purposes. See [configuration options documentation](./configuration)
|
7
|
+
for in depth information.
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
`licensed` requires a path to enumerate dependencies at (`source_path`) and a path to store cached metadata (`cache_path`).
|
10
|
-
|
11
|
-
To determine these paths across multiple environments where absolute paths will differ, a known root path is needed to evaluate relative paths against.
|
12
|
-
In using a root, relative source and cache paths can be specified in the configuration file.
|
13
|
-
|
14
|
-
When using a configuration file, the root property can be set as either a path that can be expanded from the configuration file directory using `File.expand_path`, or the value `true` to use the configuration file directory as the root.
|
15
|
-
|
16
|
-
When creating a `Licensed::Dependency` manually with a `root` property, the property must be an absolute path - no path expansion will occur.
|
17
|
-
|
18
|
-
If a root path is not specified, it will default to using the following, in order of precedence
|
19
|
-
1. the root of the local git repository, if run inside a git repository
|
20
|
-
2. the current directory
|
21
|
-
|
22
|
-
### Source path glob patterns
|
23
|
-
|
24
|
-
The `source_path` property can use a glob path to share configuration properties across multiple application entrypoints.
|
25
|
-
|
26
|
-
For example, there is a common pattern in Go projects to include multiple executable entrypoints under folders in `cmd`. Using a glob pattern allows users to avoid manually configuring and maintaining multiple licensed application `source_path`s. Using a glob pattern will also ensure that any new entrypoints matching the pattern are automatically picked up by licensed commands as they are added.
|
27
|
-
|
28
|
-
```yml
|
29
|
-
sources:
|
30
|
-
go: true
|
31
|
-
|
32
|
-
# treat all directories under `cmd` as separate apps
|
33
|
-
source_path: cmd/*
|
34
|
-
```
|
35
|
-
|
36
|
-
Glob patterns are syntactic sugar for, and provide the same functionality as, manually specifying multiple `source_path` values. See the instructions on [specifying multiple apps](./#specifying-multiple-apps) below for additional considerations when using multiple apps.
|
37
|
-
|
38
|
-
## Restricting sources
|
39
|
-
|
40
|
-
The `sources` configuration property specifies which sources `licensed` will use to enumerate dependencies.
|
41
|
-
By default, `licensed` will generally try to enumerate dependencies from all sources. As a result,
|
42
|
-
the configuration property should be used to explicitly disable sources rather than to enable a particular source.
|
43
|
-
|
44
|
-
Be aware that this configuration is separate from an individual sources `#enabled?` method, which determines
|
45
|
-
whether the source is valid for the current project. Even if a source is enabled in the configuration
|
46
|
-
it may still determine that it can't enumerate dependencies for a project.
|
9
|
+
Additionally, some dependency sources have their own specific configuration options. See the [source documentation](./sources) for details.
|
47
10
|
|
48
|
-
```yml
|
49
|
-
sources:
|
50
|
-
bower: true
|
51
|
-
bundler: false
|
52
|
-
```
|
53
|
-
|
54
|
-
`licensed` determines which sources will try to enumerate dependencies based on the following rules:
|
55
|
-
1. If no sources are configured, all sources are enabled
|
56
|
-
2. If no sources are set to true, any unconfigured sources are enabled
|
57
|
-
```yml
|
58
|
-
sources:
|
59
|
-
bower: false
|
60
|
-
# all other sources are enabled by default since there are no sources set to true
|
61
|
-
```
|
62
|
-
3. If any sources are set to true, any unconfigured sources are disabled
|
63
|
-
```yml
|
64
|
-
sources:
|
65
|
-
bower: true
|
66
|
-
# all other sources are disabled by default because a source was set to true
|
67
|
-
```
|
68
|
-
|
69
|
-
## Applications
|
70
|
-
|
71
|
-
What is an "app"? In the context of `licensed`, an app is a combination of a source path and a cache path.
|
72
|
-
|
73
|
-
Configuration can be set up for single or multiple applications in the same repo. There are a number of settings available for each app:
|
74
11
|
```yml
|
75
12
|
# If not set, defaults to the directory name of `source_path`
|
76
13
|
name: 'My application'
|
@@ -129,100 +66,11 @@ reviewed:
|
|
129
66
|
bower:
|
130
67
|
- classlist # public domain
|
131
68
|
- octicons
|
132
|
-
```
|
133
|
-
|
134
|
-
### Specifying a single app
|
135
|
-
To specify a single app, either include a single app with `source_path` in the `apps` configuration, or remove the `apps` setting entirely.
|
136
|
-
|
137
|
-
If the configuration does not contain an `apps` value, the root configuration will be used as an app definition. In this scenario, the `source_path` is not a required value and will default to the directory that `licensed` was executed from.
|
138
|
-
|
139
|
-
If the configuration contains an `apps` value with a single app configuration, `source_path` must be specified. Additionally, the applications inherited `cache_path` value will contain the application name. See [Inherited cache_path values](#inherited_cache_path_values)
|
140
|
-
|
141
|
-
### Specifying multiple apps
|
142
|
-
The configuration file can specify multiple source paths to enumerate metadata, each with their own configuration.
|
143
|
-
|
144
|
-
Nearly all configuration settings can be inherited from root configuration to app configuration. Only `source_path` is required to define an app.
|
145
69
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
```yml
|
150
|
-
sources:
|
151
|
-
go: true
|
152
|
-
bundler: false
|
153
|
-
|
154
|
-
ignored:
|
155
|
-
bundler:
|
156
|
-
- some-internal-gem
|
157
|
-
|
158
|
-
reviewed:
|
159
|
-
bundler:
|
160
|
-
- bcrypt-ruby
|
161
|
-
|
162
|
-
cache_path: 'path/to/cache'
|
163
|
-
apps:
|
164
|
-
- source_path: 'path/to/app1'
|
165
|
-
- source_path: 'path/to/app2'
|
166
|
-
sources:
|
167
|
-
bundler: true
|
168
|
-
go: false
|
169
|
-
```
|
170
|
-
|
171
|
-
In this example, two apps have been declared. The first app, with `source_path` `path/to/app1`, inherits all configuration settings from the root configuration. The second app, with `source_path` `path/to/app2`, overrides the `sources` configuration and inherits all other settings.
|
172
|
-
|
173
|
-
#### Default app names
|
174
|
-
An app will not inherit a name set from the root configuration. If not provided, the `name` value will default to the directory name from `source_path`.
|
175
|
-
```yml
|
70
|
+
# A single configuration file can be used to enumerate dependencies for multiple
|
71
|
+
# projects. Each configuration is referred to as an "application" and must include
|
72
|
+
# a source path, at a minimum
|
176
73
|
apps:
|
177
|
-
- source_path:
|
178
|
-
- source_path:
|
74
|
+
- source_path: path/to/application1
|
75
|
+
- source_path: path/to/application2
|
179
76
|
```
|
180
|
-
|
181
|
-
In this example, the apps have names of `app1` and `app2`, respectively.
|
182
|
-
|
183
|
-
#### Inherited cache_path values
|
184
|
-
When an app inherits a `cache_path` from the root configuration, it will automatically append it's name to the end of the path to separate it's metadata from other apps. To force multiple apps to use the same path to cached metadata, explicitly set the `cache_path` value for each app.
|
185
|
-
```yml
|
186
|
-
cache_path: 'path/to/cache'
|
187
|
-
apps:
|
188
|
-
- source_path: 'path/to/app1'
|
189
|
-
name: 'app1'
|
190
|
-
- source_path: 'path/to/app2'
|
191
|
-
name: 'app2'
|
192
|
-
- source_path: 'path/to/app3'
|
193
|
-
name: 'app3'
|
194
|
-
cache_path: 'path/to/app3/cache'
|
195
|
-
```
|
196
|
-
|
197
|
-
In this example `app1` and `app2` have `cache_path` values of `path/to/cache/app1` and `path/to/cache/app2`, respectively. `app3` has an explicit path set to `path/to/app3/cache`
|
198
|
-
|
199
|
-
```yml
|
200
|
-
apps:
|
201
|
-
- source_path: 'path/to/app1'
|
202
|
-
```
|
203
|
-
|
204
|
-
In this example, the root configuration will contain a default cache path of `.licenses`. `app1` will inherit this value and append it's name, resulting in a cache path of `.licenses/app1`.
|
205
|
-
|
206
|
-
### Sharing caches between apps
|
207
|
-
|
208
|
-
Dependency caches can be shared between apps by setting the same cache path on each app.
|
209
|
-
|
210
|
-
```yaml
|
211
|
-
apps:
|
212
|
-
- source_path: "path/to/app1"
|
213
|
-
cache_path: ".licenses/apps"
|
214
|
-
- source_path: "path/to/app2"
|
215
|
-
cache_path: ".licenses/apps"
|
216
|
-
```
|
217
|
-
|
218
|
-
When using a source path with a glob pattern, the apps created from the glob pattern can share a dependency by setting an explicit cache path and setting `shared_cache` to true.
|
219
|
-
|
220
|
-
```yaml
|
221
|
-
source_path: "path/to/apps/*"
|
222
|
-
cache_path: ".licenses/apps"
|
223
|
-
shared_cache: true
|
224
|
-
```
|
225
|
-
|
226
|
-
## Source specific configuration
|
227
|
-
|
228
|
-
See the [source documentation](./sources) for details on any source specific configuration.
|
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
|