deriving_license 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/Gemfile +4 -1
- data/deriving_license.gemspec +2 -1
- data/lib/deriving_license.rb +22 -17
- data/test/empty.gemfile +2 -0
- data/test/requires_license_file_parsing.gemfile +3 -0
- data/test/requires_license_file_parsing_but_is_custom.gemfile +3 -0
- data/test/requires_license_filename.gemfile +3 -0
- data/test/requires_readme_file_parsing.gemfile +3 -0
- data/test/requires_scraping.gemfile +3 -0
- data/test/test_deriving_license.rb +51 -8
- metadata +30 -2
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/deriving_license.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'deriving_license'
|
3
|
-
s.version = '0.2.
|
3
|
+
s.version = '0.2.8'
|
4
4
|
s.summary = "Deriving Licence finds the license agreements for all gems in your Gemfile"
|
5
5
|
s.description = "Deriving Licence finds the license agreements for all gems in your Gemfile if included in your project, or in a Gemfile passed to the included binary"
|
6
6
|
s.authors = ["Tom Allen"]
|
@@ -16,4 +16,5 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.add_runtime_dependency "gemnasium-parser"
|
17
17
|
s.add_runtime_dependency "safe_yaml"
|
18
18
|
s.add_runtime_dependency "curb"
|
19
|
+
s.add_development_dependency "simplecov"
|
19
20
|
end
|
data/lib/deriving_license.rb
CHANGED
@@ -10,7 +10,7 @@ class DerivingLicense
|
|
10
10
|
|
11
11
|
# TODO: Scrape http://www.gnu.org/licenses/license-list.html#SoftwareLicenses
|
12
12
|
# and auto-magically generate these details.
|
13
|
-
|
13
|
+
@license_details = {
|
14
14
|
# key -> hash of (Name, Link, [Tags]), where tags is an array that may include [:gpl_compatible, :copyleft_compatible, :has_restrictions]
|
15
15
|
"GPL" => {name:"GNU General Public License",link:"http://en.wikipedia.org/wiki/GNU_General_Public_License",tags:[:gpl_compatible, :copyleft_compatible, :has_restrictions]},
|
16
16
|
"MIT" => {name:"Expat License",link:"http://directory.fsf.org/wiki/License:Expat",tags:[:gpl_compatible, :has_restrictions]},
|
@@ -20,11 +20,12 @@ class DerivingLicense
|
|
20
20
|
"Apache" => {name:"Apache License",link:"http://www.apache.org/licenses/LICENSE-2.0",tags:[:has_restrictions]},
|
21
21
|
}
|
22
22
|
|
23
|
-
|
23
|
+
@license_aliases = {
|
24
24
|
# hash of names to keys of the license in the master list.
|
25
25
|
"FreeBSD" => "BSD",
|
26
26
|
"Expat" => "MIT",
|
27
27
|
"beer" => "beerware",
|
28
|
+
"BEER-WARE" => "beerware",
|
28
29
|
"ruby" => "Ruby",
|
29
30
|
"Apache License" => "Apache",
|
30
31
|
}
|
@@ -32,16 +33,16 @@ class DerivingLicense
|
|
32
33
|
# String array of strategies to detect licenses. Write new class functions
|
33
34
|
# (that take a string of the dependency's name) then add their names here in
|
34
35
|
# order of fastest to slowest.
|
35
|
-
|
36
|
+
@strategies = [
|
36
37
|
"from_gem_specification",
|
37
38
|
"from_scraping_homepage",
|
38
39
|
"from_license_file",
|
39
40
|
"from_parsing_readme",
|
40
41
|
]
|
41
42
|
|
42
|
-
|
43
|
+
@specs_cache = {} # Cache of gem specifications previously fetched.
|
43
44
|
|
44
|
-
def self.run(path=nil)
|
45
|
+
def self.run(path=nil, strategies=nil)
|
45
46
|
unless path
|
46
47
|
raise ArgumentError.new("Path to Gemfile or Gemspec required")
|
47
48
|
end
|
@@ -56,6 +57,8 @@ class DerivingLicense
|
|
56
57
|
raise "Invalid path to gemfile or gemspec."
|
57
58
|
end
|
58
59
|
|
60
|
+
available_strategies = strategies.nil? ? @strategies : strategies
|
61
|
+
|
59
62
|
if /(gemspec)+/.match(path.downcase)
|
60
63
|
content = Gemnasium::Parser::Gemspec.new(content)
|
61
64
|
else
|
@@ -68,7 +71,7 @@ class DerivingLicense
|
|
68
71
|
content.dependencies.each do |d|
|
69
72
|
print "Determining license for #{d.name}:\n"
|
70
73
|
# Try each license finding strategy...
|
71
|
-
|
74
|
+
available_strategies.each do |s|
|
72
75
|
print "\tTrying #{s} strategy..."
|
73
76
|
@licenses = eval("#{s}(\"#{d.name}\")")
|
74
77
|
unless @licenses.empty? # and break out of the search if successful
|
@@ -105,10 +108,10 @@ class DerivingLicense
|
|
105
108
|
licenses.each do |l|
|
106
109
|
unless l.first == "custom"
|
107
110
|
instances = "(#{l.last} instance#{l.last == 1 ? "" : "s"})"
|
108
|
-
key =
|
111
|
+
key = @license_aliases[l.first]
|
109
112
|
key ||= l.first
|
110
|
-
if
|
111
|
-
output << "#{key}: #{
|
113
|
+
if @license_details[key]
|
114
|
+
output << "#{key}: #{@license_details[key][:name]} #{instances} [#{@license_details[key][:link]}]"
|
112
115
|
else
|
113
116
|
unrecognized << key
|
114
117
|
end
|
@@ -121,14 +124,14 @@ class DerivingLicense
|
|
121
124
|
unless unrecognized.empty?
|
122
125
|
puts "There #{unrecognized.count==1 ? "is" : "are"} also #{unrecognized.count} unrecognized license#{unrecognized.count==1 ? "" : "s"}: #{unrecognized.join(', ')}"
|
123
126
|
end
|
124
|
-
if licenses
|
127
|
+
if licenses.has_key?("custom") and !licenses["custom"].empty?
|
125
128
|
puts "The following dependencies have custom licenses: #{licenses["custom"].join(', ')}"
|
126
129
|
end
|
127
130
|
end
|
128
131
|
|
129
132
|
def self.get_gem_spec(dep)
|
130
133
|
# Check spec cache first.
|
131
|
-
@spec =
|
134
|
+
@spec = @specs_cache[dep]
|
132
135
|
return @spec if @spec
|
133
136
|
# See if the gem is installed locally, and if not add -r to call
|
134
137
|
Bundler.with_clean_env do # This gets out of the bundler context.
|
@@ -136,7 +139,7 @@ class DerivingLicense
|
|
136
139
|
yaml = `gem specification #{remote}#{dep} --yaml`
|
137
140
|
@spec = YAML.load(yaml, :safe => true)
|
138
141
|
end
|
139
|
-
|
142
|
+
@specs_cache[dep] = @spec # Cache it.
|
140
143
|
@spec
|
141
144
|
end
|
142
145
|
|
@@ -163,9 +166,9 @@ class DerivingLicense
|
|
163
166
|
paths.each do |p|
|
164
167
|
if File.exist?(p)
|
165
168
|
File.open(p).each_line do |l|
|
166
|
-
if /license
|
169
|
+
if /license/i.match(l)
|
167
170
|
# Found the word "license", so now look for known license names.
|
168
|
-
(
|
171
|
+
(@license_details.keys + @license_aliases.keys).each do |n|
|
169
172
|
if /#{n}/.match(l)
|
170
173
|
licenses << n
|
171
174
|
break
|
@@ -180,7 +183,7 @@ class DerivingLicense
|
|
180
183
|
|
181
184
|
def self.search_in_content(content)
|
182
185
|
licenses = []
|
183
|
-
(
|
186
|
+
(@license_details.keys + @license_aliases.keys).each do |n|
|
184
187
|
if /#{n}/.match(content)
|
185
188
|
licenses << n
|
186
189
|
return licenses
|
@@ -259,9 +262,11 @@ class DerivingLicense
|
|
259
262
|
|
260
263
|
readme_file_paths = []
|
261
264
|
Find.find(gem_source_directory) do |path|
|
262
|
-
|
265
|
+
if path =~ /(read\.me|readme)/i
|
266
|
+
readme_file_paths << path
|
267
|
+
end
|
263
268
|
end
|
264
|
-
break
|
269
|
+
break if readme_file_paths.empty?
|
265
270
|
|
266
271
|
# Open each readme file and check the content.
|
267
272
|
licenses = search_in_paths(readme_file_paths)
|
data/test/empty.gemfile
ADDED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
1
4
|
require 'test/unit'
|
2
5
|
require 'deriving_license'
|
3
6
|
|
@@ -21,12 +24,6 @@ class DerivingLicenseTest < Test::Unit::TestCase
|
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
24
|
-
def test_run_throws_with_multiple_args
|
25
|
-
assert_raise ArgumentError do
|
26
|
-
DerivingLicense.run("Gemfile1", "Gemfile2")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
27
|
def test_run_throws_if_path_is_invalid
|
31
28
|
assert_raise ArgumentError do
|
32
29
|
DerivingLicense.run("Ceci n'est pas un dossier.")
|
@@ -39,11 +36,17 @@ class DerivingLicenseTest < Test::Unit::TestCase
|
|
39
36
|
end
|
40
37
|
end
|
41
38
|
|
39
|
+
def test_run_with_empty_gemfile_returns_empty_hash
|
40
|
+
assert_equal( true, DerivingLicense.run("./test/empty.gemfile").empty? )
|
41
|
+
end
|
42
|
+
|
42
43
|
def test_run_with_valid_arg
|
43
44
|
assert_nothing_raised do
|
44
|
-
|
45
|
+
output = capture_stdout do
|
46
|
+
@result = DerivingLicense.run("Gemfile")
|
47
|
+
end
|
45
48
|
end
|
46
|
-
assert_equal(
|
49
|
+
assert_equal( true, @result.has_key?("MIT") )
|
47
50
|
end
|
48
51
|
|
49
52
|
def test_describe_with_known_license
|
@@ -62,5 +65,45 @@ class DerivingLicenseTest < Test::Unit::TestCase
|
|
62
65
|
# Should say "unknown"
|
63
66
|
assert_equal( false, /unrecognized/.match( output.string ).nil? )
|
64
67
|
end
|
68
|
+
|
69
|
+
def test_from_scraping_strategy
|
70
|
+
output = capture_stdout do
|
71
|
+
@result = DerivingLicense.run("./test/requires_scraping.gemfile", ["from_scraping_homepage"])
|
72
|
+
end
|
73
|
+
assert_equal( false, @result.empty? )
|
74
|
+
assert_equal( false, /from_scraping_homepage strategy...SUCCESS/.match( output.string ).nil? ) # Should be SUCCESS
|
75
|
+
end
|
65
76
|
|
77
|
+
def test_from_license_filename
|
78
|
+
output = capture_stdout do
|
79
|
+
@result = DerivingLicense.run("./test/requires_license_filename.gemfile", ["from_license_file"])
|
80
|
+
end
|
81
|
+
assert_equal( false, @result.empty? )
|
82
|
+
assert_equal( true, /from_license_file strategy...FAILED/.match( output.string ).nil? ) # Shouldn't be FAILED
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_from_license_file_parsing
|
86
|
+
output = capture_stdout do
|
87
|
+
@result = DerivingLicense.run("./test/requires_license_file_parsing.gemfile", ["from_license_file"])
|
88
|
+
end
|
89
|
+
assert_equal( false, @result.empty? )
|
90
|
+
assert_equal( true, /from_license_file strategy...FAILED/.match( output.string ).nil? ) # Shouldn't be FAILED
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_from_license_file_parsing_but_is_custom
|
94
|
+
output = capture_stdout do
|
95
|
+
@result = DerivingLicense.run("./test/requires_license_file_parsing_but_is_custom.gemfile", ["from_license_file"])
|
96
|
+
end
|
97
|
+
assert_equal( false, @result.empty? )
|
98
|
+
assert_equal( false, /from_license_file strategy...CUSTOM/.match( output.string ).nil? ) # Should be CUSTOM
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_from_readme_file_parsing
|
102
|
+
output = capture_stdout do
|
103
|
+
@result = DerivingLicense.run("./test/requires_readme_file_parsing.gemfile", ["from_parsing_readme"])
|
104
|
+
end
|
105
|
+
assert_equal( false, @result.empty? )
|
106
|
+
assert_equal( false, /from_parsing_readme strategy...SUCCESS/.match( output.string ).nil? )
|
107
|
+
end
|
108
|
+
|
66
109
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deriving_license
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: gemnasium-parser
|
@@ -59,6 +59,22 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: simplecov
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
62
78
|
description: Deriving Licence finds the license agreements for all gems in your Gemfile
|
63
79
|
if included in your project, or in a Gemfile passed to the included binary
|
64
80
|
email: tom@jugglethis.net
|
@@ -75,6 +91,12 @@ files:
|
|
75
91
|
- bin/deriving_license
|
76
92
|
- deriving_license.gemspec
|
77
93
|
- lib/deriving_license.rb
|
94
|
+
- test/empty.gemfile
|
95
|
+
- test/requires_license_file_parsing.gemfile
|
96
|
+
- test/requires_license_file_parsing_but_is_custom.gemfile
|
97
|
+
- test/requires_license_filename.gemfile
|
98
|
+
- test/requires_readme_file_parsing.gemfile
|
99
|
+
- test/requires_scraping.gemfile
|
78
100
|
- test/test_deriving_license.rb
|
79
101
|
homepage: http://www.github.com/Schwolop/deriving_license
|
80
102
|
licenses:
|
@@ -102,5 +124,11 @@ signing_key:
|
|
102
124
|
specification_version: 3
|
103
125
|
summary: Deriving Licence finds the license agreements for all gems in your Gemfile
|
104
126
|
test_files:
|
127
|
+
- test/empty.gemfile
|
128
|
+
- test/requires_license_file_parsing.gemfile
|
129
|
+
- test/requires_license_file_parsing_but_is_custom.gemfile
|
130
|
+
- test/requires_license_filename.gemfile
|
131
|
+
- test/requires_readme_file_parsing.gemfile
|
132
|
+
- test/requires_scraping.gemfile
|
105
133
|
- test/test_deriving_license.rb
|
106
134
|
has_rdoc:
|