licensed 2.13.0 → 2.14.4
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 +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
|