license_scout 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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