license_finder 0.4.1 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/.rspec +1 -0
- data/{MIT-LICENSE → LICENSE} +1 -1
- data/README.markdown +125 -75
- data/Rakefile +9 -0
- data/features/rake_tasks/action_items.feature +13 -0
- data/features/rake_tasks/action_items_ok.feature +20 -0
- data/features/rake_tasks/generate_dependencies.feature +31 -0
- data/features/rake_tasks/init.feature +19 -0
- data/features/step_definitions/steps.rb +131 -0
- data/files/license_finder.yml +3 -2
- data/lib/license_finder.rb +29 -0
- data/lib/license_finder/dependency.rb +13 -14
- data/lib/license_finder/dependency_list.rb +23 -5
- data/lib/license_finder/finder.rb +6 -19
- data/lib/license_finder/gem_spec_details.rb +11 -3
- data/lib/license_finder/license_file.rb +21 -7
- data/lib/templates/ISC-body +2 -0
- data/lib/templates/LGPL-body +165 -0
- data/license_finder.gemspec +11 -16
- data/spec/fixtures/ISC-LICENSE +10 -0
- data/spec/fixtures/isc_licensed_gem/LICENSE +10 -0
- data/spec/fixtures/lgpl_licensed_gem/LICENSE +165 -0
- data/spec/{dependency_list_spec.rb → lib/license_finder/dependency_list_spec.rb} +26 -23
- data/spec/lib/license_finder/dependency_spec.rb +53 -0
- data/spec/{file_parser_spec.rb → lib/license_finder/file_parser_spec.rb} +0 -0
- data/spec/lib/license_finder/finder_spec.rb +36 -0
- data/spec/{gem_spec_details_spec.rb → lib/license_finder/gem_spec_details_spec.rb} +25 -8
- data/spec/{license_file_spec.rb → lib/license_finder/license_file_spec.rb} +38 -22
- data/spec/lib/license_finder_spec.rb +82 -0
- metadata +100 -32
- data/lib/license_finder/version.rb +0 -3
- data/spec/dependency_spec.rb +0 -57
- data/spec/finder_spec.rb +0 -64
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/{MIT-LICENSE → LICENSE}
RENAMED
data/README.markdown
CHANGED
@@ -1,98 +1,148 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# License Finder
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/pivotal/LicenseFinder.png)](http://travis-ci.org/pivotal/LicenseFinder)
|
3
4
|
|
4
5
|
With bundler it's easy for your project to depend on many gems. This decomposition is nice, but managing licenses becomes difficult. This tool gathers info about the licenses of the gems in your project.
|
5
6
|
|
6
|
-
|
7
|
+
## Installation
|
7
8
|
=====
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
Add license_finder to your Rails project's Gemfile and `bundle`:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'license_finder', :git => "https://github.com/pivotal/LicenseFinder.git"
|
14
|
+
```
|
15
|
+
|
16
|
+
Now, initialize license finder:
|
17
|
+
|
18
|
+
```sh
|
19
|
+
$ bundle exec rake license:init
|
20
|
+
```
|
21
|
+
|
22
|
+
This will create a `config/license_finder.yml` file that lets you configure license finder.
|
23
|
+
This is where you should add licenses which are allowed on the project, so they will be automatically approved.
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Once you've whitelisted licenses, you can then tell license finder to analyze your Gemfile:
|
28
|
+
|
29
|
+
```sh
|
30
|
+
$ bundle exec rake license:generate_dependencies
|
31
|
+
```
|
11
32
|
|
12
|
-
|
13
|
-
This will create a config/license_finder.yml file that lets you configure license finder. This is where you should add licenses which are allowed on the project, so they will be automatically approved.
|
33
|
+
This will write out a dependencies.yml and dependencies.txt file in the root of your project.
|
14
34
|
|
15
|
-
|
16
|
-
|
17
|
-
It will also merge in an existing dependencies.yml file, if one exists.
|
35
|
+
It will also merge in an existing dependencies.yml file, if one exists (i.e., you've previously run this command
|
36
|
+
and then edited the resulting file).
|
18
37
|
|
19
|
-
|
20
|
-
This will output a list of unapproved dependencies to the console
|
38
|
+
### Action Items
|
21
39
|
|
22
|
-
|
23
|
-
|
40
|
+
Once you've generated a `dependencies.yml` file via the `rake license:generate_dependencies` file, you can tell
|
41
|
+
License Finder to output a list of dependencies that have non-whitelisted licenses:
|
42
|
+
|
43
|
+
```sh
|
44
|
+
$ bundle exec rake license:action_items
|
45
|
+
```
|
46
|
+
|
47
|
+
This will output a list of unapproved dependencies to the console.
|
48
|
+
|
49
|
+
Similarly, `bundle exec rake license:action_items:ok` will return a non-zero exit status if there unapproved dependencies.
|
50
|
+
You could use this in a CI build, for example, to alert you whenever someone adds an unapproved dependency to the project.
|
51
|
+
|
52
|
+
|
53
|
+
## Usage outside Rails
|
24
54
|
|
25
55
|
As a standalone script:
|
26
56
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
57
|
+
```sh
|
58
|
+
$ git clone http://github.com/pivotal/LicenseFinder.git license_finder
|
59
|
+
$ cd /path/to/your/project
|
60
|
+
$ /path/to/license_finder/bin/license_finder
|
61
|
+
```
|
31
62
|
|
32
63
|
Optionally add `--with-licenses` to include the full text of the licenses in the output.
|
33
64
|
|
34
|
-
Sample Output
|
35
|
-
=============
|
36
65
|
|
37
|
-
|
66
|
+
## Sample Output
|
67
|
+
|
68
|
+
File: `config/license_finder.yml`:
|
69
|
+
|
70
|
+
```yaml
|
71
|
+
---
|
72
|
+
whitelist:
|
73
|
+
- MIT
|
74
|
+
- Apache 2.0
|
75
|
+
ignore_groups:
|
76
|
+
- test
|
77
|
+
- development
|
78
|
+
```
|
79
|
+
|
80
|
+
File: `dependencies.yml`:
|
38
81
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
82
|
+
```yaml
|
83
|
+
---
|
84
|
+
- name: "json_pure"
|
85
|
+
version: "1.5.1"
|
86
|
+
license: "other"
|
87
|
+
approved: false
|
44
88
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
89
|
+
- name: "rake"
|
90
|
+
version: "0.8.7"
|
91
|
+
license: "MIT"
|
92
|
+
approved: true
|
93
|
+
```
|
49
94
|
|
50
|
-
dependencies.txt
|
95
|
+
File: `dependencies.txt`:
|
51
96
|
|
52
97
|
json_pure 1.5.1, other
|
53
98
|
rake 0.8.7, MIT
|
54
99
|
|
55
|
-
bin/license_finder
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
100
|
+
File: `bin/license_finder`:
|
101
|
+
|
102
|
+
```yaml
|
103
|
+
---
|
104
|
+
json_pure 1.5.1:
|
105
|
+
dependency_name: json_pure
|
106
|
+
dependency_version: 1.5.1
|
107
|
+
install_path: /some/path/.rvm/gems/ruby-1.9.2-p180/gems/json_pure-1.5.1
|
108
|
+
license_files:
|
109
|
+
- file_name: COPYING
|
110
|
+
header_type: other
|
111
|
+
body_type: other
|
112
|
+
disclaimer_of_liability: other
|
113
|
+
- file_name: COPYING-json-jruby
|
114
|
+
header_type: other
|
115
|
+
body_type: other
|
116
|
+
disclaimer_of_liability: other
|
117
|
+
readme_files:
|
118
|
+
- file_name: README
|
119
|
+
mentions_license: true
|
120
|
+
- file_name: README-json-jruby.markdown
|
121
|
+
mentions_license: false
|
122
|
+
---
|
123
|
+
rake 0.8.7:
|
124
|
+
dependency_name: rake
|
125
|
+
dependency_version: 0.8.7
|
126
|
+
install_path: /some/path/.rvm/gems/ruby-1.9.2-p180/gems/rake-0.8.7
|
127
|
+
license_files:
|
128
|
+
- file_name: MIT-LICENSE
|
129
|
+
header_type: other
|
130
|
+
body_type: mit
|
131
|
+
disclaimer_of_liability: "mit: THE AUTHORS OR COPYRIGHT HOLDERS"
|
132
|
+
readme_files:
|
133
|
+
- file_name: README
|
134
|
+
mentions_license: true
|
135
|
+
```
|
136
|
+
|
137
|
+
## A note to gem authors / maintainers
|
138
|
+
|
139
|
+
For the good of humanity, please add a license to your gemspec!
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
Gem::Specification.new do |s|
|
143
|
+
s.name = "my_great_gem"
|
144
|
+
s.license = "MIT"
|
145
|
+
end
|
146
|
+
```
|
147
|
+
|
148
|
+
And add a `LICENSE` file to your gem that contains your license text.
|
data/Rakefile
CHANGED
@@ -2,6 +2,8 @@ require 'bundler'
|
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
3
|
|
4
4
|
require 'rspec/core/rake_task'
|
5
|
+
require 'cucumber'
|
6
|
+
require 'cucumber/rake/task'
|
5
7
|
|
6
8
|
desc "Run all specs in spec/"
|
7
9
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
@@ -10,3 +12,10 @@ RSpec::Core::RakeTask.new(:spec) do |t|
|
|
10
12
|
t.rspec_opts = %w[--color]
|
11
13
|
end
|
12
14
|
|
15
|
+
|
16
|
+
desc "Run all cukes in features/"
|
17
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
18
|
+
t.cucumber_opts = "features --format pretty"
|
19
|
+
end
|
20
|
+
|
21
|
+
task default: [:spec, :features]
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: rake license:action_items
|
2
|
+
As a user
|
3
|
+
I want a rake task "license:action_items" that lists any dependencies with licenses that fall outside of my whitelist
|
4
|
+
So that I know the limitations of distributing my application
|
5
|
+
|
6
|
+
Scenario: Application with non-free dependency
|
7
|
+
Given I have a rails application with license finder
|
8
|
+
And my rails app depends on a gem "gpl_licensed_gem" licensed with "GPL"
|
9
|
+
And my rails app depends on a gem "mit_licensed_gem" licensed with "MIT"
|
10
|
+
And I whitelist the "MIT" license
|
11
|
+
When I run "bundle exec rake license:action_items"
|
12
|
+
Then I should see "gpl_licensed_gem" in its output
|
13
|
+
And I should not see "mit_licensed_gem" in its output
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: rake license:action_items:ok
|
2
|
+
As a user
|
3
|
+
I want a rake task "license:action_items:ok" that returns 0/1 exit codes based on whether or not there any action items
|
4
|
+
So that I can create a CI build that fails if there are any action items
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given I have a rails application with license finder
|
8
|
+
|
9
|
+
Scenario: Application with action items
|
10
|
+
Given my rails app depends on a gem "gpl_licensed_gem" licensed with "GPL"
|
11
|
+
And I whitelist the "MIT" license
|
12
|
+
When I run "bundle exec rake license:action_items:ok"
|
13
|
+
Then I should see "Dependencies that need approval" in its output
|
14
|
+
And it should exit with status code 1
|
15
|
+
|
16
|
+
Scenario: Application with no action items
|
17
|
+
Given I whitelist the following licenses: "MIT, other"
|
18
|
+
When I run "bundle exec rake license:action_items:ok"
|
19
|
+
Then I should see "All gems are approved for use" in its output
|
20
|
+
And it should exit with status code 0
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Feature: rake license:generate_dependencies
|
2
|
+
As a user
|
3
|
+
I want a rake task the generates a list of all my application's dependencies and their licenses
|
4
|
+
So that I can manually approve a dependency with a non-whitelisted license
|
5
|
+
|
6
|
+
Scenario: Manually approve non-whitelisted dependency
|
7
|
+
Given I have a rails application with license finder
|
8
|
+
And my rails app depends on a gem "gpl_gem" licensed with "GPL"
|
9
|
+
And I whitelist the "MIT" license
|
10
|
+
|
11
|
+
When I run "bundle exec rake license:generate_dependencies"
|
12
|
+
|
13
|
+
Then license finder should generate a file "dependencies.yml" that includes the following content:
|
14
|
+
"""
|
15
|
+
- name: "gpl_gem"
|
16
|
+
version: "0.0.0"
|
17
|
+
license: "GPL"
|
18
|
+
approved: false
|
19
|
+
"""
|
20
|
+
|
21
|
+
When I replace that content with the following content in "dependencies.yml":
|
22
|
+
"""
|
23
|
+
- name: "gpl_gem"
|
24
|
+
version: "0.0.0"
|
25
|
+
license: "GPL"
|
26
|
+
approved: true
|
27
|
+
"""
|
28
|
+
|
29
|
+
And I run "bundle exec rake license:action_items"
|
30
|
+
|
31
|
+
Then I should not see "gpl_gem" in its output
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: rake license:init
|
2
|
+
As a user
|
3
|
+
I want a rake task the generates a sample license finder configuration for me
|
4
|
+
So that I can easily get started using License Finder
|
5
|
+
|
6
|
+
Scenario: No license finder configuration
|
7
|
+
Given I have a rails application with license finder
|
8
|
+
When I run "bundle exec rake license:init"
|
9
|
+
Then license finder should generate a file "config/license_finder.yml" with the following content:
|
10
|
+
"""
|
11
|
+
---
|
12
|
+
whitelist:
|
13
|
+
#- MIT
|
14
|
+
#- Apache 2.0
|
15
|
+
ignore_groups:
|
16
|
+
#- test
|
17
|
+
#- development
|
18
|
+
dependencies_file_dir: './'
|
19
|
+
"""
|
@@ -0,0 +1,131 @@
|
|
1
|
+
Given /^I have a rails application with license finder$/ do
|
2
|
+
@user = DSL::User.new
|
3
|
+
@user.create_rails_app
|
4
|
+
end
|
5
|
+
|
6
|
+
Given /^my rails app depends on a gem "(.*?)" licensed with "(.*?)"$/ do |gem_name, license|
|
7
|
+
@user.add_dependency_to_app gem_name, license
|
8
|
+
end
|
9
|
+
|
10
|
+
Given /^I whitelist the "(.*?)" license$/ do |license|
|
11
|
+
@user.configure_license_finder_whitelist [license]
|
12
|
+
end
|
13
|
+
|
14
|
+
Given /^I whitelist the following licenses: "([^"]*)"$/ do |licenses|
|
15
|
+
@user.configure_license_finder_whitelist licenses.split(", ")
|
16
|
+
end
|
17
|
+
|
18
|
+
When /^I run "(.*?)"$/ do |command|
|
19
|
+
@output = @user.execute_command command
|
20
|
+
end
|
21
|
+
|
22
|
+
When /^I replace that content with the following content in "([^"]*)":$/ do |filename, text|
|
23
|
+
@user.edit_file(filename, replace_this: @content, with: text)
|
24
|
+
end
|
25
|
+
|
26
|
+
Then /^I should see "(.*?)" in its output$/ do |gem_name|
|
27
|
+
@output.should include gem_name
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /^I should not see "(.*?)" in its output$/ do |gem_name|
|
31
|
+
@output.should_not include gem_name
|
32
|
+
end
|
33
|
+
|
34
|
+
Then /^license finder should generate a file "([^"]*)" with the following content:$/ do |filename, text|
|
35
|
+
File.read(File.join(@user.app_location, filename)).should == text.gsub(/^\s+/, "")
|
36
|
+
end
|
37
|
+
|
38
|
+
Then /^license finder should generate a file "([^"]*)" that includes the following content:$/ do |filename, text|
|
39
|
+
@content = text
|
40
|
+
file = File.read(File.join(@user.app_location, filename))
|
41
|
+
file.should include @content
|
42
|
+
end
|
43
|
+
|
44
|
+
Then /^it should exit with status code (\d)$/ do |status|
|
45
|
+
$?.exitstatus.should == status.to_i
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
module DSL
|
51
|
+
class User
|
52
|
+
def create_rails_app
|
53
|
+
reset_sandbox!
|
54
|
+
|
55
|
+
`bundle exec rails new #{app_location} --skip-bundle`
|
56
|
+
|
57
|
+
Bundler.with_clean_env do
|
58
|
+
`cd #{app_location} && echo \"gem 'license_finder', path: '../../'\" >> Gemfile`
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def edit_file(filename, options={})
|
63
|
+
replace_this = options.fetch :replace_this
|
64
|
+
with = options.fetch :with
|
65
|
+
|
66
|
+
file_contents = File.read(File.join(app_location, filename))
|
67
|
+
|
68
|
+
file_contents[replace_this] = with
|
69
|
+
|
70
|
+
File.open(File.join(app_location, filename), "w") do |f|
|
71
|
+
f.puts file_contents
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def add_dependency_to_app(gem_name, license)
|
76
|
+
`mkdir #{sandbox_location}/#{gem_name}`
|
77
|
+
|
78
|
+
File.open("#{sandbox_location}/#{gem_name}/#{gem_name}.gemspec", 'w') do |file|
|
79
|
+
file.write <<-GEMSPEC
|
80
|
+
Gem::Specification.new do |s|
|
81
|
+
s.name = "#{gem_name}"
|
82
|
+
s.version = "0.0.0"
|
83
|
+
s.author = "Cucumber"
|
84
|
+
s.summary = "Gem for testing License Finder"
|
85
|
+
s.license = "#{license}"
|
86
|
+
end
|
87
|
+
GEMSPEC
|
88
|
+
end
|
89
|
+
|
90
|
+
Bundler.with_clean_env do
|
91
|
+
`cd #{app_location} && echo \"gem '#{gem_name}', path: '../#{gem_name}'\" >> Gemfile && bundle`
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def configure_license_finder_whitelist(whitelisted_licenses=[])
|
96
|
+
File.open("tmp/my_app/config/license_finder.yml", "w") do |f|
|
97
|
+
f.write <<-YML
|
98
|
+
---
|
99
|
+
whitelist:
|
100
|
+
#{whitelisted_licenses.map {|l| "- #{l}"}.join("\n")}
|
101
|
+
YML
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def execute_command(command)
|
106
|
+
Bundler.with_clean_env do
|
107
|
+
@output = `cd #{app_location} && bundle exec #{command}`
|
108
|
+
end
|
109
|
+
|
110
|
+
@output
|
111
|
+
end
|
112
|
+
|
113
|
+
def app_location
|
114
|
+
File.join(sandbox_location, app_name)
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
def app_name
|
119
|
+
"my_app"
|
120
|
+
end
|
121
|
+
|
122
|
+
def sandbox_location
|
123
|
+
"tmp"
|
124
|
+
end
|
125
|
+
|
126
|
+
def reset_sandbox!
|
127
|
+
`rm -rf #{sandbox_location}`
|
128
|
+
`mkdir #{sandbox_location}`
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|