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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 52257de820176f3967f5ccb25d3b63c0d6ab8361
4
- data.tar.gz: 552b96f0d3f02afad489a574eb7ac65e94b8393b
3
+ metadata.gz: 83b949a77e7dcd991b2de72715882700e160e0eb
4
+ data.tar.gz: 0f5275681d5db4fe0f6ea19db30131a739d63de1
5
5
  SHA512:
6
- metadata.gz: 224df51c2fc2c5a8215693476b6198fee5295e65032432fe51bdba97bd65ea1b9652532f6e8991a6c5efde6a069ed41901a30b5d342ade64efe300307d8d04da
7
- data.tar.gz: 3bcecbde801328acc30291aa43af5768b89b37b2d50948919a5be52a99e7a5b1423bf163334006e3bae6819ddd2ed8dc20a2ed32d05f3dadb8591a1719fff4b9
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][dependency_manager.name] << license_data
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
@@ -78,7 +78,7 @@ module LicenseScout
78
78
  dependency_license_files = override_license_files.resolve_locations(cookbook_path)
79
79
  end
80
80
 
81
- dependencies << Dependency.new(
81
+ dependencies << create_dependency(
82
82
  dependency_name,
83
83
  dependency_version,
84
84
  dependency_license,
@@ -93,7 +93,7 @@ module LicenseScout
93
93
  end
94
94
  end
95
95
 
96
- dependencies << Dependency.new(
96
+ dependencies << create_dependency(
97
97
  dependency_name,
98
98
  dependency_version,
99
99
  dependency_license,
@@ -77,7 +77,8 @@ module LicenseScout
77
77
  dist,
78
78
  version,
79
79
  license,
80
- license_files
80
+ license_files,
81
+ "perl_cpan"
81
82
  )
82
83
  end
83
84
 
@@ -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 = Dependency.new(dep_name, dep_version, license_name, license_files)
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
@@ -42,6 +42,7 @@ module LicenseScout
42
42
  class InaccessibleDependency < Error; end
43
43
  class InvalidOverride < Error; end
44
44
  class InvalidOutputReport < Error; end
45
+ class InvalidManualDependency < Error; end
45
46
 
46
47
  class NetworkError < Error
47
48
 
@@ -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
- if dependency["version"].nil? || dependency["version"].empty?
45
- report << "Dependency '#{dependency["name"]}' under '#{dependency_manager}' is missing version information."
46
- end
40
+ ok_deps, problem_deps = 0, 0
47
41
 
48
- if dependency["license"].nil? || dependency["license"].empty?
49
- report << "Dependency '#{dependency["name"]}' version '#{dependency["version"]}' under '#{dependency_manager}' is missing license information."
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 dependency["license_files"].empty?
53
- report << "Dependency '#{dependency["name"]}' version '#{dependency["version"]}' under '#{dependency_manager}' is missing license files information."
45
+ if dep_ok
46
+ ok_deps += 1
54
47
  else
55
- dependency["license_files"].each do |license_file|
56
- if !File.exist?(full_path_for(license_file))
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.")
@@ -16,5 +16,5 @@
16
16
  #
17
17
 
18
18
  module LicenseScout
19
- VERSION = "0.1.2"
19
+ VERSION = "0.1.3"
20
20
  end
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.2
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-01 00:00:00.000000000 Z
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