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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 45476f98c8dd054a36758218f6337826e90b1112
4
- data.tar.gz: e040ac55ae8dbd3b7dd498318b8046a271c58832
2
+ SHA256:
3
+ metadata.gz: 94e3cbc840104e6f0d4733c82ea38805aa2db680070708b88f107420405a1956
4
+ data.tar.gz: d04aea6f7ac531c7ab5826b90ece5f3bd0936845a7d8a0e0e44d54c7119e9f08
5
5
  SHA512:
6
- metadata.gz: 6773ae7dc4f41afd8f0597c11e3ea4bda59c10de44654c9fd9b6b91bce6f2a0b0b092ecccb95dc39ce6da5678736672d6fb3fa9b48b47bf82eb1758cecc91297
7
- data.tar.gz: 80c82cfccb88980bc3b1b04da520e740683bb18d52cc3dcc5e60801e529f5c926d64c9df80a24dfc431e4ff2271a4fef67389b7bf4b9779edd7aeb739d015036
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
- - uses: actions/bin/filter@master
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 "$GEM"
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
@@ -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
@@ -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.5.0...HEAD
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-2018 GitHub, Inc. and contributors
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 whats changed.
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 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.
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
 
@@ -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
@@ -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`.
@@ -14,5 +14,6 @@ module Licensed
14
14
  require "licensed/sources/pip"
15
15
  require "licensed/sources/pipenv"
16
16
  require "licensed/sources/gradle"
17
+ require "licensed/sources/mix"
17
18
  end
18
19
  end
@@ -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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Licensed
3
- VERSION = "2.5.0".freeze
3
+ VERSION = "2.6.0".freeze
4
4
 
5
5
  def self.previous_major_versions
6
6
  major_version = Gem::Version.new(Licensed::VERSION).segments.first
@@ -16,4 +16,4 @@ if [ "$1" == "-f" ]; then
16
16
  find . -not -regex "\.*" -and -not -path "*app*" -print0 | xargs -0 rm -rf
17
17
  fi
18
18
 
19
- cabal new-build || (cabal update && cabal install)
19
+ (cabal new-update && cabal new-build) || (cabal update && cabal install)
@@ -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.5.0
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-09-27 00:00:00.000000000 Z
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
- rubyforge_project:
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.