deriving_license 0.2.7 → 0.2.8
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.
- 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:
|