licensed 2.12.0 → 2.14.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +37 -43
- data/.github/workflows/test.yml +2 -2
- data/CHANGELOG.md +40 -1
- data/CONTRIBUTING.md +7 -6
- data/docs/configuration.md +1 -7
- data/docs/sources/go.md +20 -0
- data/lib/licensed/cli.rb +8 -9
- data/lib/licensed/commands/cache.rb +3 -3
- data/lib/licensed/commands/command.rb +30 -8
- data/lib/licensed/commands/environment.rb +7 -7
- data/lib/licensed/commands/list.rb +2 -2
- data/lib/licensed/commands/notices.rb +3 -3
- data/lib/licensed/commands/status.rb +2 -2
- data/lib/licensed/configuration.rb +17 -12
- data/lib/licensed/dependency_record.rb +4 -0
- data/lib/licensed/shell.rb +21 -4
- data/lib/licensed/sources/bundler.rb +4 -3
- data/lib/licensed/sources/npm.rb +13 -1
- data/lib/licensed/version.rb +1 -1
- data/licensed.gemspec +0 -1
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e51a39bfeaf0f48ca7a05b08047b8a64236b276097a0ee7f301dc1ca4e1ad1f
|
4
|
+
data.tar.gz: ee8de1cdebb66fa213f25b4b4bcd38957a4746b86bed6375a057cdd372603cc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 583a36dbc2a4e2cb6c9ae76a8976f01e61c2ec3f855d36aac3ce68f303170c7ddd2f0a5ed1e7acc5e67ae26eedd05ee05c1b884cf73a5a6836b2e81879b12078
|
7
|
+
data.tar.gz: ca025576af3f1a385f6517d2534a39e83ae2bc6a575933559f0457cab3afd28037ab16aef79e068958c225bdacec293b21afa3e4d2f5238bde473a3a3a924daa
|
@@ -1,18 +1,12 @@
|
|
1
|
-
name:
|
1
|
+
name: Build and publish release assets
|
2
2
|
|
3
|
-
on:
|
3
|
+
on:
|
4
|
+
release:
|
5
|
+
types: [created]
|
4
6
|
|
5
7
|
jobs:
|
6
|
-
tag_filter:
|
7
|
-
runs-on: ubuntu-latest
|
8
|
-
if: startsWith(github.ref, 'refs/tags/')
|
9
|
-
steps:
|
10
|
-
- run: exit 0
|
11
|
-
|
12
8
|
package_linux:
|
13
9
|
runs-on: ubuntu-latest
|
14
|
-
needs: tag_filter
|
15
|
-
|
16
10
|
steps:
|
17
11
|
- uses: actions/checkout@v2
|
18
12
|
- name: Set up Ruby 2.6
|
@@ -23,17 +17,15 @@ jobs:
|
|
23
17
|
- name: Build package
|
24
18
|
run: script/packages/linux
|
25
19
|
env:
|
26
|
-
VERSION: ${{github.event.
|
20
|
+
VERSION: ${{github.event.release.tag_name}}
|
27
21
|
|
28
22
|
- uses: actions/upload-artifact@v2
|
29
23
|
with:
|
30
|
-
name: ${{github.event.
|
31
|
-
path: pkg/${{github.event.
|
24
|
+
name: ${{github.event.release.tag_name}}-linux
|
25
|
+
path: pkg/${{github.event.release.tag_name}}/licensed-${{github.event.release.tag_name}}-linux-x64.tar.gz
|
32
26
|
|
33
27
|
package_mac:
|
34
28
|
runs-on: macOS-latest
|
35
|
-
needs: tag_filter
|
36
|
-
|
37
29
|
steps:
|
38
30
|
- uses: actions/checkout@v2
|
39
31
|
- name: Set up Ruby 2.6
|
@@ -44,17 +36,15 @@ jobs:
|
|
44
36
|
- name: Build package
|
45
37
|
run: script/packages/mac
|
46
38
|
env:
|
47
|
-
VERSION: ${{github.event.
|
39
|
+
VERSION: ${{github.event.release.tag_name}}
|
48
40
|
|
49
41
|
- uses: actions/upload-artifact@v2
|
50
42
|
with:
|
51
|
-
name: ${{github.event.
|
52
|
-
path: pkg/${{github.event.
|
43
|
+
name: ${{github.event.release.tag_name}}-darwin
|
44
|
+
path: pkg/${{github.event.release.tag_name}}/licensed-${{github.event.release.tag_name}}-darwin-x64.tar.gz
|
53
45
|
|
54
46
|
build_gem:
|
55
47
|
runs-on: ubuntu-latest
|
56
|
-
needs: tag_filter
|
57
|
-
|
58
48
|
steps:
|
59
49
|
- uses: actions/checkout@v2
|
60
50
|
- name: Set up Ruby 2.6
|
@@ -63,25 +53,16 @@ jobs:
|
|
63
53
|
ruby-version: 2.6.x
|
64
54
|
|
65
55
|
- name: Build gem
|
66
|
-
run: gem build
|
56
|
+
run: gem build licensed.gemspec -o licensed-${{github.event.release.tag_name}}.gem
|
67
57
|
|
68
58
|
- uses: actions/upload-artifact@v2
|
69
59
|
with:
|
70
|
-
name: ${{github.event.
|
71
|
-
path: licensed-${{github.event.
|
72
|
-
|
73
|
-
create_release:
|
74
|
-
runs-on: ubuntu-latest
|
75
|
-
needs: [package_linux, package_mac, build_gem]
|
76
|
-
steps:
|
77
|
-
- uses: Roang-zero1/github-create-release-action@v1.0.2
|
78
|
-
env:
|
79
|
-
GITHUB_TOKEN: ${{ secrets.API_AUTH_TOKEN }}
|
80
|
-
VERSION_REGEX: "^[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+"
|
60
|
+
name: ${{github.event.release.tag_name}}-gem
|
61
|
+
path: licensed-${{github.event.release.tag_name}}.gem
|
81
62
|
|
82
63
|
upload_packages:
|
83
64
|
runs-on: ubuntu-latest
|
84
|
-
needs: [
|
65
|
+
needs: [package_linux, package_mac, build_gem]
|
85
66
|
|
86
67
|
steps:
|
87
68
|
- name: Set up Ruby 2.6
|
@@ -92,32 +73,45 @@ jobs:
|
|
92
73
|
- name: Download linux package
|
93
74
|
uses: actions/download-artifact@v2
|
94
75
|
with:
|
95
|
-
name: ${{github.event.
|
76
|
+
name: ${{github.event.release.tag_name}}-linux
|
96
77
|
|
97
78
|
- name: Download macOS package
|
98
79
|
uses: actions/download-artifact@v2
|
99
80
|
with:
|
100
|
-
name: ${{github.event.
|
81
|
+
name: ${{github.event.release.tag_name}}-darwin
|
101
82
|
|
102
83
|
- name: Download gem
|
103
84
|
uses: actions/download-artifact@v2
|
104
85
|
with:
|
105
|
-
name: ${{github.event.
|
86
|
+
name: ${{github.event.release.tag_name}}-gem
|
106
87
|
|
107
|
-
- name: Publish
|
108
|
-
uses:
|
88
|
+
- name: Publish linux package
|
89
|
+
uses: actions/upload-release-asset@v1
|
90
|
+
env:
|
91
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
109
92
|
with:
|
110
|
-
|
93
|
+
upload_url: ${{ github.event.release.upload_url }}
|
94
|
+
asset_path: ./licensed-${{github.event.release.tag_name}}-linux-x64.tar.gz
|
95
|
+
asset_name: licensed-${{github.event.release.tag_name}}-linux-x64.tar.gz
|
96
|
+
asset_content_type: application/gzip
|
97
|
+
|
98
|
+
- name: Publish mac package
|
99
|
+
uses: actions/upload-release-asset@v1
|
111
100
|
env:
|
112
|
-
GITHUB_TOKEN: ${{secrets.
|
101
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
102
|
+
with:
|
103
|
+
upload_url: ${{ github.event.release.upload_url }}
|
104
|
+
asset_path: ./licensed-${{github.event.release.tag_name}}-darwin-x64.tar.gz
|
105
|
+
asset_name: licensed-${{github.event.release.tag_name}}-darwin-x64.tar.gz
|
106
|
+
asset_content_type: application/gzip
|
113
107
|
|
114
108
|
- name: Publish gem to RubyGems
|
115
109
|
run: |
|
116
110
|
mkdir -p $HOME/.gem
|
117
111
|
touch $HOME/.gem/credentials
|
118
112
|
chmod 0600 $HOME/.gem/credentials
|
119
|
-
printf -- "---\n:rubygems_api_key: ${
|
113
|
+
printf -- "---\n:rubygems_api_key: ${RUBYGEMS_API_KEY}\n" > $HOME/.gem/credentials
|
120
114
|
gem push $GEM
|
121
115
|
env:
|
122
|
-
|
123
|
-
GEM: licensed-${{github.event.
|
116
|
+
RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
|
117
|
+
GEM: licensed-${{github.event.release.tag_name}}.gem
|
data/.github/workflows/test.yml
CHANGED
@@ -116,7 +116,7 @@ jobs:
|
|
116
116
|
runs-on: ubuntu-latest
|
117
117
|
strategy:
|
118
118
|
matrix:
|
119
|
-
ruby: [ 2.4.x, 2.5.x, 2.6.x ]
|
119
|
+
ruby: [ 2.4.x, 2.5.x, 2.6.x, 2.7.x ]
|
120
120
|
steps:
|
121
121
|
- uses: actions/checkout@v2
|
122
122
|
- name: Set up Ruby
|
@@ -165,7 +165,7 @@ jobs:
|
|
165
165
|
runs-on: ubuntu-latest
|
166
166
|
strategy:
|
167
167
|
matrix:
|
168
|
-
go: [ '1.
|
168
|
+
go: [ '1.10.x', '1.11.x', '1.12.x', '1.13.x', '1.14.x', '1.15.x' ]
|
169
169
|
steps:
|
170
170
|
- uses: actions/checkout@v2
|
171
171
|
- name: Setup go
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,45 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## 2.14.1
|
10
|
+
2020-10-09
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
- Shell command output is encoded to UTF8 (https://github.com/github/licensed/pull/319)
|
14
|
+
|
15
|
+
## 2.14.0
|
16
|
+
2020-10-04
|
17
|
+
|
18
|
+
### Added
|
19
|
+
- `reviewed` dependencies can use glob pattern matching (https://github.com/github/licensed/pull/313)
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
- Fix configuring source path globs that expand into a single directory (https://github.com/github/licensed/pull/312)
|
23
|
+
|
24
|
+
## 2.13.0
|
25
|
+
2020-09-23
|
26
|
+
|
27
|
+
### Added
|
28
|
+
- `status` command results can be output in YAML and JSON formats (:tada: @julianvilas https://github.com/github/licensed/pull/303)
|
29
|
+
|
30
|
+
### Fixed
|
31
|
+
- `licensed` no longer crashes when parsing invalid YAML from cached records (https://github.com/github/licensed/pull/306)
|
32
|
+
- NPM source will no longer crash when invalid JSON is returned from npm CLI calls (https://github.com/github/licensed/pull/300)
|
33
|
+
- Bundler source is fixed to work properly with `gems.rb` lockfiles (https://github.com/github/licensed/pull/299)
|
34
|
+
|
35
|
+
## 2.12.2
|
36
|
+
2020-07-07
|
37
|
+
|
38
|
+
### Changed
|
39
|
+
- Cleaned up ruby 2.7 warnings (:tada: @jurre https://github.com/github/licensed/pull/292)
|
40
|
+
- Cleaned up additional warnings in tests (https://github.com/github/licensed/pull/293)
|
41
|
+
|
42
|
+
## 2.12.1
|
43
|
+
2020-06-30
|
44
|
+
|
45
|
+
### Fixed
|
46
|
+
- `licensed` no longer exits an error code when using the `--sources` CLI argument (https://github.com/github/licensed/pull/290)
|
47
|
+
|
9
48
|
## 2.12.0
|
10
49
|
2020-06-19
|
11
50
|
|
@@ -327,4 +366,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
327
366
|
|
328
367
|
Initial release :tada:
|
329
368
|
|
330
|
-
[Unreleased]: https://github.com/github/licensed/compare/2.
|
369
|
+
[Unreleased]: https://github.com/github/licensed/compare/2.14.1...HEAD
|
data/CONTRIBUTING.md
CHANGED
@@ -39,7 +39,7 @@ Pull requests that include a new dependency source must also
|
|
39
39
|
## Releasing
|
40
40
|
If you are the current maintainer of this gem:
|
41
41
|
|
42
|
-
1. Create a branch for the release: git checkout -b cut-release-
|
42
|
+
1. Create a branch for the release: git checkout -b cut-release-xx.xx.xx
|
43
43
|
2. Make sure your local dependencies are up to date: `script/bootstrap`
|
44
44
|
3. Ensure that tests are green: `bundle exec rake test`
|
45
45
|
4. Bump gem version in lib/licensed/version.rb.
|
@@ -51,15 +51,16 @@ If you are the current maintainer of this gem:
|
|
51
51
|
2. Install the new gem locally
|
52
52
|
3. Test behavior locally, branch deploy, whatever needs to happen
|
53
53
|
9. Merge github/licensed PR
|
54
|
-
10.
|
54
|
+
10. Create a new [github/licensed release](https://github.com/github/licensed/releases)
|
55
|
+
- Set the release name and tag to the release version - `x.xx.x`
|
56
|
+
- Set the release body to the changelog entries for the release
|
55
57
|
|
56
58
|
The following steps will happen automatically from a GitHub Actions workflow
|
57
|
-
after
|
59
|
+
after creating the release. In case that fails, the following steps can be performed manually
|
58
60
|
|
59
|
-
11. Push to rubygems.org -- `gem push licensed-x.xx.xx.gem`
|
61
|
+
11. Push the gem from (7) to rubygems.org -- `gem push licensed-x.xx.xx.gem`
|
60
62
|
12. Build packages for new tag: `VERSION=x.xx.xx bundle exec rake package`
|
61
|
-
13.
|
62
|
-
14. Add built packages to new release
|
63
|
+
13. Upload packages from (12) to release from (10)
|
63
64
|
|
64
65
|
## Resources
|
65
66
|
|
data/docs/configuration.md
CHANGED
@@ -23,7 +23,7 @@ If a root path is not specified, it will default to using the following, in orde
|
|
23
23
|
|
24
24
|
The `source_path` property can use a glob path to share configuration properties across multiple application entrypoints.
|
25
25
|
|
26
|
-
For example, there is a common pattern in
|
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
27
|
|
28
28
|
```yml
|
29
29
|
sources:
|
@@ -118,12 +118,6 @@ ignored:
|
|
118
118
|
bower:
|
119
119
|
- some-internal-package
|
120
120
|
|
121
|
-
go:
|
122
|
-
# ignore all go packages from import paths starting with github.com/internal-package
|
123
|
-
# see the `File.fnmatch?` documentation for details on how patterns are matched.
|
124
|
-
# comparisons use the FNM_CASEFOLD and FNM_PATHNAME flags
|
125
|
-
- github.com/internal-package/**/*
|
126
|
-
|
127
121
|
# These dependencies have licenses not on the `allowed` list and have been reviewed.
|
128
122
|
# They will be cached and checked, but will not raise errors or warnings for a
|
129
123
|
# non-allowed license. Dependencies on this list will still raise errors if
|
data/docs/sources/go.md
CHANGED
@@ -24,6 +24,26 @@ The setting supports absolute, relative and expandable (e.g. "~") paths. Relati
|
|
24
24
|
|
25
25
|
Non-empty `GOPATH` configuration settings will override the `GOPATH` environment variable while enumerating `go` dependencies. The `GOPATH` environment variable is restored once dependencies have been enumerated.
|
26
26
|
|
27
|
+
#### Reviewing and ignoring all packages from a Go module
|
28
|
+
|
29
|
+
Go's package and module structure has common conventions that documentation and metadata for all packages in a module live in the module root. In this scenario all packages share the same LICENSE information and can be reviewed or ignored at the module level rather than per-package using glob patterns.
|
30
|
+
|
31
|
+
```yaml
|
32
|
+
reviewed:
|
33
|
+
go:
|
34
|
+
# review all Go packages from import paths starting with github.com/external-package
|
35
|
+
# see the `File.fnmatch?` documentation for details on how patterns are matched.
|
36
|
+
# comparisons use the FNM_CASEFOLD and FNM_PATHNAME flags
|
37
|
+
- github.com/external-package/**/*
|
38
|
+
|
39
|
+
ignored:
|
40
|
+
go:
|
41
|
+
# ignore all Go packages from import paths starting with github.com/internal-package
|
42
|
+
# see the `File.fnmatch?` documentation for details on how patterns are matched.
|
43
|
+
# comparisons use the FNM_CASEFOLD and FNM_PATHNAME flags
|
44
|
+
- github.com/internal-package/**/*
|
45
|
+
```
|
46
|
+
|
27
47
|
#### Versioning
|
28
48
|
|
29
49
|
The go source supports multiple versioning strategies to determine if cached dependency metadata is stale. A version strategy is chosen based on the availability of go module information along with the current app configuration.
|
data/lib/licensed/cli.rb
CHANGED
@@ -14,17 +14,18 @@ module Licensed
|
|
14
14
|
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
15
15
|
def cache
|
16
16
|
run Licensed::Commands::Cache.new(config: config),
|
17
|
-
|
17
|
+
force: options[:force], sources: options[:sources]
|
18
18
|
end
|
19
19
|
|
20
20
|
desc "status", "Check status of dependencies' cached licenses"
|
21
|
+
method_option :format, enum: ["yaml", "json"],
|
22
|
+
desc: "Output format"
|
21
23
|
method_option :config, aliases: "-c", type: :string,
|
22
24
|
desc: "Path to licensed configuration file"
|
23
25
|
method_option :sources, aliases: "-s", type: :array,
|
24
26
|
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
25
27
|
def status
|
26
|
-
run Licensed::Commands::Status.new(config: config),
|
27
|
-
{ sources: options[:sources] }
|
28
|
+
run Licensed::Commands::Status.new(config: config), sources: options[:sources], reporter: options[:format]
|
28
29
|
end
|
29
30
|
|
30
31
|
desc "list", "List dependencies"
|
@@ -33,8 +34,7 @@ module Licensed
|
|
33
34
|
method_option :sources, aliases: "-s", type: :array,
|
34
35
|
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
35
36
|
def list
|
36
|
-
run Licensed::Commands::List.new(config: config),
|
37
|
-
{ sources: options[:sources] }
|
37
|
+
run Licensed::Commands::List.new(config: config), sources: options[:sources]
|
38
38
|
end
|
39
39
|
|
40
40
|
desc "notices", "Generate a NOTICE file from cached records"
|
@@ -43,8 +43,7 @@ module Licensed
|
|
43
43
|
method_option :sources, aliases: "-s", type: :array,
|
44
44
|
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
45
45
|
def notices
|
46
|
-
run Licensed::Commands::Notices.new(config: config),
|
47
|
-
{ sources: options[:sources] }
|
46
|
+
run Licensed::Commands::Notices.new(config: config), sources: options[:sources]
|
48
47
|
end
|
49
48
|
|
50
49
|
map "-v" => :version
|
@@ -60,7 +59,7 @@ module Licensed
|
|
60
59
|
method_option :config, aliases: "-c", type: :string,
|
61
60
|
desc: "Path to licensed configuration file"
|
62
61
|
def env
|
63
|
-
run Licensed::Commands::Environment.new(config: config),
|
62
|
+
run Licensed::Commands::Environment.new(config: config), reporter: options[:format]
|
64
63
|
end
|
65
64
|
|
66
65
|
desc "migrate", "Migrate from a previous version of licensed"
|
@@ -99,7 +98,7 @@ module Licensed
|
|
99
98
|
end
|
100
99
|
|
101
100
|
def run(command, **args)
|
102
|
-
exit command.run(args)
|
101
|
+
exit command.run(**args)
|
103
102
|
end
|
104
103
|
end
|
105
104
|
end
|
@@ -2,12 +2,12 @@
|
|
2
2
|
module Licensed
|
3
3
|
module Commands
|
4
4
|
class Cache < Command
|
5
|
-
#
|
5
|
+
# Returns the default reporter to use during the command run
|
6
6
|
#
|
7
7
|
# options - The options the command was run with
|
8
8
|
#
|
9
|
-
#
|
10
|
-
def
|
9
|
+
# Returns a Licensed::Reporters::CacheReporter
|
10
|
+
def default_reporter(options)
|
11
11
|
Licensed::Reporters::CacheReporter.new
|
12
12
|
end
|
13
13
|
|
@@ -22,7 +22,7 @@ module Licensed
|
|
22
22
|
result = reporter.report_run(self) do |report|
|
23
23
|
# allow additional report data to be given by commands
|
24
24
|
if block_given?
|
25
|
-
next if (yield report) == :skip
|
25
|
+
next true if (yield report) == :skip
|
26
26
|
end
|
27
27
|
|
28
28
|
config.apps.sort_by { |app| app["name"] }
|
@@ -37,13 +37,29 @@ module Licensed
|
|
37
37
|
result
|
38
38
|
end
|
39
39
|
|
40
|
-
#
|
40
|
+
# Creates a reporter to use during a command run
|
41
41
|
#
|
42
42
|
# options - The options the command was run with
|
43
43
|
#
|
44
|
-
#
|
44
|
+
# Returns the reporter to use during the command run
|
45
45
|
def create_reporter(options)
|
46
|
-
|
46
|
+
return options[:reporter] if options[:reporter].is_a?(Licensed::Reporters::Reporter)
|
47
|
+
|
48
|
+
if options[:reporter].is_a?(String)
|
49
|
+
klass = "#{options[:reporter].capitalize}Reporter"
|
50
|
+
return Licensed::Reporters.const_get(klass).new if Licensed::Reporters.const_defined?(klass)
|
51
|
+
end
|
52
|
+
|
53
|
+
default_reporter(options)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the default reporter to use during the command run
|
57
|
+
#
|
58
|
+
# options - The options the command was run with
|
59
|
+
#
|
60
|
+
# Raises an error
|
61
|
+
def default_reporter(options)
|
62
|
+
raise "`default_reporter` must be implemented by commands"
|
47
63
|
end
|
48
64
|
|
49
65
|
protected
|
@@ -56,11 +72,17 @@ module Licensed
|
|
56
72
|
# Returns whether the command succeeded for the application.
|
57
73
|
def run_app(app)
|
58
74
|
reporter.report_app(app) do |report|
|
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
|
80
|
+
|
59
81
|
Dir.chdir app.source_path do
|
60
82
|
begin
|
61
83
|
# allow additional report data to be given by commands
|
62
84
|
if block_given?
|
63
|
-
next if (yield report) == :skip
|
85
|
+
next true if (yield report) == :skip
|
64
86
|
end
|
65
87
|
|
66
88
|
app.sources.select(&:enabled?)
|
@@ -86,7 +108,7 @@ module Licensed
|
|
86
108
|
begin
|
87
109
|
# allow additional report data to be given by commands
|
88
110
|
if block_given?
|
89
|
-
next if (yield report) == :skip
|
111
|
+
next true if (yield report) == :skip
|
90
112
|
end
|
91
113
|
|
92
114
|
source.dependencies.sort_by { |dependency| dependency.name }
|
@@ -121,11 +143,11 @@ module Licensed
|
|
121
143
|
begin
|
122
144
|
# allow additional report data to be given by commands
|
123
145
|
if block_given?
|
124
|
-
next if (yield report) == :skip
|
146
|
+
next true if (yield report) == :skip
|
125
147
|
end
|
126
148
|
|
127
149
|
evaluate_dependency(app, source, dependency, report)
|
128
|
-
rescue Licensed::Shell::Error => err
|
150
|
+
rescue Licensed::DependencyRecord::Error, Licensed::Shell::Error => err
|
129
151
|
report.errors << err.message
|
130
152
|
false
|
131
153
|
end
|
@@ -35,13 +35,13 @@ module Licensed
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
# Returns the default reporter to use during the command run
|
39
|
+
#
|
40
|
+
# options - The options the command was run with
|
41
|
+
#
|
42
|
+
# Returns a Licensed::Reporters::StatusReporter
|
43
|
+
def default_reporter(options)
|
44
|
+
Licensed::Reporters::YamlReporter.new
|
45
45
|
end
|
46
46
|
|
47
47
|
protected
|
@@ -2,12 +2,12 @@
|
|
2
2
|
module Licensed
|
3
3
|
module Commands
|
4
4
|
class List < Command
|
5
|
-
#
|
5
|
+
# Returns the default reporter to use during the command run
|
6
6
|
#
|
7
7
|
# options - The options the command was run with
|
8
8
|
#
|
9
9
|
# Returns a Licensed::Reporters::ListReporter
|
10
|
-
def
|
10
|
+
def default_reporter(options)
|
11
11
|
Licensed::Reporters::ListReporter.new
|
12
12
|
end
|
13
13
|
|
@@ -2,12 +2,12 @@
|
|
2
2
|
module Licensed
|
3
3
|
module Commands
|
4
4
|
class Notices < Command
|
5
|
-
#
|
5
|
+
# Returns the default reporter to use during the command run
|
6
6
|
#
|
7
7
|
# options - The options the command was run with
|
8
8
|
#
|
9
|
-
#
|
10
|
-
def
|
9
|
+
# Returns a Licensed::Reporters::CacheReporter
|
10
|
+
def default_reporter(options)
|
11
11
|
Licensed::Reporters::NoticesReporter.new
|
12
12
|
end
|
13
13
|
|
@@ -4,12 +4,12 @@ require "yaml"
|
|
4
4
|
module Licensed
|
5
5
|
module Commands
|
6
6
|
class Status < Command
|
7
|
-
#
|
7
|
+
# Returns the default reporter to use during the command run
|
8
8
|
#
|
9
9
|
# options - The options the command was run with
|
10
10
|
#
|
11
11
|
# Returns a Licensed::Reporters::StatusReporter
|
12
|
-
def
|
12
|
+
def default_reporter(options)
|
13
13
|
Licensed::Reporters::StatusReporter.new
|
14
14
|
end
|
15
15
|
|
@@ -69,7 +69,9 @@ module Licensed
|
|
69
69
|
|
70
70
|
# Is the given dependency reviewed?
|
71
71
|
def reviewed?(dependency)
|
72
|
-
Array(self["reviewed"][dependency["type"]]).
|
72
|
+
Array(self["reviewed"][dependency["type"]]).any? do |pattern|
|
73
|
+
File.fnmatch?(pattern, dependency["name"], File::FNM_PATHNAME | File::FNM_CASEFOLD)
|
74
|
+
end
|
73
75
|
end
|
74
76
|
|
75
77
|
# Is the given dependency ignored?
|
@@ -158,19 +160,22 @@ module Licensed
|
|
158
160
|
def self.expand_app_source_path(app_config)
|
159
161
|
return app_config if app_config["source_path"].to_s.empty?
|
160
162
|
|
163
|
+
# check if the source path maps to an existing directory
|
161
164
|
source_path = File.expand_path(app_config["source_path"], AppConfiguration.root_for(app_config))
|
165
|
+
return app_config if Dir.exist?(source_path)
|
166
|
+
|
167
|
+
# try to expand the source path for glob patterns
|
162
168
|
expanded_source_paths = Dir.glob(source_path).select { |p| File.directory?(p) }
|
163
|
-
|
164
|
-
return app_config if expanded_source_paths.size <= 1
|
169
|
+
configs = expanded_source_paths.map { |path| app_config.merge("source_path" => path) }
|
165
170
|
|
166
|
-
#
|
167
|
-
|
168
|
-
config = app_config.merge("source_path" => path)
|
171
|
+
# if no directories are found for the source path, return the original config
|
172
|
+
return app_config if configs.size == 0
|
169
173
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
+
# update configured values for name and cache_path for uniqueness.
|
175
|
+
# this is only needed when values are explicitly set, AppConfiguration
|
176
|
+
# will handle configurations that don't have these explicitly set
|
177
|
+
configs.each do |config|
|
178
|
+
dir_name = File.basename(config["source_path"])
|
174
179
|
config["name"] = "#{config["name"]}-#{dir_name}" if config["name"]
|
175
180
|
|
176
181
|
# if a cache_path is set and is not marked as shared, append the app name
|
@@ -178,9 +183,9 @@ module Licensed
|
|
178
183
|
if config["cache_path"] && config["shared_cache"] != true
|
179
184
|
config["cache_path"] = File.join(config["cache_path"], dir_name)
|
180
185
|
end
|
181
|
-
|
182
|
-
config
|
183
186
|
end
|
187
|
+
|
188
|
+
configs
|
184
189
|
end
|
185
190
|
|
186
191
|
# Find a default configuration file in the given directory.
|
@@ -5,6 +5,8 @@ require "licensee"
|
|
5
5
|
|
6
6
|
module Licensed
|
7
7
|
class DependencyRecord
|
8
|
+
class Error < StandardError; end
|
9
|
+
|
8
10
|
class License
|
9
11
|
attr_reader :text, :sources
|
10
12
|
def initialize(content)
|
@@ -46,6 +48,8 @@ module Licensed
|
|
46
48
|
notices: data.delete("notices"),
|
47
49
|
metadata: data
|
48
50
|
)
|
51
|
+
rescue Psych::SyntaxError => e
|
52
|
+
raise Licensed::DependencyRecord::Error.new(e.message)
|
49
53
|
end
|
50
54
|
|
51
55
|
def_delegators :@metadata, :[], :[]=
|
data/lib/licensed/shell.rb
CHANGED
@@ -9,11 +9,12 @@ module Licensed
|
|
9
9
|
def self.execute(cmd, *args, allow_failure: false, env: {})
|
10
10
|
stdout, stderr, status = Open3.capture3(env, cmd, *args)
|
11
11
|
|
12
|
-
if status.success?
|
13
|
-
|
14
|
-
else
|
15
|
-
raise Error.new([cmd, *args], status.exitstatus, stderr)
|
12
|
+
if !status.success? && !allow_failure
|
13
|
+
raise Error.new([cmd, *args], status.exitstatus, encode_content(stderr))
|
16
14
|
end
|
15
|
+
|
16
|
+
# ensure that returned data is properly encoded
|
17
|
+
encode_content(stdout.strip)
|
17
18
|
end
|
18
19
|
|
19
20
|
# Executes a command and returns a boolean value indicating if the command
|
@@ -55,5 +56,21 @@ module Licensed
|
|
55
56
|
end.join(" ")
|
56
57
|
end
|
57
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
ENCODING = Encoding::UTF_8
|
63
|
+
ENCODING_OPTIONS = {
|
64
|
+
invalid: :replace,
|
65
|
+
undef: :replace,
|
66
|
+
replace: "",
|
67
|
+
univeral_newline: true
|
68
|
+
}.freeze
|
69
|
+
|
70
|
+
# Ensure that content that is returned from shell commands is in a usable
|
71
|
+
# encoding for the rest of the application
|
72
|
+
def self.encode_content(content)
|
73
|
+
content.encode(ENCODING, **ENCODING_OPTIONS)
|
74
|
+
end
|
58
75
|
end
|
59
76
|
end
|
@@ -74,7 +74,7 @@ module Licensed
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
GEMFILES =
|
77
|
+
GEMFILES = { "Gemfile" => "Gemfile.lock", "gems.rb" => "gems.locked" }
|
78
78
|
DEFAULT_WITHOUT_GROUPS = %i{development test}
|
79
79
|
|
80
80
|
def enabled?
|
@@ -272,14 +272,15 @@ module Licensed
|
|
272
272
|
|
273
273
|
# Returns the path to the Bundler Gemfile
|
274
274
|
def gemfile_path
|
275
|
-
@gemfile_path ||= GEMFILES.
|
275
|
+
@gemfile_path ||= GEMFILES.keys
|
276
|
+
.map { |g| config.pwd.join g }
|
276
277
|
.find { |f| f.exist? }
|
277
278
|
end
|
278
279
|
|
279
280
|
# Returns the path to the Bundler Gemfile.lock
|
280
281
|
def lockfile_path
|
281
282
|
return unless gemfile_path
|
282
|
-
@lockfile_path ||= gemfile_path.dirname.join(
|
283
|
+
@lockfile_path ||= gemfile_path.dirname.join(GEMFILES[gemfile_path.basename.to_s])
|
283
284
|
end
|
284
285
|
|
285
286
|
# Returns the configured bundler executable to use, or "bundle" by default.
|
data/lib/licensed/sources/npm.rb
CHANGED
@@ -30,7 +30,7 @@ module Licensed
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def packages
|
33
|
-
root_dependencies =
|
33
|
+
root_dependencies = package_metadata["dependencies"]
|
34
34
|
recursive_dependencies(root_dependencies).each_with_object({}) do |(name, results), hsh|
|
35
35
|
results.uniq! { |package| package["version"] }
|
36
36
|
if results.size == 1
|
@@ -56,6 +56,18 @@ module Licensed
|
|
56
56
|
result
|
57
57
|
end
|
58
58
|
|
59
|
+
# Returns parsed package metadata returned from `npm list`
|
60
|
+
def package_metadata
|
61
|
+
return @package_metadata if defined?(@package_metadata)
|
62
|
+
|
63
|
+
@package_metadata = begin
|
64
|
+
JSON.parse(package_metadata_command)
|
65
|
+
rescue JSON::ParserError => e
|
66
|
+
raise Licensed::Sources::Source::Error,
|
67
|
+
"Licensed was unable to parse the output from 'npm list'. Please run 'npm list --json --long' and check for errors. Error: #{e.message}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
59
71
|
# Returns the output from running `npm list` to get package metadata
|
60
72
|
def package_metadata_command
|
61
73
|
args = %w(--json --long)
|
data/lib/licensed/version.rb
CHANGED
data/licensed.gemspec
CHANGED
@@ -38,5 +38,4 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_development_dependency "rubocop", "~> 0.49", "< 0.67"
|
39
39
|
spec.add_development_dependency "rubocop-github", "~> 0.6"
|
40
40
|
spec.add_development_dependency "byebug", "~> 10.0.0"
|
41
|
-
spec.add_development_dependency "spy", "~> 1.0.0"
|
42
41
|
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.14.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: licensee
|
@@ -218,20 +218,6 @@ dependencies:
|
|
218
218
|
- - "~>"
|
219
219
|
- !ruby/object:Gem::Version
|
220
220
|
version: 10.0.0
|
221
|
-
- !ruby/object:Gem::Dependency
|
222
|
-
name: spy
|
223
|
-
requirement: !ruby/object:Gem::Requirement
|
224
|
-
requirements:
|
225
|
-
- - "~>"
|
226
|
-
- !ruby/object:Gem::Version
|
227
|
-
version: 1.0.0
|
228
|
-
type: :development
|
229
|
-
prerelease: false
|
230
|
-
version_requirements: !ruby/object:Gem::Requirement
|
231
|
-
requirements:
|
232
|
-
- - "~>"
|
233
|
-
- !ruby/object:Gem::Version
|
234
|
-
version: 1.0.0
|
235
221
|
description: Licensed automates extracting and validating the licenses of dependencies.
|
236
222
|
email:
|
237
223
|
- opensource+licensed@github.com
|