license_scout 0.1.0

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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +4 -0
  5. data/.travis.yml +11 -0
  6. data/Gemfile +24 -0
  7. data/LICENSE +201 -0
  8. data/README.md +26 -0
  9. data/Rakefile +39 -0
  10. data/bin/license_scout +39 -0
  11. data/lib/license_scout/collector.rb +137 -0
  12. data/lib/license_scout/dependency.rb +20 -0
  13. data/lib/license_scout/dependency_manager/base.rb +55 -0
  14. data/lib/license_scout/dependency_manager/bundler/LICENSE.md +23 -0
  15. data/lib/license_scout/dependency_manager/bundler/_bundler_script.rb +47 -0
  16. data/lib/license_scout/dependency_manager/bundler.rb +159 -0
  17. data/lib/license_scout/dependency_manager/rebar.rb +92 -0
  18. data/lib/license_scout/dependency_manager.rb +27 -0
  19. data/lib/license_scout/exceptions.rb +74 -0
  20. data/lib/license_scout/license_file_analyzer/any_matcher.rb +37 -0
  21. data/lib/license_scout/license_file_analyzer/definitions.rb +212 -0
  22. data/lib/license_scout/license_file_analyzer/header_matcher.rb +34 -0
  23. data/lib/license_scout/license_file_analyzer/matcher.rb +46 -0
  24. data/lib/license_scout/license_file_analyzer/template.rb +45 -0
  25. data/lib/license_scout/license_file_analyzer/templates/Apache2-short.txt +11 -0
  26. data/lib/license_scout/license_file_analyzer/templates/Apache2.txt +172 -0
  27. data/lib/license_scout/license_file_analyzer/templates/BSD-2-Clause-bullets.txt +18 -0
  28. data/lib/license_scout/license_file_analyzer/templates/BSD-2-Clause.txt +19 -0
  29. data/lib/license_scout/license_file_analyzer/templates/BSD-3-Clause-alt-format.txt +24 -0
  30. data/lib/license_scout/license_file_analyzer/templates/BSD-3-Clause.txt +21 -0
  31. data/lib/license_scout/license_file_analyzer/templates/BSD.txt +24 -0
  32. data/lib/license_scout/license_file_analyzer/templates/EPLICENSE.txt +286 -0
  33. data/lib/license_scout/license_file_analyzer/templates/GPL-2.0.txt +339 -0
  34. data/lib/license_scout/license_file_analyzer/templates/GPL-3.0.txt +674 -0
  35. data/lib/license_scout/license_file_analyzer/templates/ISC.txt +2 -0
  36. data/lib/license_scout/license_file_analyzer/templates/LGPL-3.0.txt +165 -0
  37. data/lib/license_scout/license_file_analyzer/templates/MIT.txt +9 -0
  38. data/lib/license_scout/license_file_analyzer/templates/MPL2.txt +373 -0
  39. data/lib/license_scout/license_file_analyzer/templates/Python-2.0.txt +47 -0
  40. data/lib/license_scout/license_file_analyzer/templates/Ruby.txt +52 -0
  41. data/lib/license_scout/license_file_analyzer/text.rb +46 -0
  42. data/lib/license_scout/license_file_analyzer.rb +26 -0
  43. data/lib/license_scout/net_fetcher.rb +104 -0
  44. data/lib/license_scout/options.rb +45 -0
  45. data/lib/license_scout/overrides.rb +149 -0
  46. data/lib/license_scout/version.rb +20 -0
  47. data/lib/license_scout.rb +19 -0
  48. data/license_scout.gemspec +46 -0
  49. metadata +190 -0
