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.
Files changed (34) hide show
  1. data/.gitignore +2 -1
  2. data/.rspec +1 -0
  3. data/{MIT-LICENSE → LICENSE} +1 -1
  4. data/README.markdown +125 -75
  5. data/Rakefile +9 -0
  6. data/features/rake_tasks/action_items.feature +13 -0
  7. data/features/rake_tasks/action_items_ok.feature +20 -0
  8. data/features/rake_tasks/generate_dependencies.feature +31 -0
  9. data/features/rake_tasks/init.feature +19 -0
  10. data/features/step_definitions/steps.rb +131 -0
  11. data/files/license_finder.yml +3 -2
  12. data/lib/license_finder.rb +29 -0
  13. data/lib/license_finder/dependency.rb +13 -14
  14. data/lib/license_finder/dependency_list.rb +23 -5
  15. data/lib/license_finder/finder.rb +6 -19
  16. data/lib/license_finder/gem_spec_details.rb +11 -3
  17. data/lib/license_finder/license_file.rb +21 -7
  18. data/lib/templates/ISC-body +2 -0
  19. data/lib/templates/LGPL-body +165 -0
  20. data/license_finder.gemspec +11 -16
  21. data/spec/fixtures/ISC-LICENSE +10 -0
  22. data/spec/fixtures/isc_licensed_gem/LICENSE +10 -0
  23. data/spec/fixtures/lgpl_licensed_gem/LICENSE +165 -0
  24. data/spec/{dependency_list_spec.rb → lib/license_finder/dependency_list_spec.rb} +26 -23
  25. data/spec/lib/license_finder/dependency_spec.rb +53 -0
  26. data/spec/{file_parser_spec.rb → lib/license_finder/file_parser_spec.rb} +0 -0
  27. data/spec/lib/license_finder/finder_spec.rb +36 -0
  28. data/spec/{gem_spec_details_spec.rb → lib/license_finder/gem_spec_details_spec.rb} +25 -8
  29. data/spec/{license_file_spec.rb → lib/license_finder/license_file_spec.rb} +38 -22
  30. data/spec/lib/license_finder_spec.rb +82 -0
  31. metadata +100 -32
  32. data/lib/license_finder/version.rb +0 -3
  33. data/spec/dependency_spec.rb +0 -57
  34. data/spec/finder_spec.rb +0 -64
data/.gitignore CHANGED
@@ -3,4 +3,5 @@ pkg/*
3
3
  .bundle
4
4
  Gemfile.lock
5
5
  .rvmrc
6
- .idea/*
6
+ .idea/*
7
+ tmp/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2010 Jacob Maine
3
+ Copyright (c) 2012 Pivotal Labs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,98 +1,148 @@
1
- Goal
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
- Usage
7
+ ## Installation
7
8
  =====
8
9
 
9
- For a Rails project add license_finder to your Gemfile:
10
- gem 'license_finder', :git => "https://github.com/pivotal/LicenseFinder.git"
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
- Run 'rake license:init'
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
- Run 'rake license:generate_dependencies'
16
- This will write out a dependencies.yml and dependencies.txt file in the root of your project.
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
- Run 'rake license:action_items'
20
- This will output a list of unapproved dependencies to the console
38
+ ### Action Items
21
39
 
22
- Run 'rake license:action_items:ok'
23
- This will return a non-zero exit status if there are unapproved dependencies. Great for CI.
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
- cd ~
28
- git clone http://github.com/pivotal/LicenseFinder.git license_finder
29
- cd your/project
30
- ~/license_finder/bin/license_finder
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
- dependencies.yml:
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
- - name: "json_pure"
41
- version: "1.5.1"
42
- license: "other"
43
- approved: false
82
+ ```yaml
83
+ ---
84
+ - name: "json_pure"
85
+ version: "1.5.1"
86
+ license: "other"
87
+ approved: false
44
88
 
45
- - name: "rake"
46
- version: "0.8.7"
47
- license: "MIT"
48
- approved: true
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
- json_pure 1.5.1:
59
- dependency_name: json_pure
60
- dependency_version: 1.5.1
61
- install_path: /some/path/.rvm/gems/ruby-1.9.2-p180/gems/json_pure-1.5.1
62
- license_files:
63
- - file_name: COPYING
64
- header_type: other
65
- body_type: other
66
- disclaimer_of_liability: other
67
- - file_name: COPYING-json-jruby
68
- header_type: other
69
- body_type: other
70
- disclaimer_of_liability: other
71
- readme_files:
72
- - file_name: README
73
- mentions_license: true
74
- - file_name: README-json-jruby.markdown
75
- mentions_license: false
76
- ---
77
- rake 0.8.7:
78
- dependency_name: rake
79
- dependency_version: 0.8.7
80
- install_path: /some/path/.rvm/gems/ruby-1.9.2-p180/gems/rake-0.8.7
81
- license_files:
82
- - file_name: MIT-LICENSE
83
- header_type: other
84
- body_type: mit
85
- disclaimer_of_liability: "mit: THE AUTHORS OR COPYRIGHT HOLDERS"
86
- readme_files:
87
- - file_name: README
88
- mentions_license: true
89
-
90
- Gem Maintainers
91
- ===============
92
-
93
- Please add a license to your gemspec!
94
-
95
- Gem::Specification.new do |s|
96
- s.name = "my_great_gem"
97
- s.license = "MIT"
98
- end
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