licensed 2.4.0 → 2.5.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/release.yml +24 -22
- data/CHANGELOG.md +10 -1
- data/README.md +1 -1
- data/docs/commands.md +12 -14
- data/lib/licensed/cli.rb +9 -0
- data/lib/licensed/commands.rb +1 -0
- data/lib/licensed/commands/cache.rb +7 -2
- data/lib/licensed/commands/command.rb +25 -3
- data/lib/licensed/commands/environment.rb +57 -0
- data/lib/licensed/commands/list.rb +7 -2
- data/lib/licensed/commands/status.rb +42 -5
- data/lib/licensed/configuration.rb +2 -2
- data/lib/licensed/dependency_record.rb +25 -9
- data/lib/licensed/reporters.rb +2 -0
- data/lib/licensed/reporters/json_reporter.rb +35 -0
- data/lib/licensed/reporters/reporter.rb +13 -0
- data/lib/licensed/reporters/yaml_reporter.rb +48 -0
- data/lib/licensed/version.rb +1 -1
- data/licensed.gemspec +1 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45476f98c8dd054a36758218f6337826e90b1112
|
4
|
+
data.tar.gz: e040ac55ae8dbd3b7dd498318b8046a271c58832
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6773ae7dc4f41afd8f0597c11e3ea4bda59c10de44654c9fd9b6b91bce6f2a0b0b092ecccb95dc39ce6da5678736672d6fb3fa9b48b47bf82eb1758cecc91297
|
7
|
+
data.tar.gz: 80c82cfccb88980bc3b1b04da520e740683bb18d52cc3dcc5e60801e529f5c926d64c9df80a24dfc431e4ff2271a4fef67389b7bf4b9779edd7aeb739d015036
|
@@ -28,7 +28,7 @@ jobs:
|
|
28
28
|
|
29
29
|
- uses: actions/upload-artifact@master
|
30
30
|
with:
|
31
|
-
name:
|
31
|
+
name: ${{github.event.ref}}-linux
|
32
32
|
path: pkg/${{github.event.ref}}/licensed-${{github.event.ref}}-linux-x64.tar.gz
|
33
33
|
|
34
34
|
package_mac:
|
@@ -49,28 +49,28 @@ jobs:
|
|
49
49
|
|
50
50
|
- uses: actions/upload-artifact@master
|
51
51
|
with:
|
52
|
-
name:
|
52
|
+
name: ${{github.event.ref}}-darwin
|
53
53
|
path: pkg/${{github.event.ref}}/licensed-${{github.event.ref}}-darwin-x64.tar.gz
|
54
|
-
|
54
|
+
|
55
55
|
build_gem:
|
56
56
|
runs-on: ubuntu-latest
|
57
57
|
needs: tag_filter
|
58
|
-
|
58
|
+
|
59
59
|
steps:
|
60
60
|
- uses: actions/checkout@master
|
61
61
|
- name: Set up Ruby 2.6
|
62
62
|
uses: actions/setup-ruby@v1
|
63
63
|
with:
|
64
64
|
version: 2.6.x
|
65
|
-
|
65
|
+
|
66
66
|
- name: Build gem
|
67
67
|
run: gem build *.gemspec
|
68
|
-
|
68
|
+
|
69
69
|
- uses: actions/upload-artifact@master
|
70
70
|
with:
|
71
|
-
name:
|
71
|
+
name: ${{github.event.ref}}-gem
|
72
72
|
path: licensed-${{github.event.ref}}.gem
|
73
|
-
|
73
|
+
|
74
74
|
create_release:
|
75
75
|
runs-on: ubuntu-latest
|
76
76
|
needs: [package_linux, package_mac, build_gem]
|
@@ -86,38 +86,40 @@ jobs:
|
|
86
86
|
needs: [create_release]
|
87
87
|
|
88
88
|
steps:
|
89
|
+
- name: Set up Ruby 2.6
|
90
|
+
uses: actions/setup-ruby@v1
|
91
|
+
with:
|
92
|
+
version: 2.6.x
|
93
|
+
|
89
94
|
- name: Download linux package
|
90
95
|
uses: actions/download-artifact@master
|
91
96
|
with:
|
92
|
-
name:
|
97
|
+
name: ${{github.event.ref}}-linux
|
98
|
+
|
93
99
|
- name: Download macOS package
|
94
100
|
uses: actions/download-artifact@master
|
95
101
|
with:
|
96
|
-
name:
|
102
|
+
name: ${{github.event.ref}}-darwin
|
103
|
+
|
104
|
+
- name: Download gem
|
105
|
+
uses: actions/download-artifact@master
|
106
|
+
with:
|
107
|
+
name: ${{github.event.ref}}-gem
|
97
108
|
|
98
109
|
- name: Publish packages to GitHub Release
|
99
110
|
uses: Roang-zero1/github-upload-release-artifacts-action@v2.0.0
|
100
111
|
with:
|
101
|
-
args:
|
112
|
+
args: ${{github.event.ref}}-linux ${{github.event.ref}}-darwin
|
102
113
|
env:
|
103
114
|
GITHUB_TOKEN: ${{secrets.API_AUTH_TOKEN}}
|
104
115
|
|
105
|
-
- name: Download gem
|
106
|
-
uses: actions/download-artifact@master
|
107
|
-
with:
|
108
|
-
name: licensed-${{github.event.ref}}.gem
|
109
|
-
|
110
|
-
- name: Set up Ruby 2.6
|
111
|
-
uses: actions/setup-ruby@v1
|
112
|
-
with:
|
113
|
-
version: 2.6.x
|
114
|
-
|
115
116
|
- name: Publish gem to RubyGems
|
116
117
|
run: |
|
117
118
|
mkdir -p $HOME/.gem
|
118
119
|
touch $HOME/.gem/credentials
|
119
120
|
chmod 0600 $HOME/.gem/credentials
|
120
121
|
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
121
|
-
gem push
|
122
|
+
gem push "$GEM"
|
122
123
|
env:
|
123
124
|
GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
|
125
|
+
GEM: ${{github.event.ref}}-gem/*.gem
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## 2.5.0
|
10
|
+
2019-09-26
|
11
|
+
|
12
|
+
### Added
|
13
|
+
- `env` command to output application environment configuration (https://github.com/github/licensed/pull/187, https://github.com/github/licensed/pull/191)
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
- `status` command will pass if multiple allowed licenses are found (https://github.com/github/licensed/pull/188)
|
17
|
+
|
9
18
|
## 2.4.0
|
10
19
|
2019-09-15
|
11
20
|
|
@@ -214,4 +223,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
214
223
|
|
215
224
|
Initial release :tada:
|
216
225
|
|
217
|
-
[Unreleased]: https://github.com/github/licensed/compare/2.
|
226
|
+
[Unreleased]: https://github.com/github/licensed/compare/2.5.0...HEAD
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ Licensed is **not** a complete open source license compliance solution. Please u
|
|
8
8
|
|
9
9
|
## Current Status
|
10
10
|
|
11
|
-
|
11
|
+

|
12
12
|
|
13
13
|
Licensed is in active development and currently used at GitHub. See the [open issues](https://github.com/github/licensed/issues) for a list of potential work.
|
14
14
|
|
data/docs/commands.md
CHANGED
@@ -25,8 +25,15 @@ The status command finds all dependencies and checks whether each dependency has
|
|
25
25
|
A dependency will fail the status checks if:
|
26
26
|
1. No cached record is found
|
27
27
|
2. The cached record's version is different than the current dependency's version
|
28
|
-
3. The cached record
|
28
|
+
3. The cached record's `licenses` data is empty
|
29
29
|
4. The cached record's `license` metadata doesn't match an `allowed` license from the dependency's application configuration.
|
30
|
+
- If `license: other` is specified and all of the `licenses` entries match an `allowed` license a failure will not be logged
|
31
|
+
|
32
|
+
## `env`
|
33
|
+
|
34
|
+
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.
|
35
|
+
|
36
|
+
The output will not be equivalent to configuration input. For example, all paths will be
|
30
37
|
|
31
38
|
## `version`
|
32
39
|
|
@@ -41,7 +48,7 @@ Licensed commands inherit and override the [`Licensed::Sources::Command`](../lib
|
|
41
48
|
#### Required method overrides
|
42
49
|
1. `Licensed::Commands::Command#evaluate_dependency`
|
43
50
|
- Runs a command execution on an application dependency.
|
44
|
-
|
51
|
+
|
45
52
|
The `evaluate_dependency` method should contain the specific command logic. This method has access to the application configuration, dependency source enumerator and dependency currently being evaluated as well as a reporting hash to contain information about the command execution.
|
46
53
|
|
47
54
|
#### Optional method overrides
|
@@ -59,23 +66,14 @@ The following methods break apart the different levels of command execution. Ea
|
|
59
66
|
|
60
67
|
As an example, `Licensed::Commands::Command#run_app` calls `Reporter#report_app` to wrap every call to `Licensed::Commands::Command#run_source`.
|
61
68
|
|
62
|
-
#####
|
69
|
+
##### Specifying additional report data
|
63
70
|
|
64
|
-
The `run` methods can be overridden to provide additional reporting data or functionality.
|
71
|
+
The `run` methods can be overridden and pass a block to `super` to provide additional reporting data or functionality.
|
65
72
|
|
66
73
|
```ruby
|
67
74
|
def run_app(app)
|
68
75
|
super do |report|
|
69
|
-
|
70
|
-
|
71
|
-
# do other thing
|
72
|
-
call_additional_functionality(app)
|
73
|
-
|
74
|
-
# add reporting information
|
75
|
-
report["result"] = result
|
76
|
-
|
77
|
-
# return the result
|
78
|
-
result
|
76
|
+
report["my_app_data"] = true
|
79
77
|
end
|
80
78
|
end
|
81
79
|
```
|
data/lib/licensed/cli.rb
CHANGED
@@ -35,6 +35,15 @@ module Licensed
|
|
35
35
|
puts Licensed::VERSION
|
36
36
|
end
|
37
37
|
|
38
|
+
desc "env", "Output licensed environment configuration"
|
39
|
+
method_option :format, enum: ["yaml", "json"], default: "yaml",
|
40
|
+
desc: "Output format"
|
41
|
+
method_option :config, aliases: "-c", type: :string,
|
42
|
+
desc: "Path to licensed configuration file"
|
43
|
+
def env
|
44
|
+
run Licensed::Commands::Environment.new(config: config), format: options[:format]
|
45
|
+
end
|
46
|
+
|
38
47
|
desc "migrate", "Migrate from a previous version of licensed"
|
39
48
|
method_option :config, aliases: "-c", type: :string, required: true,
|
40
49
|
desc: "Path to licensed configuration file"
|
data/lib/licensed/commands.rb
CHANGED
@@ -2,8 +2,13 @@
|
|
2
2
|
module Licensed
|
3
3
|
module Commands
|
4
4
|
class Cache < Command
|
5
|
-
|
6
|
-
|
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::CacheReporter.new
|
7
12
|
end
|
8
13
|
|
9
14
|
protected
|
@@ -6,9 +6,8 @@ module Licensed
|
|
6
6
|
attr_reader :reporter
|
7
7
|
attr_reader :options
|
8
8
|
|
9
|
-
def initialize(config
|
9
|
+
def initialize(config:)
|
10
10
|
@config = config
|
11
|
-
@reporter = reporter
|
12
11
|
end
|
13
12
|
|
14
13
|
# Run the command
|
@@ -18,19 +17,33 @@ module Licensed
|
|
18
17
|
# Returns whether the command was a success
|
19
18
|
def run(**options)
|
20
19
|
@options = options
|
20
|
+
@reporter = create_reporter(options)
|
21
21
|
begin
|
22
|
-
result = reporter.report_run(self) do
|
22
|
+
result = reporter.report_run(self) do |report|
|
23
|
+
# allow additional report data to be given by commands
|
24
|
+
yield report if block_given?
|
25
|
+
|
23
26
|
config.apps.sort_by { |app| app["name"] }
|
24
27
|
.map { |app| run_app(app) }
|
25
28
|
.all?
|
26
29
|
end
|
27
30
|
ensure
|
28
31
|
@options = nil
|
32
|
+
@reporter = nil
|
29
33
|
end
|
30
34
|
|
31
35
|
result
|
32
36
|
end
|
33
37
|
|
38
|
+
# Create a reporter to use during a command run
|
39
|
+
#
|
40
|
+
# options - The options the command was run with
|
41
|
+
#
|
42
|
+
# Raises an error
|
43
|
+
def create_reporter(options)
|
44
|
+
raise "`create_reporter` must be implemented by commands"
|
45
|
+
end
|
46
|
+
|
34
47
|
protected
|
35
48
|
|
36
49
|
# Run the command for all enabled sources for an application configuration,
|
@@ -43,6 +56,9 @@ module Licensed
|
|
43
56
|
reporter.report_app(app) do |report|
|
44
57
|
Dir.chdir app.source_path do
|
45
58
|
begin
|
59
|
+
# allow additional report data to be given by commands
|
60
|
+
yield report if block_given?
|
61
|
+
|
46
62
|
app.sources.select(&:enabled?)
|
47
63
|
.sort_by { |source| source.class.type }
|
48
64
|
.map { |source| run_source(app, source) }.all?
|
@@ -64,6 +80,9 @@ module Licensed
|
|
64
80
|
def run_source(app, source)
|
65
81
|
reporter.report_source(source) do |report|
|
66
82
|
begin
|
83
|
+
# allow additional report data to be given by commands
|
84
|
+
yield report if block_given?
|
85
|
+
|
67
86
|
source.dependencies.sort_by { |dependency| dependency.name }
|
68
87
|
.map { |dependency| run_dependency(app, source, dependency) }
|
69
88
|
.all?
|
@@ -94,6 +113,9 @@ module Licensed
|
|
94
113
|
end
|
95
114
|
|
96
115
|
begin
|
116
|
+
# allow additional report data to be given by commands
|
117
|
+
yield report if block_given?
|
118
|
+
|
97
119
|
evaluate_dependency(app, source, dependency, report)
|
98
120
|
rescue Licensed::Shell::Error => err
|
99
121
|
report.errors << err.message
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Licensed
|
3
|
+
module Commands
|
4
|
+
class Environment < Command
|
5
|
+
class AppEnvironment
|
6
|
+
include Licensed::Sources::ContentVersioning
|
7
|
+
|
8
|
+
attr_reader :config
|
9
|
+
def initialize(config)
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
def enabled_source_types
|
14
|
+
config.sources.select { |s| s.enabled? }.map { |s| s.class.type }
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_h
|
18
|
+
{
|
19
|
+
"name" => config["name"],
|
20
|
+
"source_path" => config.source_path,
|
21
|
+
"cache_path" => config.cache_path,
|
22
|
+
"sources" => enabled_source_types,
|
23
|
+
"allowed" => config["allowed"],
|
24
|
+
"ignored" => config["ignored"],
|
25
|
+
"reviewed" => config["reviewed"],
|
26
|
+
"version_strategy" => self.version_strategy
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def run(**options)
|
32
|
+
super do |report|
|
33
|
+
report["root"] = config.root
|
34
|
+
report["git_repo"] = Licensed::Git.git_repo?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_reporter(options)
|
39
|
+
case options[:format]
|
40
|
+
when "json"
|
41
|
+
Licensed::Reporters::JsonReporter.new
|
42
|
+
else
|
43
|
+
Licensed::Reporters::YamlReporter.new
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def run_app(app)
|
50
|
+
reporter.report_app(app) do |report|
|
51
|
+
report.merge! AppEnvironment.new(app).to_h
|
52
|
+
true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -2,8 +2,13 @@
|
|
2
2
|
module Licensed
|
3
3
|
module Commands
|
4
4
|
class List < Command
|
5
|
-
|
6
|
-
|
5
|
+
# Create a reporter to use during a command run
|
6
|
+
#
|
7
|
+
# options - The options the command was run with
|
8
|
+
#
|
9
|
+
# Returns a Licensed::Reporters::ListReporter
|
10
|
+
def create_reporter(options)
|
11
|
+
Licensed::Reporters::ListReporter.new
|
7
12
|
end
|
8
13
|
|
9
14
|
protected
|
@@ -4,8 +4,13 @@ require "yaml"
|
|
4
4
|
module Licensed
|
5
5
|
module Commands
|
6
6
|
class Status < Command
|
7
|
-
|
8
|
-
|
7
|
+
# Create a reporter to use during a command run
|
8
|
+
#
|
9
|
+
# options - The options the command was run with
|
10
|
+
#
|
11
|
+
# Returns a Licensed::Reporters::StatusReporter
|
12
|
+
def create_reporter(options)
|
13
|
+
Licensed::Reporters::StatusReporter.new
|
9
14
|
end
|
10
15
|
|
11
16
|
protected
|
@@ -30,20 +35,52 @@ module Licensed
|
|
30
35
|
else
|
31
36
|
report.errors << "cached dependency record out of date" if cached_record["version"] != dependency.version
|
32
37
|
report.errors << "missing license text" if cached_record.licenses.empty?
|
33
|
-
report.errors << "license needs review: #{cached_record["license"]}"
|
38
|
+
report.errors << "license needs review: #{cached_record["license"]}" if license_needs_review?(app, cached_record)
|
34
39
|
end
|
35
40
|
|
36
41
|
report.errors.empty?
|
37
42
|
end
|
38
43
|
|
39
|
-
|
40
|
-
|
44
|
+
# Returns true if a cached record needs further review based on the
|
45
|
+
# record's license(s) and the app's configuration
|
46
|
+
def license_needs_review?(app, cached_record)
|
47
|
+
# review is not needed if the record is set as reviewed
|
48
|
+
return false if app.reviewed?(cached_record)
|
49
|
+
# review is not needed if the top level license is allowed
|
50
|
+
return false if app.allowed?(cached_record["license"])
|
51
|
+
|
52
|
+
# the remaining checks are meant to allow records marked as "other"
|
53
|
+
# that have multiple licenses, all of which are allowed
|
54
|
+
|
55
|
+
# review is needed for non-"other" licenses
|
56
|
+
return true unless cached_record["license"] == "other"
|
57
|
+
|
58
|
+
licenses = cached_record.licenses.map { |license| license_from_text(license.text) }
|
59
|
+
|
60
|
+
# review is needed when there is only one license notice
|
61
|
+
# this is a performance optimization for the single license case
|
62
|
+
return true unless licenses.length > 1
|
63
|
+
|
64
|
+
# review is needed if any license notices don't represent an allowed license
|
65
|
+
licenses.any? { |license| !app.allowed?(license) }
|
41
66
|
end
|
42
67
|
|
43
68
|
def cached_record(filename)
|
44
69
|
return nil unless File.exist?(filename)
|
45
70
|
DependencyRecord.read(filename)
|
46
71
|
end
|
72
|
+
|
73
|
+
# Returns a license key based on the content from a cached records `licenses`
|
74
|
+
# entry content
|
75
|
+
def license_from_text(text)
|
76
|
+
licenses = [
|
77
|
+
Licensee::ProjectFiles::LicenseFile.new(text).license&.key,
|
78
|
+
Licensee::ProjectFiles::ReadmeFile.new(text).license&.key,
|
79
|
+
"other"
|
80
|
+
].compact
|
81
|
+
|
82
|
+
licenses.sort_by { |license| license != "other" ? 0 : 1 }.first
|
83
|
+
end
|
47
84
|
end
|
48
85
|
end
|
49
86
|
end
|
@@ -79,8 +79,8 @@ module Licensed
|
|
79
79
|
end
|
80
80
|
|
81
81
|
# Is the license of the dependency allowed?
|
82
|
-
def allowed?(
|
83
|
-
Array(self["allowed"]).include?(
|
82
|
+
def allowed?(license)
|
83
|
+
Array(self["allowed"]).include?(license)
|
84
84
|
end
|
85
85
|
|
86
86
|
# Ignore a dependency
|
@@ -5,6 +5,28 @@ require "licensee"
|
|
5
5
|
|
6
6
|
module Licensed
|
7
7
|
class DependencyRecord
|
8
|
+
class License
|
9
|
+
attr_reader :text, :sources
|
10
|
+
def initialize(content)
|
11
|
+
@sources = []
|
12
|
+
|
13
|
+
if content.is_a?(String)
|
14
|
+
@text = content.to_s
|
15
|
+
elsif content.respond_to?(:[])
|
16
|
+
@sources.concat content["sources"].to_s.split(", ")
|
17
|
+
@text = content["text"]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_cache
|
22
|
+
return text if sources.empty?
|
23
|
+
{
|
24
|
+
"sources" => sources.join(", "),
|
25
|
+
"text" => text
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
8
30
|
include Licensee::ContentHelper
|
9
31
|
extend Forwardable
|
10
32
|
|
@@ -36,7 +58,7 @@ module Licensed
|
|
36
58
|
# notices - a string, or array of strings, representing the content of each legal notice
|
37
59
|
# metadata - a Hash of the metadata for the package
|
38
60
|
def initialize(licenses: [], notices: [], metadata: {})
|
39
|
-
@licenses = [licenses].flatten.compact
|
61
|
+
@licenses = [licenses].flatten.compact.map { |l| DependencyRecord::License.new(l) }
|
40
62
|
@notices = [notices].flatten.compact
|
41
63
|
@metadata = metadata
|
42
64
|
end
|
@@ -46,7 +68,7 @@ module Licensed
|
|
46
68
|
# filename - The destination file to save record contents at
|
47
69
|
def save(filename)
|
48
70
|
data_to_save = @metadata.merge({
|
49
|
-
"licenses" => licenses,
|
71
|
+
"licenses" => licenses.map(&:to_cache),
|
50
72
|
"notices" => notices
|
51
73
|
})
|
52
74
|
|
@@ -58,13 +80,7 @@ module Licensed
|
|
58
80
|
# `Licensee::CotentHelper`
|
59
81
|
def content
|
60
82
|
return if licenses.nil? || licenses.empty?
|
61
|
-
licenses.map
|
62
|
-
if license.is_a?(String)
|
63
|
-
license
|
64
|
-
elsif license.respond_to?(:[])
|
65
|
-
license["text"]
|
66
|
-
end
|
67
|
-
end.join
|
83
|
+
licenses.map(&:text).compact.join
|
68
84
|
end
|
69
85
|
|
70
86
|
# Returns whether two records match based on their contents
|
data/lib/licensed/reporters.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Licensed
|
5
|
+
module Reporters
|
6
|
+
class JsonReporter < Reporter
|
7
|
+
def report_run(command)
|
8
|
+
super do |report|
|
9
|
+
result = yield report
|
10
|
+
|
11
|
+
report["apps"] = report.reports.map(&:to_h) if report.reports.any?
|
12
|
+
shell.info JSON.pretty_generate(report.to_h)
|
13
|
+
|
14
|
+
result
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def report_app(app)
|
19
|
+
super do |report|
|
20
|
+
result = yield report
|
21
|
+
report["sources"] = report.reports.map(&:to_h) if report.reports.any?
|
22
|
+
result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def report_source(source)
|
27
|
+
super do |report|
|
28
|
+
result = yield report
|
29
|
+
report["dependencies"] = report.reports.map(&:to_h) if report.reports.any?
|
30
|
+
result
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -28,6 +28,19 @@ module Licensed
|
|
28
28
|
result << self
|
29
29
|
result.push(*reports.flat_map(&:all_reports))
|
30
30
|
end
|
31
|
+
|
32
|
+
# Returns the data from the report as a hash
|
33
|
+
def to_h
|
34
|
+
# add name, errors and warnings if they have real data
|
35
|
+
output = {}
|
36
|
+
output["name"] = name unless name.to_s.empty?
|
37
|
+
output["errors"] = errors.dup if errors.any?
|
38
|
+
output["warnings"] = warnings.dup if warnings.any?
|
39
|
+
|
40
|
+
# merge the hash data from the report. command-specified data always
|
41
|
+
# overwrites local data
|
42
|
+
output.merge(super)
|
43
|
+
end
|
31
44
|
end
|
32
45
|
|
33
46
|
class ReportingError < StandardError; end;
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Licensed
|
3
|
+
module Reporters
|
4
|
+
class YamlReporter < Reporter
|
5
|
+
def report_run(command)
|
6
|
+
super do |report|
|
7
|
+
result = yield report
|
8
|
+
|
9
|
+
report["apps"] = report.reports.map(&:to_h) if report.reports.any?
|
10
|
+
shell.info sanitize(report.to_h).to_yaml
|
11
|
+
|
12
|
+
result
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def report_app(app)
|
17
|
+
super do |report|
|
18
|
+
result = yield report
|
19
|
+
report["sources"] = report.reports.map(&:to_h) if report.reports.any?
|
20
|
+
result
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def report_source(source)
|
25
|
+
super do |report|
|
26
|
+
result = yield report
|
27
|
+
report["dependencies"] = report.reports.map(&:to_h) if report.reports.any?
|
28
|
+
result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def sanitize(object)
|
33
|
+
case object
|
34
|
+
when String, TrueClass, FalseClass, Numeric
|
35
|
+
object
|
36
|
+
when Array
|
37
|
+
object.compact.map { |item| sanitize(item) }
|
38
|
+
when Hash
|
39
|
+
object.reject { |_, v| v.nil? }
|
40
|
+
.map { |k, v| [k.to_s, sanitize(v)] }
|
41
|
+
.to_h
|
42
|
+
else
|
43
|
+
object.to_s
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/licensed/version.rb
CHANGED
data/licensed.gemspec
CHANGED
@@ -36,4 +36,5 @@ Gem::Specification.new do |spec|
|
|
36
36
|
spec.add_development_dependency "rubocop", "~> 0.49", "< 0.67"
|
37
37
|
spec.add_development_dependency "rubocop-github", "~> 0.6"
|
38
38
|
spec.add_development_dependency "byebug", "~> 10.0.0"
|
39
|
+
spec.add_development_dependency "spy", "~> 1.0.0"
|
39
40
|
end
|
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.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: licensee
|
@@ -184,6 +184,20 @@ dependencies:
|
|
184
184
|
- - "~>"
|
185
185
|
- !ruby/object:Gem::Version
|
186
186
|
version: 10.0.0
|
187
|
+
- !ruby/object:Gem::Dependency
|
188
|
+
name: spy
|
189
|
+
requirement: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - "~>"
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: 1.0.0
|
194
|
+
type: :development
|
195
|
+
prerelease: false
|
196
|
+
version_requirements: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - "~>"
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: 1.0.0
|
187
201
|
description: Licensed automates extracting and validating the licenses of dependencies.
|
188
202
|
email:
|
189
203
|
- opensource+licensed@github.com
|
@@ -231,6 +245,7 @@ files:
|
|
231
245
|
- lib/licensed/commands.rb
|
232
246
|
- lib/licensed/commands/cache.rb
|
233
247
|
- lib/licensed/commands/command.rb
|
248
|
+
- lib/licensed/commands/environment.rb
|
234
249
|
- lib/licensed/commands/list.rb
|
235
250
|
- lib/licensed/commands/status.rb
|
236
251
|
- lib/licensed/configuration.rb
|
@@ -241,9 +256,11 @@ files:
|
|
241
256
|
- lib/licensed/migrations/v2.rb
|
242
257
|
- lib/licensed/reporters.rb
|
243
258
|
- lib/licensed/reporters/cache_reporter.rb
|
259
|
+
- lib/licensed/reporters/json_reporter.rb
|
244
260
|
- lib/licensed/reporters/list_reporter.rb
|
245
261
|
- lib/licensed/reporters/reporter.rb
|
246
262
|
- lib/licensed/reporters/status_reporter.rb
|
263
|
+
- lib/licensed/reporters/yaml_reporter.rb
|
247
264
|
- lib/licensed/shell.rb
|
248
265
|
- lib/licensed/sources.rb
|
249
266
|
- lib/licensed/sources/bower.rb
|