papers 1.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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MjJiMDlhOTlmYjAzNjcwNDE1N2QxN2IyOGU2MTllOGNhNjVlMDI3Yg==
5
+ data.tar.gz: !binary |-
6
+ MDBlNGZjZTRmMGQ5NTQ2Mjg4YWNjYzM0Y2M1MzNlM2RiMWY2NTBiYw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NGFhMTE2ZDg5MTg4ZDQ4NThhMDZjZTE3MzVkNDUwMDE4YzA0YzhhNDY3NWJk
10
+ ZDYwNGQzM2ExZWM1ZGU3ZmJjODgzNGM2NzRlYzBjMjhlOWFkYjI5OGFmODI4
11
+ NzQzZjI0ZWYxMzcyZDM1M2QyMmE3ZDgyOWFkMDQ3ZWUyNzg5NTU=
12
+ data.tar.gz: !binary |-
13
+ OWRkODEwYmFmNTRkZjE5OTg3OGUwZjU0MTJiNTVhNWVkZTgxMGIwNDc1MTEw
14
+ YzU1ZGU0ZGIyODQ0ZDNjODllZjBkYWM2MjdhMDJlYmI5ZWNiNWU1MzQ5ZDZm
15
+ YWUzZDBlM2Q0ZjBlNzA1YjE4YjRmNWMxMzgxYTI1ZDg3ZmQ4ZDY=
@@ -0,0 +1,5 @@
1
+ config/*
2
+ .DS_Store
3
+ Guardfile
4
+ *.swp
5
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,20 @@
1
+ Copyright 2013 New Relic
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,163 @@
1
+ # Papers
2
+
3
+ > "Papers, please."
4
+
5
+ Check that your Ruby/Rails project's dependencies are licensed with only the licenses you specify. **Papers** will validate that your gems and JavaScript files conform to a whitelist of software licenses. Don't get caught flat-footed by the GPL.
6
+
7
+ # Contents
8
+ * [Usage](#usage)
9
+ * [Validations](#validations)
10
+ * [Configuration](#configuration)
11
+ * [Structure of Dependency Manifest](#dependency-manifest-structure)
12
+ * [License](#license)
13
+ * [Contributing](#contributing)
14
+
15
+
16
+ # Usage
17
+
18
+ tl;dr -- add gem, generate dependency manifest, run spec
19
+
20
+ ### 0. Add gem to Gemfile
21
+
22
+ ```
23
+ gem 'papers'
24
+ ```
25
+ ### 1. Generate Dependency Manifest from your bundled gems and JS
26
+
27
+ ```
28
+ $ papers
29
+ ```
30
+ ### 2. Create [Validation Spec](#testing-with-rspec)
31
+
32
+ ### 3. Run the specs
33
+
34
+ ```
35
+ $ rake spec spec/integration/papers_license_validation_spec.rb
36
+ ...
37
+ Failures:
38
+
39
+ 1) Papers License Validation finds no errors during license validation
40
+ Failure/Error: expect(validator.errors).to eq([])
41
+
42
+ expected: []
43
+ got: ["sass-3.2.12 is licensed under GPL, which is not whitelisted"]
44
+
45
+ (compared using ==)
46
+ # ./spec/integration/papers_license_validation_spec.rb:14:in `block (2 levels) in <top (required)>'
47
+
48
+ 2) Papers License Validation knows and is satisfied by all dependency licenses
49
+ Failure/Error: expect(validator.valid?).to be_true
50
+ expected: true value
51
+ got: false
52
+ # ./spec/integration/papers_license_validation_spec.rb:9:in `block (2 levels) in <top (required)>'
53
+
54
+ Finished in 0.01043 seconds
55
+ 2 examples, 2 failures
56
+ ...
57
+ ```
58
+
59
+ # Validations
60
+
61
+ ## testing with RSpec
62
+
63
+ ```
64
+ # => spec/integration/papers_license_validation_spec.rb
65
+
66
+ require 'spec_helper'
67
+ require 'papers'
68
+
69
+ describe 'Papers License Validation' do
70
+
71
+ let(:validator) { Papers::LicenseValidator.new }
72
+
73
+ it 'knows and is satisfied by all dependency licenses' do
74
+ expect(validator.valid?).to be_true
75
+ end
76
+
77
+ it 'finds no errors during license validation' do
78
+ validator.valid?
79
+ expect(validator.errors).to eq([])
80
+ end
81
+ end
82
+ ```
83
+
84
+ ## testing with MiniTest
85
+
86
+ ```
87
+ # => test/integration/papers_license_validation_test.rb
88
+
89
+ require 'test_helper'
90
+ require 'papers'
91
+
92
+ class PapersLicenseValidationTest < ActiveSupport::TestCase
93
+ def test_know_and_be_satisfied_by_all_licenses
94
+ validator = Papers::LicenseValidator.new
95
+
96
+ assert validator.valid?, "License validator failed:\n#{validator.errors.join("\n")}"
97
+
98
+ assert_equal validator.errors, []
99
+ end
100
+ end
101
+ ```
102
+
103
+ # Configuration
104
+
105
+ The default whitelist allows for permissive licensing for proprietary or commercial usage while avoiding strong copyleft licenses.
106
+
107
+ ```
108
+ @license_whitelist = [
109
+ 'MIT',
110
+ 'BSD',
111
+ 'Apache 2.0',
112
+ 'Apache-2.0',
113
+ 'LGPLv2.1',
114
+ 'LGPLv3',
115
+ 'Ruby',
116
+ 'Manually Reviewed',
117
+ 'Unlicensed'
118
+ ]
119
+ ```
120
+
121
+ ## Available configuration options
122
+
123
+ To configure the Papers gem, pass options to ```Papers.configure``` before initialization of LicenseValidator:
124
+
125
+ ```
126
+ Papers.configure do |c|
127
+ c.license_whitelist << 'New Relic'
128
+ c.manifest_file = File.join('some','other','dependency_manifest.yml')
129
+ c.validate_gems = true
130
+ c.validate_javascript = true
131
+ c.javascript_paths << File.join('some','other','javascripts')
132
+ end
133
+
134
+ validator = Papers::LicenseValidator.new
135
+ ...
136
+ ```
137
+
138
+ # Dependency Manifest structure
139
+
140
+ ```
141
+ # => config/papers_manifest.yml
142
+ ---
143
+ gems:
144
+ sqlite3-1.3.7:
145
+ license: MIT
146
+ license_url: https://github.com/luislavena/sqlite3-ruby
147
+ project_url: https://github.com/luislavena/sqlite3-ruby/blob/master/LICENSE
148
+ ...
149
+
150
+ javascripts:
151
+ app/assets/javascripts/application.js:
152
+ license: New Relic
153
+ license_url: http://newrelic.com
154
+ project_url: http://newrelic.com
155
+ ```
156
+
157
+ # License
158
+
159
+ The Papers Gem is licensed under the __MIT License__. See [MIT-LICENSE](https://github.com/newrelic/papers/blob/master/MIT-LICENSE) for full text.
160
+
161
+ # Contributing
162
+
163
+ You are welcome to send pull requests to us - however, by doing so you agree that you are granting New Relic a non-exclusive, non-revokable, no-cost license to use the code, algorithms, patents, and ideas in that code in our products if we so choose. You also agree the code is provided as-is and you provide no warranties as to its fitness or correctness for any purpose.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.rspec_opts = "-c"
6
+ end
7
+
8
+ task :default => :spec
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ $LOAD_PATH.unshift(File.dirname(File.realpath(__FILE__)) + '/../lib')
5
+ require 'papers'
6
+
7
+ cli = Papers::CLI.new
8
+ cli.run
@@ -0,0 +1,25 @@
1
+ require 'papers/configuration'
2
+ require 'papers/license_validator'
3
+ require 'papers/manifest_generator'
4
+ require 'papers/cli'
5
+ require 'papers/version'
6
+
7
+ require 'papers/dependency_specification'
8
+ require 'papers/dependency_specification/gem'
9
+ require 'papers/dependency_specification/javascript'
10
+
11
+ module Papers
12
+ def self.configure(&block)
13
+ yield configuration
14
+ end
15
+
16
+ def self.configuration
17
+ @config ||= Configuration.new
18
+ end
19
+
20
+ # alias
21
+ def self.config
22
+ configuration
23
+ end
24
+
25
+ end
@@ -0,0 +1,41 @@
1
+ require 'optparse'
2
+
3
+ module Papers
4
+
5
+ class CLI
6
+
7
+ def run
8
+ if parse_options[:generate]
9
+ begin
10
+ generator = Papers::ManifestGenerator.new
11
+ generator.generate!
12
+ rescue Papers::FileExistsError => e
13
+ warn "Error: 'papers_manifest.yml' already exists at '#{e.message}'. Aborting..."
14
+ end
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def parse_options
21
+ options = {}
22
+ OptionParser.new do |opts|
23
+ opts.banner = "Usage: papers [options]"
24
+
25
+ opts.on("-g", "--generate", "Generate papers_manifest.yml") do |v|
26
+ options[:generate] = v
27
+ end
28
+
29
+ opts.on_tail( '-h', '--help', 'Display this screen' ) do |v|
30
+ p opts
31
+ exit
32
+ end
33
+ @avail_opts = opts
34
+ end.parse!
35
+
36
+ p @avail_opts if options.empty?
37
+
38
+ return options
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,46 @@
1
+ module Papers
2
+ class Configuration
3
+ attr_accessor :license_whitelist
4
+
5
+ attr_accessor :manifest_file
6
+
7
+ attr_accessor :validate_gems
8
+
9
+ attr_accessor :validate_javascript
10
+
11
+ attr_accessor :javascript_paths
12
+
13
+ def initialize
14
+ @license_whitelist = [
15
+ 'MIT',
16
+ 'BSD',
17
+ 'Apache 2.0',
18
+ 'Apache-2.0',
19
+ 'LGPLv2.1',
20
+ 'LGPLv3',
21
+ 'Ruby',
22
+ 'Manually Reviewed',
23
+ 'Unlicensed'
24
+ ]
25
+
26
+ @manifest_file = File.join(Dir.pwd, 'config', 'papers_manifest.yml')
27
+
28
+ @validate_gems = true
29
+ @validate_javascript = true
30
+
31
+ @javascript_paths = [
32
+ File.join(Dir.pwd, 'app', 'assets', 'javascripts'),
33
+ File.join(Dir.pwd, 'lib', 'assets', 'javascripts'),
34
+ File.join(Dir.pwd, 'vendor', 'assets', 'javascripts')
35
+ ]
36
+ end
37
+
38
+ def validate_gems?
39
+ !!@validate_gems
40
+ end
41
+
42
+ def validate_javascript?
43
+ !!@validate_javascript
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,35 @@
1
+ module Papers
2
+ class DependencySpecification
3
+ attr_accessor :name, :license, :license_url, :project_url
4
+
5
+ def initialize(options)
6
+ @name = options[:name]
7
+ @license = options[:license]
8
+ @license_url = options[:license_url]
9
+ @project_url = options[:project_url]
10
+ end
11
+
12
+ def acceptable_license?
13
+ Papers.config.license_whitelist.include?(license)
14
+ end
15
+
16
+ protected
17
+
18
+ def self.all_from_manifest(manifest)
19
+ (manifest[manifest_key] || []).map do |name, info|
20
+ license_url = info['license_url']
21
+ license = info['license']
22
+ project_url = info['project_url']
23
+ self.new(name: name, license: license, license_url: license_url, project_url: project_url)
24
+ end.sort { |a, b| a.name.downcase <=> b.name.downcase }
25
+ end
26
+
27
+ def self.missing_from_manifest(manifest)
28
+ introspected.to_set - all_from_manifest(manifest).map(&:name).to_set
29
+ end
30
+
31
+ def self.unknown_in_manifest(manifest)
32
+ all_from_manifest(manifest).map(&:name).to_set - introspected.to_set
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,32 @@
1
+ module Papers
2
+ class Gem < DependencySpecification
3
+ def pretty_hash
4
+ {
5
+ name: name_without_version,
6
+ license: license,
7
+ license_url: @license_url,
8
+ project_url: @project_url
9
+ }
10
+ end
11
+
12
+ def name_without_version
13
+ return @name unless @name.include?('-')
14
+ @name.split('-')[0..-2].join('-')
15
+ end
16
+
17
+ def self.introspected
18
+ Bundler.load.specs.map do |spec|
19
+ # bundler versions aren't controlled by the Gemfile
20
+ if spec.name == "bundler"
21
+ spec.name
22
+ else
23
+ "#{spec.name}-#{spec.version}"
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.manifest_key
29
+ "gems"
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ module Papers
2
+ class Javascript < DependencySpecification
3
+ def pretty_hash
4
+ {
5
+ name: @name,
6
+ license: license,
7
+ license_url: @license_url,
8
+ project_url: @project_url
9
+ }
10
+ end
11
+
12
+ def self.introspected
13
+ dirs = Papers.config.javascript_paths
14
+
15
+ # TODO: add logic for determining rails. Is Rails.root better than Dir.pwd for such a case?
16
+ root_regexp = /^#{Regexp.escape Dir.pwd.to_s}\//
17
+ dirs.map { |dir| Dir["#{dir}/**/*.js"] }.flatten.map { |name| name.sub(root_regexp, '') }
18
+ end
19
+
20
+ def self.manifest_key
21
+ "javascripts"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,62 @@
1
+ require 'yaml'
2
+
3
+ require 'papers/dependency_specification'
4
+ require 'papers/dependency_specification/gem'
5
+ require 'papers/dependency_specification/javascript'
6
+
7
+ module Papers
8
+ class LicenseValidator
9
+ attr_reader :errors
10
+
11
+ def initialize
12
+ @errors = []
13
+ end
14
+
15
+ def valid?
16
+ @errors = []
17
+
18
+ validate_gems if Papers.config.validate_gems?
19
+ validate_js if Papers.config.validate_javascript?
20
+
21
+ @errors.empty?
22
+ end
23
+
24
+ def manifest
25
+ @manifest ||= YAML.load_file(Papers.config.manifest_file)
26
+ end
27
+
28
+ def pretty_gem_list
29
+ Gem.all_from_manifest(manifest).map(&:pretty_hash)
30
+ end
31
+
32
+ def pretty_js_list
33
+ Javascript.all_from_manifest(manifest).map(&:pretty_hash)
34
+ end
35
+
36
+ private
37
+
38
+ def validate_spec_type(spec_type)
39
+ spec_type.missing_from_manifest(manifest).each do |name|
40
+ errors << "#{name} is included in the application, but not in the manifest"
41
+ end
42
+
43
+ spec_type.unknown_in_manifest(manifest).each do |name|
44
+ errors << "#{name} is included in the manifest, but not in the application"
45
+ end
46
+
47
+ spec_type.all_from_manifest(manifest).each do |spec|
48
+ unless spec.acceptable_license?
49
+ errors << "#{spec.name} is licensed under #{spec.license}, which is not whitelisted"
50
+ end
51
+ end
52
+ end
53
+
54
+ def validate_gems
55
+ validate_spec_type Gem
56
+ end
57
+
58
+ def validate_js
59
+ validate_spec_type Javascript
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,92 @@
1
+ require 'bundler'
2
+ require 'yaml'
3
+ require 'fileutils'
4
+
5
+ module Papers
6
+
7
+ class FileExistsError < StandardError;
8
+ attr_reader :manifest_path
9
+
10
+ def initialize(path)
11
+ @manifest_path = path
12
+ super
13
+ end
14
+ end
15
+
16
+ class ManifestGenerator
17
+
18
+ def generate!(args = ARGV)
19
+ @manifest_path = File.join('config','papers_manifest.yml')
20
+
21
+ raise Papers::FileExistsError.new(@manifest_path) if manifest_exists?
22
+
23
+ begin
24
+ if FileUtils.mkdir_p(File.dirname(@manifest_path))
25
+ File.open(@manifest_path, 'w') do |file|
26
+ file.write(build_header)
27
+ file.write(YAML.dump(build_manifest))
28
+ end
29
+ puts "Created #{@manifest_path}!"
30
+ end
31
+ rescue RuntimeError => e
32
+ warn "Failure! #{e}"
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def build_manifest
39
+ manifest = {
40
+ "gems" => get_installed_gems,
41
+ "javascripts" => get_installed_javascripts
42
+ }
43
+ return manifest
44
+ end
45
+
46
+ def get_installed_gems
47
+ gems = {}
48
+ Bundler.load.specs.each do |spec|
49
+ if spec.name == 'bundler'
50
+ name_and_version = spec.name
51
+ else
52
+ name_and_version = "#{spec.name}-#{spec.version}"
53
+ end
54
+
55
+ gems[name_and_version] = {
56
+ 'license' => spec.license || 'Unknown',
57
+ 'license_url' => nil,
58
+ 'project_url' => spec.homepage || nil
59
+ # TODO: add support for multiple licenses? some gemspecs have dual licensing
60
+ }
61
+ end
62
+ return gems
63
+ end
64
+
65
+ def get_installed_javascripts
66
+ js = {}
67
+ Javascript.introspected.each do |entry|
68
+ js[entry] = {
69
+ 'license' => 'Unknown',
70
+ 'license_url' => nil,
71
+ 'project_url' => nil
72
+ }
73
+ end
74
+ js.empty? ? nil : js
75
+ end
76
+
77
+ def manifest_exists?
78
+ !!File.exist?(@manifest_path)
79
+ end
80
+
81
+ def build_header
82
+ [
83
+ "# Dependency Manifest for the Papers gem",
84
+ "# Used to test your gems and javascript against license whitelist",
85
+ "#",
86
+ "# http://github.com/newrelic/papers\n"
87
+ ].join("\n")
88
+ end
89
+
90
+ end
91
+
92
+ end
@@ -0,0 +1,8 @@
1
+ module Papers
2
+ MAJOR = 1
3
+ MINOR = 0
4
+ PATCH = 1
5
+
6
+ VERSION = [MAJOR, MINOR, PATCH].join('.')
7
+ end
8
+
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
4
+
5
+ require 'papers/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'papers'
9
+ s.version = Papers::VERSION
10
+ s.summary = 'Validate the licenses of software dependencies you use'
11
+
12
+ s.description = <<-DESCRIPTION
13
+ Validate that the licenses used by your Ruby project's dependencies (both gems
14
+ and javascript libraries) conform to a software license whitelist. Don't get
15
+ caught flat-footed by the GPL.
16
+ DESCRIPTION
17
+
18
+ s.authors = ['Ralph Bodenner', 'Jade Rubick', 'Andrew Bloomgarden', 'Lucas Charles']
19
+ s.email = 'support@newrelic.com'
20
+ s.license = 'MIT'
21
+ s.homepage = 'http://github.com/newrelic/papers'
22
+
23
+ s.files = `git ls-files`.split($/)
24
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split($/)
25
+ s.executables = s.files.grep(/^bin\//) { |f| File.basename(f) }
26
+
27
+ s.require_paths = ['lib']
28
+
29
+ # dependencies
30
+ s.add_dependency 'rake', '~> 10.1'
31
+ s.add_development_dependency 'rspec', '~> 2.14'
32
+ end
@@ -0,0 +1,206 @@
1
+ require 'bundler/setup'
2
+ require 'rspec'
3
+ require_relative '../lib/papers'
4
+
5
+ describe 'Papers' do
6
+
7
+ let(:validator) { Papers::LicenseValidator.new }
8
+
9
+ it 'validates a manifest with empty values and set of dependencies' do
10
+ Papers::LicenseValidator.any_instance.stub(:manifest).and_return({
11
+ "javascripts" => {},
12
+ "gems" => {}
13
+ })
14
+ Papers::Gem.stub(:introspected).and_return([])
15
+
16
+ expect(validator.valid?).to be_true
17
+ end
18
+
19
+ it 'detects mismatched gems' do
20
+ Papers::LicenseValidator.any_instance.stub(:manifest).and_return({
21
+ "javascripts" => {},
22
+ "gems" => {
23
+ "foo-1.2" => {
24
+ 'license' => "MIT",
25
+ 'license_url' => nil,
26
+ 'project_url' => nil
27
+ },
28
+ "baz-1.3" => {
29
+ 'license' => "BSD",
30
+ 'license_url' => nil,
31
+ 'project_url' => nil
32
+ }
33
+ }
34
+ })
35
+ Papers::Gem.stub(:introspected).and_return(["bar-1.2", "baz-1.3"])
36
+
37
+ expect(validator.valid?).to be_false
38
+
39
+ expect(validator.errors).to eq([
40
+ "bar-1.2 is included in the application, but not in the manifest",
41
+ "foo-1.2 is included in the manifest, but not in the application"
42
+ ])
43
+
44
+ validator.valid?
45
+ end
46
+
47
+ it 'detects mismatched gem versions' do
48
+ Papers::Configuration.any_instance.stub(:validate_javascript?).and_return(true)
49
+
50
+ expect(validator).to receive(:validate_js).at_least(:once)
51
+
52
+ Papers::LicenseValidator.any_instance.stub(:manifest).and_return({
53
+ "javascripts" => {},
54
+ "gems" => {
55
+ "foo-1.2" => {
56
+ 'license' => "MIT",
57
+ 'license_url' => nil,
58
+ 'project_url' => nil
59
+ },
60
+ "baz-1.3" => {
61
+ 'license' => "BSD",
62
+ 'license_url' => nil,
63
+ 'project_url' => nil
64
+ }
65
+ }
66
+ })
67
+ Papers::Gem.stub(:introspected).and_return(["foo-1.2", "baz-1.2"])
68
+
69
+ expect(validator.valid?).to be_false
70
+
71
+ expect(validator.errors).to eq([
72
+ "baz-1.2 is included in the application, but not in the manifest",
73
+ "baz-1.3 is included in the manifest, but not in the application"
74
+ ])
75
+ validator.valid?
76
+ end
77
+
78
+ it 'is OK with matching gem sets' do
79
+ Papers::LicenseValidator.any_instance.stub(:manifest).and_return({
80
+ "javascripts" => {},
81
+ "gems" => {
82
+ "foo-1.2" => {
83
+ 'license' => "MIT",
84
+ 'license_url' => nil,
85
+ 'project_url' => nil
86
+ },
87
+ "baz-1.3" => {
88
+ 'license' => "BSD",
89
+ 'license_url' => nil,
90
+ 'project_url' => nil
91
+ }
92
+ },
93
+ })
94
+ Papers::Gem.stub(:introspected).and_return(["foo-1.2", "baz-1.3"])
95
+
96
+ expect(validator.valid?).to be_true
97
+ end
98
+
99
+ it 'is OK with matching gem sets but complain about a license issue' do
100
+ Papers::LicenseValidator.any_instance.stub(:manifest).and_return({
101
+ "javascripts" => {},
102
+ "gems" => {
103
+ "foo-1.2" => {
104
+ 'license' => "MIT",
105
+ 'license_url' => nil,
106
+ 'project_url' => nil
107
+ },
108
+ "baz-1.3" => {
109
+ 'license' => "GPL",
110
+ 'license_url' => nil,
111
+ 'project_url' => nil
112
+ }
113
+ },
114
+ })
115
+ Papers::Gem.stub(:introspected).and_return(["foo-1.2", "baz-1.3"])
116
+
117
+ expect(validator.valid?).to be_false
118
+
119
+ expect(validator.errors).to eq([
120
+ "baz-1.3 is licensed under GPL, which is not whitelisted"
121
+ ])
122
+
123
+ validator.valid?
124
+ end
125
+
126
+ it 'displays gem licenses in a pretty format without versions' do
127
+ Papers::LicenseValidator.any_instance.stub(:manifest).and_return({
128
+ "javascripts" => {},
129
+ "gems" => {
130
+ "foo-1.2" => {
131
+ 'license' => "MIT",
132
+ 'license_url' => nil,
133
+ 'project_url' => nil
134
+ },
135
+ "baz-1.3" => {
136
+ 'license' => "BSD",
137
+ 'license_url' => nil,
138
+ 'project_url' => nil
139
+ },
140
+ "with-hyphens-1.4" => {
141
+ 'license' => "MIT",
142
+ 'license_url' => nil,
143
+ 'project_url' => nil
144
+ }
145
+ },
146
+ })
147
+ expect(validator.pretty_gem_list).to eq([
148
+ {
149
+ :name=>"baz",
150
+ :license=>"BSD",
151
+ :license_url => nil,
152
+ :project_url => nil
153
+ },
154
+ {
155
+ :name=>"foo",
156
+ :license=>"MIT",
157
+ :license_url => nil,
158
+ :project_url => nil
159
+ },
160
+ {
161
+ :name=>"with-hyphens",
162
+ :license=>"MIT",
163
+ :license_url => nil,
164
+ :project_url => nil
165
+ }
166
+ ])
167
+ end
168
+
169
+ it 'displays JS libraries in a pretty format without versions' do
170
+ Papers::LicenseValidator.any_instance.stub(:manifest).and_return({
171
+ "javascripts" => {
172
+ "/path/to/foo.js" => {
173
+ 'license' => "MIT",
174
+ 'license_url' => nil,
175
+ 'project_url' => nil
176
+ },
177
+ "/path/to/newrelic.js" => {
178
+ 'license' => "New Relic",
179
+ 'license_url' => nil,
180
+ 'project_url' => nil
181
+ }
182
+ },
183
+ "gems" => {}
184
+ })
185
+ expect(validator.pretty_js_list).to eq([
186
+ {
187
+ :name =>"/path/to/foo.js",
188
+ :license =>"MIT",
189
+ :license_url => nil,
190
+ :project_url => nil
191
+ },
192
+ {
193
+ :name =>"/path/to/newrelic.js",
194
+ :license =>"New Relic",
195
+ :license_url => nil,
196
+ :project_url => nil
197
+ }
198
+ ])
199
+ end
200
+
201
+ it 'displays the gem name when the gemspec does not specify a version' do
202
+ gemspec = Papers::Gem.new(name: 'foo')
203
+ expect('foo').to eq(gemspec.name_without_version)
204
+ end
205
+
206
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: papers
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ralph Bodenner
8
+ - Jade Rubick
9
+ - Andrew Bloomgarden
10
+ - Lucas Charles
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2013-12-10 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rake
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '10.1'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '10.1'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ~>
35
+ - !ruby/object:Gem::Version
36
+ version: '2.14'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '2.14'
44
+ description: ! 'Validate that the licenses used by your Ruby project''s dependencies
45
+ (both gems
46
+
47
+ and javascript libraries) conform to a software license whitelist. Don''t get
48
+
49
+ caught flat-footed by the GPL.
50
+
51
+ '
52
+ email: support@newrelic.com
53
+ executables:
54
+ - papers
55
+ extensions: []
56
+ extra_rdoc_files: []
57
+ files:
58
+ - .gitignore
59
+ - Gemfile
60
+ - MIT-LICENSE
61
+ - README.md
62
+ - Rakefile
63
+ - bin/papers
64
+ - lib/papers.rb
65
+ - lib/papers/cli.rb
66
+ - lib/papers/configuration.rb
67
+ - lib/papers/dependency_specification.rb
68
+ - lib/papers/dependency_specification/gem.rb
69
+ - lib/papers/dependency_specification/javascript.rb
70
+ - lib/papers/license_validator.rb
71
+ - lib/papers/manifest_generator.rb
72
+ - lib/papers/version.rb
73
+ - papers.gemspec
74
+ - spec/papers_spec.rb
75
+ homepage: http://github.com/newrelic/papers
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.1.5
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Validate the licenses of software dependencies you use
99
+ test_files:
100
+ - spec/papers_spec.rb
101
+ has_rdoc: