licensed 2.14.4 → 3.0.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 +9 -9
- data/.github/workflows/test.yml +42 -42
- data/.gitignore +1 -0
- data/CHANGELOG.md +47 -4
- data/README.md +14 -3
- data/docs/{migrating_to_newer_versions.md → migrations/v2.md} +1 -1
- data/docs/migrations/v3.md +109 -0
- data/docs/sources/bundler.md +1 -11
- data/docs/sources/npm.md +1 -1
- data/lib/licensed/cli.rb +4 -1
- data/lib/licensed/sources/bundler.rb +22 -208
- data/lib/licensed/sources/bundler/missing_specification.rb +54 -0
- data/lib/licensed/sources/cabal.rb +17 -6
- data/lib/licensed/sources/manifest.rb +1 -1
- data/lib/licensed/sources/npm.rb +57 -7
- data/lib/licensed/sources/pip.rb +1 -1
- data/lib/licensed/version.rb +1 -1
- data/script/packages/build +4 -1
- data/script/packages/mac +3 -0
- data/script/source-setup/npm +18 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8e24e2f900732197c5d4b91212a7477dd7ab68a61892e0ea56ae1a99f4c29e6
|
4
|
+
data.tar.gz: 19c679898ccab8f60d219d739c18a14b849cdd87ad04608b24dcf1ea67613f82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 171905b06dca655364341c888c5e8845e6dff8d163ffb009f28de624e4d14d399c7add250d80ebb7391b4c94316c8a3c9bbae7bdfb7b219996a8415f463b7a5c
|
7
|
+
data.tar.gz: 054fc3dd7ccb7e3a92b6585e757b85efd0880b1b9c3fa93855ba50ba79d0c7727d707a76d30f588a94b9f7bb1dd0d6bc6f3959e40bf96685f5dda5ea1a7d127f
|
@@ -83,7 +83,7 @@ jobs:
|
|
83
83
|
|
84
84
|
package_linux:
|
85
85
|
needs: vars
|
86
|
-
runs-on: ubuntu-
|
86
|
+
runs-on: ubuntu-18.04
|
87
87
|
steps:
|
88
88
|
- uses: actions/checkout@v2
|
89
89
|
with:
|
@@ -93,9 +93,9 @@ jobs:
|
|
93
93
|
fetch-depth: 0
|
94
94
|
|
95
95
|
- name: Set up Ruby 2.6
|
96
|
-
uses:
|
96
|
+
uses: ruby/setup-ruby@v1
|
97
97
|
with:
|
98
|
-
ruby-version: 2.6
|
98
|
+
ruby-version: 2.6
|
99
99
|
|
100
100
|
- name: Build package
|
101
101
|
run: script/packages/linux
|
@@ -119,9 +119,9 @@ jobs:
|
|
119
119
|
fetch-depth: 0
|
120
120
|
|
121
121
|
- name: Set up Ruby 2.6
|
122
|
-
uses:
|
122
|
+
uses: ruby/setup-ruby@v1
|
123
123
|
with:
|
124
|
-
ruby-version: 2.6
|
124
|
+
ruby-version: 2.6
|
125
125
|
|
126
126
|
- name: Build package
|
127
127
|
run: script/packages/mac
|
@@ -143,9 +143,9 @@ jobs:
|
|
143
143
|
ref: ${{needs.vars.outputs.version}}
|
144
144
|
|
145
145
|
- name: Set up Ruby 2.6
|
146
|
-
uses:
|
146
|
+
uses: ruby/setup-ruby@v1
|
147
147
|
with:
|
148
|
-
ruby-version: 2.6
|
148
|
+
ruby-version: 2.6
|
149
149
|
|
150
150
|
- name: Build gem
|
151
151
|
run: gem build licensed.gemspec -o licensed-${{needs.vars.outputs.version}}.gem
|
@@ -162,9 +162,9 @@ jobs:
|
|
162
162
|
|
163
163
|
steps:
|
164
164
|
- name: Set up Ruby 2.6
|
165
|
-
uses:
|
165
|
+
uses: ruby/setup-ruby@v1
|
166
166
|
with:
|
167
|
-
ruby-version: 2.6
|
167
|
+
ruby-version: 2.6
|
168
168
|
|
169
169
|
- name: Download linux package
|
170
170
|
uses: actions/download-artifact@v2
|
data/.github/workflows/test.yml
CHANGED
@@ -8,15 +8,15 @@ jobs:
|
|
8
8
|
steps:
|
9
9
|
- uses: actions/checkout@v2
|
10
10
|
- name: Setup node
|
11
|
-
uses: actions/setup-node@
|
11
|
+
uses: actions/setup-node@v2
|
12
12
|
with:
|
13
13
|
node-version: 8
|
14
14
|
- name: Install Bower
|
15
15
|
run: npm install -g bower
|
16
16
|
- name: Set up Ruby
|
17
|
-
uses:
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
18
|
with:
|
19
|
-
ruby-version: 2.6
|
19
|
+
ruby-version: 2.6
|
20
20
|
- run: bundle lock
|
21
21
|
- uses: actions/cache@v1
|
22
22
|
with:
|
@@ -37,9 +37,9 @@ jobs:
|
|
37
37
|
steps:
|
38
38
|
- uses: actions/checkout@v2
|
39
39
|
- name: Set up Ruby
|
40
|
-
uses:
|
40
|
+
uses: ruby/setup-ruby@v1
|
41
41
|
with:
|
42
|
-
ruby-version: 2.6
|
42
|
+
ruby-version: 2.6
|
43
43
|
- name: Set up Bundler
|
44
44
|
run: |
|
45
45
|
yes | gem uninstall bundler --all
|
@@ -60,16 +60,16 @@ jobs:
|
|
60
60
|
runs-on: ubuntu-latest
|
61
61
|
strategy:
|
62
62
|
matrix:
|
63
|
-
ghc: [ '8.2
|
64
|
-
cabal: [ '2.
|
63
|
+
ghc: [ '8.2', '8.6', '8.8', '8.10' ]
|
64
|
+
cabal: [ '2.4', '3.0', '3.2' ]
|
65
65
|
steps:
|
66
66
|
- uses: actions/checkout@v2
|
67
67
|
- name: Set up Ruby
|
68
|
-
uses:
|
68
|
+
uses: ruby/setup-ruby@v1
|
69
69
|
with:
|
70
|
-
ruby-version: 2.6
|
70
|
+
ruby-version: 2.6
|
71
71
|
- name: Setup Haskell
|
72
|
-
uses: actions/setup
|
72
|
+
uses: haskell/actions/setup@v1
|
73
73
|
with:
|
74
74
|
ghc-version: ${{ matrix.ghc }}
|
75
75
|
cabal-version: ${{ matrix.cabal }}
|
@@ -89,17 +89,17 @@ jobs:
|
|
89
89
|
runs-on: ubuntu-latest
|
90
90
|
strategy:
|
91
91
|
matrix:
|
92
|
-
php: [ '
|
92
|
+
php: [ '7.3', '7.4' ]
|
93
93
|
steps:
|
94
94
|
- uses: actions/checkout@v2
|
95
95
|
- name: Setup php
|
96
|
-
uses: nanasess/setup-php@v3.0.
|
96
|
+
uses: nanasess/setup-php@v3.0.6
|
97
97
|
with:
|
98
98
|
php-version: ${{ matrix.php }}
|
99
99
|
- name: Set up Ruby
|
100
|
-
uses:
|
100
|
+
uses: ruby/setup-ruby@v1
|
101
101
|
with:
|
102
|
-
ruby-version: 2.6
|
102
|
+
ruby-version: 2.6
|
103
103
|
- run: bundle lock
|
104
104
|
- uses: actions/cache@v1
|
105
105
|
with:
|
@@ -116,11 +116,11 @@ jobs:
|
|
116
116
|
runs-on: ubuntu-latest
|
117
117
|
strategy:
|
118
118
|
matrix:
|
119
|
-
ruby: [ 2.
|
119
|
+
ruby: [ 2.5, 2.6, 2.7 ]
|
120
120
|
steps:
|
121
121
|
- uses: actions/checkout@v2
|
122
122
|
- name: Set up Ruby
|
123
|
-
uses:
|
123
|
+
uses: ruby/setup-ruby@v1
|
124
124
|
with:
|
125
125
|
ruby-version: ${{matrix.ruby}}
|
126
126
|
- name: Set up Bundler
|
@@ -146,9 +146,9 @@ jobs:
|
|
146
146
|
with:
|
147
147
|
go-version: 1.10.x
|
148
148
|
- name: Set up Ruby
|
149
|
-
uses:
|
149
|
+
uses: ruby/setup-ruby@v1
|
150
150
|
with:
|
151
|
-
ruby-version: 2.6
|
151
|
+
ruby-version: 2.6
|
152
152
|
- run: bundle lock
|
153
153
|
- uses: actions/cache@v1
|
154
154
|
with:
|
@@ -173,9 +173,9 @@ jobs:
|
|
173
173
|
with:
|
174
174
|
go-version: ${{ matrix.go }}
|
175
175
|
- name: Set up Ruby
|
176
|
-
uses:
|
176
|
+
uses: ruby/setup-ruby@v1
|
177
177
|
with:
|
178
|
-
ruby-version: 2.6
|
178
|
+
ruby-version: 2.6
|
179
179
|
- run: bundle lock
|
180
180
|
- uses: actions/cache@v1
|
181
181
|
with:
|
@@ -193,9 +193,9 @@ jobs:
|
|
193
193
|
steps:
|
194
194
|
- uses: actions/checkout@v2
|
195
195
|
- name: Set up Ruby
|
196
|
-
uses:
|
196
|
+
uses: ruby/setup-ruby@v1
|
197
197
|
with:
|
198
|
-
ruby-version: 2.6
|
198
|
+
ruby-version: 2.6
|
199
199
|
- run: bundle lock
|
200
200
|
- uses: actions/cache@v1
|
201
201
|
with:
|
@@ -213,9 +213,9 @@ jobs:
|
|
213
213
|
steps:
|
214
214
|
- uses: actions/checkout@v2
|
215
215
|
- name: Set up Ruby
|
216
|
-
uses:
|
216
|
+
uses: ruby/setup-ruby@v1
|
217
217
|
with:
|
218
|
-
ruby-version: 2.6
|
218
|
+
ruby-version: 2.6
|
219
219
|
- run: bundle lock
|
220
220
|
- uses: actions/cache@v1
|
221
221
|
with:
|
@@ -230,18 +230,18 @@ jobs:
|
|
230
230
|
runs-on: ubuntu-latest
|
231
231
|
strategy:
|
232
232
|
matrix:
|
233
|
-
otp: [21.x, 22.x]
|
234
|
-
elixir: [1.
|
233
|
+
otp: [21.x, 22.x, 23.x]
|
234
|
+
elixir: [ 1.10.x, 1.11.x ]
|
235
235
|
steps:
|
236
236
|
- uses: actions/checkout@v2
|
237
|
-
- uses:
|
237
|
+
- uses: erlef/setup-elixir@v1.6.0
|
238
238
|
with:
|
239
239
|
otp-version: ${{matrix.otp}}
|
240
240
|
elixir-version: ${{matrix.elixir}}
|
241
241
|
- name: Set up Ruby
|
242
|
-
uses:
|
242
|
+
uses: ruby/setup-ruby@v1
|
243
243
|
with:
|
244
|
-
ruby-version: 2.6
|
244
|
+
ruby-version: 2.6
|
245
245
|
- run: bundle lock
|
246
246
|
- uses: actions/cache@v1
|
247
247
|
with:
|
@@ -258,17 +258,17 @@ jobs:
|
|
258
258
|
runs-on: ubuntu-latest
|
259
259
|
strategy:
|
260
260
|
matrix:
|
261
|
-
node_version: [
|
261
|
+
node_version: [ 10, 12, 14, 15 ]
|
262
262
|
steps:
|
263
263
|
- uses: actions/checkout@v2
|
264
264
|
- name: Setup node
|
265
|
-
uses: actions/setup-node@
|
265
|
+
uses: actions/setup-node@v2
|
266
266
|
with:
|
267
267
|
node-version: ${{ matrix.node_version }}
|
268
268
|
- name: Set up Ruby
|
269
|
-
uses:
|
269
|
+
uses: ruby/setup-ruby@v1
|
270
270
|
with:
|
271
|
-
ruby-version: 2.6
|
271
|
+
ruby-version: 2.6
|
272
272
|
- run: bundle lock
|
273
273
|
- uses: actions/cache@v1
|
274
274
|
with:
|
@@ -290,9 +290,9 @@ jobs:
|
|
290
290
|
with:
|
291
291
|
dotnet-version: 3.1.202
|
292
292
|
- name: Set up Ruby
|
293
|
-
uses:
|
293
|
+
uses: ruby/setup-ruby@v1
|
294
294
|
with:
|
295
|
-
ruby-version: 2.6
|
295
|
+
ruby-version: 2.6
|
296
296
|
- run: bundle lock
|
297
297
|
- uses: actions/cache@v1
|
298
298
|
with:
|
@@ -318,9 +318,9 @@ jobs:
|
|
318
318
|
python-version: ${{ matrix.python }}
|
319
319
|
architecture: x64
|
320
320
|
- name: Set up Ruby
|
321
|
-
uses:
|
321
|
+
uses: ruby/setup-ruby@v1
|
322
322
|
with:
|
323
|
-
ruby-version: 2.6
|
323
|
+
ruby-version: 2.6
|
324
324
|
- run: bundle lock
|
325
325
|
- uses: actions/cache@v1
|
326
326
|
with:
|
@@ -345,9 +345,9 @@ jobs:
|
|
345
345
|
python-version: '3.x'
|
346
346
|
architecture: x64
|
347
347
|
- name: Set up Ruby
|
348
|
-
uses:
|
348
|
+
uses: ruby/setup-ruby@v1
|
349
349
|
with:
|
350
|
-
ruby-version: 2.6
|
350
|
+
ruby-version: 2.6
|
351
351
|
- run: bundle lock
|
352
352
|
- uses: actions/cache@v1
|
353
353
|
with:
|
@@ -371,7 +371,7 @@ jobs:
|
|
371
371
|
steps:
|
372
372
|
- uses: actions/checkout@v2
|
373
373
|
- name: Setup node
|
374
|
-
uses: actions/setup-node@
|
374
|
+
uses: actions/setup-node@v2
|
375
375
|
with:
|
376
376
|
node-version: 12
|
377
377
|
- name: Install Yarn
|
@@ -379,9 +379,9 @@ jobs:
|
|
379
379
|
env:
|
380
380
|
YARN_VERSION: ${{ matrix.yarn_version }}
|
381
381
|
- name: Set up Ruby
|
382
|
-
uses:
|
382
|
+
uses: ruby/setup-ruby@v1
|
383
383
|
with:
|
384
|
-
ruby-version: 2.6
|
384
|
+
ruby-version: 2.6
|
385
385
|
- run: bundle lock
|
386
386
|
- uses: actions/cache@v1
|
387
387
|
with:
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -6,23 +6,66 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## 3.0.1
|
10
|
+
|
11
|
+
2021-05-17
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
|
15
|
+
- The bundler source will correctly enumerate dependencies pulled with a `git:` directive (https://github.com/github/licensed/pull/360)
|
16
|
+
|
17
|
+
## 3.0.0
|
18
|
+
|
19
|
+
2021-04-27
|
20
|
+
|
21
|
+
**This is a major release and includes potentially breaking changes to bundler dependency enumeration.**
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
|
25
|
+
- The bundler source will return an error when run from an executable. Please install licensed as a gem to continue using the bundler source. Please see the [v3 migration document](./docs/migrations/v3.md) for full details and migration strategies.
|
26
|
+
|
27
|
+
## 2.15.2
|
28
|
+
|
29
|
+
2021-04-06
|
30
|
+
|
31
|
+
### Fixed
|
32
|
+
|
33
|
+
- The pip source works with package names containing periods (:tada: @bcskda https://github.com/github/licensed/pull/350)
|
34
|
+
|
35
|
+
## 2.15.1
|
36
|
+
|
37
|
+
2021-03-29
|
38
|
+
|
39
|
+
### Changed
|
40
|
+
|
41
|
+
- The npm source will ignore dependencies that are marked as both extraneous and missing (https://github.com/github/licensed/pull/347)
|
42
|
+
|
43
|
+
## 2.15.0
|
44
|
+
2021-03-24
|
45
|
+
|
46
|
+
### Added
|
47
|
+
- Support for npm 7 (https://github.com/github/licensed/pull/341)
|
48
|
+
|
49
|
+
### Fixed
|
50
|
+
- Files in the manifest source will be found correctly for apps that are not at the repository root (https://github.com/github/licensed/pull/345)
|
51
|
+
|
9
52
|
## 2.14.4
|
10
53
|
2021-02-09
|
11
54
|
|
12
|
-
|
55
|
+
### Added
|
13
56
|
- `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
57
|
- `list` command will include detected license keys using the `--licenses/-l` flag (https://github.com/github/licensed/pull/334)
|
15
58
|
|
16
59
|
## 2.14.3
|
17
60
|
2020-12-11
|
18
61
|
|
19
|
-
|
62
|
+
### Fixed
|
20
63
|
- 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
64
|
|
22
65
|
## 2.14.2
|
23
66
|
2020-11-20
|
24
67
|
|
25
|
-
|
68
|
+
### Fixed
|
26
69
|
- Yarn source correctly finds dependency paths on disk (https://github.com/github/licensed/pull/326)
|
27
70
|
- Go source better handles finding dependencies that have been vendored (https://github.com/github/licensed/pull/323)
|
28
71
|
|
@@ -386,4 +429,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
386
429
|
|
387
430
|
Initial release :tada:
|
388
431
|
|
389
|
-
[Unreleased]: https://github.com/github/licensed/compare/
|
432
|
+
[Unreleased]: https://github.com/github/licensed/compare/3.0.1...HEAD
|
data/README.md
CHANGED
@@ -12,12 +12,24 @@ Licensed is **not** a complete open source license compliance solution. Please u
|
|
12
12
|
|
13
13
|
Licensed is in active development and currently used at GitHub. See the [open issues](https://github.com/github/licensed/issues) for a list of potential work.
|
14
14
|
|
15
|
+
## Licensed v3
|
16
|
+
|
17
|
+
Licensed v3 includes a breaking change if both of the following are true:
|
18
|
+
|
19
|
+
1. a project uses bundler to manage ruby dependencies
|
20
|
+
2. a project uses the self-contained executable build of licensed
|
21
|
+
|
22
|
+
All other usages of licensed should not encounter any major changes migrating from the latest 2.x build to 3.0.
|
23
|
+
|
24
|
+
See [CHANGELOG.md](./CHANGELOG.md) for more details on what's changed.
|
25
|
+
See the [v3 migration documentation](./docs/migrations/v3.md) for more info on migrating to v3.
|
26
|
+
|
15
27
|
## Licensed v2
|
16
28
|
|
17
29
|
Licensed v2 includes many internal changes intended to make licensed more extensible and easier to update in the future. While not too much has changed externally, v2 is incompatible with configuration files and cached records from previous versions. Fortunately, migrating is easy using the `licensed migrate` command.
|
18
30
|
|
19
31
|
See [CHANGELOG.md](./CHANGELOG.md) for more details on what's changed.
|
20
|
-
See the [migration documentation](./docs/
|
32
|
+
See the [v2 migration documentation](./docs/migrations/v2.md) for more info on migrating to v2, or run `licensed help migrate`.
|
21
33
|
|
22
34
|
## Installation
|
23
35
|
|
@@ -82,7 +94,6 @@ The [bundler-licensed plugin](https://github.com/sergey-alekseev/bundler-license
|
|
82
94
|
The [licensed-ci](https://github.com/marketplace/actions/licensed-ci) GitHub Action runs `licensed` as part of an opinionated CI workflow and can be configured to run on any GitHub Action event. See the linked actions for usage and details.
|
83
95
|
|
84
96
|
The [setup-licensed](https://github.com/marketplace/actions/setup-github-licensed) GitHub Action installs `licensed` to the workflow environment. See the linked actions for usage and details.
|
85
|
-
- This action is intended for projects that don't have a ruby installation setup. If your workflow has ruby setup please install `licensed` via `Gemfile` + `bundle install` or with `gem install`.
|
86
97
|
|
87
98
|
### Configuration
|
88
99
|
|
@@ -110,7 +121,7 @@ Dependencies will be automatically detected for all of the following sources by
|
|
110
121
|
1. [Gradle](./docs/sources/gradle.md)
|
111
122
|
1. [Manifest lists (manifests)](./docs/sources/manifests.md)
|
112
123
|
1. [Mix](./docs/sources/mix.md)
|
113
|
-
1. [
|
124
|
+
1. [npm](./docs/sources/npm.md)
|
114
125
|
1. [NuGet](./docs/sources/nuget.md)
|
115
126
|
1. [Pip](./docs/sources/pip.md)
|
116
127
|
1. [Pipenv](./docs/sources/pipenv.md)
|
@@ -1,3 +1,3 @@
|
|
1
|
-
# Migrating your licensed configuration and cached records to
|
1
|
+
# Migrating your licensed configuration and cached records to licensed v2
|
2
2
|
|
3
3
|
Licensed v2+ ships with an additional executable, `licensed-migrator`, that can be used to update your licensed files to the format expected by the currently installed version. To run, execute `licensed migrate --from v1 -c <path to licensed configuration file>`, replacing `v1` with the major version of licensed to migrate from.
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# Breaking changes to bundler dependency enumeration in v3
|
2
|
+
|
3
|
+
**NOTE** If you are migrating from a version earlier than v2, please first [migrate to v2](./v2.md) before continuing.
|
4
|
+
|
5
|
+
Licensed v3 includes a breaking change to bundler dependency enumeration when using the executable form of licensed. Bundler dependency enumeration will no longer work with the licensed executable as of 3.0.0.
|
6
|
+
|
7
|
+
**If your project does not use bundler, or if you already install the licensed gem, you are not affected by this breaking change.**
|
8
|
+
|
9
|
+
## Migrating bundler enumeration for v3
|
10
|
+
|
11
|
+
When using licensed v3 with bundler dependencies, licensed must be installed from its [gem](https://rubygems.org/gems/licensed). This can be accomplished with `gem install`, or by adding licensed to a bundler gem file.
|
12
|
+
|
13
|
+
### Usage in a GitHub Actions workflow
|
14
|
+
|
15
|
+
Using licensed to enumerate bundler dependencies in a GitHub Actions workflow will require ruby to be available in the actions VM environment. Ruby can be setup in an actions workflow using [ruby/setup-ruby](https://github.com/ruby/setup-ruby)(preferred) or [actions/setup-ruby](https://github.com/actions/setup-ruby)(deprecated).
|
16
|
+
|
17
|
+
If you are using licensed in a GitHub Actions workflow, [jonabc/setup-licensed](https://github.com/jonabc/setup-licensed) has been updated according to this breaking change. `setup-licensed` will install the licensed gem when ruby is available, or the licensed executable when ruby is not available. Alternatively, you can `gem install` licensed directly as an actions step.
|
18
|
+
|
19
|
+
This is an example workflow definition that runs [jonabc/licensed-ci](https://github.com/jonabc/licensed-ci)'s opinionated license compliance workflow in CI. It includes jobs that demonstrate installing licensed using
|
20
|
+
- `gem install`
|
21
|
+
- [jonabc/setup-licensed](https://github.com/jonabc/setup-licensed)
|
22
|
+
- installing when included in a bundler gem file
|
23
|
+
|
24
|
+
```yml
|
25
|
+
name: Cache and verify dependency license metadata
|
26
|
+
|
27
|
+
on:
|
28
|
+
# run when PRs are opened, reopened or updated
|
29
|
+
pull_request:
|
30
|
+
types:
|
31
|
+
- opened
|
32
|
+
- reopened
|
33
|
+
- synchronize
|
34
|
+
|
35
|
+
# run on demand
|
36
|
+
workflow_dispatch:
|
37
|
+
|
38
|
+
jobs:
|
39
|
+
# install licensed with setup-licensed
|
40
|
+
licensed-ci-setup-licensed:
|
41
|
+
runs-on: ubuntu-latest
|
42
|
+
|
43
|
+
steps:
|
44
|
+
# checkout the repo
|
45
|
+
- uses: actions/checkout@v1
|
46
|
+
|
47
|
+
# install ruby
|
48
|
+
- uses: ruby/setup-ruby@v1
|
49
|
+
with:
|
50
|
+
ruby-version: "3.0"
|
51
|
+
|
52
|
+
# install licensed gem using setup-licensed
|
53
|
+
- uses: jonabc/setup-licensed@v1
|
54
|
+
with:
|
55
|
+
version: '3.x'
|
56
|
+
|
57
|
+
# install dependencies in CI environment
|
58
|
+
- run: bundle install
|
59
|
+
|
60
|
+
# run licensed-ci to cache any metadata changes and verify compliance
|
61
|
+
- uses: jonabc/licensed-ci@v1
|
62
|
+
|
63
|
+
# OR
|
64
|
+
|
65
|
+
# install licensed using gem install
|
66
|
+
licensed-ci-gem:
|
67
|
+
runs-on: ubuntu-latest
|
68
|
+
|
69
|
+
steps:
|
70
|
+
# checkout the repo
|
71
|
+
- uses: actions/checkout@v1
|
72
|
+
|
73
|
+
# install ruby and bundler
|
74
|
+
- uses: ruby/setup-ruby@v1
|
75
|
+
with:
|
76
|
+
ruby-version: "3.0"
|
77
|
+
|
78
|
+
# install licensed gem using setup-licensed
|
79
|
+
- run: gem install licensed -v '~> 3.0'
|
80
|
+
|
81
|
+
# install dependencies in CI environment
|
82
|
+
- run: bundle install
|
83
|
+
|
84
|
+
# run licensed-ci to cache any metadata changes and verify compliance
|
85
|
+
- uses: jonabc/licensed-ci@v1
|
86
|
+
|
87
|
+
# OR
|
88
|
+
|
89
|
+
# install licensed as part of bundle installation
|
90
|
+
licensed-ci-bundle:
|
91
|
+
runs-on: ubuntu-latest
|
92
|
+
|
93
|
+
steps:
|
94
|
+
# checkout the repo
|
95
|
+
- uses: actions/checkout@v1
|
96
|
+
|
97
|
+
# install ruby and bundler
|
98
|
+
- uses: ruby/setup-ruby@v1
|
99
|
+
with:
|
100
|
+
ruby-version: "3.0"
|
101
|
+
|
102
|
+
# install licensed and other dependencies in CI environment
|
103
|
+
- run: bundle install
|
104
|
+
|
105
|
+
# run licensed-ci to cache any metadata changes and verify compliance
|
106
|
+
- uses: jonabc/licensed-ci@v1
|
107
|
+
with:
|
108
|
+
command: 'bundle exec licensed' # run licensed within the bundler context
|
109
|
+
```
|
data/docs/sources/bundler.md
CHANGED
@@ -2,17 +2,7 @@
|
|
2
2
|
|
3
3
|
The bundler source will detect dependencies `Gemfile` and `Gemfile.lock` files are found at an apps `source_path`. The source uses the `Bundler` API to enumerate dependencies from `Gemfile` and `Gemfile.lock`.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
**Note** this content only applies to running licensed from an executable. It does not apply when using licensed as a gem.
|
8
|
-
|
9
|
-
_It is required that the ruby runtime is available when running the licensed executable._
|
10
|
-
|
11
|
-
The licensed executable contains and runs a version of ruby. When using the Bundler APIs, a mismatch between the version of ruby built into the licensed executable and the version of licensed used during `bundle install` can occur. This mismatch can lead to licensed raising errors due to not finding dependencies.
|
12
|
-
|
13
|
-
For example, if `bundle install` was run with ruby 2.5.0 then the bundler specification path would be `<bundle path>/ruby/2.5.0/specifications`. However, if the licensed executable contains ruby 2.4.0, then licensed will be looking for specifications at `<bundle path>/ruby/2.4.0/specifications`. That path may not exist, or it may contain invalid or stale content.
|
14
|
-
|
15
|
-
To prevent confusion, licensed uses the local ruby runtime to determine the ruby version for local gems during `bundle install`. If bundler is also available, then the ruby command will be run from a `bundle exec` context.
|
5
|
+
**Note** The bundler source cannot be used when running the [packaged licensed executable](../packaging.md)
|
16
6
|
|
17
7
|
### Excluding gem groups
|
18
8
|
|
data/docs/sources/npm.md
CHANGED
data/lib/licensed/cli.rb
CHANGED
@@ -74,11 +74,14 @@ module Licensed
|
|
74
74
|
method_option :from, aliases: "-f", type: :string, required: true,
|
75
75
|
desc: "Licensed version to migrate from - #{Licensed.previous_major_versions.map { |major| "v#{major}" }.join(", ")}"
|
76
76
|
def migrate
|
77
|
+
shell = Thor::Base.shell.new
|
77
78
|
case options["from"]
|
78
79
|
when "v1"
|
79
80
|
Licensed::Migrations::V2.migrate(options["config"])
|
81
|
+
when "v2"
|
82
|
+
shell.say "No configuration or cached file migration needed."
|
83
|
+
shell.say "Please see the documentation at https://github.com/github/licensed/tree/master/docs/migrations/v3.md for details."
|
80
84
|
else
|
81
|
-
shell = Thor::Base.shell.new
|
82
85
|
shell.say "Unrecognized option from=#{options["from"]}", :red
|
83
86
|
CLI.command_help(shell, "migrate")
|
84
87
|
exit 1
|
@@ -2,50 +2,13 @@
|
|
2
2
|
require "delegate"
|
3
3
|
begin
|
4
4
|
require "bundler"
|
5
|
+
require "licensed/sources/bundler/missing_specification"
|
5
6
|
rescue LoadError
|
6
7
|
end
|
7
8
|
|
8
9
|
module Licensed
|
9
10
|
module Sources
|
10
11
|
class Bundler < Source
|
11
|
-
class MissingSpecification < Gem::BasicSpecification
|
12
|
-
attr_reader :name, :requirement
|
13
|
-
alias_method :version, :requirement
|
14
|
-
def initialize(name:, requirement:)
|
15
|
-
@name = name
|
16
|
-
@requirement = requirement
|
17
|
-
end
|
18
|
-
|
19
|
-
def dependencies
|
20
|
-
[]
|
21
|
-
end
|
22
|
-
|
23
|
-
def source
|
24
|
-
nil
|
25
|
-
end
|
26
|
-
|
27
|
-
def platform; end
|
28
|
-
def gem_dir; end
|
29
|
-
def gems_dir
|
30
|
-
Gem.dir
|
31
|
-
end
|
32
|
-
def summary; end
|
33
|
-
def homepage; end
|
34
|
-
|
35
|
-
def error
|
36
|
-
"could not find #{name} (#{requirement}) in any sources"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class BundlerSpecification < ::SimpleDelegator
|
41
|
-
def gem_dir
|
42
|
-
dir = super
|
43
|
-
return dir if File.exist?(dir)
|
44
|
-
|
45
|
-
File.join(Gem.dir, "gems", full_name)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
12
|
class Dependency < Licensed::Dependency
|
50
13
|
attr_reader :loaded_from
|
51
14
|
|
@@ -76,6 +39,7 @@ module Licensed
|
|
76
39
|
|
77
40
|
GEMFILES = { "Gemfile" => "Gemfile.lock", "gems.rb" => "gems.locked" }
|
78
41
|
DEFAULT_WITHOUT_GROUPS = %i{development test}
|
42
|
+
RUBY_PACKER_ERROR = "The bundler source cannot be used from the executable built with ruby-packer. Please install licensed using `gem install` or using bundler."
|
79
43
|
|
80
44
|
def enabled?
|
81
45
|
# running a ruby-packer-built licensed exe when ruby isn't available
|
@@ -85,13 +49,18 @@ module Licensed
|
|
85
49
|
end
|
86
50
|
|
87
51
|
def enumerate_dependencies
|
52
|
+
raise Licensed::Sources::Source::Error.new(RUBY_PACKER_ERROR) if ruby_packer?
|
53
|
+
|
88
54
|
with_local_configuration do
|
89
55
|
specs.map do |spec|
|
56
|
+
next if spec.name == "bundler" && !include_bundler?
|
57
|
+
next if spec.name == config["name"]
|
58
|
+
|
90
59
|
error = spec.error if spec.respond_to?(:error)
|
91
60
|
Dependency.new(
|
92
61
|
name: spec.name,
|
93
62
|
version: spec.version.to_s,
|
94
|
-
path: spec.
|
63
|
+
path: spec.full_gem_path,
|
95
64
|
loaded_from: spec.loaded_from,
|
96
65
|
errors: Array(error),
|
97
66
|
metadata: {
|
@@ -106,136 +75,18 @@ module Licensed
|
|
106
75
|
|
107
76
|
# Returns an array of Gem::Specifications for all gem dependencies
|
108
77
|
def specs
|
109
|
-
|
110
|
-
root_dependencies = definition.dependencies.select { |d| include?(d, nil) }
|
111
|
-
root_specs = specs_for_dependencies(root_dependencies, nil).compact
|
112
|
-
|
113
|
-
# recursively find the remaining specifications
|
114
|
-
all_specs = recursive_specs(root_specs)
|
115
|
-
|
116
|
-
# delete any specifications loaded from a gemspec
|
117
|
-
all_specs.delete_if { |s| s.source.is_a?(::Bundler::Source::Gemspec) }
|
118
|
-
end
|
119
|
-
|
120
|
-
# Recursively finds the dependencies for Gem specifications.
|
121
|
-
# Returns a `Set` containing the package names for all dependencies
|
122
|
-
def recursive_specs(specs, results = Set.new)
|
123
|
-
return [] if specs.nil? || specs.empty?
|
124
|
-
|
125
|
-
new_specs = Set.new(specs) - results.to_a
|
126
|
-
return [] if new_specs.empty?
|
127
|
-
|
128
|
-
results.merge new_specs
|
129
|
-
|
130
|
-
dependency_specs = new_specs.flat_map { |s| specs_for_dependencies(s.dependencies, s.source) }
|
131
|
-
|
132
|
-
return results if dependency_specs.empty?
|
133
|
-
|
134
|
-
results.merge recursive_specs(dependency_specs, results)
|
78
|
+
@specs ||= definition.specs_for(groups)
|
135
79
|
end
|
136
80
|
|
137
|
-
# Returns
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
# Returns a Gem::Specification for the provided gem argument.
|
147
|
-
def gem_spec(dependency)
|
148
|
-
return unless dependency
|
149
|
-
|
150
|
-
# find a specifiction from the resolved ::Bundler::Definition specs
|
151
|
-
spec = definition.resolve.find { |s| s.satisfies?(dependency) }
|
152
|
-
|
153
|
-
# a nil spec should be rare, generally only seen from bundler
|
154
|
-
return matching_spec(dependency) || bundle_exec_gem_spec(dependency.name, dependency.requirement) if spec.nil?
|
155
|
-
|
156
|
-
# try to find a non-lazy specification that matches `spec`
|
157
|
-
# spec.source.specs gives access to specifications with more
|
158
|
-
# information than spec itself, including platform-specific gems.
|
159
|
-
# these objects should have all the information needed to detect license metadata
|
160
|
-
source_spec = spec.source.specs.find { |s| s.name == spec.name && s.version == spec.version }
|
161
|
-
return source_spec if source_spec
|
162
|
-
|
163
|
-
# look for a specification at the bundler specs path
|
164
|
-
spec_path = ::Bundler.specs_path.join("#{spec.full_name}.gemspec")
|
165
|
-
return Gem::Specification.load(spec_path.to_s) if File.exist?(spec_path.to_s)
|
166
|
-
|
167
|
-
# if the specification file doesn't exist, get the specification using
|
168
|
-
# the bundler and gem CLI
|
169
|
-
bundle_exec_gem_spec(dependency.name, dependency.requirement)
|
170
|
-
end
|
171
|
-
|
172
|
-
# Returns whether a dependency should be included in the final
|
173
|
-
def include?(dependency, source)
|
174
|
-
# ::Bundler::Dependency has an extra `should_include?`
|
175
|
-
return false unless dependency.should_include? if dependency.respond_to?(:should_include?)
|
176
|
-
|
177
|
-
# Don't return gems added from `add_development_dependency` in a gemspec
|
178
|
-
# if the :development group is excluded
|
179
|
-
gemspec_source = source.is_a?(::Bundler::Source::Gemspec)
|
180
|
-
return false if dependency.type == :development && (!gemspec_source || exclude_development_dependencies?)
|
181
|
-
|
182
|
-
# Gem::Dependency don't have groups - in our usage these objects always
|
183
|
-
# come as child-dependencies and are never directly from a Gemfile.
|
184
|
-
# We assume that all Gem::Dependencies are ok at this point
|
185
|
-
return true if dependency.groups.nil?
|
186
|
-
|
187
|
-
# check if the dependency is in any groups we're interested in
|
188
|
-
(dependency.groups & groups).any?
|
189
|
-
end
|
190
|
-
|
191
|
-
# Returns whether development dependencies should be excluded
|
192
|
-
def exclude_development_dependencies?
|
193
|
-
@include_development ||= begin
|
194
|
-
# check whether the development dependency group is explicitly removed
|
195
|
-
# or added via bundler and licensed configurations
|
196
|
-
groups = [:development] - Array(::Bundler.settings[:without]) + Array(::Bundler.settings[:with]) - exclude_groups
|
197
|
-
!groups.include?(:development)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
# Load a gem specification from the YAML returned from `gem specification`
|
202
|
-
# This is a last resort when licensed can't obtain a specification from other means
|
203
|
-
def bundle_exec_gem_spec(name, requirement)
|
204
|
-
# `gem` must be available to run `gem specification`
|
205
|
-
return unless Licensed::Shell.tool_available?("gem")
|
206
|
-
|
207
|
-
# use `gem specification` with a clean ENV and clean Gem.dir paths
|
208
|
-
# to get gem specification at the right directory
|
209
|
-
begin
|
210
|
-
::Bundler.with_original_env do
|
211
|
-
::Bundler.rubygems.clear_paths
|
212
|
-
yaml = Licensed::Shell.execute(*ruby_command_args("gem", "specification", name, "-v", requirement.to_s))
|
213
|
-
spec = Gem::Specification.from_yaml(yaml)
|
214
|
-
# this is horrible, but it will cache the gem_dir using the clean env
|
215
|
-
# so that it can be used outside of this block when running from
|
216
|
-
# the ruby packer executable environment
|
217
|
-
spec.gem_dir if ruby_packer?
|
218
|
-
spec
|
219
|
-
end
|
220
|
-
rescue Licensed::Shell::Error
|
221
|
-
# return nil
|
222
|
-
ensure
|
223
|
-
::Bundler.configure
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
# Loads a dependency specification using rubygems' built-in
|
228
|
-
# `Dependency#matching_specs` and `Dependency#to_spec`, from the original
|
229
|
-
# gem environment
|
230
|
-
def matching_spec(dependency)
|
231
|
-
begin
|
232
|
-
::Bundler.with_original_env do
|
233
|
-
::Bundler.rubygems.clear_paths
|
234
|
-
return unless dependency.matching_specs(true).any?
|
235
|
-
BundlerSpecification.new(dependency.to_spec)
|
236
|
-
end
|
237
|
-
ensure
|
238
|
-
::Bundler.configure
|
81
|
+
# Returns whether to include bundler as a listed dependency of the project
|
82
|
+
def include_bundler?
|
83
|
+
@include_bundler ||= begin
|
84
|
+
# include if bundler is listed as a direct dependency that should be included
|
85
|
+
requested_dependencies = definition.dependencies.select { |d| (d.groups & groups).any? && d.should_include? }
|
86
|
+
return true if requested_dependencies.any? { |d| d.name == "bundler" }
|
87
|
+
# include if bundler is an indirect dependency
|
88
|
+
return true if specs.flat_map(&:dependencies).any? { |d| d.name == "bundler" }
|
89
|
+
false
|
239
90
|
end
|
240
91
|
end
|
241
92
|
|
@@ -283,23 +134,6 @@ module Licensed
|
|
283
134
|
@lockfile_path ||= gemfile_path.dirname.join(GEMFILES[gemfile_path.basename.to_s])
|
284
135
|
end
|
285
136
|
|
286
|
-
# Returns the configured bundler executable to use, or "bundle" by default.
|
287
|
-
def bundler_exe
|
288
|
-
@bundler_exe ||= begin
|
289
|
-
exe = config.dig("bundler", "bundler_exe")
|
290
|
-
return "bundle" unless exe
|
291
|
-
return exe if Licensed::Shell.tool_available?(exe)
|
292
|
-
config.root.join(exe)
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
# Determines if the configured bundler executable is available and returns
|
297
|
-
# shell command args with or without `bundle exec` depending on availability.
|
298
|
-
def ruby_command_args(*args)
|
299
|
-
return Array(args) unless Licensed::Shell.tool_available?(bundler_exe)
|
300
|
-
[bundler_exe, "exec", *args]
|
301
|
-
end
|
302
|
-
|
303
137
|
private
|
304
138
|
|
305
139
|
# helper to clear all bundler environment around a yielded block
|
@@ -307,18 +141,8 @@ module Licensed
|
|
307
141
|
# force bundler to use the local gem file
|
308
142
|
original_bundle_gemfile, ENV["BUNDLE_GEMFILE"] = ENV["BUNDLE_GEMFILE"], gemfile_path.to_s
|
309
143
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
# hack: setting this ENV var allows licensed to use Gem paths outside
|
314
|
-
# of the ruby-packer filesystem. this is needed to find spec sources
|
315
|
-
# from the host filesystem
|
316
|
-
ENV["ENCLOSE_IO_RUBYC_1ST_PASS"] = "1"
|
317
|
-
ruby_version = Gem::ConfigMap[:ruby_version]
|
318
|
-
# set the ruby version in Gem::ConfigMap to the ruby version from the host.
|
319
|
-
# this helps Bundler find the correct spec sources and paths
|
320
|
-
Gem::ConfigMap[:ruby_version] = host_ruby_version
|
321
|
-
end
|
144
|
+
# silence any bundler warnings while running licensed
|
145
|
+
bundler_ui, ::Bundler.ui = ::Bundler.ui, ::Bundler::UI::Silent.new
|
322
146
|
|
323
147
|
# reset all bundler configuration
|
324
148
|
::Bundler.reset!
|
@@ -327,15 +151,10 @@ module Licensed
|
|
327
151
|
|
328
152
|
yield
|
329
153
|
ensure
|
330
|
-
if ruby_packer?
|
331
|
-
# if running under ruby-packer, restore environment after block is finished
|
332
|
-
ENV.delete("ENCLOSE_IO_RUBYC_1ST_PASS")
|
333
|
-
Gem::ConfigMap[:ruby_version] = ruby_version
|
334
|
-
end
|
335
|
-
|
336
154
|
ENV["BUNDLE_GEMFILE"] = original_bundle_gemfile
|
155
|
+
::Bundler.ui = bundler_ui
|
156
|
+
|
337
157
|
# restore bundler configuration
|
338
|
-
::Bundler.reset!
|
339
158
|
::Bundler.configure
|
340
159
|
end
|
341
160
|
|
@@ -343,11 +162,6 @@ module Licensed
|
|
343
162
|
def ruby_packer?
|
344
163
|
@ruby_packer ||= RbConfig::TOPDIR =~ /__enclose_io_memfs__/
|
345
164
|
end
|
346
|
-
|
347
|
-
# Returns the ruby version found in the bundler environment
|
348
|
-
def host_ruby_version
|
349
|
-
Licensed::Shell.execute(*ruby_command_args("ruby", "-e", "puts Gem::ConfigMap[:ruby_version]"))
|
350
|
-
end
|
351
165
|
end
|
352
166
|
end
|
353
167
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/match_platform"
|
4
|
+
|
5
|
+
# Bundler normally raises a "GemNotFound" error when a specification
|
6
|
+
# can't be materialized which halts bundler dependency enumeration.
|
7
|
+
|
8
|
+
# This monkey patch instead creates MissingSpecification objects to
|
9
|
+
# identify missing specs without raising errors and halting enumeration.
|
10
|
+
# It was the most minimal-touch solution I could think of that should reliably
|
11
|
+
# work across many bundler versions
|
12
|
+
|
13
|
+
module Licensed
|
14
|
+
module Bundler
|
15
|
+
class MissingSpecification < Gem::BasicSpecification
|
16
|
+
include ::Bundler::MatchPlatform
|
17
|
+
|
18
|
+
attr_reader :name, :version, :platform, :source
|
19
|
+
def initialize(name:, version:, platform:, source:)
|
20
|
+
@name = name
|
21
|
+
@version = version
|
22
|
+
@platform = platform
|
23
|
+
@source = source
|
24
|
+
end
|
25
|
+
|
26
|
+
def dependencies
|
27
|
+
[]
|
28
|
+
end
|
29
|
+
|
30
|
+
def gem_dir; end
|
31
|
+
def gems_dir
|
32
|
+
Gem.dir
|
33
|
+
end
|
34
|
+
def summary; end
|
35
|
+
def homepage; end
|
36
|
+
|
37
|
+
def error
|
38
|
+
"could not find #{name} (#{version}) in any sources"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module Bundler
|
45
|
+
class LazySpecification
|
46
|
+
alias_method :orig_materialize, :__materialize__
|
47
|
+
def __materialize__
|
48
|
+
spec = orig_materialize
|
49
|
+
return spec if spec
|
50
|
+
|
51
|
+
Licensed::Bundler:: MissingSpecification.new(name: name, version: version, platform: platform, source: source)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -222,14 +222,25 @@ module Licensed
|
|
222
222
|
|
223
223
|
# Returns a package info structure with an error set
|
224
224
|
def missing_package(id)
|
225
|
-
name,
|
226
|
-
id.rpartition("-") # e.g. to match the right-most dash from ipid fused-effects-1.0.0.0
|
227
|
-
else
|
228
|
-
id.partition(/\s/) # e.g. to match the left-most space from constraint fused-effects > 1.0.0.0
|
229
|
-
end
|
230
|
-
|
225
|
+
name, version = package_id_name_version(id)
|
231
226
|
{ "name" => name, "version" => version, "error" => "package not found" }
|
232
227
|
end
|
228
|
+
|
229
|
+
# Parses the name and version pieces from an id or package requirement string
|
230
|
+
def package_id_name_version(id)
|
231
|
+
name, version = id.split(" ", 2)
|
232
|
+
return [name, version] if version
|
233
|
+
|
234
|
+
# split by dashes, find the rightmost thing that looks like an
|
235
|
+
parts = id.split("-")
|
236
|
+
version_start_index = parts.rindex { |part| part.match?(/^[\d\.]+$/) }
|
237
|
+
return [id, nil] if version_start_index.nil?
|
238
|
+
|
239
|
+
[
|
240
|
+
parts[0...version_start_index].join("-"),
|
241
|
+
parts[version_start_index..-1].join("-")
|
242
|
+
]
|
243
|
+
end
|
233
244
|
end
|
234
245
|
end
|
235
246
|
end
|
@@ -170,7 +170,7 @@ module Licensed
|
|
170
170
|
def all_files
|
171
171
|
# remove files if they are tracked but don't exist on the file system
|
172
172
|
@all_files ||= Set.new(Licensed::Git.files || [])
|
173
|
-
.delete_if { |f| !File.exist?(f) }
|
173
|
+
.delete_if { |f| !File.exist?(File.join(Licensed::Git.repository_root, f)) }
|
174
174
|
end
|
175
175
|
|
176
176
|
class Dependency < Licensed::Dependency
|
data/lib/licensed/sources/npm.rb
CHANGED
@@ -4,6 +4,25 @@ require "json"
|
|
4
4
|
module Licensed
|
5
5
|
module Sources
|
6
6
|
class NPM < Source
|
7
|
+
class Dependency < ::Licensed::Dependency
|
8
|
+
# override license_metadata to pull homepage and summary information
|
9
|
+
# from a packages package.json file, if it exists
|
10
|
+
# this accounts for the lack of this information in npm 7's `npm list` output
|
11
|
+
def license_metadata
|
12
|
+
data = super
|
13
|
+
return data if !data["homepage"].to_s.empty? && !data["summary"].to_s.empty?
|
14
|
+
|
15
|
+
package_json_path = File.join(path, "package.json")
|
16
|
+
return data unless File.exist?(package_json_path)
|
17
|
+
|
18
|
+
package_json = JSON.parse(File.read(package_json_path))
|
19
|
+
data["homepage"] = package_json["homepage"]
|
20
|
+
data["summary"] = package_json["description"]
|
21
|
+
|
22
|
+
data
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
7
26
|
def self.type
|
8
27
|
"npm"
|
9
28
|
end
|
@@ -50,6 +69,9 @@ module Licensed
|
|
50
69
|
dependencies.each do |name, dependency|
|
51
70
|
next if dependency["peerMissing"]
|
52
71
|
next if yarn_lock_present && dependency["missing"]
|
72
|
+
next if dependency["extraneous"] && dependency["missing"]
|
73
|
+
|
74
|
+
dependency["name"] = name
|
53
75
|
(result[name] ||= []) << dependency
|
54
76
|
recursive_dependencies(dependency["dependencies"] || {}, result)
|
55
77
|
end
|
@@ -59,22 +81,50 @@ module Licensed
|
|
59
81
|
# Returns parsed package metadata returned from `npm list`
|
60
82
|
def package_metadata
|
61
83
|
return @package_metadata if defined?(@package_metadata)
|
84
|
+
@package_metadata = JSON.parse(package_metadata_command)
|
85
|
+
rescue JSON::ParserError => e
|
86
|
+
message = "Licensed was unable to parse the output from 'npm list'. JSON Error: #{e.message}"
|
87
|
+
npm_error = package_metadata_error
|
88
|
+
message = "#{message}. npm Error: #{npm_error}" if npm_error
|
89
|
+
raise Licensed::Sources::Source::Error, message
|
90
|
+
end
|
62
91
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
92
|
+
# Returns an error, if one exists, from running `npm list` to get package metadata
|
93
|
+
def package_metadata_error
|
94
|
+
Licensed::Shell.execute("npm", "list", *package_metadata_args)
|
95
|
+
return ""
|
96
|
+
rescue Licensed::Shell::Error => e
|
97
|
+
return e.message
|
69
98
|
end
|
70
99
|
|
71
100
|
# Returns the output from running `npm list` to get package metadata
|
72
101
|
def package_metadata_command
|
73
102
|
args = %w(--json --long)
|
74
|
-
args
|
103
|
+
args.concat(package_metadata_args)
|
104
|
+
|
75
105
|
Licensed::Shell.execute("npm", "list", *args, allow_failure: true)
|
76
106
|
end
|
77
107
|
|
108
|
+
# Returns an array of arguments that should be used for all `npm list`
|
109
|
+
# calls, regardless of how the output is formatted
|
110
|
+
def package_metadata_args
|
111
|
+
args = []
|
112
|
+
args << "--production" unless include_non_production?
|
113
|
+
|
114
|
+
# on npm 7+, the --all argument is necessary to evaluate the project's
|
115
|
+
# full dependency tree
|
116
|
+
args << "--all" if npm_version >= Gem::Version.new("7.0.0")
|
117
|
+
|
118
|
+
return args
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns the currently installed version of npm as a Gem::Version object
|
122
|
+
def npm_version
|
123
|
+
@npm_version ||= begin
|
124
|
+
Gem::Version.new(Licensed::Shell.execute("npm", "-v").strip)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
78
128
|
# Returns true if a yarn.lock file exists in the current directory
|
79
129
|
def yarn_lock_present
|
80
130
|
@yarn_lock_present ||= File.exist?(config.pwd.join("yarn.lock"))
|
data/lib/licensed/sources/pip.rb
CHANGED
@@ -8,7 +8,7 @@ module Licensed
|
|
8
8
|
module Sources
|
9
9
|
class Pip < Source
|
10
10
|
VERSION_OPERATORS = %w(< > <= >= == !=).freeze
|
11
|
-
PACKAGE_REGEX = /^([\w
|
11
|
+
PACKAGE_REGEX = /^([\w\.-]+)(#{VERSION_OPERATORS.join("|")})?/
|
12
12
|
|
13
13
|
def enabled?
|
14
14
|
return unless virtual_env_pip && Licensed::Shell.tool_available?(virtual_env_pip)
|
data/lib/licensed/version.rb
CHANGED
data/script/packages/build
CHANGED
@@ -51,8 +51,11 @@ cd $COPY_DIR
|
|
51
51
|
trap "git checkout $CURRENT_BRANCH" EXIT
|
52
52
|
fi
|
53
53
|
|
54
|
+
# get the openssl dir to use when building based on ruby's default ssl cert dir
|
55
|
+
OPENSSL_DIR="$(cd "$(ruby -e 'require "net/https"; puts OpenSSL::X509::DEFAULT_CERT_DIR')/.." && pwd)"
|
56
|
+
|
54
57
|
# build the licensed rubyc executable
|
55
|
-
"$RUBYC" --clean-tmpdir -o "$BUILD_DIR/licensed" "$COPY_DIR/exe/licensed"
|
58
|
+
"$RUBYC" --openssl-dir "$OPENSSL_DIR" --clean-tmpdir -o "$BUILD_DIR/licensed" "$COPY_DIR/exe/licensed"
|
56
59
|
chmod +x $BUILD_DIR/licensed
|
57
60
|
)
|
58
61
|
|
data/script/packages/mac
CHANGED
@@ -28,6 +28,9 @@ brew update
|
|
28
28
|
brew list "squashfs" &>/dev/null || brew install "squashfs"
|
29
29
|
brew list "pkg-config" &>/dev/null || brew install "pkg-config"
|
30
30
|
|
31
|
+
gem update --system
|
32
|
+
gem update bundler
|
33
|
+
|
31
34
|
if [ ! -f "$RUBYC" ]; then
|
32
35
|
mkdir -p "$(dirname "$RUBYC")"
|
33
36
|
curl -L https://github.com/kontena/ruby-packer/releases/download/2.6.0-0.6.0/rubyc-2.6.0-0.6.0-osx-amd64.gz | gunzip > "$RUBYC"
|
data/script/source-setup/npm
CHANGED
@@ -10,8 +10,25 @@ fi
|
|
10
10
|
BASE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
11
11
|
cd $BASE_PATH/test/fixtures/npm
|
12
12
|
|
13
|
+
FORCE=""
|
13
14
|
if [ "$1" == "-f" ]; then
|
14
|
-
|
15
|
+
FORCE=1
|
16
|
+
fi
|
17
|
+
|
18
|
+
NPM_MAJOR_VERSION="$(npm -v | cut -d'.' -f1)"
|
19
|
+
if [ "$NPM_MAJOR_VERSION" -ge "7" ]; then
|
20
|
+
PACKAGE_JSON_SRC="package.json.npm7"
|
21
|
+
else
|
22
|
+
PACKAGE_JSON_SRC="package.json.npm6"
|
23
|
+
fi
|
24
|
+
|
25
|
+
if [ ! -f "package.json" ] || [ "$(cat package.json | md5sum )" != "$(cat "$PACKAGE_JSON_SRC" | md5sum)" ]; then
|
26
|
+
FORCE=1
|
27
|
+
cp -f "$PACKAGE_JSON_SRC" package.json
|
28
|
+
fi
|
29
|
+
|
30
|
+
if [ -n "$FORCE" ]; then
|
31
|
+
find . -not -regex "\.*" -and -not -name "package\.json*" -print0 | xargs -0 rm -rf
|
15
32
|
fi
|
16
33
|
|
17
34
|
npm install
|
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:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: licensee
|
@@ -243,7 +243,8 @@ files:
|
|
243
243
|
- docs/adding_a_new_source.md
|
244
244
|
- docs/commands.md
|
245
245
|
- docs/configuration.md
|
246
|
-
- docs/
|
246
|
+
- docs/migrations/v2.md
|
247
|
+
- docs/migrations/v3.md
|
247
248
|
- docs/packaging.md
|
248
249
|
- docs/reporters.md
|
249
250
|
- docs/sources/bower.md
|
@@ -290,6 +291,7 @@ files:
|
|
290
291
|
- lib/licensed/sources.rb
|
291
292
|
- lib/licensed/sources/bower.rb
|
292
293
|
- lib/licensed/sources/bundler.rb
|
294
|
+
- lib/licensed/sources/bundler/missing_specification.rb
|
293
295
|
- lib/licensed/sources/cabal.rb
|
294
296
|
- lib/licensed/sources/composer.rb
|
295
297
|
- lib/licensed/sources/dep.rb
|
@@ -348,7 +350,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
348
350
|
- !ruby/object:Gem::Version
|
349
351
|
version: '0'
|
350
352
|
requirements: []
|
351
|
-
rubygems_version: 3.0.3
|
353
|
+
rubygems_version: 3.0.3.1
|
352
354
|
signing_key:
|
353
355
|
specification_version: 4
|
354
356
|
summary: Extract and validate the licenses of dependencies.
|