licensee 0.0.1
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 +7 -0
- data/LICENSE.md +21 -0
- data/README.md +124 -0
- data/Rakefile +13 -0
- data/bin/licensee +11 -0
- data/lib/licensee.rb +29 -0
- data/lib/licensee/license.rb +45 -0
- data/lib/licensee/license_file.rb +69 -0
- data/lib/licensee/licenses.rb +30 -0
- data/lib/licensee/project.rb +23 -0
- data/lib/licensee/version.rb +3 -0
- data/test/fixtures/md/LICENSE.md +21 -0
- data/test/fixtures/simple/LICENSE +21 -0
- data/test/fixtures/txt/LICENSE.txt +21 -0
- data/test/helper.rb +17 -0
- data/test/test_licensee.rb +13 -0
- data/test/test_licensee_bin.rb +11 -0
- data/test/test_licensee_license.rb +19 -0
- data/test/test_licensee_license_file.rb +52 -0
- data/test/test_licensee_licenses.rb +20 -0
- data/test/test_licensee_project.rb +16 -0
- metadata +135 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: da987b46bd2ebeb6b8e471f3ed51eb7ffd90879f
|
|
4
|
+
data.tar.gz: b554305bc92b5d90e55332a4df72d621dc48ab1a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 847fa7da0debf9e7e22de770a8297b1c6a0649a53c3fdbf3a83dfd07c606f3bce1ae30c1580d28d8cf57a718bcf3503f764bebb654e1ee08e701a68126ae3f90
|
|
7
|
+
data.tar.gz: 240e989c5bd228121872d5ac3272173a545109a0c3eee490e42d52b9c19274da4d57647a688543adefb2e0301db7b63982decb0f0636c59af429eda7b4d87a2f
|
data/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014 Ben Balter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Licensee
|
|
2
|
+
|
|
3
|
+
*A Ruby Gem to detect under what license a project is distributed.*
|
|
4
|
+
|
|
5
|
+
## The problem
|
|
6
|
+
|
|
7
|
+
* You've got an open source project. How do you know what you can and can't do with the software?
|
|
8
|
+
* You've got a bunch of open source projects, how do you know what their licenses are?
|
|
9
|
+
* You've got a project with a license file, but which license is it? Has it been modified?
|
|
10
|
+
|
|
11
|
+
## The solution
|
|
12
|
+
|
|
13
|
+
Licensee automates the process of reading `LICENSE` files and compares their contents to known licenses using a fancy math thing called the [Levenshtein Distance](http://en.wikipedia.org/wiki/Levenshtein_distance).
|
|
14
|
+
|
|
15
|
+
By calculating the percent changed from the known license, you can tell, e.g., that a given license is 98% similar to the MIT license, that 2% likely representing the copyright line being properly adapted to the project.
|
|
16
|
+
|
|
17
|
+
Licensee will even diff the distributed license with the original, so you can see exactly what, if anything's been changed.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
`gem install licensee` or add `gem 'licensee'` to your project's `Gemfile`.
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
license = Licensee.license "/path/to/a/project"
|
|
27
|
+
=> #<Licensee::License name="MIT" match=0.9842154131847726>
|
|
28
|
+
|
|
29
|
+
license.meta["title"]
|
|
30
|
+
=> "MIT License"
|
|
31
|
+
|
|
32
|
+
license.meta["source"]
|
|
33
|
+
=> "http://opensource.org/licenses/MIT"
|
|
34
|
+
|
|
35
|
+
license.meta["description"]
|
|
36
|
+
=> "A permissive license that is short and to the point. It lets people do anything with your code with proper attribution and without warranty."
|
|
37
|
+
|
|
38
|
+
license.meta["permitted"]
|
|
39
|
+
=> ["commercial-use","modifications","distribution","sublicense","private-use"]
|
|
40
|
+
|
|
41
|
+
# Getting all matches
|
|
42
|
+
Licensee.matches "/path/to/a/project"
|
|
43
|
+
=> [#<Licensee::License name="MIT" match=0.9842154131847726>,
|
|
44
|
+
#<Licensee::License name="unlicense" match=0.4326833797585887>,
|
|
45
|
+
...
|
|
46
|
+
#<Licensee::License name="no-license" match=0.0232126276694522>]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Diffing
|
|
50
|
+
|
|
51
|
+
You can also generate a diff of the known license to the distributed license.
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
puts Licensee.diff "/path/to/a/project"
|
|
55
|
+
-Copyright (c) [year] [fullname]
|
|
56
|
+
+Copyright (c) 2014 Ben Balter
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For a full list of diff options (HTML output, color output, etc.) see [Diffy](https://github.com/samg/diffy).
|
|
60
|
+
|
|
61
|
+
## Command line usage
|
|
62
|
+
|
|
63
|
+
1. `cd` into a project directory
|
|
64
|
+
2. execute the `licensee` command
|
|
65
|
+
|
|
66
|
+
You'll get an output that looks like:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
License: MIT
|
|
70
|
+
Match: 98.42%
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## What it looks at
|
|
74
|
+
|
|
75
|
+
* `LICENSE`, `LICENSE.txt`, etc. files in the root of the project, comparing the body to known licenses
|
|
76
|
+
* Crowdsourced license content and metadata from [`choosealicense.com`](http://choosealicense.com)
|
|
77
|
+
|
|
78
|
+
## What it doesn't look at
|
|
79
|
+
|
|
80
|
+
* Dependency licensing
|
|
81
|
+
* References to licenses in `README`, `README.md`, etc.
|
|
82
|
+
* Structured license data in package manager configuration files (like Gemfiles)
|
|
83
|
+
* Every single possible license (just the most popular ones)
|
|
84
|
+
* Compliance (e.g., whitelisting certain licenses)
|
|
85
|
+
|
|
86
|
+
If you're looking for dependency license checking and compliance, take a look at [LicenseFinder](https://github.com/pivotal/LicenseFinder).
|
|
87
|
+
|
|
88
|
+
## Huh? Why don't you look at X?
|
|
89
|
+
|
|
90
|
+
Because reasons.
|
|
91
|
+
|
|
92
|
+
### Why not just look at the "license" field of [insert package manager here]?
|
|
93
|
+
|
|
94
|
+
Because it's not legally binding. A license is a legal contract. You give up certain rights (e.g., the right to sue the author) in exchange for the right to use the software.
|
|
95
|
+
|
|
96
|
+
Most popular licenses today *require* that the license itself be distributed along side the software. Simply putting the letters "MIT" or "GPL" in a configuration file doesn't really meet that requirement.
|
|
97
|
+
|
|
98
|
+
Not to mention, it doesn't tell you much about your rights as a user. Is it GPLv2? GPLv2 or later? Those files are designed to be read by computers (who can't enter into contracts), not humans (who can). It's great metadata, but that's about it.
|
|
99
|
+
|
|
100
|
+
### What about looking to see if the author said something in the readme?
|
|
101
|
+
|
|
102
|
+
You could make an argument that, when linked or sufficiently identified, the terms of the license are incorporated by reference, or at least that the author's intent is there. There's a handful of reasons why this isn't ideal. For one, if you're using the MIT or BSD (ISC) license, along with a few others, there's templematic language, like the copyright notice, which would go unfilled.
|
|
103
|
+
|
|
104
|
+
### What about checking every single file for a copyright header?
|
|
105
|
+
|
|
106
|
+
Because that's silly in the context of how software is developed today. You wouldn't put a copyright notice on each page of a book. Besides, it's a lot of work, as there's no standardized, cross-platform way to describe a project's license within a comment.
|
|
107
|
+
|
|
108
|
+
Checking the actual text into version control is definitive, so that's what this project looks at.
|
|
109
|
+
|
|
110
|
+
## Bootstrapping a local development environment
|
|
111
|
+
|
|
112
|
+
`script/bootstrap`
|
|
113
|
+
|
|
114
|
+
## Running tests
|
|
115
|
+
|
|
116
|
+
`script/cibuild`
|
|
117
|
+
|
|
118
|
+
## Updating the licenses
|
|
119
|
+
|
|
120
|
+
License data is pulled from `choosealicense.com`. To update the license data, simple run `bower update`.
|
|
121
|
+
|
|
122
|
+
## Roadmap
|
|
123
|
+
|
|
124
|
+
See [proposed enhancements](https://github.com/benbalter/licensee/labels/enhancement).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/testtask'
|
|
3
|
+
|
|
4
|
+
Rake::TestTask.new(:test) do |test|
|
|
5
|
+
test.libs << 'lib' << 'test'
|
|
6
|
+
test.pattern = 'test/**/test_licensee*.rb'
|
|
7
|
+
test.verbose = true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
desc "Open console with Licensee loaded"
|
|
11
|
+
task :console do
|
|
12
|
+
exec "pry -r ./lib/licensee.rb"
|
|
13
|
+
end
|
data/bin/licensee
ADDED
data/lib/licensee.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'levenshtein-ffi'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require 'diffy'
|
|
4
|
+
|
|
5
|
+
require_relative "licensee/license"
|
|
6
|
+
require_relative "licensee/licenses"
|
|
7
|
+
require_relative "licensee/license_file"
|
|
8
|
+
require_relative "licensee/project"
|
|
9
|
+
|
|
10
|
+
class Licensee
|
|
11
|
+
|
|
12
|
+
CONFIDENCE_THRESHOLD = ".90".to_f
|
|
13
|
+
|
|
14
|
+
def self.licenses
|
|
15
|
+
Licensee::Licenses.list
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.license(path)
|
|
19
|
+
Licensee::Project.new(path).license
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.matches(path)
|
|
23
|
+
Licensee::Project.new(path).matches
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.diff(path, options=nil)
|
|
27
|
+
Licensee::Project.new(path).license_file.diff(options)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
class Licensee
|
|
2
|
+
class License
|
|
3
|
+
|
|
4
|
+
attr_reader :name
|
|
5
|
+
attr_accessor :match
|
|
6
|
+
|
|
7
|
+
def initialize(name)
|
|
8
|
+
@name=name
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def path
|
|
12
|
+
@path ||= File.expand_path "#{@name}.txt", Licensee::Licenses.base
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def content
|
|
16
|
+
@content ||= File.open(path).read
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def parts
|
|
20
|
+
@parts ||= content.match /^(---\n.*\n---)?(.*)/m
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def meta
|
|
24
|
+
@meta ||= front_matter = YAML.load(parts[1]) if parts[1]
|
|
25
|
+
rescue
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def length
|
|
30
|
+
@length ||= body.length
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def body
|
|
34
|
+
@body ||= parts[2]
|
|
35
|
+
end
|
|
36
|
+
alias_method :to_s, :body
|
|
37
|
+
|
|
38
|
+
def inspect
|
|
39
|
+
s = "#<Licensee::License name=\"#{name}\""
|
|
40
|
+
s += " match=#{match}" if match
|
|
41
|
+
s += ">"
|
|
42
|
+
s
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
class Licensee
|
|
2
|
+
class LicenseFile
|
|
3
|
+
|
|
4
|
+
FILENAMES = %w[
|
|
5
|
+
LICENSE
|
|
6
|
+
LICENSE.txt
|
|
7
|
+
LICENSE.md
|
|
8
|
+
UNLICENSE
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
attr_reader :path
|
|
12
|
+
|
|
13
|
+
def initialize(path)
|
|
14
|
+
@path = File.expand_path(path)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def contents
|
|
18
|
+
@contents ||= File.open(path).read
|
|
19
|
+
end
|
|
20
|
+
alias_method :to_s, :contents
|
|
21
|
+
alias_method :content, :contents
|
|
22
|
+
|
|
23
|
+
def self.find(base_path)
|
|
24
|
+
raise "Invalid directory" unless File.directory?(base_path)
|
|
25
|
+
file = self::FILENAMES.find { |file| File.exists? File.expand_path(file, base_path) }
|
|
26
|
+
new(File.expand_path(file, base_path)) if file
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def length
|
|
30
|
+
@length ||= content.length
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def length_delta(license)
|
|
34
|
+
(length - license.length).abs
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def potential_licenses
|
|
38
|
+
@potential_licenses ||= Licensee::Licenses.list.clone.select { |l| length_delta(l) < length }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def licenses_sorted
|
|
42
|
+
@licenses_sorted ||= potential_licenses.sort_by { |l| length_delta(l) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def matches
|
|
46
|
+
@matches ||= begin
|
|
47
|
+
licenses_sorted.each { |l| l.match = 1 - percent_changed(l) }
|
|
48
|
+
licenses_sorted.sort_by { |l| l.match }.select { |l| l.match > 0}.reverse
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def match
|
|
53
|
+
@match ||= licenses_sorted.find do |license|
|
|
54
|
+
confidence = 1 - percent_changed(license)
|
|
55
|
+
next unless confidence >= Licensee::CONFIDENCE_THRESHOLD
|
|
56
|
+
license.match = confidence
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def percent_changed(license)
|
|
61
|
+
(Levenshtein.distance(content, license.body).to_f / content.length.to_f).abs
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def diff(options=nil)
|
|
65
|
+
Diffy::Diff.new(match.body, content).to_s(options)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class Licensee
|
|
2
|
+
class Licenses
|
|
3
|
+
class << self
|
|
4
|
+
def names
|
|
5
|
+
@names ||= begin
|
|
6
|
+
names = Dir.entries(base)
|
|
7
|
+
names.map! { |l| File.basename(l, ".txt") }
|
|
8
|
+
names.reject! { |l| l =~ /^\./ || l.nil? }
|
|
9
|
+
names
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def list
|
|
14
|
+
@licenses ||= begin
|
|
15
|
+
licenses = []
|
|
16
|
+
names.each { |name| licenses.push License.new(name) }
|
|
17
|
+
licenses
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def base
|
|
22
|
+
@base ||= File.expand_path "../../vendor/choosealicense.com/licenses", File.dirname(__FILE__)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def find(name)
|
|
26
|
+
list.find { |l| l.name == name }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class Licensee
|
|
2
|
+
class Project
|
|
3
|
+
|
|
4
|
+
attr_reader :base_path
|
|
5
|
+
|
|
6
|
+
def initialize(base_path)
|
|
7
|
+
raise "Invalid directory" unless File.directory?(base_path)
|
|
8
|
+
@base_path = File.expand_path(base_path)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def license_file
|
|
12
|
+
@license_file ||= Licensee::LicenseFile.find(base_path)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def matches
|
|
16
|
+
@matches ||= license_file.matches if license_file
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def license
|
|
20
|
+
@license ||= license_file.match if license_file
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014 Ben Balter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014 Ben Balter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014 Ben Balter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/test/helper.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'bundler'
|
|
3
|
+
require 'minitest/autorun'
|
|
4
|
+
require 'shoulda'
|
|
5
|
+
require 'open3'
|
|
6
|
+
|
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
8
|
+
|
|
9
|
+
require 'licensee'
|
|
10
|
+
|
|
11
|
+
def fixtures_base
|
|
12
|
+
File.expand_path "fixtures", File.dirname( __FILE__ )
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def fixture_path(fixture)
|
|
16
|
+
File.expand_path fixture, fixtures_base
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class TestLicensee < Minitest::Test
|
|
4
|
+
should "know the licenses" do
|
|
5
|
+
assert_equal Array, Licensee.licenses.class
|
|
6
|
+
assert_equal 16, Licensee.licenses.size
|
|
7
|
+
assert_equal Licensee::License, Licensee.licenses.first.class
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
should "detect a project's license" do
|
|
11
|
+
assert_equal "MIT", Licensee.license(fixture_path("simple")).name
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class TestLicenseeBin < Minitest::Test
|
|
4
|
+
should "work via commandline" do
|
|
5
|
+
root = File.expand_path "..", File.dirname(__FILE__)
|
|
6
|
+
Dir.chdir root
|
|
7
|
+
stdout,stderr,status = Open3.capture3("#{root}/bin/licensee")
|
|
8
|
+
assert stdout.include? "License: MIT"
|
|
9
|
+
assert stdout.include? "Match: 98.42%"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class TestLicenseeLicense < Minitest::Test
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
@license = Licensee::License.new "MIT"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
should "read the license body" do
|
|
10
|
+
assert @license.body
|
|
11
|
+
assert @license.length > 0
|
|
12
|
+
assert @license.body =~ /MIT/
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
should "read the license meta" do
|
|
16
|
+
assert_equal "MIT License", @license.meta["title"]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class TestLicenseeLicenseFile < Minitest::Test
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
@file = Licensee::LicenseFile.find fixture_path("simple")
|
|
7
|
+
@gpl = Licensee::Licenses.find "GPL-3.0"
|
|
8
|
+
@mit = Licensee::Licenses.find "MIT"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
should "read the file" do
|
|
12
|
+
assert @file.contents =~ /MIT/
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
should "known the file length" do
|
|
16
|
+
assert_equal 1077, @file.length
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
should "calcualte length deltas" do
|
|
20
|
+
assert_equal 4, @file.length_delta(@mit)
|
|
21
|
+
assert_equal 34065, @file.length_delta(@gpl)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
should "sort licenses by length delta" do
|
|
25
|
+
assert_equal "MIT", @file.licenses_sorted.first.name
|
|
26
|
+
assert_equal "no-license", @file.licenses_sorted.last.name
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
should "calculate percent changed" do
|
|
30
|
+
assert @file.percent_changed(@mit) < ".02".to_f
|
|
31
|
+
assert @file.percent_changed(@gpl) > 30
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
should "match the license" do
|
|
35
|
+
assert_equal "MIT", @file.match.name
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
should "match a txt license" do
|
|
39
|
+
file = Licensee::LicenseFile.find fixture_path("txt")
|
|
40
|
+
assert_equal "MIT", file.match.name
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
should "match a md license" do
|
|
44
|
+
file = Licensee::LicenseFile.find fixture_path("md")
|
|
45
|
+
assert_equal "MIT", file.match.name
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
should "diff the file" do
|
|
49
|
+
expected = "-Copyright (c) [year] [fullname]\n+Copyright (c) 2014 Ben Balter"
|
|
50
|
+
assert @file.diff.include?(expected)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class TestLicenseeLicenses < Minitest::Test
|
|
4
|
+
|
|
5
|
+
should "know license names" do
|
|
6
|
+
assert_equal Array, Licensee::Licenses.names.class
|
|
7
|
+
assert_equal 16, Licensee::Licenses.names.size
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
should "load the licenses" do
|
|
11
|
+
assert_equal Array, Licensee::Licenses.list.class
|
|
12
|
+
assert_equal 16, Licensee::Licenses.list.size
|
|
13
|
+
assert_equal Licensee::License, Licensee::Licenses.list.first.class
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
should "find a license" do
|
|
17
|
+
assert_equal "MIT", Licensee::Licenses.find("MIT").name
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class TestLicenseeProject < Minitest::Test
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
@project = Licensee::Project.new fixture_path("simple")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
should "detect the license file" do
|
|
10
|
+
assert_equal Licensee::LicenseFile, @project.license_file.class
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
should "detect the license" do
|
|
14
|
+
assert_equal "MIT", @project.license.name
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: licensee
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ben Balter
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-08-17 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: levenshtein-ffi
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.1'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.1'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: diffy
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: pry
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0.9'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0.9'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: shoulda
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '3.5'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.5'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rake
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '10.3'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '10.3'
|
|
83
|
+
description: Licensee automates the process of reading LICENSE files and compares
|
|
84
|
+
their contents to known licenses using a fancy math thing called the Levenshtein
|
|
85
|
+
Distance.
|
|
86
|
+
email: ben.balter@github.com
|
|
87
|
+
executables:
|
|
88
|
+
- licensee
|
|
89
|
+
extensions: []
|
|
90
|
+
extra_rdoc_files: []
|
|
91
|
+
files:
|
|
92
|
+
- LICENSE.md
|
|
93
|
+
- README.md
|
|
94
|
+
- Rakefile
|
|
95
|
+
- bin/licensee
|
|
96
|
+
- lib/licensee.rb
|
|
97
|
+
- lib/licensee/license.rb
|
|
98
|
+
- lib/licensee/license_file.rb
|
|
99
|
+
- lib/licensee/licenses.rb
|
|
100
|
+
- lib/licensee/project.rb
|
|
101
|
+
- lib/licensee/version.rb
|
|
102
|
+
- test/fixtures/md/LICENSE.md
|
|
103
|
+
- test/fixtures/simple/LICENSE
|
|
104
|
+
- test/fixtures/txt/LICENSE.txt
|
|
105
|
+
- test/helper.rb
|
|
106
|
+
- test/test_licensee.rb
|
|
107
|
+
- test/test_licensee_bin.rb
|
|
108
|
+
- test/test_licensee_license.rb
|
|
109
|
+
- test/test_licensee_license_file.rb
|
|
110
|
+
- test/test_licensee_licenses.rb
|
|
111
|
+
- test/test_licensee_project.rb
|
|
112
|
+
homepage: http://github.com/benbalter/licensee
|
|
113
|
+
licenses: []
|
|
114
|
+
metadata: {}
|
|
115
|
+
post_install_message:
|
|
116
|
+
rdoc_options: []
|
|
117
|
+
require_paths:
|
|
118
|
+
- lib
|
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
|
+
requirements:
|
|
126
|
+
- - ">="
|
|
127
|
+
- !ruby/object:Gem::Version
|
|
128
|
+
version: '0'
|
|
129
|
+
requirements: []
|
|
130
|
+
rubyforge_project:
|
|
131
|
+
rubygems_version: 2.2.0
|
|
132
|
+
signing_key:
|
|
133
|
+
specification_version: 4
|
|
134
|
+
summary: A Ruby Gem to detect under what license a project is distributed
|
|
135
|
+
test_files: []
|