license_scout 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/appveyor.yml +19 -0
- data/lib/license_scout/canonical_licenses/BSD-4-Clause.txt +31 -0
- data/lib/license_scout/canonical_licenses/ISC.txt +14 -0
- data/lib/license_scout/canonical_licenses/MIT.txt +20 -0
- data/lib/license_scout/collector.rb +3 -3
- data/lib/license_scout/dependency.rb +14 -1
- data/lib/license_scout/dependency_manager/base.rb +11 -0
- data/lib/license_scout/dependency_manager/berkshelf.rb +1 -1
- data/lib/license_scout/dependency_manager/bundler.rb +1 -1
- data/lib/license_scout/dependency_manager/cpan.rb +2 -1
- data/lib/license_scout/dependency_manager/manual.rb +67 -0
- data/lib/license_scout/dependency_manager/npm.rb +166 -0
- data/lib/license_scout/dependency_manager/rebar.rb +1 -1
- data/lib/license_scout/dependency_manager.rb +3 -1
- data/lib/license_scout/exceptions.rb +1 -0
- data/lib/license_scout/options.rb +2 -1
- data/lib/license_scout/overrides.rb +152 -2
- data/lib/license_scout/reporter.rb +38 -17
- data/lib/license_scout/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83b949a77e7dcd991b2de72715882700e160e0eb
|
4
|
+
data.tar.gz: 0f5275681d5db4fe0f6ea19db30131a739d63de1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6835e670ec069a60fee4b27e5042217c79b59470103d62a4b3c316733edcbf2e12b9bc024250bad67f0a7e6b11cb537449e74ff1a4c55d6ea66e3d61985705a3
|
7
|
+
data.tar.gz: bc383bdc559ad4dc050564647a14674c5667d63fcf64722dac82e201ec08c114cbc277591c9417b25b6b31a10018ec9c1774e1b5648cff9e74f426a666424a11
|
data/appveyor.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
os: Windows Server 2012 R2
|
2
|
+
platform:
|
3
|
+
- x64
|
4
|
+
|
5
|
+
skip_tags: true
|
6
|
+
branches:
|
7
|
+
only:
|
8
|
+
- master
|
9
|
+
|
10
|
+
install:
|
11
|
+
- set PATH=C:\Ruby22\bin;%PATH%
|
12
|
+
- appveyor DownloadFile http://curl.haxx.se/ca/cacert.pem -FileName C:\cacert.pem
|
13
|
+
- set SSL_CERT_FILE=C:\cacert.pem
|
14
|
+
|
15
|
+
build_script:
|
16
|
+
- bundle install || bundle install || bundle install
|
17
|
+
|
18
|
+
test_script:
|
19
|
+
- bundle exec rake spec
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Copyright (c) <year> <owner> . All rights reserved.
|
2
|
+
Redistribution and use in source and binary forms, with or without
|
3
|
+
modification, are permitted provided that the following conditions are met:
|
4
|
+
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
6
|
+
list of conditions and the following disclaimer.
|
7
|
+
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
9
|
+
this list of conditions and the following disclaimer in the documentation
|
10
|
+
and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
3. All advertising materials mentioning features or use of this software must
|
13
|
+
display the following acknowledgement: This product includes software developed
|
14
|
+
by the the organization .
|
15
|
+
|
16
|
+
4. Neither the name of the copyright holder nor the names of its contributors
|
17
|
+
may be used to endorse or promote products derived from this software without
|
18
|
+
specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
|
21
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
22
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
23
|
+
EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
25
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
26
|
+
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
27
|
+
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
ISC License (ISC)
|
2
|
+
Copyright (c) 4-digit year, Company or Person's Name <E-mail address>
|
3
|
+
|
4
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
5
|
+
purpose with or without fee is hereby granted, provided that the above
|
6
|
+
copyright notice and this permission notice appear in all copies.
|
7
|
+
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
9
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
10
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
11
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
12
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
13
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
14
|
+
PERFORMANCE OF THIS SOFTWARE.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
MIT License
|
2
|
+
Copyright (c) <year> <copyright holders>
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
|
+
this software and associated documentation files (the "Software"), to deal in
|
6
|
+
the Software without restriction, including without limitation the rights to
|
7
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
8
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
9
|
+
so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
12
|
+
copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
SOFTWARE.
|
@@ -78,9 +78,9 @@ module LicenseScout
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def collect_licenses_from(dependency_manager)
|
81
|
-
license_manifest_data[:dependency_managers][dependency_manager.name] = []
|
82
|
-
|
83
81
|
dependency_manager.dependencies.each do |dep|
|
82
|
+
license_manifest_data[:dependency_managers][dep.dep_mgr_name] ||= []
|
83
|
+
|
84
84
|
license_data = {
|
85
85
|
name: dep.name,
|
86
86
|
version: dep.version,
|
@@ -101,7 +101,7 @@ module LicenseScout
|
|
101
101
|
license_data[:license_files] << output_license_filename
|
102
102
|
end
|
103
103
|
|
104
|
-
license_manifest_data[:dependency_managers][
|
104
|
+
license_manifest_data[:dependency_managers][dep.dep_mgr_name] << license_data
|
105
105
|
|
106
106
|
end
|
107
107
|
end
|
@@ -16,5 +16,18 @@
|
|
16
16
|
#
|
17
17
|
|
18
18
|
module LicenseScout
|
19
|
-
Dependency = Struct.new(:name, :version, :license, :license_files)
|
19
|
+
Dependency = Struct.new(:name, :version, :license, :license_files, :dep_mgr_name) do
|
20
|
+
|
21
|
+
def eql?(other)
|
22
|
+
other.kind_of?(self.class) && other.hash == hash
|
23
|
+
end
|
24
|
+
|
25
|
+
# hash code for when Dependency is used as a key in a Hash or member of a
|
26
|
+
# Set. The implementation is somewhat naive, but will work fine if you
|
27
|
+
# don't go too crazy mixing different types.
|
28
|
+
def hash
|
29
|
+
[dep_mgr_name, name, version, license].hash
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
20
33
|
end
|
@@ -33,13 +33,19 @@ module LicenseScout
|
|
33
33
|
License.rdoc
|
34
34
|
Licence.rdoc
|
35
35
|
Licence.md
|
36
|
+
license
|
37
|
+
LICENCE
|
38
|
+
licence
|
36
39
|
MIT-LICENSE
|
37
40
|
MIT-LICENSE.txt
|
38
41
|
LICENSE.MIT
|
42
|
+
LICENSE-MIT
|
43
|
+
LICENSE-MIT.txt
|
39
44
|
LGPL-2.1
|
40
45
|
COPYING.txt
|
41
46
|
COPYING
|
42
47
|
BSD_LICENSE
|
48
|
+
LICENSE.BSD
|
43
49
|
}
|
44
50
|
|
45
51
|
attr_reader :project_dir
|
@@ -50,6 +56,11 @@ module LicenseScout
|
|
50
56
|
@options = options
|
51
57
|
end
|
52
58
|
|
59
|
+
def create_dependency(dep_name, version, license, license_files, dep_mgr_name = self.name)
|
60
|
+
# add name of the dependency manager `name` to the dependency we are
|
61
|
+
# creating.
|
62
|
+
Dependency.new(dep_name, version, license, license_files, dep_mgr_name)
|
63
|
+
end
|
53
64
|
end
|
54
65
|
end
|
55
66
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright 2016, Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "license_scout/dependency_manager/base"
|
19
|
+
require "license_scout/dependency"
|
20
|
+
require "license_scout/overrides"
|
21
|
+
|
22
|
+
module LicenseScout
|
23
|
+
module DependencyManager
|
24
|
+
class Manual < Base
|
25
|
+
def name
|
26
|
+
"manual"
|
27
|
+
end
|
28
|
+
|
29
|
+
def detected?
|
30
|
+
!options.manual_licenses.nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
def dependencies
|
34
|
+
validate_input!
|
35
|
+
|
36
|
+
options.manual_licenses.map do |d|
|
37
|
+
create_dependency(
|
38
|
+
d[:name],
|
39
|
+
d[:version],
|
40
|
+
d[:license],
|
41
|
+
resolve_license_file_locations(d[:license_files]),
|
42
|
+
d[:dependency_manager]
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def resolve_license_file_locations(license_files)
|
48
|
+
LicenseScout::Overrides::OverrideLicenseSet.new(license_files)
|
49
|
+
.resolve_locations(project_dir)
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate_input!
|
53
|
+
if !options.manual_licenses.is_a?(Array)
|
54
|
+
raise LicenseScout::Exceptions::InvalidManualDependency.new("Invalid manual dependency is specified. :manual_licenses should be an Array in options.")
|
55
|
+
end
|
56
|
+
|
57
|
+
options.manual_licenses.each do |l|
|
58
|
+
l.keys.each do |k|
|
59
|
+
if ![:name, :version, :license, :license_files, :dependency_manager].include?(k)
|
60
|
+
raise LicenseScout::Exceptions::InvalidManualDependency.new("Invalid manual dependency is specified. Key '#{k}' is not supported.")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright 2016, Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "set"
|
19
|
+
require "ffi_yajl"
|
20
|
+
require "license_scout/dependency_manager/base"
|
21
|
+
|
22
|
+
module LicenseScout
|
23
|
+
module DependencyManager
|
24
|
+
class NPM < Base
|
25
|
+
|
26
|
+
def name
|
27
|
+
"js_npm"
|
28
|
+
end
|
29
|
+
|
30
|
+
def detected?
|
31
|
+
File.exist?(root_node_modules_path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def dependencies
|
35
|
+
packages = all_package_json_files.inject(Set.new) do |package_set, package_json_file|
|
36
|
+
pkg_info = File.open(package_json_file) do |f|
|
37
|
+
FFI_Yajl::Parser.parse(f)
|
38
|
+
end
|
39
|
+
|
40
|
+
pkg_name = pkg_info["name"]
|
41
|
+
pkg_version = pkg_info["version"]
|
42
|
+
package_path = File.dirname(package_json_file)
|
43
|
+
|
44
|
+
license = options.overrides.license_for(name, pkg_name, pkg_version) ||
|
45
|
+
normalize_license_data(pkg_info["license"] || pkg_info["licence"] || pkg_info["licenses"])
|
46
|
+
|
47
|
+
override_license_files = options.overrides.license_files_for(name, pkg_name, pkg_version)
|
48
|
+
if override_license_files.empty?
|
49
|
+
license_files = find_license_files_in(package_path)
|
50
|
+
else
|
51
|
+
license_files = override_license_files.resolve_locations(package_path)
|
52
|
+
end
|
53
|
+
|
54
|
+
package_set << create_dependency(
|
55
|
+
pkg_name,
|
56
|
+
pkg_version,
|
57
|
+
license,
|
58
|
+
license_files
|
59
|
+
)
|
60
|
+
end
|
61
|
+
packages.to_a
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# List all the package.json files in the project
|
67
|
+
#
|
68
|
+
# It would be easier to implement this with a dir glob using the `**`
|
69
|
+
# metacharacter, but that approach will find "fake" packages that exist
|
70
|
+
# as test fixtures inside a package. For example, one of our projects,
|
71
|
+
# the 'module-deps' package contains a file
|
72
|
+
# `test/files/tr_2dep_module/node_modules/g/package.json` which isn't a
|
73
|
+
# "real" package. Therefore we do our own looping to traverse the
|
74
|
+
# directories; at each step we look for `$PACKAGE_PATH/node_modules/*` to
|
75
|
+
# find the next level of modules. This approach can miss cases where the
|
76
|
+
# package authors have vendored packages in a directory not named
|
77
|
+
# `node_modules`, but this case is rare and doesn't have a satisfactory
|
78
|
+
# general solution (e.g., we cannot detect a vendored package if the
|
79
|
+
# package metadata is removed).
|
80
|
+
def all_package_json_files
|
81
|
+
all_files = []
|
82
|
+
package_dirs = [project_dir]
|
83
|
+
loop do
|
84
|
+
break if package_dirs.empty?
|
85
|
+
|
86
|
+
package_dir = package_dirs.pop
|
87
|
+
package_json_path = File.join(package_dir, "package.json")
|
88
|
+
|
89
|
+
all_files << package_json_path if File.exist?(package_json_path)
|
90
|
+
|
91
|
+
node_modules_dir = File.join(package_dir, "node_modules")
|
92
|
+
if File.exist?(node_modules_dir)
|
93
|
+
# Sort makes deduplication of identical deps deterministic
|
94
|
+
package_dirs.concat(Dir[File.join(node_modules_dir, "*")].sort)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
all_files
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_license_files_in(dir)
|
102
|
+
root_files = Dir["#{dir}/*"]
|
103
|
+
root_files.select { |f| POSSIBLE_LICENSE_FILES.include?(File.basename(f)) }
|
104
|
+
end
|
105
|
+
|
106
|
+
def normalize_license_data(license_metadata)
|
107
|
+
license_string =
|
108
|
+
case license_metadata
|
109
|
+
when nil
|
110
|
+
nil
|
111
|
+
when String
|
112
|
+
license_metadata
|
113
|
+
when Hash
|
114
|
+
license_metadata["type"]
|
115
|
+
when Array
|
116
|
+
if (map = license_metadata.first) && map.kind_of?(Hash) && (type = map["type"])
|
117
|
+
type
|
118
|
+
else
|
119
|
+
nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
select_best_license(license_string)
|
123
|
+
end
|
124
|
+
|
125
|
+
# npm packages use SPDX "expressions" for their licenses; Thus far we've
|
126
|
+
# only seen a single license, optional multiple licenses like "(MIT OR Apache-2.0)"
|
127
|
+
# or mandatory multiple licenses like "(MIT AND CC-BY-3.0)"
|
128
|
+
#
|
129
|
+
# If there are multiple options, we want to pick just one to keep it simple.
|
130
|
+
def select_best_license(license_string)
|
131
|
+
return nil if license_string.nil?
|
132
|
+
options = license_string.tr("(", "").tr(")", "").split(" OR ")
|
133
|
+
options.inject do |selected_license, license|
|
134
|
+
if license_rank(selected_license) < license_rank(license)
|
135
|
+
selected_license
|
136
|
+
else
|
137
|
+
license
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Rank licenses when selecting one of multiple options. Licenses are
|
143
|
+
# converted to integer scores, the lower the better.
|
144
|
+
#
|
145
|
+
# We prefer Apache-2.0 since it matches our own projects, then MIT, then
|
146
|
+
# BSDs. Everything else is considered equal.
|
147
|
+
def license_rank(license)
|
148
|
+
case license
|
149
|
+
when "Apache-2.0"
|
150
|
+
0
|
151
|
+
when "MIT"
|
152
|
+
1
|
153
|
+
when /bsd/i
|
154
|
+
2
|
155
|
+
else
|
156
|
+
3
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def root_node_modules_path
|
161
|
+
File.join(project_dir, "node_modules")
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -84,7 +84,7 @@ module LicenseScout
|
|
84
84
|
|
85
85
|
license_name = options.overrides.license_for(name, dep_name, dep_version) || scan_licenses(license_files)
|
86
86
|
|
87
|
-
dep =
|
87
|
+
dep = create_dependency(dep_name, dep_version, license_name, license_files)
|
88
88
|
|
89
89
|
dependencies << dep
|
90
90
|
end
|
@@ -19,11 +19,13 @@ require "license_scout/dependency_manager/bundler"
|
|
19
19
|
require "license_scout/dependency_manager/rebar"
|
20
20
|
require "license_scout/dependency_manager/cpan"
|
21
21
|
require "license_scout/dependency_manager/berkshelf"
|
22
|
+
require "license_scout/dependency_manager/npm"
|
23
|
+
require "license_scout/dependency_manager/manual"
|
22
24
|
|
23
25
|
module LicenseScout
|
24
26
|
module DependencyManager
|
25
27
|
def self.implementations
|
26
|
-
[Bundler, Rebar, CPAN, Berkshelf]
|
28
|
+
[Bundler, Rebar, CPAN, Berkshelf, NPM, Manual]
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
@@ -19,7 +19,7 @@ require "license_scout/overrides"
|
|
19
19
|
|
20
20
|
module LicenseScout
|
21
21
|
class Options
|
22
|
-
SUPPORTED_OPTIONS = [:overrides, :environment, :ruby_bin, :cpan_cache]
|
22
|
+
SUPPORTED_OPTIONS = [:overrides, :environment, :ruby_bin, :cpan_cache, :manual_licenses]
|
23
23
|
|
24
24
|
SUPPORTED_OPTIONS.each do |o|
|
25
25
|
self.send(:attr_reader, o)
|
@@ -40,6 +40,7 @@ module LicenseScout
|
|
40
40
|
environment: {},
|
41
41
|
ruby_bin: nil,
|
42
42
|
cpan_cache: Dir.tmpdir,
|
43
|
+
manual_licenses: nil,
|
43
44
|
}
|
44
45
|
end
|
45
46
|
end
|
@@ -58,11 +58,11 @@ module LicenseScout
|
|
58
58
|
|
59
59
|
attr_reader :override_rules
|
60
60
|
|
61
|
-
def initialize(&rules)
|
61
|
+
def initialize(exclude_default: false, &rules)
|
62
62
|
@override_rules = {}
|
63
63
|
instance_eval(&rules) if block_given?
|
64
64
|
|
65
|
-
default_overrides
|
65
|
+
default_overrides unless exclude_default
|
66
66
|
end
|
67
67
|
|
68
68
|
def override_license(dependency_manager, dependency_name, &rule)
|
@@ -91,6 +91,10 @@ module LicenseScout
|
|
91
91
|
override_rules[dependency_manager][dependency_name].call(dependency_version)
|
92
92
|
end
|
93
93
|
|
94
|
+
def canonical(shortname)
|
95
|
+
File.expand_path("../canonical_licenses/#{shortname}.txt", __FILE__)
|
96
|
+
end
|
97
|
+
|
94
98
|
def default_overrides
|
95
99
|
# Default overrides for ruby_bundler dependency manager.
|
96
100
|
[
|
@@ -143,6 +147,7 @@ module LicenseScout
|
|
143
147
|
["knife-opc", "Apache-2.0", nil],
|
144
148
|
["highline", "Ruby", ["LICENSE"]],
|
145
149
|
["unicorn", "Ruby", ["LICENSE"]],
|
150
|
+
["winrm-fs", "Apache-2.0", nil],
|
146
151
|
# Overrides that require file fetching from internet
|
147
152
|
["sfl", "Ruby", ["https://raw.githubusercontent.com/ujihisa/spawn-for-legacy/master/LICENCE.md"]],
|
148
153
|
["json_pure", nil, ["https://raw.githubusercontent.com/flori/json/master/README.md"]],
|
@@ -189,6 +194,7 @@ module LicenseScout
|
|
189
194
|
["rails", nil, ["https://raw.githubusercontent.com/rails/rails/master/README.md"]],
|
190
195
|
["unicorn-rails", "MIT", ["https://raw.githubusercontent.com/samuelkadolph/unicorn-rails/master/LICENSE"]],
|
191
196
|
["hoe", "MIT", ["https://raw.githubusercontent.com/seattlerb/hoe/master/README.rdoc"]],
|
197
|
+
["rubyzip", nil, ["https://raw.githubusercontent.com/rubyzip/rubyzip/master/README.md"]],
|
192
198
|
].each do |override_data|
|
193
199
|
override_license "ruby_bundler", override_data[0] do |version|
|
194
200
|
{}.tap do |d|
|
@@ -198,6 +204,7 @@ module LicenseScout
|
|
198
204
|
end
|
199
205
|
end
|
200
206
|
|
207
|
+
# chef_berkshelf
|
201
208
|
[
|
202
209
|
["apt", nil, ["https://raw.githubusercontent.com/chef-cookbooks/apt/master/LICENSE"]],
|
203
210
|
["chef-ha-drbd", nil, ["https://raw.githubusercontent.com/chef/chef-server/master/LICENSE"]],
|
@@ -286,6 +293,7 @@ module LicenseScout
|
|
286
293
|
end
|
287
294
|
end
|
288
295
|
|
296
|
+
# erlang_rebar
|
289
297
|
[
|
290
298
|
["sync", "MIT", ["https://raw.githubusercontent.com/rustyio/sync/11df81d196eaab2d84caa3fbe8def5d476ef79d8/src/sync.erl"]],
|
291
299
|
["rebar_vsn_plugin", "Apache-2.0", ["https://raw.githubusercontent.com/erlware/rebar_vsn_plugin/master/src/rebar_vsn_plugin.erl"]],
|
@@ -299,6 +307,10 @@ module LicenseScout
|
|
299
307
|
["rabbit_common", "MPL-2.0", ["https://raw.githubusercontent.com/muxspace/rabbit_common/master/include/rabbit_msg_store.hrl"]],
|
300
308
|
["uuid", "BSD-2-Clause", ["https://raw.githubusercontent.com/okeuday/uuid/master/README.markdown"]],
|
301
309
|
["ibrowse", "BSD-2-Clause", nil],
|
310
|
+
["eunit_formatters", "Apache-2.0", ["https://raw.githubusercontent.com/seancribbs/eunit_formatters/master/README.md"]],
|
311
|
+
["erlware_commons", "MIT", ["https://raw.githubusercontent.com/erlware/erlware_commons/master/COPYING"]],
|
312
|
+
["getopt", "MIT", nil],
|
313
|
+
["relx", "Apache-2.0", ["https://raw.githubusercontent.com/erlware/relx/master/LICENSE.md"]],
|
302
314
|
].each do |override_data|
|
303
315
|
override_license "erlang_rebar", override_data[0] do |version|
|
304
316
|
{}.tap do |d|
|
@@ -307,6 +319,144 @@ module LicenseScout
|
|
307
319
|
end
|
308
320
|
end
|
309
321
|
end
|
322
|
+
|
323
|
+
# js_npm
|
324
|
+
[
|
325
|
+
["isarray", nil, [canonical("MIT")]],
|
326
|
+
["array-filter", nil, [canonical("MIT")]],
|
327
|
+
["chokidar", nil, ["README.md"]],
|
328
|
+
["set-immediate-shim", "MIT", ["https://raw.githubusercontent.com/sindresorhus/set-immediate-shim/master/license"]],
|
329
|
+
["process-nextick-args", nil, [canonical("MIT")]],
|
330
|
+
["buffer-shims", nil, [canonical("MIT")]],
|
331
|
+
["brace-expansion", nil, ["README.md"]],
|
332
|
+
["verror", "MIT", ["https://github.com/joyent/node-verror/blob/master/LICENSE"]],
|
333
|
+
# From the json-schema readme:
|
334
|
+
# Code is licensed under the AFL or BSD license as part of the
|
335
|
+
# Persevere project which is administered under the Dojo foundation,
|
336
|
+
# and all contributions require a Dojo CLA.
|
337
|
+
["json-schema", "BSD", ["https://raw.githubusercontent.com/dojo/dojo/master/LICENSE"]],
|
338
|
+
["tweetnacl", "BSD", ["https://raw.githubusercontent.com/dchest/tweetnacl-js/master/COPYING.txt"]],
|
339
|
+
["assert-plus", "MIT", ["README.md"]],
|
340
|
+
["sntp", "BSD-3-Clause", nil],
|
341
|
+
["node-uuid", "MIT", nil],
|
342
|
+
["ms", "MIT", nil],
|
343
|
+
["jsonpointer", nil, ["https://raw.githubusercontent.com/janl/node-jsonpointer/master/LICENSE.md"]],
|
344
|
+
["has-color", nil, ["https://raw.githubusercontent.com/chalk/supports-color/master/license"]],
|
345
|
+
["generate-function", nil, ["https://github.com/mafintosh/generate-function/blob/master/LICENSE"]],
|
346
|
+
["extsprintf", "MIT", nil],
|
347
|
+
["debug", nil, ["README.md"]],
|
348
|
+
["dashdash", nil, ["https://raw.githubusercontent.com/trentm/node-dashdash/master/LICENSE.txt"]],
|
349
|
+
# The link here is what's included in the readme
|
350
|
+
["async-each", nil, ["https://raw.githubusercontent.com/paulmillr/mit/master/README.md"]],
|
351
|
+
# README on https://www.npmjs.com/package/indexof just says "MIT"
|
352
|
+
["indexof", "MIT", [canonical("MIT")]],
|
353
|
+
["querystring", "MIT", nil],
|
354
|
+
["timers-browserify", "MIT", nil],
|
355
|
+
["shell-quote", nil, ["https://raw.githubusercontent.com/substack/node-shell-quote/master/LICENSE"]],
|
356
|
+
["querystring-es3", "MIT", nil],
|
357
|
+
["xtend", "MIT", nil],
|
358
|
+
["source-map", nil, ["https://raw.githubusercontent.com/mozilla/source-map/master/LICENSE"]],
|
359
|
+
["randombytes", nil, [canonical("MIT")]],
|
360
|
+
["public-encrypt", nil, [canonical("MIT")]],
|
361
|
+
["parse-asn1", nil, [canonical("ISC")]],
|
362
|
+
["evp_bytestokey", nil, [canonical("MIT")]],
|
363
|
+
["cipher-base", nil, [canonical("MIT")]],
|
364
|
+
["asn1.js", nil, ["README.md"]],
|
365
|
+
["minimalistic-assert", nil, [canonical("ISC")]],
|
366
|
+
["bn.js", nil, ["README.md"]],
|
367
|
+
["diffie-hellman", nil, [canonical("MIT")]],
|
368
|
+
["miller-rabin", nil, ["README.md"]],
|
369
|
+
["brorand", nil, ["README.md"]],
|
370
|
+
["create-hmac", nil, [canonical("MIT")]],
|
371
|
+
["create-hash", nil, [canonical("MIT")]],
|
372
|
+
["ripemd160", nil, ["https://github.com/crypto-browserify/ripemd160/blob/master/LICENSE.md"]],
|
373
|
+
["create-ecdh", nil, [canonical("MIT")]],
|
374
|
+
["elliptic", nil, ["README.md"]],
|
375
|
+
["hash.js", nil, ["README.md"]],
|
376
|
+
["adm-zip", nil, ["https://raw.githubusercontent.com/cthackers/adm-zip/master/MIT-LICENSE.txt"]],
|
377
|
+
["after", "MIT", nil],
|
378
|
+
["agent-base", nil, ["README.md"]],
|
379
|
+
["angular-embedly", "BSD-2-Clause", nil],
|
380
|
+
["angular-feature-flags", nil, ["https://mjt01.mit-license.org/"]],
|
381
|
+
["angular-restmod", "MIT", nil],
|
382
|
+
["angular-spinner", nil, [canonical("MIT")]],
|
383
|
+
["ansi", "MIT", ["https://raw.githubusercontent.com/TooTallNate/ansi.js/master/LICENSE"]],
|
384
|
+
["ansi-regex", nil, ["https://raw.githubusercontent.com/chalk/ansi-regex/master/license"]],
|
385
|
+
["ansi-styles", nil, [canonical("MIT")]],
|
386
|
+
["ansi_up", "MIT", ["README.md"]],
|
387
|
+
["are-we-there-yet", nil, ["https://raw.githubusercontent.com/iarna/are-we-there-yet/master/LICENSE"]],
|
388
|
+
["arraybuffer.slice", "MIT", ["README.md"]],
|
389
|
+
["asn1", "MIT", nil],
|
390
|
+
["async-foreach", "MIT", nil],
|
391
|
+
["aws-sign2", "Apache-2.0", nil],
|
392
|
+
["babel", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
393
|
+
["babel-code-frame", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
394
|
+
["babel-core", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
395
|
+
["babel-generator", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
396
|
+
["babel-helper-call-delegate", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
397
|
+
["babel-helper-define-map", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
398
|
+
["babel-helper-function-name", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
399
|
+
["babel-helper-get-function-arity", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
400
|
+
["babel-helper-hoist-variables", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
401
|
+
["babel-helper-optimise-call-expression", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
402
|
+
["babel-helper-regex", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
403
|
+
["babel-helper-replace-supers", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
404
|
+
["babel-helpers", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
405
|
+
["babel-messages", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
406
|
+
["babel-plugin-check-es2015-constants", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
407
|
+
["babel-plugin-syntax-async-functions", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
408
|
+
["babel-plugin-transform-es2015-arrow-functions", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
409
|
+
["babel-plugin-transform-es2015-block-scoped-functions", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
410
|
+
["babel-plugin-transform-es2015-block-scoping", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
411
|
+
["babel-plugin-transform-es2015-classes", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
412
|
+
["babel-plugin-transform-es2015-computed-properties", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
413
|
+
["babel-plugin-transform-es2015-destructuring", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
414
|
+
["babel-plugin-transform-es2015-duplicate-keys", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
415
|
+
["babel-plugin-transform-es2015-for-of", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
416
|
+
["babel-plugin-transform-es2015-function-name", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
417
|
+
["babel-plugin-transform-es2015-literals", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
418
|
+
["babel-plugin-transform-es2015-modules-amd", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
419
|
+
["babel-plugin-transform-es2015-modules-commonjs", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
420
|
+
["babel-plugin-transform-es2015-modules-systemjs", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
421
|
+
["babel-plugin-transform-es2015-modules-umd", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
422
|
+
["babel-plugin-transform-es2015-object-super", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
423
|
+
["babel-plugin-transform-es2015-parameters", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
424
|
+
["babel-plugin-transform-es2015-shorthand-properties", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
425
|
+
["babel-plugin-transform-es2015-spread", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
426
|
+
["babel-plugin-transform-es2015-sticky-regex", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
427
|
+
["babel-plugin-transform-es2015-template-literals", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
428
|
+
["babel-plugin-transform-es2015-typeof-symbol", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
429
|
+
["babel-plugin-transform-es2015-unicode-regex", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
430
|
+
["babel-plugin-transform-strict-mode", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
431
|
+
["babel-preset-es2015", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
432
|
+
["babel-register", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
433
|
+
["babel-runtime", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
434
|
+
["babel-template", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
435
|
+
["babel-traverse", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
436
|
+
["babel-types", nil, ["https://raw.githubusercontent.com/babel/babel/master/LICENSE"]],
|
437
|
+
["backo2", nil, ["https://raw.githubusercontent.com/mokesmokes/backo/master/LICENSE"]],
|
438
|
+
["balanced-match", nil, ["https://raw.githubusercontent.com/juliangruber/balanced-match/master/LICENSE.md"]],
|
439
|
+
["base64id", "MIT", ["https://raw.githubusercontent.com/faeldt/base64id/master/LICENSE"]],
|
440
|
+
["batch", nil, ["README.md"]],
|
441
|
+
["bcrypt-pbkdf", nil, [canonical("BSD-4-Clause")]],
|
442
|
+
["better-assert", "MIT", ["https://raw.githubusercontent.com/tj/better-assert/master/LICENSE"]],
|
443
|
+
["binary", nil, [canonical("MIT")]],
|
444
|
+
["bindings", nil, ["README.md"]],
|
445
|
+
["blob", "MIT", ["https://raw.githubusercontent.com/webmodules/blob/master/LICENSE"]],
|
446
|
+
["bluebird", nil, ["https://github.com/petkaantonov/bluebird/blob/master/LICENSE"]],
|
447
|
+
["browserify-cipher", nil, [canonical("MIT")]],
|
448
|
+
["browserify-des", nil, [canonical("MIT")]],
|
449
|
+
["browserify-zlib", nil, ["https://raw.githubusercontent.com/devongovett/browserify-zlib/master/LICENSE"]],
|
450
|
+
["buffers", "MIT", [canonical("MIT")]],
|
451
|
+
["bufferutil", nil, [canonical("MIT")]],
|
452
|
+
].each do |override_data|
|
453
|
+
override_license "js_npm", override_data[0] do |version|
|
454
|
+
{}.tap do |d|
|
455
|
+
d[:license] = override_data[1] if override_data[1]
|
456
|
+
d[:license_files] = override_data[2] if override_data[2]
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
310
460
|
end
|
311
461
|
|
312
462
|
end
|
@@ -36,34 +36,55 @@ module LicenseScout
|
|
36
36
|
license_report = FFI_Yajl::Parser.parse(File.read(license_manifest_path))
|
37
37
|
|
38
38
|
license_report["dependency_managers"].each do |dependency_manager, dependencies|
|
39
|
-
dependencies.each do |dependency|
|
40
|
-
if dependency["name"].nil? || dependency["name"].empty?
|
41
|
-
report << "There is a dependency with a missing name in '#{dependency_manager}'."
|
42
|
-
end
|
43
39
|
|
44
|
-
|
45
|
-
report << "Dependency '#{dependency["name"]}' under '#{dependency_manager}' is missing version information."
|
46
|
-
end
|
40
|
+
ok_deps, problem_deps = 0, 0
|
47
41
|
|
48
|
-
|
49
|
-
|
50
|
-
end
|
42
|
+
dependencies.sort { |a, b| a["name"] <=> b["name"] }.each do |dependency|
|
43
|
+
dep_ok, problems = license_info_ok?(dependency_manager, dependency)
|
51
44
|
|
52
|
-
if
|
53
|
-
|
45
|
+
if dep_ok
|
46
|
+
ok_deps += 1
|
54
47
|
else
|
55
|
-
|
56
|
-
|
57
|
-
report << "License file '#{license_file}' for the dependency '#{dependency["name"]}' version '#{dependency["version"]}' under '#{dependency_manager}' is missing."
|
58
|
-
end
|
59
|
-
end
|
48
|
+
problem_deps += 1
|
49
|
+
report.concat(problems)
|
60
50
|
end
|
61
51
|
end
|
52
|
+
|
53
|
+
if problem_deps > 0
|
54
|
+
report << ">> Found #{dependencies.size} dependencies for #{dependency_manager}. #{ok_deps} OK, #{problem_deps} with problems"
|
55
|
+
end
|
62
56
|
end
|
63
57
|
|
64
58
|
report
|
65
59
|
end
|
66
60
|
|
61
|
+
def license_info_ok?(dependency_manager, dependency)
|
62
|
+
problems = []
|
63
|
+
if dependency["name"].nil? || dependency["name"].empty?
|
64
|
+
problems << "There is a dependency with a missing name in '#{dependency_manager}'."
|
65
|
+
end
|
66
|
+
|
67
|
+
if dependency["version"].nil? || dependency["version"].empty?
|
68
|
+
problems << "Dependency '#{dependency["name"]}' under '#{dependency_manager}' is missing version information."
|
69
|
+
end
|
70
|
+
|
71
|
+
if dependency["license"].nil? || dependency["license"].empty?
|
72
|
+
problems << "Dependency '#{dependency["name"]}' version '#{dependency["version"]}' under '#{dependency_manager}' is missing license information."
|
73
|
+
end
|
74
|
+
|
75
|
+
if dependency["license_files"].empty?
|
76
|
+
problems << "Dependency '#{dependency["name"]}' version '#{dependency["version"]}' under '#{dependency_manager}' is missing license files information."
|
77
|
+
else
|
78
|
+
dependency["license_files"].each do |license_file|
|
79
|
+
if !File.exist?(full_path_for(license_file))
|
80
|
+
problems << "License file '#{license_file}' for the dependency '#{dependency["name"]}' version '#{dependency["version"]}' under '#{dependency_manager}' is missing."
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
[ problems.empty?, problems ]
|
86
|
+
end
|
87
|
+
|
67
88
|
def find_license_manifest!
|
68
89
|
if !File.exist?(output_directory)
|
69
90
|
raise LicenseScout::Exceptions::InvalidOutputReport.new("Output directory '#{output_directory}' does not exist.")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: license_scout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Serdar Sutay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi-yajl
|
@@ -138,9 +138,13 @@ files:
|
|
138
138
|
- LICENSE
|
139
139
|
- README.md
|
140
140
|
- Rakefile
|
141
|
+
- appveyor.yml
|
141
142
|
- bin/config_to_json
|
142
143
|
- bin/license_scout
|
143
144
|
- lib/license_scout.rb
|
145
|
+
- lib/license_scout/canonical_licenses/BSD-4-Clause.txt
|
146
|
+
- lib/license_scout/canonical_licenses/ISC.txt
|
147
|
+
- lib/license_scout/canonical_licenses/MIT.txt
|
144
148
|
- lib/license_scout/collector.rb
|
145
149
|
- lib/license_scout/dependency.rb
|
146
150
|
- lib/license_scout/dependency_manager.rb
|
@@ -151,6 +155,8 @@ files:
|
|
151
155
|
- lib/license_scout/dependency_manager/bundler/_bundler_script.rb
|
152
156
|
- lib/license_scout/dependency_manager/cpan.rb
|
153
157
|
- lib/license_scout/dependency_manager/json/README.md
|
158
|
+
- lib/license_scout/dependency_manager/manual.rb
|
159
|
+
- lib/license_scout/dependency_manager/npm.rb
|
154
160
|
- lib/license_scout/dependency_manager/rebar.rb
|
155
161
|
- lib/license_scout/exceptions.rb
|
156
162
|
- lib/license_scout/license_file_analyzer.rb
|