@@ -0,0 +1,159 @@
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/net_fetcher"
20
+ require "license_scout/exceptions"
21
+
22
+ require "bundler"
23
+ require "mixlib/shellout"
24
+ require "ffi_yajl"
25
+ require "pathname"
26
+
27
+ module LicenseScout
28
+ module DependencyManager
29
+ class Bundler < Base
30
+
31
+ def name
32
+ "ruby_bundler"
33
+ end
34
+
35
+ def detected?
36
+ # We only check for the existence of Gemfile in order to declare a
37
+ # project a Bundler project. If the Gemfile.lock does not exist
38
+ # we will raise a specific error to indicate that "bundle install"
39
+ # needs to be run before proceeding.
40
+ File.exists?(gemfile_path)
41
+ end
42
+
43
+ def dependency_data
44
+ bundler_script = File.join(File.dirname(__FILE__), "bundler/_bundler_script.rb")
45
+
46
+ Dir.chdir(project_dir) do
47
+ json_dep_data = with_clean_env do
48
+ ruby_bin_path = options.ruby_bin || "ruby"
49
+ s = Mixlib::ShellOut.new("#{ruby_bin_path} #{bundler_script}", environment: options.environment)
50
+ s.run_command
51
+ s.error!
52
+ s.stdout
53
+ end
54
+ FFI_Yajl::Parser.parse(json_dep_data)
55
+ end
56
+ end
57
+
58
+ def dependencies
59
+ if !File.exists?(lockfile_path)
60
+ raise LicenseScout::Exceptions::DependencyManagerNotRun.new(project_dir, name)
61
+ end
62
+
63
+ dependencies = []
64
+ dependency_data.each do |gem_data|
65
+ dependency_name = gem_data["name"]
66
+ dependency_version = gem_data["version"]
67
+ dependency_license = nil
68
+ dependency_license_files = []
69
+
70
+ if dependency_name == "bundler"
71
+ # Bundler is weird. It inserts itself as a dependency, but is a
72
+ # special case, so rubygems cannot correctly report the license.
73
+ # Additionally, rubygems reports the gem path as a path inside
74
+ # bundler's lib/ dir, so we have to munge it.
75
+ dependency_license = "MIT"
76
+ dependency_license_files = [File.join(File.dirname(__FILE__), "bundler/LICENSE.md")]
77
+ else
78
+ # Check license override and license_files override separately since
79
+ # only one might be set in the overrides.
80
+ dependency_license = options.overrides.license_for(name, dependency_name, dependency_version) || gem_data["license"]
81
+
82
+ override_license_files = options.overrides.license_files_for(name, dependency_name, dependency_version)
83
+ if override_license_files.empty?
84
+ dependency_license_files = auto_detect_license_files(gem_data["path"])
85
+ else
86
+ dependency_license_files = override_license_files.resolve_locations(gem_data["path"])
87
+ end
88
+ end
89
+
90
+ dependencies << Dependency.new(
91
+ dependency_name,
92
+ dependency_version,
93
+ dependency_license,
94
+ dependency_license_files
95
+ )
96
+ end
97
+
98
+ dependencies
99
+ end
100
+
101
+ private
102
+
103
+ #
104
+ # Execute the given command, removing any Ruby-specific environment
105
+ # variables. This is an "enhanced" version of +Bundler.with_clean_env+,
106
+ # which only removes Bundler-specific values. We need to remove all
107
+ # values, specifically:
108
+ #
109
+ # - _ORIGINAL_GEM_PATH
110
+ # - GEM_PATH
111
+ # - GEM_HOME
112
+ # - GEM_ROOT
113
+ # - BUNDLE_BIN_PATH
114
+ # - BUNDLE_GEMFILE
115
+ # - RUBYLIB
116
+ # - RUBYOPT
117
+ # - RUBY_ENGINE
118
+ # - RUBY_ROOT
119
+ # - RUBY_VERSION
120
+ #
121
+ # The original environment restored at the end of this call.
122
+ #
123
+ # @param [Proc] block
124
+ # the block to execute with the cleaned environment
125
+ #
126
+ def with_clean_env(&block)
127
+ original = ENV.to_hash
128
+
129
+ ENV.delete("_ORIGINAL_GEM_PATH")
130
+ ENV.delete_if { |k, _| k.start_with?("BUNDLE_") }
131
+ ENV.delete_if { |k, _| k.start_with?("GEM_") }
132
+ ENV.delete_if { |k, _| k.start_with?("RUBY") }
133
+
134
+ yield
135
+ ensure
136
+ ENV.replace(original.to_hash)
137
+ end
138
+
139
+ def auto_detect_license_files(gem_path)
140
+ unless File.exist?(gem_path)
141
+ raise LicenseScout::Exceptions::InaccessibleDependency.new "Autodetected gem path '#{gem_path}' does not exist"
142
+ end
143
+
144
+ Dir.glob("#{gem_path}/*").select do |f|
145
+ POSSIBLE_LICENSE_FILES.include?(File.basename(f))
146
+ end
147
+ end
148
+
149
+ def gemfile_path
150
+ File.join(project_dir, "Gemfile")
151
+ end
152
+
153
+ def lockfile_path
154
+ File.join(project_dir, "Gemfile.lock")
155
+ end
156
+
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,92 @@
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/net_fetcher"
20
+ require "license_scout/exceptions"
21
+ require "license_scout/license_file_analyzer"
22
+
23
+ require "mixlib/shellout"
24
+
25
+ module LicenseScout
26
+ module DependencyManager
27
+ class Rebar < Base
28
+
29
+ def name
30
+ "erlang_rebar"
31
+ end
32
+
33
+ def detected?
34
+ File.exist?(rebar_config_path)
35
+ end
36
+
37
+ def dependencies
38
+ dependencies = []
39
+
40
+ Dir.glob("#{project_deps_dir}/*").each do |dep_dir|
41
+ next unless File.directory?(dep_dir)
42
+
43
+ dep_name = File.basename(dep_dir)
44
+ dep_version = git_rev_parse(dep_dir)
45
+
46
+ override_license_files = options.overrides.license_files_for(name, dep_name, dep_version)
47
+ license_files =
48
+ if override_license_files.empty?
49
+ Dir.glob("#{dep_dir}/*").select { |f| POSSIBLE_LICENSE_FILES.include?(File.basename(f)) }
50
+ else
51
+ override_license_files.resolve_locations(dep_dir)
52
+ end
53
+
54
+ license_name = options.overrides.license_for(name, dep_name, dep_version) || scan_licenses(license_files)
55
+
56
+ dep = Dependency.new(dep_name, dep_version, license_name, license_files)
57
+
58
+ dependencies << dep
59
+ end
60
+
61
+ dependencies
62
+ end
63
+
64
+ private
65
+
66
+ def git_rev_parse(dependency_dir)
67
+ s = Mixlib::ShellOut.new("git rev-parse HEAD", cwd: dependency_dir)
68
+ s.run_command
69
+ s.error!
70
+ s.stdout.strip
71
+ end
72
+
73
+ def project_deps_dir
74
+ File.join(project_dir, "deps")
75
+ end
76
+
77
+ def rebar_config_path
78
+ File.join(project_dir, "rebar.config")
79
+ end
80
+
81
+ def scan_licenses(license_files)
82
+ if license_files.empty?
83
+ nil
84
+ else
85
+ found_license = LicenseScout::LicenseFileAnalyzer.find_by_text(IO.read(license_files.first))
86
+ found_license ? found_license.short_name : nil
87
+ end
88
+ end
89
+
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,27 @@
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/bundler"
19
+ require "license_scout/dependency_manager/rebar"
20
+
21
+ module LicenseScout
22
+ module DependencyManager
23
+ def self.implementations
24
+ [Bundler, Rebar]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,74 @@
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
+ module LicenseScout
19
+ module Exceptions
20
+ class Error < RuntimeError; end
21
+
22
+ class ProjectDirectoryMissing < Error
23
+ def initialize(project_dir)
24
+ @project_dir = project_dir
25
+ end
26
+
27
+ def to_s
28
+ "Could not locate or access the provided project directory '#{@project_dir}'."
29
+ end
30
+ end
31
+
32
+ class UnsupportedProjectType < Error
33
+ def initialize(project_dir)
34
+ @project_dir = project_dir
35
+ end
36
+
37
+ def to_s
38
+ "Could not find a supported dependency manager for the project in the provided directory '#{@project_dir}'."
39
+ end
40
+ end
41
+
42
+ class DependencyManagerNotRun < Error
43
+ def initialize(project_dir, dependency_manager_name)
44
+ @project_dir = project_dir
45
+ @dependency_manager_name = dependency_manager_name
46
+ end
47
+
48
+ def to_s
49
+ "Dependency manager '#{@dependency_manager_name}' is not yet run for project at '#{@project_dir}'."
50
+ end
51
+ end
52
+
53
+ class InaccessibleDependency < Error; end
54
+ class InvalidOverride < Error; end
55
+
56
+ class NetworkError < Error
57
+
58
+ attr_reader :from_url
59
+ attr_reader :network_error
60
+
61
+ def initialize(from_url, network_error)
62
+ @from_url = from_url
63
+ @network_error = network_error
64
+ end
65
+
66
+ def to_s
67
+ [
68
+ "Network error while fetching '#{from_url}'",
69
+ network_error.to_s,
70
+ ].join("\n")
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,37 @@
1
+ # Copied from https://github.com/pivotal/LicenseFinder
2
+ #
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2012 Pivotal Labs
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ module LicenseScout
26
+ module LicenseFileAnalyzer
27
+ class AnyMatcher
28
+ def initialize(*matchers)
29
+ @matchers = matchers
30
+ end
31
+
32
+ def matches_text?(text)
33
+ @matchers.any? { |m| m.matches_text? text }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,212 @@
1
+ # Copied from https://github.com/pivotal/LicenseFinder
2
+ #
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2012 Pivotal Labs
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ require "license_scout/license_file_analyzer/matcher"
26
+ require "license_scout/license_file_analyzer/any_matcher"
27
+ require "license_scout/license_file_analyzer/header_matcher"
28
+ require "license_scout/license_file_analyzer/template"
29
+
30
+ module LicenseScout
31
+ module LicenseFileAnalyzer
32
+
33
+ class License
34
+
35
+ attr_reader :matcher
36
+ attr_reader :short_name
37
+
38
+ def initialize(short_name:, matcher: nil)
39
+ @short_name = short_name
40
+ @matcher = matcher || Matcher.from_template(Template.named(short_name))
41
+ end
42
+
43
+ def matches_text?(text)
44
+ matcher.matches_text?(text)
45
+ end
46
+
47
+ end
48
+
49
+ module Definitions
50
+ extend self
51
+
52
+ def all
53
+ [
54
+ apache2,
55
+ bsd,
56
+ gplv2,
57
+ gplv3,
58
+ isc,
59
+ lgpl,
60
+ mit,
61
+ mpl2,
62
+ bsd_3_clause,
63
+ python,
64
+ ruby,
65
+ bsd_2_clause,
66
+ erlang_public,
67
+ ]
68
+ end
69
+
70
+ private
71
+
72
+ def apache2
73
+ matcher = AnyMatcher.new(
74
+ Matcher.from_template(Template.named("Apache2")),
75
+ Matcher.from_template(Template.named("Apache2-short"))
76
+ )
77
+
78
+ License.new(
79
+ short_name: "Apache-2.0",
80
+ matcher: matcher
81
+ )
82
+ end
83
+
84
+ def bsd
85
+ License.new(
86
+ short_name: "BSD"
87
+ )
88
+ end
89
+
90
+ def gplv2
91
+ License.new(
92
+ short_name: "GPL-2.0"
93
+ )
94
+ end
95
+
96
+ def gplv3
97
+ License.new(
98
+ short_name: "GPL-3.0"
99
+ )
100
+ end
101
+
102
+ def isc
103
+ License.new(
104
+ short_name: "ISC"
105
+ )
106
+ end
107
+
108
+ def lgpl
109
+ License.new(
110
+ short_name: "LGPL-3.0"
111
+ )
112
+ end
113
+
114
+ def mit
115
+ url_regexp = %r{MIT Licen[sc]e.*http://(?:www\.)?opensource\.org/licenses/mit-license}
116
+ header_regexp = /The MIT Licen[sc]e/
117
+ one_liner_regexp = /is released under the MIT licen[sc]e/
118
+
119
+ matcher = AnyMatcher.new(
120
+ Matcher.from_template(Template.named("MIT")),
121
+ Matcher.from_regex(url_regexp),
122
+ HeaderMatcher.new(Matcher.from_regex(header_regexp)),
123
+ Matcher.from_regex(one_liner_regexp)
124
+ )
125
+
126
+ License.new(
127
+ short_name: "MIT",
128
+ matcher: matcher
129
+ )
130
+ end
131
+
132
+ def mpl2
133
+ header_regexp = /Mozilla Public Licen[sc]e, version 2.0/
134
+
135
+ matcher = AnyMatcher.new(
136
+ Matcher.from_template(Template.named("MPL2")),
137
+ HeaderMatcher.new(Matcher.from_regex(header_regexp))
138
+ )
139
+
140
+ License.new(
141
+ short_name: "MPL-2.0",
142
+ matcher: matcher
143
+ )
144
+ end
145
+
146
+ def bsd_3_clause
147
+ substitution = [
148
+ "Neither the name of <organization> nor the names of <possessive> contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
149
+ "The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission.",
150
+ ]
151
+
152
+ template = Template.named("BSD-3-Clause")
153
+ alternate_content = template.content.gsub(*substitution)
154
+
155
+ alt_format_template = Template.named("BSD-3-Clause-alt-format")
156
+ alt_format_with_alt_content = alt_format_template.content.gsub(*substitution)
157
+
158
+ matcher = AnyMatcher.new(
159
+ Matcher.from_template(template),
160
+ Matcher.from_text(alternate_content),
161
+ Matcher.from_template(alt_format_template),
162
+ Matcher.from_text(alt_format_with_alt_content)
163
+ )
164
+
165
+ License.new(
166
+ short_name: "BSD-3-Clause",
167
+ matcher: matcher
168
+ )
169
+ end
170
+
171
+ def python
172
+ License.new(
173
+ short_name: "Python-2.0"
174
+ )
175
+ end
176
+
177
+ def ruby
178
+ url = "http://www.ruby-lang.org/en/LICENSE.txt"
179
+
180
+ matcher = AnyMatcher.new(
181
+ Matcher.from_template(Template.named("Ruby")),
182
+ Matcher.from_text(url)
183
+ )
184
+
185
+ License.new(
186
+ short_name: "Ruby",
187
+ matcher: matcher
188
+ )
189
+ end
190
+
191
+ def bsd_2_clause
192
+ matcher = AnyMatcher.new(
193
+ Matcher.from_template(Template.named("BSD-2-Clause")),
194
+ Matcher.from_template(Template.named("BSD-2-Clause-bullets"))
195
+ )
196
+
197
+ License.new(
198
+ short_name: "BSD-2-Clause",
199
+ matcher: matcher
200
+ )
201
+ end
202
+
203
+ def erlang_public
204
+ License.new(
205
+ short_name: "Erlang-Public",
206
+ matcher: Matcher.from_template(Template.named("EPLICENSE"))
207
+ )
208
+ end
209
+
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,34 @@
1
+ # Copied from https://github.com/pivotal/LicenseFinder
2
+ #
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2012 Pivotal Labs
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ module LicenseScout
26
+ module LicenseFileAnalyzer
27
+ HeaderMatcher = Struct.new(:base_matcher) do
28
+ def matches_text?(text)
29
+ header = text.split("\n").first || ""
30
+ base_matcher.matches_text?(header)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,46 @@
1
+ # Copied from https://github.com/pivotal/LicenseFinder
2
+ #
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2012 Pivotal Labs
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ module LicenseScout
26
+ module LicenseFileAnalyzer
27
+ Matcher = Struct.new(:regexp) do
28
+ def self.from_template(template)
29
+ from_text(template.content)
30
+ end
31
+
32
+ def self.from_text(text)
33
+ from_regex(Text.compile_to_regex(text))
34
+ end
35
+
36
+ # an alias for Matcher.new, for uniformity of constructors
37
+ def self.from_regex(regexp)
38
+ new(regexp)
39
+ end
40
+
41
+ def matches_text?(text)
42
+ !!(Text.normalize_punctuation(text) =~ regexp)
43
+ end
44
+ end
45
+ end
46
+ end