license_finder 0.9.4 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -7
- data/.travis.yml +1 -3
- data/CHANGELOG.rdoc +13 -0
- data/db/migrate/201307251004_data_fix_manual_licenses.rb +2 -2
- data/db/migrate/201307251107_reassociate_license.rb +18 -18
- data/db/migrate/201311192002_add_manually_approved_to_dependencies.rb +7 -0
- data/db/migrate/201311192003_reassociate_manual_approval.rb +14 -0
- data/db/migrate/201311192010_drop_approvals.rb +5 -0
- data/features/cli.feature +1 -1
- data/features/html_report.feature +1 -1
- data/features/{non_bundler_dependencies.feature → manually_managed_dependencies.feature} +6 -6
- data/features/step_definitions/html_report_steps.rb +2 -9
- data/features/step_definitions/{non_bundler_steps.rb → manually_managed_steps.rb} +0 -0
- data/features/step_definitions/shared_steps.rb +4 -8
- data/lib/license_finder.rb +21 -17
- data/lib/license_finder/bower.rb +3 -34
- data/lib/license_finder/bower_package.rb +63 -0
- data/lib/license_finder/bundler.rb +73 -0
- data/lib/license_finder/bundler_package.rb +33 -0
- data/lib/license_finder/cli.rb +33 -35
- data/lib/license_finder/dependency_manager.rb +14 -23
- data/lib/license_finder/license/apache2.rb +1 -1
- data/lib/license_finder/license/lgpl.rb +1 -0
- data/lib/license_finder/npm.rb +22 -39
- data/lib/license_finder/npm_package.rb +61 -0
- data/lib/license_finder/package.rb +14 -80
- data/lib/license_finder/package_saver.rb +13 -75
- data/lib/license_finder/pip.rb +21 -33
- data/lib/license_finder/pip_package.rb +51 -0
- data/lib/license_finder/platform.rb +3 -15
- data/lib/license_finder/possible_license_file.rb +0 -4
- data/lib/license_finder/possible_license_files.rb +4 -0
- data/lib/license_finder/tables.rb +2 -2
- data/lib/license_finder/tables/bundler_group.rb +3 -0
- data/lib/license_finder/tables/dependency.rb +43 -18
- data/lib/license_finder/tables/license_alias.rb +4 -0
- data/lib/license_finder/yml_to_sql.rb +22 -30
- data/license_finder.gemspec +3 -3
- data/readme.md +5 -5
- data/spec/lib/license_finder/bower_package_spec.rb +56 -0
- data/spec/lib/license_finder/bower_spec.rb +3 -24
- data/spec/lib/license_finder/bundler_package_spec.rb +62 -0
- data/spec/lib/license_finder/{bundle_spec.rb → bundler_spec.rb} +7 -7
- data/spec/lib/license_finder/cli_spec.rb +6 -6
- data/spec/lib/license_finder/dependency_manager_spec.rb +14 -15
- data/spec/lib/license_finder/html_report_spec.rb +2 -3
- data/spec/lib/license_finder/markdown_report_spec.rb +4 -4
- data/spec/lib/license_finder/npm_package_spec.rb +51 -0
- data/spec/lib/license_finder/npm_spec.rb +25 -25
- data/spec/lib/license_finder/package_saver_spec.rb +50 -190
- data/spec/lib/license_finder/pip_package_spec.rb +74 -0
- data/spec/lib/license_finder/pip_spec.rb +33 -55
- data/spec/lib/license_finder/tables/dependency_spec.rb +83 -32
- data/spec/lib/license_finder/yml_to_sql_spec.rb +5 -12
- data/spec/spec_helper.rb +22 -2
- metadata +30 -18
- data/lib/license_finder/bundle.rb +0 -74
- data/lib/license_finder/tables/approval.rb +0 -4
- data/spec/lib/license_finder/package_spec.rb +0 -98
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
describe NpmPackage do
|
5
|
+
subject do
|
6
|
+
described_class.new(
|
7
|
+
"name" => "jasmine-node",
|
8
|
+
"version" => "1.3.1",
|
9
|
+
"description" => "a description",
|
10
|
+
"readme" => "a readme",
|
11
|
+
"path" => "some/node/package/path"
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
it_behaves_like "it conforms to interface required by PackageSaver"
|
16
|
+
|
17
|
+
its(:name) { should == "jasmine-node" }
|
18
|
+
its(:version) { should == "1.3.1" }
|
19
|
+
its(:summary) { should == "a description" }
|
20
|
+
its(:description) { should == "a readme" }
|
21
|
+
|
22
|
+
describe '#license' do
|
23
|
+
def stub_license_files(license_files)
|
24
|
+
PossibleLicenseFiles.stub(:find).with("some/node/package/path").and_return(license_files)
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:node_module1) { {"license" => "MIT"} }
|
28
|
+
let(:node_module2) { {"licenses" => [{"type" => "BSD"}]} }
|
29
|
+
let(:node_module3) { {"license" => {"type" => "PSF"}} }
|
30
|
+
|
31
|
+
it 'finds the license for both license structures' do
|
32
|
+
NpmPackage.new(node_module1).license.should eq("MIT")
|
33
|
+
NpmPackage.new(node_module2).license.should eq("BSD")
|
34
|
+
NpmPackage.new(node_module3).license.should eq("PSF")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns a license in a file if detected" do
|
38
|
+
stub_license_files [double(:file, license: 'Detected License')]
|
39
|
+
|
40
|
+
subject.license.should == "Detected License"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns 'other' otherwise" do
|
44
|
+
stub_license_files []
|
45
|
+
|
46
|
+
subject.license.should == "other"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -2,10 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module LicenseFinder
|
4
4
|
describe NPM do
|
5
|
-
describe '.
|
5
|
+
describe '.current_packages' do
|
6
6
|
before { NPM.instance_variable_set(:@modules, nil) }
|
7
7
|
|
8
|
-
it '
|
8
|
+
it 'fetches data from npm' do
|
9
9
|
json = <<-JSON
|
10
10
|
{
|
11
11
|
"dependencies": {
|
@@ -64,40 +64,40 @@ module LicenseFinder
|
|
64
64
|
JSON
|
65
65
|
allow(NPM).to receive(:capture).with(/npm/).and_return([json, true])
|
66
66
|
|
67
|
-
|
67
|
+
current_packages = NPM.current_packages
|
68
68
|
|
69
|
-
expect(
|
70
|
-
expect(
|
69
|
+
expect(current_packages.map(&:name)).to eq(["depjs", "dep2js", "dep3js", "dep5js", "dep4js"])
|
70
|
+
expect(current_packages.first).to be_a(Package)
|
71
|
+
expect(current_packages.first.name).to eq("depjs")
|
71
72
|
end
|
72
73
|
|
73
|
-
it
|
74
|
-
|
74
|
+
it "does not support name version string" do
|
75
|
+
json = <<-JSON
|
76
|
+
{
|
77
|
+
"devDependencies": {
|
78
|
+
"foo": "4.2"
|
79
|
+
}
|
80
|
+
}
|
81
|
+
JSON
|
82
|
+
allow(NPM).to receive(:capture).with(/npm/).and_return([json, true])
|
83
|
+
|
84
|
+
current_packages = NPM.current_packages
|
75
85
|
|
76
|
-
|
77
|
-
NPM.current_modules
|
86
|
+
expect(current_packages.map(&:name)).to eq([])
|
78
87
|
end
|
79
88
|
|
80
89
|
it "fails when command fails" do
|
81
90
|
allow(NPM).to receive(:capture).with(/npm/).and_return('Some error', false).once
|
82
|
-
expect { NPM.
|
91
|
+
expect { NPM.current_packages }.to raise_error(RuntimeError)
|
83
92
|
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe '.harvest_license' do
|
87
|
-
let(:node_module1) { {"license" => "MIT"} }
|
88
|
-
let(:node_module2) { {"licenses" => [{"type" => "BSD", "url" => "github.github/github"}]} }
|
89
|
-
let(:node_module3) { {"license" => {"type" => "PSF", "url" => "github.github/github"}} }
|
90
|
-
let(:node_module4) { {"licenses" => ["MIT"]} }
|
91
93
|
|
92
|
-
it
|
93
|
-
NPM.
|
94
|
-
NPM.
|
95
|
-
NPM.harvest_license(node_module3).should eq("PSF")
|
96
|
-
NPM.harvest_license(node_module4).should eq("MIT")
|
94
|
+
it "does not fail when command fails but produces output" do
|
95
|
+
allow(NPM).to receive(:capture).with(/npm/).and_return('{"foo":"bar"}', false).once
|
96
|
+
NPM.current_packages
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
-
describe '.
|
100
|
+
describe '.active?' do
|
101
101
|
let(:package) { Pathname.new('package.json').expand_path }
|
102
102
|
|
103
103
|
context 'with a package.json file' do
|
@@ -106,7 +106,7 @@ module LicenseFinder
|
|
106
106
|
end
|
107
107
|
|
108
108
|
it 'returns true' do
|
109
|
-
expect(NPM.
|
109
|
+
expect(NPM.active?).to eq(true)
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
@@ -116,7 +116,7 @@ module LicenseFinder
|
|
116
116
|
end
|
117
117
|
|
118
118
|
it 'returns false' do
|
119
|
-
expect(NPM.
|
119
|
+
expect(NPM.active?).to eq(false)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
@@ -2,206 +2,66 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module LicenseFinder
|
4
4
|
describe PackageSaver do
|
5
|
-
let(:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
let(:package) do
|
6
|
+
double(
|
7
|
+
:package,
|
8
|
+
license: 'license',
|
9
|
+
children: ['child'],
|
10
|
+
groups: [:group],
|
11
|
+
summary: 'summary',
|
12
|
+
description: 'description',
|
13
|
+
name: 'spec_name',
|
14
|
+
version: '1.2.3',
|
15
|
+
homepage: 'http://example.com'
|
16
|
+
)
|
15
17
|
end
|
16
18
|
|
17
|
-
describe ".
|
18
|
-
let(:
|
19
|
-
let(:gem) { double(:package) }
|
19
|
+
describe ".save_all" do
|
20
|
+
let(:dependency) { double(:dependency).as_null_object }
|
20
21
|
|
21
|
-
it "
|
22
|
-
|
23
|
-
|
24
|
-
described_class.
|
22
|
+
it "find and updates relevant dependencies" do
|
23
|
+
Dependency.should_receive(:named).with('spec_name').and_return(dependency)
|
24
|
+
dependency.should_receive(:save_changes)
|
25
|
+
described_class.save_all([package])
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
29
|
describe "#save" do
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
context "with a bundler dependency" do
|
56
|
-
let(:package) { Package.new(gemspec, double(:bundler_dependency, groups: %w[1 2 3]))}
|
57
|
-
|
58
|
-
it "saves the bundler groups" do
|
59
|
-
subject.bundler_groups.map(&:name).should =~ %w[1 2 3]
|
60
|
-
end
|
61
|
-
end
|
30
|
+
it "persists changes" do
|
31
|
+
dep = Dependency.create(
|
32
|
+
name: 'spec_name',
|
33
|
+
version: '0.1.2',
|
34
|
+
summary: 'old summary',
|
35
|
+
description: 'old desription',
|
36
|
+
homepage: 'old homepage',
|
37
|
+
license: LicenseAlias.named('old license')
|
38
|
+
)
|
39
|
+
dep.add_bundler_group BundlerGroup.named("old group")
|
40
|
+
dep.add_child Dependency.named("old child")
|
41
|
+
|
42
|
+
saver = described_class.new(dep, package)
|
43
|
+
subject = saver.save
|
44
|
+
|
45
|
+
subject.id.should be
|
46
|
+
subject.name.should == "spec_name"
|
47
|
+
subject.version.should == "1.2.3"
|
48
|
+
subject.summary.should == "summary"
|
49
|
+
subject.description.should == "description"
|
50
|
+
subject.homepage.should == "http://example.com"
|
51
|
+
subject.bundler_groups.map(&:name).should == ['group']
|
52
|
+
subject.children.map(&:name).should == ['child']
|
53
|
+
subject.license.name.should == 'license'
|
62
54
|
end
|
63
55
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
)
|
72
|
-
Dependency.create(
|
73
|
-
name: 'spec_name',
|
74
|
-
version: '2.1.3',
|
75
|
-
summary: 'summary',
|
76
|
-
description: 'description',
|
77
|
-
homepage: 'homepage',
|
78
|
-
license: license
|
79
|
-
)
|
80
|
-
end
|
81
|
-
let(:package_saver) { described_class.find_or_create_by_name(package) }
|
82
|
-
|
83
|
-
it "does not save the dependency" do
|
84
|
-
package_saver.dependency.should_not_receive(:save)
|
85
|
-
package_saver.save
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
context "the values have changed" do
|
90
|
-
let!(:old_copy) do
|
91
|
-
dep = Dependency.create(
|
92
|
-
name: 'spec_name',
|
93
|
-
version: '0.1.2',
|
94
|
-
summary: 'old summary',
|
95
|
-
description: 'old desription',
|
96
|
-
homepage: 'old homepage'
|
97
|
-
)
|
98
|
-
dep.approval = Approval.create
|
99
|
-
dep
|
100
|
-
end
|
101
|
-
|
102
|
-
it "merges in the latest data" do
|
103
|
-
subject.id.should == old_copy.id
|
104
|
-
subject.name.should == old_copy.name
|
105
|
-
subject.version.should == "2.1.3"
|
106
|
-
subject.summary.should == "summary"
|
107
|
-
subject.description.should == "description"
|
108
|
-
subject.homepage.should == "homepage"
|
109
|
-
end
|
110
|
-
|
111
|
-
it "keeps a manually assigned license" do
|
112
|
-
old_copy.license = LicenseAlias.create(name: 'foo')
|
113
|
-
old_copy.license_manual = true
|
114
|
-
old_copy.save
|
115
|
-
subject.license.name.should == 'foo'
|
116
|
-
end
|
117
|
-
|
118
|
-
it "keeps approval" do
|
119
|
-
old_copy.approval = Approval.create(state: true)
|
120
|
-
old_copy.save
|
121
|
-
subject.approval.state.should
|
122
|
-
if LicenseFinder::Platform.java?
|
123
|
-
subject.approval.state.should == 1
|
124
|
-
else
|
125
|
-
subject.approval.state.should == true
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
it "ensures correct children are associated" do
|
130
|
-
old_copy.add_child Dependency.new(name: 'bob')
|
131
|
-
old_copy.add_child Dependency.new(name: 'joe')
|
132
|
-
old_copy.children.each(&:save)
|
133
|
-
subject.children.map(&:name).should =~ ['foo']
|
134
|
-
end
|
135
|
-
|
136
|
-
context "with a bundler dependency" do
|
137
|
-
let(:package) { Package.new(gemspec, double(:bundler_dependency)) }
|
138
|
-
|
139
|
-
before do
|
140
|
-
package.stub(:groups) { [:group_1, :group_2, :b] }
|
141
|
-
old_copy.add_bundler_group BundlerGroup.find_or_create(name: 'a')
|
142
|
-
old_copy.add_bundler_group BundlerGroup.find_or_create(name: 'b')
|
143
|
-
end
|
144
|
-
|
145
|
-
it "ensures the correct bundler groups are associated" do
|
146
|
-
subject.bundler_groups.map(&:name).should =~ %w[group_1 group_2 b]
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
context "license has changed" do
|
151
|
-
before do
|
152
|
-
old_copy.license = LicenseAlias.create(name: 'other')
|
153
|
-
old_copy.save
|
154
|
-
gemspec.license = "new license"
|
155
|
-
end
|
156
|
-
|
157
|
-
context "new license is whitelisted" do
|
158
|
-
before { LicenseFinder.config.stub(:whitelist).and_return [gemspec.license] }
|
159
|
-
|
160
|
-
it "should set the approval to true" do
|
161
|
-
subject.should be_approved
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
context "new license is not whitelisted" do
|
166
|
-
it "should set the approval to false" do
|
167
|
-
subject.should_not be_approved
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
context "license already exists" do
|
172
|
-
it "uses the existing license" do
|
173
|
-
new_license = LicenseAlias.create(name: 'new license')
|
174
|
-
subject.license.should == new_license
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
context "license does not change" do
|
180
|
-
let(:package_saver) { described_class.find_or_create_by_name(package) }
|
181
|
-
|
182
|
-
before do
|
183
|
-
old_copy.license = LicenseAlias.create(name: 'MIT')
|
184
|
-
old_copy.approval = Approval.create(state: false)
|
185
|
-
old_copy.save
|
186
|
-
gemspec.license = "MIT"
|
187
|
-
end
|
188
|
-
|
189
|
-
it "should not change the license or approval" do
|
190
|
-
dependency = package_saver.save
|
191
|
-
if LicenseFinder::Platform.java?
|
192
|
-
dependency.approved?.should_not == 1
|
193
|
-
else
|
194
|
-
dependency.should_not be_approved
|
195
|
-
end
|
196
|
-
dependency.license.name.should == "MIT"
|
197
|
-
end
|
56
|
+
it "keeps approval" do
|
57
|
+
dep = Dependency.create(
|
58
|
+
name: 'spec_name',
|
59
|
+
manually_approved: true
|
60
|
+
)
|
61
|
+
saver = described_class.new(dep, package)
|
62
|
+
subject = saver.save
|
198
63
|
|
199
|
-
|
200
|
-
package_saver.dependency.license.should_not_receive(:save)
|
201
|
-
package_saver.save
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
64
|
+
subject.should be_approved
|
205
65
|
end
|
206
66
|
end
|
207
67
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
describe PipPackage do
|
5
|
+
subject { make_package({}) }
|
6
|
+
|
7
|
+
it_behaves_like "it conforms to interface required by PackageSaver"
|
8
|
+
|
9
|
+
def make_package(pypi_def)
|
10
|
+
described_class.new('jasmine', '1.3.1', "jasmine/install/path", pypi_def)
|
11
|
+
end
|
12
|
+
|
13
|
+
its(:name) { should == "jasmine" }
|
14
|
+
its(:version) { should == "1.3.1" }
|
15
|
+
|
16
|
+
describe "#summary" do
|
17
|
+
it "delegates to pypi def" do
|
18
|
+
subject = make_package("summary" => "A summary")
|
19
|
+
expect(subject.summary).to eq("A summary")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "falls back to nothing" do
|
23
|
+
expect(subject.summary).to eq("")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#description" do
|
28
|
+
it "delegates to pypi def" do
|
29
|
+
subject = make_package("description" => "A description")
|
30
|
+
expect(subject.description).to eq("A description")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "falls back to nothing" do
|
34
|
+
expect(subject.description).to eq("")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#license' do
|
39
|
+
describe "with pypi license" do
|
40
|
+
it "returns the license from 'license' preferentially" do
|
41
|
+
data = { "license" => "MIT", "classifiers" => [ 'License :: OSI Approved :: Apache 2.0 License' ] }
|
42
|
+
|
43
|
+
subject = make_package(data)
|
44
|
+
|
45
|
+
expect(subject.license).to eq('MIT')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns the first license from the 'classifiers' if no 'license' exists" do
|
49
|
+
data = { "classifiers" => [ 'License :: OSI Approved :: Apache 2.0 License' ] }
|
50
|
+
|
51
|
+
subject = make_package(data)
|
52
|
+
|
53
|
+
expect(subject.license).to eq('Apache 2.0 License')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "without pypi license" do
|
58
|
+
def stub_license_files(license_files)
|
59
|
+
PossibleLicenseFiles.stub(:find).with("jasmine/install/path").and_return(license_files)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns license from file' do
|
63
|
+
stub_license_files [double(:license_file, license: 'License from file')]
|
64
|
+
expect(subject.license).to eq('License from file')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'returns other if no license can be found' do
|
68
|
+
stub_license_files []
|
69
|
+
expect(subject.license).to eq('other')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|