licensed 2.13.0 → 2.14.4
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 +131 -41
- data/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +36 -1
- data/CONTRIBUTING.md +7 -6
- data/docker/Dockerfile.build-linux +1 -0
- data/docs/configuration.md +1 -7
- data/docs/sources/go.md +20 -0
- data/lib/licensed/cli.rb +8 -2
- data/lib/licensed/commands/command.rb +6 -0
- data/lib/licensed/commands/list.rb +7 -0
- data/lib/licensed/configuration.rb +17 -12
- data/lib/licensed/dependency.rb +1 -0
- data/lib/licensed/reporters/list_reporter.rb +3 -1
- data/lib/licensed/shell.rb +21 -4
- data/lib/licensed/sources/go.rb +43 -43
- data/lib/licensed/sources/yarn.rb +14 -6
- data/lib/licensed/version.rb +1 -1
- data/script/packages/linux +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1042edfc8e49ab1430a73001612f260fb20f80931139649f8b8ae6f044d74463
|
4
|
+
data.tar.gz: 386c548165ed4c4ed1b5b78131635552c11ec03f6a09e8f75e328d1446b129a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c163d4d2bbffe0756b4aecfa353a99d8d3be92ea7fe5b536d00dc79b1581132b31bf69fd0947a85de095ec2d5604da547d175507a199427b1e74da25e8b63a03
|
7
|
+
data.tar.gz: 719df2438ad31e8e525f15ae2b9948f1fc3a0a83b5e72f2e109b10d498f65734d6ab49af99fb92486e31d4314a635a0a2d5bdca793bd51412804b76d9b48042a
|
@@ -1,20 +1,97 @@
|
|
1
|
-
name:
|
2
|
-
|
3
|
-
on:
|
1
|
+
name: Build and publish release assets
|
2
|
+
|
3
|
+
on:
|
4
|
+
release:
|
5
|
+
types: [created]
|
6
|
+
workflow_dispatch:
|
7
|
+
inputs:
|
8
|
+
version:
|
9
|
+
description: 'Commit-like version of github/licensed to build package at'
|
10
|
+
required: true
|
11
|
+
release_tag:
|
12
|
+
description: 'Release tag to upload built packages to'
|
13
|
+
required: false
|
4
14
|
|
5
15
|
jobs:
|
6
|
-
|
16
|
+
vars:
|
17
|
+
name: "Gather values for remainder of steps"
|
7
18
|
runs-on: ubuntu-latest
|
8
|
-
|
19
|
+
outputs:
|
20
|
+
version: ${{ steps.get_version.outputs.result }}
|
21
|
+
upload_url: ${{ steps.get_url.outputs.result }}
|
22
|
+
ref: ${{ steps.get_ref.outputs.result }}
|
9
23
|
steps:
|
10
|
-
-
|
24
|
+
- id: get_version
|
25
|
+
name: Get package version
|
26
|
+
uses: actions/github-script@v3
|
27
|
+
with:
|
28
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
29
|
+
result-encoding: string
|
30
|
+
script: |
|
31
|
+
let version = "${{ github.event.release.tag_name }}"
|
32
|
+
if (!version) {
|
33
|
+
version = "${{ github.event.inputs.version }}"
|
34
|
+
}
|
35
|
+
|
36
|
+
if (!version) {
|
37
|
+
throw new Error("unable to find package build version")
|
38
|
+
}
|
39
|
+
|
40
|
+
return version
|
41
|
+
|
42
|
+
- id: get_url
|
43
|
+
name: Get release upload url
|
44
|
+
uses: actions/github-script@v3
|
45
|
+
with:
|
46
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
47
|
+
result-encoding: string
|
48
|
+
script: |
|
49
|
+
let uploadUrl = "${{ github.event.release.upload_url}}"
|
50
|
+
const tag = "${{ github.event.inputs.release_tag }}"
|
51
|
+
if (!uploadUrl && tag) {
|
52
|
+
const { data: release } = await github.repos.getReleaseByTag({
|
53
|
+
...context.repo,
|
54
|
+
tag
|
55
|
+
})
|
56
|
+
|
57
|
+
if (!release.upload_url) {
|
58
|
+
throw new Error("unable to find a release upload url")
|
59
|
+
}
|
60
|
+
|
61
|
+
uploadUrl = release.upload_url
|
62
|
+
}
|
63
|
+
|
64
|
+
return uploadUrl
|
65
|
+
|
66
|
+
- id: get_ref
|
67
|
+
name: Get checkout ref for custom build scripts
|
68
|
+
uses: actions/github-script@v3
|
69
|
+
with:
|
70
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
71
|
+
result-encoding: string
|
72
|
+
script: |
|
73
|
+
let ref = "${{ github.event.release.tag_name }}"
|
74
|
+
if (!ref) {
|
75
|
+
ref = "${{ github.event.ref }}".replace(/refs\/[^\/]+\//, '')
|
76
|
+
}
|
77
|
+
|
78
|
+
if (!ref) {
|
79
|
+
throw new Error("unable to find a ref for action")
|
80
|
+
}
|
81
|
+
|
82
|
+
return ref
|
11
83
|
|
12
84
|
package_linux:
|
85
|
+
needs: vars
|
13
86
|
runs-on: ubuntu-latest
|
14
|
-
needs: tag_filter
|
15
|
-
|
16
87
|
steps:
|
17
88
|
- uses: actions/checkout@v2
|
89
|
+
with:
|
90
|
+
# checkout at the ref for the action, separate from the target build version
|
91
|
+
# this allows running build scripts independent of the target version
|
92
|
+
ref: ${{needs.vars.outputs.ref}}
|
93
|
+
fetch-depth: 0
|
94
|
+
|
18
95
|
- name: Set up Ruby 2.6
|
19
96
|
uses: actions/setup-ruby@v1
|
20
97
|
with:
|
@@ -23,19 +100,24 @@ jobs:
|
|
23
100
|
- name: Build package
|
24
101
|
run: script/packages/linux
|
25
102
|
env:
|
26
|
-
VERSION: ${{
|
103
|
+
VERSION: ${{needs.vars.outputs.version}}
|
27
104
|
|
28
105
|
- uses: actions/upload-artifact@v2
|
29
106
|
with:
|
30
|
-
name: ${{
|
31
|
-
path: pkg/${{
|
107
|
+
name: ${{needs.vars.outputs.version}}-linux
|
108
|
+
path: pkg/${{needs.vars.outputs.version}}/licensed-${{needs.vars.outputs.version}}-linux-x64.tar.gz
|
32
109
|
|
33
110
|
package_mac:
|
111
|
+
needs: vars
|
34
112
|
runs-on: macOS-latest
|
35
|
-
needs: tag_filter
|
36
|
-
|
37
113
|
steps:
|
38
114
|
- uses: actions/checkout@v2
|
115
|
+
with:
|
116
|
+
# checkout at the ref for the action, separate from the target build version
|
117
|
+
# this allows running build scripts independent of the target version
|
118
|
+
ref: ${{needs.vars.outputs.ref}}
|
119
|
+
fetch-depth: 0
|
120
|
+
|
39
121
|
- name: Set up Ruby 2.6
|
40
122
|
uses: actions/setup-ruby@v1
|
41
123
|
with:
|
@@ -44,44 +126,39 @@ jobs:
|
|
44
126
|
- name: Build package
|
45
127
|
run: script/packages/mac
|
46
128
|
env:
|
47
|
-
VERSION: ${{
|
129
|
+
VERSION: ${{needs.vars.outputs.version}}
|
48
130
|
|
49
131
|
- uses: actions/upload-artifact@v2
|
50
132
|
with:
|
51
|
-
name: ${{
|
52
|
-
path: pkg/${{
|
133
|
+
name: ${{needs.vars.outputs.version}}-darwin
|
134
|
+
path: pkg/${{needs.vars.outputs.version}}/licensed-${{needs.vars.outputs.version}}-darwin-x64.tar.gz
|
53
135
|
|
54
136
|
build_gem:
|
137
|
+
needs: vars
|
55
138
|
runs-on: ubuntu-latest
|
56
|
-
needs: tag_filter
|
57
|
-
|
58
139
|
steps:
|
59
140
|
- uses: actions/checkout@v2
|
141
|
+
with:
|
142
|
+
# building a gem doesn't use a different ref from the version input
|
143
|
+
ref: ${{needs.vars.outputs.version}}
|
144
|
+
|
60
145
|
- name: Set up Ruby 2.6
|
61
146
|
uses: actions/setup-ruby@v1
|
62
147
|
with:
|
63
148
|
ruby-version: 2.6.x
|
64
149
|
|
65
150
|
- name: Build gem
|
66
|
-
run: gem build
|
151
|
+
run: gem build licensed.gemspec -o licensed-${{needs.vars.outputs.version}}.gem
|
67
152
|
|
68
153
|
- uses: actions/upload-artifact@v2
|
69
154
|
with:
|
70
|
-
name: ${{
|
71
|
-
path: licensed-${{
|
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:]]+"
|
155
|
+
name: ${{needs.vars.outputs.version}}-gem
|
156
|
+
path: licensed-${{needs.vars.outputs.version}}.gem
|
81
157
|
|
82
158
|
upload_packages:
|
159
|
+
if: ${{ needs.vars.outputs.upload_url != '' }}
|
83
160
|
runs-on: ubuntu-latest
|
84
|
-
needs: [
|
161
|
+
needs: [vars, package_linux, package_mac, build_gem]
|
85
162
|
|
86
163
|
steps:
|
87
164
|
- name: Set up Ruby 2.6
|
@@ -92,32 +169,45 @@ jobs:
|
|
92
169
|
- name: Download linux package
|
93
170
|
uses: actions/download-artifact@v2
|
94
171
|
with:
|
95
|
-
name: ${{
|
172
|
+
name: ${{needs.vars.outputs.version}}-linux
|
96
173
|
|
97
174
|
- name: Download macOS package
|
98
175
|
uses: actions/download-artifact@v2
|
99
176
|
with:
|
100
|
-
name: ${{
|
177
|
+
name: ${{needs.vars.outputs.version}}-darwin
|
101
178
|
|
102
179
|
- name: Download gem
|
103
180
|
uses: actions/download-artifact@v2
|
104
181
|
with:
|
105
|
-
name: ${{
|
182
|
+
name: ${{needs.vars.outputs.version}}-gem
|
106
183
|
|
107
|
-
- name: Publish
|
108
|
-
uses:
|
184
|
+
- name: Publish linux package
|
185
|
+
uses: actions/upload-release-asset@v1
|
186
|
+
env:
|
187
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
109
188
|
with:
|
110
|
-
|
189
|
+
upload_url: ${{ needs.vars.outputs.upload_url }}
|
190
|
+
asset_path: ./licensed-${{needs.vars.outputs.version}}-linux-x64.tar.gz
|
191
|
+
asset_name: licensed-${{needs.vars.outputs.version}}-linux-x64.tar.gz
|
192
|
+
asset_content_type: application/gzip
|
193
|
+
|
194
|
+
- name: Publish mac package
|
195
|
+
uses: actions/upload-release-asset@v1
|
111
196
|
env:
|
112
|
-
GITHUB_TOKEN: ${{secrets.
|
197
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
198
|
+
with:
|
199
|
+
upload_url: ${{ needs.vars.outputs.upload_url }}
|
200
|
+
asset_path: ./licensed-${{needs.vars.outputs.version}}-darwin-x64.tar.gz
|
201
|
+
asset_name: licensed-${{needs.vars.outputs.version}}-darwin-x64.tar.gz
|
202
|
+
asset_content_type: application/gzip
|
113
203
|
|
114
204
|
- name: Publish gem to RubyGems
|
115
205
|
run: |
|
116
206
|
mkdir -p $HOME/.gem
|
117
207
|
touch $HOME/.gem/credentials
|
118
208
|
chmod 0600 $HOME/.gem/credentials
|
119
|
-
printf -- "---\n:rubygems_api_key: ${
|
209
|
+
printf -- "---\n:rubygems_api_key: ${RUBYGEMS_API_KEY}\n" > $HOME/.gem/credentials
|
120
210
|
gem push $GEM
|
121
211
|
env:
|
122
|
-
|
123
|
-
GEM: licensed-${{
|
212
|
+
RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
|
213
|
+
GEM: licensed-${{needs.vars.outputs.version}}.gem
|
data/.github/workflows/test.yml
CHANGED
@@ -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,41 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## 2.14.4
|
10
|
+
2021-02-09
|
11
|
+
|
12
|
+
## Added
|
13
|
+
- `list` and `cache` commands optionally print output in JSON or YML formats using the `--format/-f` flag (https://github.com/github/licensed/pull/334)
|
14
|
+
- `list` command will include detected license keys using the `--licenses/-l` flag (https://github.com/github/licensed/pull/334)
|
15
|
+
|
16
|
+
## 2.14.3
|
17
|
+
2020-12-11
|
18
|
+
|
19
|
+
## Fixed
|
20
|
+
- Auto-generating license text for a known license will no longer raise an error if the found license has no text (:tada: @Eun https://github.com/github/licensed/pull/328)
|
21
|
+
|
22
|
+
## 2.14.2
|
23
|
+
2020-11-20
|
24
|
+
|
25
|
+
## Fixed
|
26
|
+
- Yarn source correctly finds dependency paths on disk (https://github.com/github/licensed/pull/326)
|
27
|
+
- Go source better handles finding dependencies that have been vendored (https://github.com/github/licensed/pull/323)
|
28
|
+
|
29
|
+
## 2.14.1
|
30
|
+
2020-10-09
|
31
|
+
|
32
|
+
### Fixed
|
33
|
+
- Shell command output is encoded to UTF8 (https://github.com/github/licensed/pull/319)
|
34
|
+
|
35
|
+
## 2.14.0
|
36
|
+
2020-10-04
|
37
|
+
|
38
|
+
### Added
|
39
|
+
- `reviewed` dependencies can use glob pattern matching (https://github.com/github/licensed/pull/313)
|
40
|
+
|
41
|
+
### Fixed
|
42
|
+
- Fix configuring source path globs that expand into a single directory (https://github.com/github/licensed/pull/312)
|
43
|
+
|
9
44
|
## 2.13.0
|
10
45
|
2020-09-23
|
11
46
|
|
@@ -351,4 +386,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
351
386
|
|
352
387
|
Initial release :tada:
|
353
388
|
|
354
|
-
[Unreleased]: https://github.com/github/licensed/compare/2.
|
389
|
+
[Unreleased]: https://github.com/github/licensed/compare/2.14.4...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
@@ -12,9 +12,11 @@ module Licensed
|
|
12
12
|
desc: "Path to licensed configuration file"
|
13
13
|
method_option :sources, aliases: "-s", type: :array,
|
14
14
|
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
15
|
+
method_option :format, aliases: "-f", enum: ["yaml", "json"],
|
16
|
+
desc: "Output format"
|
15
17
|
def cache
|
16
18
|
run Licensed::Commands::Cache.new(config: config),
|
17
|
-
force: options[:force], sources: options[:sources]
|
19
|
+
force: options[:force], sources: options[:sources], reporter: options[:format]
|
18
20
|
end
|
19
21
|
|
20
22
|
desc "status", "Check status of dependencies' cached licenses"
|
@@ -33,8 +35,12 @@ module Licensed
|
|
33
35
|
desc: "Path to licensed configuration file"
|
34
36
|
method_option :sources, aliases: "-s", type: :array,
|
35
37
|
desc: "Individual source(s) to evaluate. Must also be enabled via configuration."
|
38
|
+
method_option :format, aliases: "-f", enum: ["yaml", "json"],
|
39
|
+
desc: "Output format"
|
40
|
+
method_option :licenses, aliases: "-l", type: :boolean,
|
41
|
+
desc: "Include detected licenses in output"
|
36
42
|
def list
|
37
|
-
run Licensed::Commands::List.new(config: config), sources: options[:sources]
|
43
|
+
run Licensed::Commands::List.new(config: config), sources: options[:sources], reporter: options[:format], licenses: options[:licenses]
|
38
44
|
end
|
39
45
|
|
40
46
|
desc "notices", "Generate a NOTICE file from cached records"
|
@@ -72,6 +72,12 @@ module Licensed
|
|
72
72
|
# Returns whether the command succeeded for the application.
|
73
73
|
def run_app(app)
|
74
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
|
+
|
75
81
|
Dir.chdir app.source_path do
|
76
82
|
begin
|
77
83
|
# allow additional report data to be given by commands
|
@@ -41,6 +41,13 @@ module Licensed
|
|
41
41
|
#
|
42
42
|
# Returns true.
|
43
43
|
def evaluate_dependency(app, source, dependency, report)
|
44
|
+
report["dependency"] = dependency.name
|
45
|
+
report["version"] = dependency.version
|
46
|
+
|
47
|
+
if options[:licenses]
|
48
|
+
report["license"] = dependency.license_key
|
49
|
+
end
|
50
|
+
|
44
51
|
true
|
45
52
|
end
|
46
53
|
end
|
@@ -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.
|
data/lib/licensed/dependency.rb
CHANGED
@@ -142,6 +142,7 @@ module Licensed
|
|
142
142
|
def generated_license_contents
|
143
143
|
return unless license
|
144
144
|
return if license.key == "other"
|
145
|
+
return if license.text.nil?
|
145
146
|
|
146
147
|
# strip copyright clauses and any extra newlines
|
147
148
|
# many package managers don't provide enough information to
|
@@ -75,7 +75,9 @@ module Licensed
|
|
75
75
|
def report_dependency(dependency)
|
76
76
|
super do |report|
|
77
77
|
result = yield report
|
78
|
-
|
78
|
+
info = "#{dependency.name} (#{dependency.version})"
|
79
|
+
info = "#{info}: #{report["license"]}" if report["license"]
|
80
|
+
shell.info " #{info}"
|
79
81
|
|
80
82
|
result
|
81
83
|
end
|
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
|
data/lib/licensed/sources/go.rb
CHANGED
@@ -15,8 +15,7 @@ module Licensed
|
|
15
15
|
def enumerate_dependencies
|
16
16
|
with_configured_gopath do
|
17
17
|
packages.map do |package|
|
18
|
-
import_path =
|
19
|
-
import_path ||= package["ImportPath"]
|
18
|
+
import_path = non_vendored_import_path(package)
|
20
19
|
error = package.dig("Error", "Err") if package["Error"]
|
21
20
|
|
22
21
|
Dependency.new(
|
@@ -81,34 +80,26 @@ module Licensed
|
|
81
80
|
# return true if package self-identifies
|
82
81
|
return true if package["Standard"]
|
83
82
|
|
84
|
-
import_path = package
|
83
|
+
import_path = non_vendored_import_path(package)
|
85
84
|
return false unless import_path
|
86
85
|
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
# return true if any of the go standard packages matches against
|
98
|
-
# the non-vendored import path
|
99
|
-
return true if go_std_packages.include?(non_vendored_import_path)
|
100
|
-
return true if go_std_packages.include?(non_vendored_import_path.sub("golang.org", "internal"))
|
101
|
-
|
102
|
-
# modify the import path to look like the import path `go list` returns for vendored std packages
|
103
|
-
vendor_path = import_path.sub("#{root_package["ImportPath"]}/", "")
|
104
|
-
go_std_packages.include?(vendor_path) || go_std_packages.include?(vendor_path.sub("golang.org", "golang_org"))
|
86
|
+
# check different variations of the import path to match against
|
87
|
+
# what's returned from `go list std`
|
88
|
+
[
|
89
|
+
import_path,
|
90
|
+
import_path.sub("golang.org", "internal"),
|
91
|
+
import_path.sub("golang.org", "golang_org"),
|
92
|
+
].any? do |path|
|
93
|
+
# true if go standard packages includes the path or "vendor/<path>"
|
94
|
+
go_std_packages.include?(path) || go_std_packages.include?("vendor/#{path}")
|
95
|
+
end
|
105
96
|
end
|
106
97
|
|
107
98
|
# Returns whether the package is local to the current project
|
108
99
|
def local_package?(package)
|
109
|
-
return false unless package && package["
|
110
|
-
|
111
|
-
|
100
|
+
return false unless package && package["Dir"]
|
101
|
+
return false unless File.fnmatch?("#{config.root.to_s}*", package["Dir"])
|
102
|
+
vendored_path_parts(package).nil?
|
112
103
|
end
|
113
104
|
|
114
105
|
# Returns the version for a given package
|
@@ -155,36 +146,45 @@ module Licensed
|
|
155
146
|
|
156
147
|
# search root choices:
|
157
148
|
# 1. module directory if using go modules and directory is available
|
158
|
-
# 2. vendor folder if package is vendored
|
159
|
-
# 3. package root value if available
|
160
|
-
# 4. GOPATH if the package directory is under the gopath
|
161
|
-
# 5. nil
|
162
149
|
module_dir = package.dig("Module", "Dir")
|
163
150
|
return module_dir if module_dir
|
164
|
-
|
151
|
+
|
152
|
+
# 2. vendor folder if package is vendored
|
153
|
+
parts = vendored_path_parts(package)
|
154
|
+
return parts[:vendor_path] if parts
|
155
|
+
|
156
|
+
# 3. package root value if available
|
165
157
|
return package["Root"] if package["Root"]
|
158
|
+
|
159
|
+
# 4. GOPATH if the package directory is under the gopath
|
166
160
|
return gopath if package["Dir"]&.start_with?(gopath)
|
161
|
+
|
162
|
+
# 5. nil
|
167
163
|
nil
|
168
164
|
end
|
169
165
|
|
170
|
-
#
|
171
|
-
#
|
166
|
+
# If the package is vendored, returns a Match object containing named
|
167
|
+
# :vendor_path and :import_path match groups based on the packages "Dir" value
|
168
|
+
#
|
169
|
+
# If the package is not vendored, returns nil
|
172
170
|
#
|
173
|
-
#
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
path.start_with?(base.to_s) && path.include?("vendor/")
|
171
|
+
# package - Package to get vendored path information for
|
172
|
+
def vendored_path_parts(package)
|
173
|
+
return if package.nil? || package["Dir"].nil?
|
174
|
+
package["Dir"].match(/^(?<vendor_path>#{config.root}(\/.+)*\/[^\/]*vendor[^\/]*)\/(?<import_path>.+)$/i)
|
178
175
|
end
|
179
176
|
|
180
|
-
# Returns the
|
177
|
+
# Returns the non-vendored portion of the package import path if vendored,
|
178
|
+
# otherwise returns the package's import path as given
|
181
179
|
#
|
182
|
-
#
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
return
|
187
|
-
|
180
|
+
# package - Package to get the non-vendored import path for
|
181
|
+
def non_vendored_import_path(package)
|
182
|
+
return if package.nil?
|
183
|
+
parts = vendored_path_parts(package)
|
184
|
+
return parts[:import_path] if parts
|
185
|
+
|
186
|
+
# if a package isn't vendored, return the packages "ImportPath"
|
187
|
+
package["ImportPath"]
|
188
188
|
end
|
189
189
|
|
190
190
|
# Returns a hash of information about the package with a given import path
|
@@ -36,7 +36,7 @@ module Licensed
|
|
36
36
|
def packages
|
37
37
|
return [] if yarn_package_tree.nil?
|
38
38
|
all_dependencies = {}
|
39
|
-
recursive_dependencies(
|
39
|
+
recursive_dependencies(yarn_package_tree).each do |name, results|
|
40
40
|
results.uniq! { |package| package["version"] }
|
41
41
|
if results.size == 1
|
42
42
|
# if there is only one package for a name, reference it by name
|
@@ -55,26 +55,34 @@ module Licensed
|
|
55
55
|
|
56
56
|
# Recursively parse dependency JSON data. Returns a hash mapping the
|
57
57
|
# package name to it's metadata
|
58
|
-
def recursive_dependencies(
|
58
|
+
def recursive_dependencies(dependencies, result = {})
|
59
59
|
dependencies.each do |dependency|
|
60
60
|
# "shadow" indicate a dependency requirement only, not a
|
61
61
|
# resolved package identifier
|
62
62
|
next if dependency["shadow"]
|
63
63
|
name, _, version = dependency["name"].rpartition("@")
|
64
64
|
|
65
|
-
# the dependency should be found under the parent's "node_modules" path
|
66
|
-
dependency_path = path.join("node_modules", name)
|
67
65
|
(result[name] ||= []) << {
|
68
66
|
"id" => dependency["name"],
|
69
67
|
"name" => name,
|
70
68
|
"version" => version,
|
71
|
-
"path" =>
|
69
|
+
"path" => dependency_paths[dependency["name"]]
|
72
70
|
}
|
73
|
-
recursive_dependencies(
|
71
|
+
recursive_dependencies(dependency["children"], result)
|
74
72
|
end
|
75
73
|
result
|
76
74
|
end
|
77
75
|
|
76
|
+
# Returns a hash that maps all dependency names to their location on disk
|
77
|
+
# by parsing every package.json file under node_modules.
|
78
|
+
def dependency_paths
|
79
|
+
@dependency_paths ||= Dir.glob(config.pwd.join("node_modules/**/package.json")).each_with_object({}) do |file, hsh|
|
80
|
+
dirname = File.dirname(file)
|
81
|
+
json = JSON.parse(File.read(file))
|
82
|
+
hsh["#{json["name"]}@#{json["version"]}"] = dirname
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
78
86
|
# Finds and returns the yarn package tree listing from `yarn list` output
|
79
87
|
def yarn_package_tree
|
80
88
|
return @yarn_package_tree if defined?(@yarn_package_tree)
|
data/lib/licensed/version.rb
CHANGED
data/script/packages/linux
CHANGED
@@ -34,6 +34,9 @@ build_linux_local() {
|
|
34
34
|
sudo apt-get update
|
35
35
|
sudo apt-get install -y --no-install-recommends cmake make gcc pkg-config squashfs-tools curl bison git rsync
|
36
36
|
|
37
|
+
sudo gem update --system
|
38
|
+
sudo gem update bundler
|
39
|
+
|
37
40
|
RUBYC="$BASE_DIR/bin/rubyc-linux"
|
38
41
|
if [ ! -f "$RUBYC" ]; then
|
39
42
|
mkdir -p "$(dirname "$RUBYC")"
|
@@ -42,6 +45,7 @@ build_linux_local() {
|
|
42
45
|
fi
|
43
46
|
|
44
47
|
export CPPFLAGS="-P"
|
48
|
+
export SSL_CERT_DIR="/etc/ssl/certs"
|
45
49
|
export RUBYC
|
46
50
|
"$BASE_DIR"/script/packages/build
|
47
51
|
}
|
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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: licensee
|