licensed 2.15.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +27 -0
- data/CHANGELOG.md +53 -1
- data/README.md +14 -2
- data/docs/configuration.md +14 -2
- 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/swift.md +4 -0
- data/lib/licensed/cli.rb +4 -1
- data/lib/licensed/configuration.rb +28 -5
- data/lib/licensed/sources.rb +1 -0
- data/lib/licensed/sources/bundler.rb +35 -216
- data/lib/licensed/sources/bundler/missing_specification.rb +54 -0
- data/lib/licensed/sources/go.rb +1 -1
- data/lib/licensed/sources/npm.rb +2 -0
- data/lib/licensed/sources/nuget.rb +57 -27
- data/lib/licensed/sources/pip.rb +1 -1
- data/lib/licensed/sources/swift.rb +69 -0
- data/lib/licensed/version.rb +1 -1
- data/script/source-setup/swift +22 -0
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9411b608edb8210d926f1c927bcaa65e396eac39dbf6300b946e842a33071a23
|
4
|
+
data.tar.gz: a4dd2527919e79c111107482233945f476df72d9f282431abf99f40a3516b221
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07f9153972ac85375a1cb8273d9990052a8d13bc3918c0cd7697c7a0686ef31ed45045065b10091b569a53ad0f2494ae32f0cf2392ae937d242b2954af92c0f6
|
7
|
+
data.tar.gz: 90364cc7be14673627b0280b018498a0feffc962b1c48a89094b9503d5743362f99ee0c36d601478b1818b10ee48d5b1ef97bdd120d6fbc7299b55efa9c5278c
|
data/.github/workflows/test.yml
CHANGED
@@ -362,6 +362,33 @@ jobs:
|
|
362
362
|
- name: Run tests
|
363
363
|
run: script/test pipenv
|
364
364
|
|
365
|
+
swift:
|
366
|
+
runs-on: ubuntu-latest
|
367
|
+
strategy:
|
368
|
+
matrix:
|
369
|
+
swift: [ "5.4", "5.3" ]
|
370
|
+
steps:
|
371
|
+
- uses: actions/checkout@v2
|
372
|
+
- name: Setup Swift
|
373
|
+
uses: fwal/setup-swift@v1
|
374
|
+
with:
|
375
|
+
swift-version: ${{ matrix.swift }}
|
376
|
+
- name: Set up Ruby
|
377
|
+
uses: ruby/setup-ruby@v1
|
378
|
+
with:
|
379
|
+
ruby-version: 2.6
|
380
|
+
- run: bundle lock
|
381
|
+
- uses: actions/cache@v1
|
382
|
+
with:
|
383
|
+
path: vendor/gems
|
384
|
+
key: ${{ runner.os }}-gem-2.6.x-${{ hashFiles('**/Gemfile.lock') }}
|
385
|
+
- name: Bootstrap
|
386
|
+
run: script/bootstrap
|
387
|
+
- name: Set up fixtures
|
388
|
+
run: script/source-setup/swift
|
389
|
+
- name: Run tests
|
390
|
+
run: script/test swift
|
391
|
+
|
365
392
|
yarn:
|
366
393
|
runs-on: ubuntu-latest
|
367
394
|
strategy:
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,58 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## 3.1.0
|
10
|
+
|
11
|
+
2021-06-16
|
12
|
+
|
13
|
+
### Added
|
14
|
+
|
15
|
+
- Licensed supports Swift/Swift package manager as a dependency source (:tada: @mattt https://github.com/github/licensed/pull/363)'
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
- The `source_path` configuration property accepts arrays of inclusion and exclusion glob patterns (https://github.com/github/licensed/pull/368)
|
20
|
+
- The Nuget source now uses configured fallback folders to find dependencies that are not in found in the project folder (https://github.com/github/licensed/pull/366)
|
21
|
+
- The Nuget source supports a configurable property for the path from the project source path to the project's `obj` folder (https://github.com/github/licensed/pull/365)
|
22
|
+
|
23
|
+
### Fixed
|
24
|
+
- The Go source's checks for local packages will correctly find paths in case-insensitive file systems (https://github.com/github/licensed/pull/370)
|
25
|
+
- The Bundler source will no longer unnecessarily reset the local Bundler environment configuration (https://github.com/github/licensed/pull/372)
|
26
|
+
|
27
|
+
## 3.0.1
|
28
|
+
|
29
|
+
2021-05-17
|
30
|
+
|
31
|
+
### Fixed
|
32
|
+
|
33
|
+
- The bundler source will correctly enumerate dependencies pulled with a `git:` directive (https://github.com/github/licensed/pull/360)
|
34
|
+
|
35
|
+
## 3.0.0
|
36
|
+
|
37
|
+
2021-04-27
|
38
|
+
|
39
|
+
**This is a major release and includes potentially breaking changes to bundler dependency enumeration.**
|
40
|
+
|
41
|
+
### Changed
|
42
|
+
|
43
|
+
- 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.
|
44
|
+
|
45
|
+
## 2.15.2
|
46
|
+
|
47
|
+
2021-04-06
|
48
|
+
|
49
|
+
### Fixed
|
50
|
+
|
51
|
+
- The pip source works with package names containing periods (:tada: @bcskda https://github.com/github/licensed/pull/350)
|
52
|
+
|
53
|
+
## 2.15.1
|
54
|
+
|
55
|
+
2021-03-29
|
56
|
+
|
57
|
+
### Changed
|
58
|
+
|
59
|
+
- The npm source will ignore dependencies that are marked as both extraneous and missing (https://github.com/github/licensed/pull/347)
|
60
|
+
|
9
61
|
## 2.15.0
|
10
62
|
2021-03-24
|
11
63
|
|
@@ -395,4 +447,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
395
447
|
|
396
448
|
Initial release :tada:
|
397
449
|
|
398
|
-
[Unreleased]: https://github.com/github/licensed/compare/
|
450
|
+
[Unreleased]: https://github.com/github/licensed/compare/3.1.0...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
|
|
@@ -114,6 +125,7 @@ Dependencies will be automatically detected for all of the following sources by
|
|
114
125
|
1. [NuGet](./docs/sources/nuget.md)
|
115
126
|
1. [Pip](./docs/sources/pip.md)
|
116
127
|
1. [Pipenv](./docs/sources/pipenv.md)
|
128
|
+
1. [Swift](./docs/sources/swift.md)
|
117
129
|
1. [Yarn](./docs/sources/yarn.md)
|
118
130
|
|
119
131
|
You can disable any of them in the configuration file:
|
data/docs/configuration.md
CHANGED
@@ -19,9 +19,13 @@ If a root path is not specified, it will default to using the following, in orde
|
|
19
19
|
1. the root of the local git repository, if run inside a git repository
|
20
20
|
2. the current directory
|
21
21
|
|
22
|
-
### Source
|
22
|
+
### Source paths
|
23
23
|
|
24
|
-
|
24
|
+
A source path is the directory in which licensed should run to enumerate dependencies. This is often dependent on the project type, for example the bundler source should be run from the directory containing a `Gemfile` or `gems.rb` while the go source should be run from the directory containing an entrypoint function.
|
25
|
+
|
26
|
+
#### Using glob patterns
|
27
|
+
|
28
|
+
The `source_path` property can use one or more glob patterns to share configuration properties across multiple application entrypoints.
|
25
29
|
|
26
30
|
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
31
|
|
@@ -33,6 +37,14 @@ sources:
|
|
33
37
|
source_path: cmd/*
|
34
38
|
```
|
35
39
|
|
40
|
+
In order to better filter the results from glob patterns, the `source_path` property also accepts an array of inclusion and exclusion glob patterns similar to gitignore files. Inclusion patterns will add matching directory paths to resulting set of source paths, while exclusion patterns will remove matching directory paths.
|
41
|
+
|
42
|
+
```yml
|
43
|
+
source_path:
|
44
|
+
- "projects/*" # include by default all directories under "projects"
|
45
|
+
- "!projects/*Test" # exclude all projects ending in "Test"
|
46
|
+
```
|
47
|
+
|
36
48
|
Glob patterns are syntactic sugar for, and provide the same functionality as, manually specifying multiple `source_path` values. See the instructions on [specifying multiple apps](./#specifying-multiple-apps) below for additional considerations when using multiple apps.
|
37
49
|
|
38
50
|
## Restricting sources
|
@@ -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/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
|
@@ -158,18 +158,41 @@ module Licensed
|
|
158
158
|
private
|
159
159
|
|
160
160
|
def self.expand_app_source_path(app_config)
|
161
|
-
|
161
|
+
# map a source_path configuration value to an array of non-empty values
|
162
|
+
source_path_array = Array(app_config["source_path"])
|
163
|
+
.reject { |path| path.to_s.empty? }
|
164
|
+
.compact
|
165
|
+
app_root = AppConfiguration.root_for(app_config)
|
166
|
+
return app_config.merge("source_path" => app_root) if source_path_array.empty?
|
162
167
|
|
163
168
|
# check if the source path maps to an existing directory
|
164
|
-
|
165
|
-
|
169
|
+
if source_path_array.length == 1
|
170
|
+
source_path = File.expand_path(source_path_array[0], app_root)
|
171
|
+
return app_config.merge("source_path" => source_path) if Dir.exist?(source_path)
|
172
|
+
end
|
166
173
|
|
167
174
|
# try to expand the source path for glob patterns
|
168
|
-
expanded_source_paths =
|
175
|
+
expanded_source_paths = source_path_array.reduce(Set.new) do |matched_paths, pattern|
|
176
|
+
current_matched_paths = if pattern.start_with?("!")
|
177
|
+
# if the pattern is an exclusion, remove all matching files
|
178
|
+
# from the result
|
179
|
+
matched_paths - Dir.glob(pattern[1..-1])
|
180
|
+
else
|
181
|
+
# if the pattern is an inclusion, add all matching files
|
182
|
+
# to the result
|
183
|
+
matched_paths + Dir.glob(pattern)
|
184
|
+
end
|
185
|
+
|
186
|
+
current_matched_paths.select { |p| File.directory?(p) }
|
187
|
+
end
|
188
|
+
|
169
189
|
configs = expanded_source_paths.map { |path| app_config.merge("source_path" => path) }
|
170
190
|
|
171
191
|
# if no directories are found for the source path, return the original config
|
172
|
-
|
192
|
+
if configs.size == 0
|
193
|
+
app_config["source_path"] = app_root if app_config["source_path"].is_a?(Array)
|
194
|
+
return app_config
|
195
|
+
end
|
173
196
|
|
174
197
|
# update configured values for name and cache_path for uniqueness.
|
175
198
|
# this is only needed when values are explicitly set, AppConfiguration
|
data/lib/licensed/sources.rb
CHANGED
@@ -14,6 +14,7 @@ module Licensed
|
|
14
14
|
require "licensed/sources/nuget"
|
15
15
|
require "licensed/sources/pip"
|
16
16
|
require "licensed/sources/pipenv"
|
17
|
+
require "licensed/sources/swift"
|
17
18
|
require "licensed/sources/gradle"
|
18
19
|
require "licensed/sources/mix"
|
19
20
|
require "licensed/sources/yarn"
|
@@ -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)
|
135
|
-
end
|
136
|
-
|
137
|
-
# Returns the specs for dependencies that pass the checks in `include?`.
|
138
|
-
# Returns a `MissingSpecification` if a gem specification isn't found.
|
139
|
-
def specs_for_dependencies(dependencies, source)
|
140
|
-
included_dependencies = dependencies.select { |d| include?(d, source) }
|
141
|
-
included_dependencies.map do |dep|
|
142
|
-
gem_spec(dep) || MissingSpecification.new(name: dep.name, requirement: dep.requirement)
|
143
|
-
end
|
144
|
-
end
|
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
|
78
|
+
@specs ||= definition.specs_for(groups)
|
225
79
|
end
|
226
80
|
|
227
|
-
#
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
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,71 +134,39 @@ 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
|
-
private
|
304
|
-
|
305
137
|
# helper to clear all bundler environment around a yielded block
|
306
138
|
def with_local_configuration
|
307
|
-
#
|
308
|
-
|
139
|
+
# silence any bundler warnings while running licensed
|
140
|
+
bundler_ui, ::Bundler.ui = ::Bundler.ui, ::Bundler::UI::Silent.new
|
309
141
|
|
310
|
-
|
311
|
-
|
142
|
+
original_bundle_gemfile = nil
|
143
|
+
if gemfile_path.to_s != ENV["BUNDLE_GEMFILE"]
|
144
|
+
# force bundler to use the local gem file
|
145
|
+
original_bundle_gemfile, ENV["BUNDLE_GEMFILE"] = ENV["BUNDLE_GEMFILE"], gemfile_path.to_s
|
312
146
|
|
313
|
-
#
|
314
|
-
|
315
|
-
#
|
316
|
-
|
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
|
147
|
+
# reset all bundler configuration
|
148
|
+
::Bundler.reset!
|
149
|
+
# and re-configure with settings for current directory
|
150
|
+
::Bundler.configure
|
321
151
|
end
|
322
152
|
|
323
|
-
# reset all bundler configuration
|
324
|
-
::Bundler.reset!
|
325
|
-
# and re-configure with settings for current directory
|
326
|
-
::Bundler.configure
|
327
|
-
|
328
153
|
yield
|
329
154
|
ensure
|
330
|
-
if
|
331
|
-
|
332
|
-
|
333
|
-
|
155
|
+
if original_bundle_gemfile
|
156
|
+
ENV["BUNDLE_GEMFILE"] = original_bundle_gemfile
|
157
|
+
|
158
|
+
# restore bundler configuration
|
159
|
+
::Bundler.reset!
|
160
|
+
::Bundler.configure
|
334
161
|
end
|
335
162
|
|
336
|
-
|
337
|
-
# restore bundler configuration
|
338
|
-
::Bundler.reset!
|
339
|
-
::Bundler.configure
|
163
|
+
::Bundler.ui = bundler_ui
|
340
164
|
end
|
341
165
|
|
342
166
|
# Returns whether the current licensed execution is running ruby-packer
|
343
167
|
def ruby_packer?
|
344
168
|
@ruby_packer ||= RbConfig::TOPDIR =~ /__enclose_io_memfs__/
|
345
169
|
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
170
|
end
|
352
171
|
end
|
353
172
|
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
|
data/lib/licensed/sources/go.rb
CHANGED
@@ -98,7 +98,7 @@ module Licensed
|
|
98
98
|
# Returns whether the package is local to the current project
|
99
99
|
def local_package?(package)
|
100
100
|
return false unless package && package["Dir"]
|
101
|
-
return false unless File.fnmatch?("#{config.root.to_s}*", package["Dir"])
|
101
|
+
return false unless File.fnmatch?("#{config.root.to_s}*", package["Dir"], File::FNM_CASEFOLD)
|
102
102
|
vendored_path_parts(package).nil?
|
103
103
|
end
|
104
104
|
|
data/lib/licensed/sources/npm.rb
CHANGED
@@ -69,6 +69,8 @@ module Licensed
|
|
69
69
|
dependencies.each do |name, dependency|
|
70
70
|
next if dependency["peerMissing"]
|
71
71
|
next if yarn_lock_present && dependency["missing"]
|
72
|
+
next if dependency["extraneous"] && dependency["missing"]
|
73
|
+
|
72
74
|
dependency["name"] = name
|
73
75
|
(result[name] ||= []) << dependency
|
74
76
|
recursive_dependencies(dependency["dependencies"] || {}, result)
|
@@ -164,7 +164,7 @@ module Licensed
|
|
164
164
|
end
|
165
165
|
|
166
166
|
def project_assets_file_path
|
167
|
-
File.join(config.pwd, "project.assets.json")
|
167
|
+
File.join(config.pwd, nuget_obj_path, "project.assets.json")
|
168
168
|
end
|
169
169
|
|
170
170
|
def project_assets_file
|
@@ -172,6 +172,17 @@ module Licensed
|
|
172
172
|
@project_assets_file = File.read(project_assets_file_path)
|
173
173
|
end
|
174
174
|
|
175
|
+
def project_assets_json
|
176
|
+
@project_assets_json ||= JSON.parse(project_assets_file)
|
177
|
+
rescue JSON::ParserError => e
|
178
|
+
message = "Licensed was unable to read the project.assets.json file. Error: #{e.message}"
|
179
|
+
raise Licensed::Sources::Source::Error, message
|
180
|
+
end
|
181
|
+
|
182
|
+
def nuget_obj_path
|
183
|
+
config.dig("nuget", "obj_path") || ""
|
184
|
+
end
|
185
|
+
|
175
186
|
def enabled?
|
176
187
|
File.exist?(project_assets_file_path)
|
177
188
|
end
|
@@ -180,32 +191,51 @@ module Licensed
|
|
180
191
|
# Ideally we'd use `dotnet list package` instead, but its output isn't
|
181
192
|
# easily machine readable and doesn't contain everything we need.
|
182
193
|
def enumerate_dependencies
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
name
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
194
|
+
reference_keys.map do |reference_key|
|
195
|
+
package_id_parts = reference_key.partition("/")
|
196
|
+
name = package_id_parts[0]
|
197
|
+
version = package_id_parts[-1]
|
198
|
+
id = "#{name}-#{version}"
|
199
|
+
|
200
|
+
path = full_dependency_path(reference_key)
|
201
|
+
error = "Package #{id} path was not found in project.assets.json, or does not exist on disk at any project package folder" if path.nil?
|
202
|
+
|
203
|
+
NuGetDependency.new(
|
204
|
+
name: id,
|
205
|
+
version: version,
|
206
|
+
path: path,
|
207
|
+
errors: Array(error),
|
208
|
+
metadata: {
|
209
|
+
"type" => NuGet.type,
|
210
|
+
"name" => name
|
211
|
+
}
|
212
|
+
)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Returns a unique set of the package reference keys used across all target groups
|
217
|
+
def reference_keys
|
218
|
+
all_reference_keys = project_assets_json["targets"].flat_map do |_, references|
|
219
|
+
references.select { |key, reference| reference["type"] == "package" }
|
220
|
+
.keys
|
221
|
+
end
|
222
|
+
|
223
|
+
Set.new(all_reference_keys)
|
224
|
+
end
|
225
|
+
|
226
|
+
# Returns a dependency's path, if it exists, in one of the project's global or fallback package folders
|
227
|
+
def full_dependency_path(reference_key)
|
228
|
+
dependency_path = project_assets_json.dig("libraries", reference_key, "path")
|
229
|
+
return unless dependency_path
|
230
|
+
|
231
|
+
nuget_package_dirs = [
|
232
|
+
project_assets_json.dig("project", "restore", "packagesPath"),
|
233
|
+
*Array(project_assets_json.dig("project", "restore", "fallbackFolders"))
|
234
|
+
].compact
|
235
|
+
|
236
|
+
nuget_package_dirs.map { |dir| File.join(dir, dependency_path) }
|
237
|
+
.select { |path| File.directory?(path) }
|
238
|
+
.first
|
209
239
|
end
|
210
240
|
end
|
211
241
|
end
|
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)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "json"
|
3
|
+
require "pathname"
|
4
|
+
require "uri"
|
5
|
+
|
6
|
+
module Licensed
|
7
|
+
module Sources
|
8
|
+
class Swift < Source
|
9
|
+
def enabled?
|
10
|
+
return unless Licensed::Shell.tool_available?("swift") && swift_package?
|
11
|
+
File.exist?(package_resolved_file_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def enumerate_dependencies
|
15
|
+
pins.map { |pin|
|
16
|
+
name = pin["package"]
|
17
|
+
version = pin.dig("state", "version")
|
18
|
+
path = dependency_path_for_url(pin["repositoryURL"])
|
19
|
+
error = "Unable to determine project path from #{url}" unless path
|
20
|
+
|
21
|
+
Dependency.new(
|
22
|
+
name: name,
|
23
|
+
path: path,
|
24
|
+
version: version,
|
25
|
+
errors: Array(error),
|
26
|
+
metadata: {
|
27
|
+
"type" => Swift.type,
|
28
|
+
"homepage" => homepage_for_url(pin["repositoryURL"])
|
29
|
+
}
|
30
|
+
)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def pins
|
37
|
+
return @pins if defined?(@pins)
|
38
|
+
|
39
|
+
@pins = begin
|
40
|
+
json = JSON.parse(File.read(package_resolved_file_path))
|
41
|
+
json.dig("object", "pins")
|
42
|
+
rescue => e
|
43
|
+
message = "Licensed was unable to read the Package.resolved file. Error: #{e.message}"
|
44
|
+
raise Licensed::Sources::Source::Error, message
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def dependency_path_for_url(url)
|
49
|
+
last_path_component = URI(url).path.split("/").last.sub(/\.git$/, "")
|
50
|
+
File.join(config.pwd, ".build", "checkouts", last_path_component)
|
51
|
+
rescue URI::InvalidURIError
|
52
|
+
end
|
53
|
+
|
54
|
+
def homepage_for_url(url)
|
55
|
+
return unless %w{http https}.include?(URI(url).scheme)
|
56
|
+
url.sub(/\.git$/, "")
|
57
|
+
rescue URI::InvalidURIError
|
58
|
+
end
|
59
|
+
|
60
|
+
def package_resolved_file_path
|
61
|
+
File.join(config.pwd, "Package.resolved")
|
62
|
+
end
|
63
|
+
|
64
|
+
def swift_package?
|
65
|
+
Licensed::Shell.success?("swift", "package", "describe")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/licensed/version.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -e
|
3
|
+
|
4
|
+
if [ -z "$(which swift)" ]; then
|
5
|
+
echo "A local swift installation is required for swift development." >&2
|
6
|
+
exit 127
|
7
|
+
fi
|
8
|
+
|
9
|
+
swift --version
|
10
|
+
|
11
|
+
BASE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
12
|
+
cd $BASE_PATH/test/fixtures/swift
|
13
|
+
|
14
|
+
if [ "$1" == "-f" ]; then
|
15
|
+
find . -not -regex "\.*" \
|
16
|
+
-and -not -path "*/Package.swift" \
|
17
|
+
-and -not -path "*/Sources*" \
|
18
|
+
-and -not -path "*/Tests*" \
|
19
|
+
-print0 | xargs -0 rm -rf
|
20
|
+
fi
|
21
|
+
|
22
|
+
swift package resolve
|
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.1.0
|
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-06-16 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
|
@@ -261,6 +262,7 @@ files:
|
|
261
262
|
- docs/sources/pip.md
|
262
263
|
- docs/sources/pipenv.md
|
263
264
|
- docs/sources/stack.md
|
265
|
+
- docs/sources/swift.md
|
264
266
|
- docs/sources/yarn.md
|
265
267
|
- exe/licensed
|
266
268
|
- lib/licensed.rb
|
@@ -290,6 +292,7 @@ files:
|
|
290
292
|
- lib/licensed/sources.rb
|
291
293
|
- lib/licensed/sources/bower.rb
|
292
294
|
- lib/licensed/sources/bundler.rb
|
295
|
+
- lib/licensed/sources/bundler/missing_specification.rb
|
293
296
|
- lib/licensed/sources/cabal.rb
|
294
297
|
- lib/licensed/sources/composer.rb
|
295
298
|
- lib/licensed/sources/dep.rb
|
@@ -304,6 +307,7 @@ files:
|
|
304
307
|
- lib/licensed/sources/pip.rb
|
305
308
|
- lib/licensed/sources/pipenv.rb
|
306
309
|
- lib/licensed/sources/source.rb
|
310
|
+
- lib/licensed/sources/swift.rb
|
307
311
|
- lib/licensed/sources/yarn.rb
|
308
312
|
- lib/licensed/ui/shell.rb
|
309
313
|
- lib/licensed/version.rb
|
@@ -327,6 +331,7 @@ files:
|
|
327
331
|
- script/source-setup/nuget
|
328
332
|
- script/source-setup/pip
|
329
333
|
- script/source-setup/pipenv
|
334
|
+
- script/source-setup/swift
|
330
335
|
- script/source-setup/yarn
|
331
336
|
- script/test
|
332
337
|
homepage: https://github.com/github/licensed
|
@@ -348,7 +353,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
348
353
|
- !ruby/object:Gem::Version
|
349
354
|
version: '0'
|
350
355
|
requirements: []
|
351
|
-
rubygems_version: 3.0.3
|
356
|
+
rubygems_version: 3.0.3.1
|
352
357
|
signing_key:
|
353
358
|
specification_version: 4
|
354
359
|
summary: Extract and validate the licenses of dependencies.
|