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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -7
  3. data/.travis.yml +1 -3
  4. data/CHANGELOG.rdoc +13 -0
  5. data/db/migrate/201307251004_data_fix_manual_licenses.rb +2 -2
  6. data/db/migrate/201307251107_reassociate_license.rb +18 -18
  7. data/db/migrate/201311192002_add_manually_approved_to_dependencies.rb +7 -0
  8. data/db/migrate/201311192003_reassociate_manual_approval.rb +14 -0
  9. data/db/migrate/201311192010_drop_approvals.rb +5 -0
  10. data/features/cli.feature +1 -1
  11. data/features/html_report.feature +1 -1
  12. data/features/{non_bundler_dependencies.feature → manually_managed_dependencies.feature} +6 -6
  13. data/features/step_definitions/html_report_steps.rb +2 -9
  14. data/features/step_definitions/{non_bundler_steps.rb → manually_managed_steps.rb} +0 -0
  15. data/features/step_definitions/shared_steps.rb +4 -8
  16. data/lib/license_finder.rb +21 -17
  17. data/lib/license_finder/bower.rb +3 -34
  18. data/lib/license_finder/bower_package.rb +63 -0
  19. data/lib/license_finder/bundler.rb +73 -0
  20. data/lib/license_finder/bundler_package.rb +33 -0
  21. data/lib/license_finder/cli.rb +33 -35
  22. data/lib/license_finder/dependency_manager.rb +14 -23
  23. data/lib/license_finder/license/apache2.rb +1 -1
  24. data/lib/license_finder/license/lgpl.rb +1 -0
  25. data/lib/license_finder/npm.rb +22 -39
  26. data/lib/license_finder/npm_package.rb +61 -0
  27. data/lib/license_finder/package.rb +14 -80
  28. data/lib/license_finder/package_saver.rb +13 -75
  29. data/lib/license_finder/pip.rb +21 -33
  30. data/lib/license_finder/pip_package.rb +51 -0
  31. data/lib/license_finder/platform.rb +3 -15
  32. data/lib/license_finder/possible_license_file.rb +0 -4
  33. data/lib/license_finder/possible_license_files.rb +4 -0
  34. data/lib/license_finder/tables.rb +2 -2
  35. data/lib/license_finder/tables/bundler_group.rb +3 -0
  36. data/lib/license_finder/tables/dependency.rb +43 -18
  37. data/lib/license_finder/tables/license_alias.rb +4 -0
  38. data/lib/license_finder/yml_to_sql.rb +22 -30
  39. data/license_finder.gemspec +3 -3
  40. data/readme.md +5 -5
  41. data/spec/lib/license_finder/bower_package_spec.rb +56 -0
  42. data/spec/lib/license_finder/bower_spec.rb +3 -24
  43. data/spec/lib/license_finder/bundler_package_spec.rb +62 -0
  44. data/spec/lib/license_finder/{bundle_spec.rb → bundler_spec.rb} +7 -7
  45. data/spec/lib/license_finder/cli_spec.rb +6 -6
  46. data/spec/lib/license_finder/dependency_manager_spec.rb +14 -15
  47. data/spec/lib/license_finder/html_report_spec.rb +2 -3
  48. data/spec/lib/license_finder/markdown_report_spec.rb +4 -4
  49. data/spec/lib/license_finder/npm_package_spec.rb +51 -0
  50. data/spec/lib/license_finder/npm_spec.rb +25 -25
  51. data/spec/lib/license_finder/package_saver_spec.rb +50 -190
  52. data/spec/lib/license_finder/pip_package_spec.rb +74 -0
  53. data/spec/lib/license_finder/pip_spec.rb +33 -55
  54. data/spec/lib/license_finder/tables/dependency_spec.rb +83 -32
  55. data/spec/lib/license_finder/yml_to_sql_spec.rb +5 -12
  56. data/spec/spec_helper.rb +22 -2
  57. metadata +30 -18
  58. data/lib/license_finder/bundle.rb +0 -74
  59. data/lib/license_finder/tables/approval.rb +0 -4
  60. 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 '.current_modules' do
5
+ describe '.current_packages' do
6
6
  before { NPM.instance_variable_set(:@modules, nil) }
7
7
 
8
- it 'lists all the current modules' do
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
- current_modules = NPM.current_modules
67
+ current_packages = NPM.current_packages
68
68
 
69
- expect(current_modules.map(&:name)).to eq(["depjs 1.3.3.7", "dep2js 4.2", "dep3js 4.2", "dep5js 4.2", "dep4js 4.2"])
70
- expect(current_modules.first).to be_a(Package)
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 'memoizes the current_modules' do
74
- allow(NPM).to receive(:capture).with(/npm/).and_return(['{}', true]).once
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
- NPM.current_modules
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.current_modules }.to raise_error(RuntimeError)
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 'finds the license for both license structures' do
93
- NPM.harvest_license(node_module1).should eq("MIT")
94
- NPM.harvest_license(node_module2).should eq("BSD")
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 '.has_package?' do
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.has_package?).to eq(true)
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.has_package?).to eq(false)
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(:gemspec) do
6
- Gem::Specification.new do |s|
7
- s.name = 'spec_name'
8
- s.version = '2.1.3'
9
- s.summary = 'summary'
10
- s.description = 'description'
11
- s.homepage = 'homepage'
12
-
13
- s.add_dependency 'foo'
14
- end
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 ".save_gems" do
18
- let(:packages) { [gem] }
19
- let(:gem) { double(:package) }
19
+ describe ".save_all" do
20
+ let(:dependency) { double(:dependency).as_null_object }
20
21
 
21
- it "calls find_or_create_by_name on all passed in gems" do
22
- described_class.should_receive(:find_or_create_by_name).with(gem).and_return(gem)
23
- gem.should_receive(:save)
24
- described_class.save_packages(packages)
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
- let(:package) { Package.new(gemspec) }
30
- subject { described_class.find_or_create_by_name(package).save }
31
-
32
- before { package.children = ["foo"] }
33
-
34
- context "when the dependency is new" do
35
- it "persists gem data" do
36
- subject.id.should be
37
- subject.name.should == "spec_name"
38
- subject.version.should == "2.1.3"
39
- subject.summary.should == "summary"
40
- subject.description.should == "description"
41
- subject.homepage.should == "homepage"
42
- end
43
-
44
- describe "associating children" do
45
- it "associates children" do
46
- subject.children.map(&:name).should == ['foo']
47
- subject.children.each { |child| child.id.should_not be_nil }
48
- end
49
- end
50
-
51
- it "marks depenency as unapproved by default" do
52
- subject.approval.state.should == nil
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
- context "when the dependency already existed" do
65
- before { LicenseFinder.stub(:current_gems).and_return([double(:gemspec, name: "foo 0.0")]) }
66
-
67
- context "the values have not changed" do
68
- let!(:original_dependency) do
69
- license = LicenseAlias.create(
70
- name: 'other'
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
- it "should not save the license" do
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