licensed 2.5.0 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/release.yml +3 -4
- data/.github/workflows/test.yml +33 -1
- data/.gitignore +3 -0
- data/CHANGELOG.md +7 -1
- data/LICENSE +1 -1
- data/README.md +7 -2
- data/docs/configuration.md +2 -0
- data/docs/sources/mix.md +23 -0
- data/lib/licensed/sources.rb +1 -0
- data/lib/licensed/sources/mix.rb +194 -0
- data/lib/licensed/version.rb +1 -1
- data/script/source-setup/cabal +1 -1
- data/script/source-setup/mix +19 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 94e3cbc840104e6f0d4733c82ea38805aa2db680070708b88f107420405a1956
|
4
|
+
data.tar.gz: d04aea6f7ac531c7ab5826b90ece5f3bd0936845a7d8a0e0e44d54c7119e9f08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aab7fc74e7905ab4acad59d1e997c3ea95c8121299ba5cd52ae96bc2a7451314de1155754d5c41fe7834037217469e49b8b2fc4c88b68b1b08036bedc06a0ee7
|
7
|
+
data.tar.gz: 8572722b1cfca8af7527278f269b410a7c4edc699dc0ffba6e991e2ececb78d575addf0fe548ae95ac6347b7c59431ec553d1c0003b8a4abbd3f2dbfd534abc5
|
@@ -5,10 +5,9 @@ on: create
|
|
5
5
|
jobs:
|
6
6
|
tag_filter:
|
7
7
|
runs-on: ubuntu-latest
|
8
|
+
if: startsWith(github.ref, 'refs/tags/')
|
8
9
|
steps:
|
9
|
-
|
10
|
-
with:
|
11
|
-
args: 'tag'
|
10
|
+
- run: exit 0
|
12
11
|
|
13
12
|
package_linux:
|
14
13
|
runs-on: ubuntu-latest
|
@@ -119,7 +118,7 @@ jobs:
|
|
119
118
|
touch $HOME/.gem/credentials
|
120
119
|
chmod 0600 $HOME/.gem/credentials
|
121
120
|
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
122
|
-
gem push
|
121
|
+
gem push $GEM
|
123
122
|
env:
|
124
123
|
GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
|
125
124
|
GEM: ${{github.event.ref}}-gem/*.gem
|
data/.github/workflows/test.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
name: Test
|
2
2
|
|
3
|
-
on:
|
3
|
+
on:
|
4
4
|
push:
|
5
5
|
branches:
|
6
6
|
- "*"
|
@@ -51,12 +51,21 @@ jobs:
|
|
51
51
|
|
52
52
|
cabal:
|
53
53
|
runs-on: ubuntu-latest
|
54
|
+
strategy:
|
55
|
+
matrix:
|
56
|
+
ghc: [ '8.2.2', '8.6.5' ]
|
57
|
+
cabal: [ '2.0', '3.0' ]
|
54
58
|
steps:
|
55
59
|
- uses: actions/checkout@master
|
56
60
|
- name: Set up Ruby
|
57
61
|
uses: actions/setup-ruby@v1
|
58
62
|
with:
|
59
63
|
version: 2.6.x
|
64
|
+
- name: Setup Haskell
|
65
|
+
uses: actions/setup-haskell@v1
|
66
|
+
with:
|
67
|
+
ghc-version: ${{ matrix.ghc }}
|
68
|
+
cabal-version: ${{ matrix.cabal }}
|
60
69
|
- name: Bootstrap
|
61
70
|
run: script/bootstrap
|
62
71
|
- name: Set up fixtures
|
@@ -230,3 +239,26 @@ jobs:
|
|
230
239
|
run: script/source-setup/composer
|
231
240
|
- name: Run tests
|
232
241
|
run: script/test composer
|
242
|
+
|
243
|
+
mix:
|
244
|
+
runs-on: ubuntu-latest
|
245
|
+
strategy:
|
246
|
+
matrix:
|
247
|
+
otp: [21.x, 22.x]
|
248
|
+
elixir: [1.8.x, 1.9.x]
|
249
|
+
steps:
|
250
|
+
- uses: actions/checkout@master
|
251
|
+
- uses: actions/setup-elixir@v1.0.0
|
252
|
+
with:
|
253
|
+
otp-version: ${{matrix.otp}}
|
254
|
+
elixir-version: ${{matrix.elixir}}
|
255
|
+
- name: Set up Ruby
|
256
|
+
uses: actions/setup-ruby@v1
|
257
|
+
with:
|
258
|
+
version: 2.6.x
|
259
|
+
- name: Bootstrap
|
260
|
+
run: script/bootstrap
|
261
|
+
- name: Set up fixtures
|
262
|
+
run: script/source-setup/mix
|
263
|
+
- name: Run tests
|
264
|
+
run: script/test mix
|
data/.gitignore
CHANGED
@@ -28,6 +28,9 @@ test/fixtures/pipenv/Pipfile.lock
|
|
28
28
|
!test/fixtures/migrations/**/*
|
29
29
|
test/fixtures/composer/**/*
|
30
30
|
!test/fixtures/composer/composer.json
|
31
|
+
test/fixtures/mix/_build
|
32
|
+
test/fixtures/mix/deps
|
33
|
+
test/fixtures/mix/mix.lock
|
31
34
|
|
32
35
|
vendor/licenses
|
33
36
|
.licenses
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## 2.6.0
|
10
|
+
2019-10-22
|
11
|
+
|
12
|
+
### Added
|
13
|
+
- Mix source for Elixir (:tada: @bruce https://github.com/github/licensed/pull/195)
|
14
|
+
|
9
15
|
## 2.5.0
|
10
16
|
2019-09-26
|
11
17
|
|
@@ -223,4 +229,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
223
229
|
|
224
230
|
Initial release :tada:
|
225
231
|
|
226
|
-
[Unreleased]: https://github.com/github/licensed/compare/2.
|
232
|
+
[Unreleased]: https://github.com/github/licensed/compare/2.6.0...HEAD
|
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2015-
|
3
|
+
Copyright (c) 2015-2019 GitHub, Inc. and contributors
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -16,7 +16,7 @@ Licensed is in active development and currently used at GitHub. See the [open i
|
|
16
16
|
|
17
17
|
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
18
|
|
19
|
-
See [CHANGELOG.md](./CHANGELOG.md) for more details on
|
19
|
+
See [CHANGELOG.md](./CHANGELOG.md) for more details on what's changed.
|
20
20
|
See the [migration documentation](./docs/migrating_to_newer_versions.md) for more info on migrating to v2, or run `licensed help migrate`.
|
21
21
|
|
22
22
|
## Installation
|
@@ -50,7 +50,7 @@ For system wide usage, install licensed to a location on `$PATH`, e.g. `/usr/loc
|
|
50
50
|
|
51
51
|
#### Dependencies
|
52
52
|
|
53
|
-
Licensed uses the
|
53
|
+
Licensed uses the `libgit2` bindings for Ruby provided by `rugged`. `rugged` has its own dependencies - `cmake` and `pkg-config` - which you may need to install before you can install Licensed.
|
54
54
|
|
55
55
|
For example, on macOS with Homebrew: `brew install cmake pkg-config` and on Ubuntu: `apt-get install cmake pkg-config`.
|
56
56
|
|
@@ -63,6 +63,10 @@ For example, on macOS with Homebrew: `brew install cmake pkg-config` and on Ubun
|
|
63
63
|
|
64
64
|
See the [commands documentation](./docs/commands.md) for additional documentation, or run `licensed -h` to see all of the current available commands.
|
65
65
|
|
66
|
+
### Automation
|
67
|
+
|
68
|
+
The [bundler-licensed plugin](https://github.com/sergey-alekseev/bundler-licensed) runs `licensed cache` automatically when using `bundler`. See the linked repo for usage and details.
|
69
|
+
|
66
70
|
### Configuration
|
67
71
|
|
68
72
|
All commands, except `version`, accept a `-c|--config` option to specify a path to a configuration file or directory.
|
@@ -90,6 +94,7 @@ Dependencies will be automatically detected for all of the following sources by
|
|
90
94
|
1. [Pip](./docs/sources/pip.md)
|
91
95
|
1. [Pipenv](./docs/sources/pipenv.md)
|
92
96
|
1. [Git Submodules (git_submodule)](./docs/sources/git_submodule.md)
|
97
|
+
1. [Mix](./docs/sources/mix.md)
|
93
98
|
|
94
99
|
You can disable any of them in the configuration file:
|
95
100
|
|
data/docs/configuration.md
CHANGED
@@ -87,6 +87,7 @@ allowed:
|
|
87
87
|
- cc0-1.0
|
88
88
|
|
89
89
|
# These dependencies are explicitly ignored.
|
90
|
+
# They shouldn't be cached at all, and will not have cached metadata written to the repo.
|
90
91
|
ignored:
|
91
92
|
bundler:
|
92
93
|
- some-internal-gem
|
@@ -95,6 +96,7 @@ ignored:
|
|
95
96
|
- some-internal-package
|
96
97
|
|
97
98
|
# These dependencies have been reviewed.
|
99
|
+
# They need to be cached and checked, but do not have a license found that matches the allowed configured licenses.
|
98
100
|
reviewed:
|
99
101
|
bundler:
|
100
102
|
- bcrypt-ruby
|
data/docs/sources/mix.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Mix
|
2
|
+
|
3
|
+
The mix source will detect `mix.lock` lockfiles, and parse their contents to enumerate dependencies.
|
4
|
+
|
5
|
+
The `mix` CLI tool itself isn't used to extract dependency data, and no project compilation occurs during license extraction, but your dependencies should be present in your project `deps/` directory, as is conventional with Elixir projects.
|
6
|
+
|
7
|
+
## Installing Dependencies
|
8
|
+
|
9
|
+
Your project should contain a `deps/` directory containing the dependency sources. You can download your dependencies (which are defined in `mix.exs`) using `mix`:
|
10
|
+
|
11
|
+
```
|
12
|
+
mix deps.get
|
13
|
+
```
|
14
|
+
|
15
|
+
This will create your `mix.lock` lockfile if needed.
|
16
|
+
|
17
|
+
Be sure to re-run this command whenever your `mix.exs` dependencies change to update your lockfile and dependency sources.
|
18
|
+
|
19
|
+
## Limitations
|
20
|
+
|
21
|
+
Because `mix deps.get` does not generate `mix.lock` entries for `:path` dependencies (nor are they stored in `deps/`), license information is not extracted from them.
|
22
|
+
|
23
|
+
If you need to extract license information from dependencies from another local directory (that is a Git repository), consider using a `:git` dependency with a file path in your `mix.exs`.
|
data/lib/licensed/sources.rb
CHANGED
@@ -0,0 +1,194 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Licensed
|
4
|
+
module Sources
|
5
|
+
class Mix < Source
|
6
|
+
|
7
|
+
LOCKFILE = "mix.lock"
|
8
|
+
|
9
|
+
# Returns whether a mix.lock is present
|
10
|
+
def enabled?
|
11
|
+
File.exist?(lockfile_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def enumerate_dependencies
|
15
|
+
find_packages.map do |package|
|
16
|
+
convert_package_to_dependency(package)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# Returns the parsed mix.lock information as an Array of Hash objects.
|
23
|
+
def find_packages
|
24
|
+
LockfileParser.read(lockfile_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the absolute path to the mix.lock as a Pathname.
|
28
|
+
def lockfile_path
|
29
|
+
config.pwd.join(LOCKFILE)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Converts a raw package representation to a dependency.
|
33
|
+
#
|
34
|
+
# name - The name of the package as a String.
|
35
|
+
# pkg - The parsed package data as a Hash.
|
36
|
+
#
|
37
|
+
# Returns a Dependency.
|
38
|
+
def convert_package_to_dependency(pkg)
|
39
|
+
path, errors = check_dep_path(pkg)
|
40
|
+
Dependency.new(
|
41
|
+
name: pkg[:name],
|
42
|
+
version: pkg[:version],
|
43
|
+
path: path,
|
44
|
+
metadata: pkg[:metadata].merge("type" => self.class.type),
|
45
|
+
errors: errors + Array(pkg[:error])
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Check that the package has been installed in deps/.
|
50
|
+
#
|
51
|
+
# pkg - The package information as a Hash
|
52
|
+
#
|
53
|
+
# Returns an Array with two members; the path as a String and an Array of
|
54
|
+
# any errors.
|
55
|
+
def check_dep_path(pkg)
|
56
|
+
path = dep_path(pkg[:name])
|
57
|
+
if File.directory?(path)
|
58
|
+
return [path, []]
|
59
|
+
else
|
60
|
+
return [path, ["Not installed by `mix deps.get` in deps/"]]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Generate the absolute path to the named package.
|
65
|
+
#
|
66
|
+
# name - The name of the package dependency as a String.
|
67
|
+
#
|
68
|
+
# Returns a Pathname.
|
69
|
+
def dep_path(name)
|
70
|
+
config.pwd.join("deps", name)
|
71
|
+
end
|
72
|
+
|
73
|
+
class LockfileParser
|
74
|
+
|
75
|
+
class ParseError < RuntimeError; end
|
76
|
+
|
77
|
+
# Top-level pattern extracting the name and Mix.SCM type
|
78
|
+
LINE_PATTERN = /
|
79
|
+
\A # At the beginning of input
|
80
|
+
\s* # after any number of spaces
|
81
|
+
"(?<name>.*?)" # capture the contents of a double-quoted string as the name
|
82
|
+
:\s*\{ # then skipping a colon, any number of spaces, and an opening brace,
|
83
|
+
:(?<scm>hex|git) # capture the contents of a Elixir atom as the scm
|
84
|
+
,\s* # and, skipping a comma and any number of spaces,
|
85
|
+
(?<contents>.*) # capture the rest of input as the contents.
|
86
|
+
/x
|
87
|
+
|
88
|
+
# Patterns to extract the version and repo information for each Mix.SCM type.
|
89
|
+
SCM_PATTERN = {
|
90
|
+
# The Hex Package Manager
|
91
|
+
"hex" => /
|
92
|
+
\A # At the beginning of input
|
93
|
+
:[a-zA-Z0-9_]+ # after an Elixir atom,
|
94
|
+
,\s* # and skipping a comma and any number of spaces,
|
95
|
+
"(?<version>.*?)" # capture the contents of a double-quoted string as the version,
|
96
|
+
.* # and later
|
97
|
+
"(?<repo>.*?)" # capture the contents of a double-quoted string as the repo
|
98
|
+
\},?\s*\Z # right before the final closing brace.
|
99
|
+
/x,
|
100
|
+
|
101
|
+
# Git
|
102
|
+
"git" => /
|
103
|
+
\A # At the beginning of input
|
104
|
+
"(?<repo>.*?)" # capture the contents of a double-quoted string as the repo
|
105
|
+
,\s* # and, skipping a comma and any number of spaces,
|
106
|
+
"(?<version>.*?)" # capture the contents of a second double-quoted string as the version.
|
107
|
+
/x
|
108
|
+
}
|
109
|
+
|
110
|
+
# Parses a mix.lock to extract raw package information.
|
111
|
+
#
|
112
|
+
# path - The path to the mix.lock as a Pathname or String.
|
113
|
+
#
|
114
|
+
# Returns an Array of Hash package entries, or raises a ParserError if
|
115
|
+
# unsuccessful.
|
116
|
+
def self.read(path)
|
117
|
+
lines = File.readlines(path)
|
118
|
+
new(lines).result
|
119
|
+
end
|
120
|
+
|
121
|
+
def initialize(lines)
|
122
|
+
@lines = lines
|
123
|
+
end
|
124
|
+
|
125
|
+
# Parses the input lines.
|
126
|
+
#
|
127
|
+
# Returns an Array of Hash package entries, or raises a ParseError if
|
128
|
+
# unsuccessful.
|
129
|
+
def result
|
130
|
+
# Ignore the first and last lines of the file (the beginning and
|
131
|
+
# ending of the enclosing map).
|
132
|
+
@lines[1..-2].map do |line|
|
133
|
+
parse_line(line)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
# Parse a line from the mix.lock file.
|
140
|
+
#
|
141
|
+
# line - A line of input as a String.
|
142
|
+
#
|
143
|
+
# Returns a Hash package entry, or raises a ParserError if unsuccessful.
|
144
|
+
def parse_line(line)
|
145
|
+
match = LINE_PATTERN.match(line)
|
146
|
+
if match
|
147
|
+
data = SCM_PATTERN[match[:scm]].match(match[:contents])
|
148
|
+
if data
|
149
|
+
valid_package_entry(match, data)
|
150
|
+
else
|
151
|
+
invalid_package_entry(match, line)
|
152
|
+
end
|
153
|
+
else
|
154
|
+
raise Licensed::Sources::Source::Error, "Unknown mix.lock line format: #{line}"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Format a valid package entry.
|
159
|
+
#
|
160
|
+
# match - A MatchData containing name and scm information.
|
161
|
+
# data - A MatchData containing version and repo information.
|
162
|
+
#
|
163
|
+
# Returns a Hash representing the package.
|
164
|
+
def valid_package_entry(match, data)
|
165
|
+
{
|
166
|
+
name: match[:name],
|
167
|
+
version: data[:version],
|
168
|
+
metadata: {
|
169
|
+
"scm" => match[:scm],
|
170
|
+
"repo" => data[:repo]
|
171
|
+
}
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
# Format an invalid package entry.
|
176
|
+
#
|
177
|
+
# match - A MatchData containing name and scm information.
|
178
|
+
# line - The line from mix.lock that could not be parsed, as a String.
|
179
|
+
#
|
180
|
+
# Returns a Hash representing the package, with error information.
|
181
|
+
def invalid_package_entry(match, line)
|
182
|
+
{
|
183
|
+
name: match[:name],
|
184
|
+
version: nil,
|
185
|
+
metadata: {
|
186
|
+
"scm" => match[:scm]
|
187
|
+
},
|
188
|
+
error: "Could not extract data from mix.lock line: #{line}"
|
189
|
+
}
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
data/lib/licensed/version.rb
CHANGED
data/script/source-setup/cabal
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -e
|
3
|
+
|
4
|
+
if [ -z "$(which mix)" ]; then
|
5
|
+
echo "A local mix installation is required for elixir development." >&2
|
6
|
+
exit 127
|
7
|
+
fi
|
8
|
+
|
9
|
+
# setup test fixtures
|
10
|
+
BASE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
11
|
+
cd $BASE_PATH/test/fixtures/mix
|
12
|
+
|
13
|
+
if [ "$1" == "-f" ]; then
|
14
|
+
echo "removing old fixture setup..."
|
15
|
+
mix deps.clean --all || true
|
16
|
+
mix clean || true
|
17
|
+
fi
|
18
|
+
|
19
|
+
mix deps.get
|
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.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: licensee
|
@@ -235,6 +235,7 @@ files:
|
|
235
235
|
- docs/sources/go.md
|
236
236
|
- docs/sources/gradle.md
|
237
237
|
- docs/sources/manifests.md
|
238
|
+
- docs/sources/mix.md
|
238
239
|
- docs/sources/npm.md
|
239
240
|
- docs/sources/pip.md
|
240
241
|
- docs/sources/pipenv.md
|
@@ -273,6 +274,7 @@ files:
|
|
273
274
|
- lib/licensed/sources/gradle.rb
|
274
275
|
- lib/licensed/sources/helpers/content_versioning.rb
|
275
276
|
- lib/licensed/sources/manifest.rb
|
277
|
+
- lib/licensed/sources/mix.rb
|
276
278
|
- lib/licensed/sources/npm.rb
|
277
279
|
- lib/licensed/sources/pip.rb
|
278
280
|
- lib/licensed/sources/pipenv.rb
|
@@ -294,6 +296,7 @@ files:
|
|
294
296
|
- script/source-setup/composer
|
295
297
|
- script/source-setup/git_submodule
|
296
298
|
- script/source-setup/go
|
299
|
+
- script/source-setup/mix
|
297
300
|
- script/source-setup/npm
|
298
301
|
- script/source-setup/pip
|
299
302
|
- script/source-setup/pipenv
|
@@ -317,8 +320,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
317
320
|
- !ruby/object:Gem::Version
|
318
321
|
version: '0'
|
319
322
|
requirements: []
|
320
|
-
|
321
|
-
rubygems_version: 2.6.8
|
323
|
+
rubygems_version: 3.0.3
|
322
324
|
signing_key:
|
323
325
|
specification_version: 4
|
324
326
|
summary: Extract and validate the licenses of dependencies.
|