license_finder 0.8.1 → 0.8.2

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.rdoc +14 -1
  4. data/bin/license_finder +1 -61
  5. data/db/migrate/201304181524_add_manual_to_dependencies.rb +7 -0
  6. data/features/non_bundler_dependencies.feature +19 -0
  7. data/features/step_definitions/approve_dependencies_steps.rb +1 -1
  8. data/features/step_definitions/cli_steps.rb +1 -1
  9. data/features/step_definitions/html_report_steps.rb +1 -6
  10. data/features/step_definitions/ignore_bundle_groups_steps.rb +1 -1
  11. data/features/step_definitions/non_bundler_steps.rb +33 -0
  12. data/features/step_definitions/set_license_steps.rb +1 -1
  13. data/features/step_definitions/shared_steps.rb +8 -3
  14. data/lib/license_finder.rb +23 -25
  15. data/lib/license_finder/bundle.rb +2 -2
  16. data/lib/license_finder/bundled_gem.rb +3 -3
  17. data/lib/license_finder/{gem_saver.rb → bundled_gem_saver.rb} +3 -5
  18. data/lib/license_finder/cli.rb +109 -32
  19. data/lib/license_finder/configuration.rb +19 -8
  20. data/lib/license_finder/dependency_manager.rb +49 -0
  21. data/lib/license_finder/license.rb +3 -3
  22. data/lib/license_finder/{license_files.rb → possible_license_files.rb} +2 -2
  23. data/lib/license_finder/{dependency_report.rb → reports/dependency_report.rb} +1 -1
  24. data/lib/license_finder/{html_report.rb → reports/html_report.rb} +0 -0
  25. data/lib/license_finder/{reporter.rb → reports/reporter.rb} +0 -0
  26. data/lib/license_finder/{text_report.rb → reports/text_report.rb} +0 -0
  27. data/lib/license_finder/tables.rb +1 -1
  28. data/lib/license_finder/tables/dependency.rb +24 -5
  29. data/lib/license_finder/yml_to_sql.rb +5 -0
  30. data/lib/tasks/license_finder.rake +1 -1
  31. data/license_finder.gemspec +5 -3
  32. data/readme.md +80 -26
  33. data/spec/lib/license_finder/bundle_spec.rb +4 -11
  34. data/spec/lib/license_finder/{gem_saver_spec.rb → bundled_gem_saver_spec.rb} +7 -4
  35. data/spec/lib/license_finder/bundled_gem_spec.rb +1 -1
  36. data/spec/lib/license_finder/cli_spec.rb +86 -18
  37. data/spec/lib/license_finder/configuration_spec.rb +5 -2
  38. data/spec/lib/license_finder/dependency_manager_spec.rb +107 -0
  39. data/spec/lib/license_finder/html_report_spec.rb +3 -3
  40. data/spec/lib/license_finder/{license_files_spec.rb → possible_license_files_spec.rb} +7 -7
  41. data/spec/lib/license_finder/tables/dependency_spec.rb +31 -44
  42. data/spec/lib/license_finder/yml_to_sql_spec.rb +24 -2
  43. data/spec/support/silence_stdout.rb +13 -0
  44. metadata +66 -72
  45. data/lib/license_finder/bundle_syncer.rb +0 -11
  46. data/spec/lib/license_finder/bundle_syncer_spec.rb +0 -16
@@ -26,20 +26,15 @@ module LicenseFinder
26
26
  end
27
27
  end
28
28
 
29
- describe '.current_gem_dependencies' do
29
+ describe '.current_gems' do
30
30
  subject do
31
- Bundle.current_gem_dependencies(definition)
31
+ Bundle.current_gems(definition)
32
32
  end
33
33
 
34
34
  it "should have 2 dependencies" do
35
35
  subject.size.should == 2
36
36
  end
37
37
 
38
- it "returns persisted dependencies" do
39
- subject.first.id.should be
40
- subject.last.id.should be
41
- end
42
-
43
38
  context "when initialized with a parent and child gem" do
44
39
  before do
45
40
  definition.stub(:specs_for).and_return([
@@ -49,11 +44,9 @@ module LicenseFinder
49
44
  end
50
45
 
51
46
  it "should update the child dependency with its parent data" do
52
- gem1 = subject.first.reload
53
- gem2 = subject.last.reload
47
+ gem1 = subject.first
54
48
 
55
- gem2.parents.should == [gem1]
56
- gem1.children.should == [gem2]
49
+ gem1.children.should == ["gem2"]
57
50
  end
58
51
  end
59
52
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module LicenseFinder
4
- describe GemSaver do
4
+ describe BundledGemSaver do
5
5
  let(:gemspec) do
6
6
  Gem::Specification.new do |s|
7
7
  s.name = 'spec_name'
@@ -30,6 +30,7 @@ module LicenseFinder
30
30
 
31
31
  it "associates children" do
32
32
  subject.children.map(&:name).should == ['foo']
33
+ subject.children.each { |child| child.approval.should be }
33
34
  end
34
35
 
35
36
  it "marks depenency as unapproved by default" do
@@ -37,7 +38,7 @@ module LicenseFinder
37
38
  end
38
39
 
39
40
  context "with a bundler dependency" do
40
- let(:bundled_gem) { BundledGem.new(gemspec, stub(:bundler_dependency, groups: %w[1 2 3]))}
41
+ let(:bundled_gem) { BundledGem.new(gemspec, double(:bundler_dependency, groups: %w[1 2 3]))}
41
42
 
42
43
  it "saves the bundler groups" do
43
44
  subject.bundler_groups.map(&:name).should =~ %w[1 2 3]
@@ -47,13 +48,15 @@ module LicenseFinder
47
48
 
48
49
  context "when the dependency already existed" do
49
50
  let!(:old_copy) do
50
- Dependency.create(
51
+ dep = Dependency.create(
51
52
  name: 'spec_name',
52
53
  version: '0.1.2',
53
54
  summary: 'old summary',
54
55
  description: 'old desription',
55
56
  homepage: 'old homepage'
56
57
  )
58
+ dep.approval = Approval.create
59
+ dep
57
60
  end
58
61
 
59
62
  it "merges in the latest data" do
@@ -85,7 +88,7 @@ module LicenseFinder
85
88
  end
86
89
 
87
90
  context "with a bundler dependency" do
88
- let(:bundled_gem) { BundledGem.new(gemspec, stub(:bundler_dependency, groups: %w[1 2 3]))}
91
+ let(:bundled_gem) { BundledGem.new(gemspec, double(:bundler_dependency, groups: %w[1 2 3]))}
89
92
 
90
93
  before do
91
94
  old_copy.add_bundler_group BundlerGroup.find_or_create(name: 'a')
@@ -54,7 +54,7 @@ module LicenseFinder
54
54
 
55
55
  describe "#license_files" do
56
56
  it "delegates to the license files helper" do
57
- LicenseFiles.should_receive(:new).with(gemspec.full_gem_path) { stub(files: [] )}
57
+ PossibleLicenseFiles.should_receive(:new).with(gemspec.full_gem_path) { double(find: [] )}
58
58
  subject.license_files
59
59
  end
60
60
  end
@@ -1,36 +1,104 @@
1
1
  require "spec_helper"
2
2
 
3
3
  module LicenseFinder
4
- describe CLI do
5
- describe "#execute!(options)" do
6
- before { CLI.stub(:check_for_action_items) }
4
+ module CLI
5
+ describe Dependencies do
6
+ describe "add" do
7
+ it "should add a dependency" do
8
+ DependencyManager.should_receive(:create_non_bundler).with("MIT", "js_dep", "1.2.3")
7
9
 
8
- context "when the approve option is provided" do
9
- it "should approve the requested gem" do
10
- dependency = double('dependency', :name => nil)
11
- dependency.should_receive(:approve!)
10
+ silence_stdout do
11
+ subject.add("MIT", "js_dep", "1.2.3")
12
+ end
13
+ end
14
+
15
+ it "does not require a version" do
16
+ DependencyManager.should_receive(:create_non_bundler).with("MIT", "js_dep", nil)
17
+
18
+ silence_stdout do
19
+ subject.add("MIT", "js_dep")
20
+ end
21
+ end
22
+
23
+ it "should have a -a option to approve the added dependency" do
24
+ DependencyManager.should_receive(:create_non_bundler).with("MIT", "js_dep", "1.2.3")
25
+ DependencyManager.should_receive(:approve!).with("js_dep")
26
+
27
+ silence_stdout do
28
+ LicenseFinder::CLI::Main.start(["dependencies", "add", "--approve", "MIT", "js_dep", "1.2.3"])
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "remove" do
34
+ it "should remove a dependency" do
35
+ DependencyManager.should_receive(:destroy_non_bundler).with("js_dep")
36
+ silence_stdout do
37
+ subject.remove("js_dep")
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ describe Main do
44
+ describe "default" do
45
+ it "should check for action items" do
46
+ DependencyManager.should_receive(:sync_with_bundler)
47
+ Dependency.stub(:unapproved) { [] }
48
+ silence_stdout do
49
+ described_class.start([])
50
+ end
51
+ end
52
+ end
12
53
 
13
- Dependency.stub(:first).with(name: 'foo').and_return(dependency)
54
+ describe "#rescan" do
55
+ it "resyncs with Gemfile" do
56
+ DependencyManager.should_receive(:sync_with_bundler)
57
+ Dependency.stub(:unapproved) { [] }
14
58
 
15
- CLI.execute! approve: true, dependency: 'foo'
59
+ silence_stdout do
60
+ subject.rescan
61
+ end
16
62
  end
17
63
  end
18
64
 
19
- context "when the -l (--license) switch is provided" do
65
+ describe "#license" do
20
66
  it "should update the license on the requested gem" do
21
- dependency = double :dependency, :name => nil
22
- dependency.should_receive(:set_license_manually).with("foo")
67
+ DependencyManager.should_receive(:license!).with("foo_gem", "foo")
68
+
69
+ silence_stdout do
70
+ subject.license 'foo', 'foo_gem'
71
+ end
72
+ end
73
+ end
23
74
 
24
- Dependency.stub(:first).with(name: "foo_gem").and_return dependency
75
+ describe "#approve" do
76
+ it "should approve the requested gem" do
77
+ DependencyManager.should_receive(:approve!).with("foo")
25
78
 
26
- CLI.execute! license: "foo", dependency: 'foo_gem'
79
+ silence_stdout do
80
+ subject.approve 'foo'
81
+ end
27
82
  end
28
83
  end
29
84
 
30
- context "when no options are provided" do
31
- it "should check for action items" do
32
- CLI.should_receive(:check_for_action_items)
33
- CLI.execute!
85
+ describe "#action_items" do
86
+ it "reports unapproved dependencies" do
87
+ Dependency.stub(:unapproved) { ['one dependency'] }
88
+ TextReport.stub(:new) { double(:report, to_s: "a report!") }
89
+ silence_stdout do
90
+ $stdout.stub(:puts)
91
+ $stdout.should_receive(:puts).with(/dependencies/i)
92
+ expect { subject.action_items }.to raise_error(SystemExit)
93
+ end
94
+ end
95
+
96
+ it "reports that all dependencies are approved" do
97
+ Dependency.stub(:unapproved) { [] }
98
+ silence_stdout do
99
+ $stdout.should_receive(:puts).with(/approved/i)
100
+ expect { subject.action_items }.to_not raise_error
101
+ end
34
102
  end
35
103
  end
36
104
  end
@@ -24,9 +24,12 @@ module LicenseFinder
24
24
  subject.dependencies_dir.should == attributes['dependencies_file_dir']
25
25
  end
26
26
  end
27
+ end
27
28
 
28
- it "uses absolute path in database_path" do
29
- subject.database_path.should_not start_with(".")
29
+ describe "#database_uri" do
30
+ it "should URI escape absolute path the dependencies_file_dir" do
31
+ config = described_class.new('dependencies_file_dir' => 'test path')
32
+ config.database_uri.should =~ /test%20path\/dependencies\.db$/
30
33
  end
31
34
  end
32
35
 
@@ -0,0 +1,107 @@
1
+ require 'spec_helper'
2
+
3
+ module LicenseFinder
4
+ describe DependencyManager do
5
+ let(:config) { Configuration.new }
6
+
7
+ before do
8
+ LicenseFinder.stub(:config).and_return config
9
+ config.whitelist = ["MIT", "other"]
10
+ Reporter.stub(:write_reports)
11
+ end
12
+
13
+ describe "#sync_with_bundler" do
14
+ it "destroys every dependency except for the ones Bundler reports as 'current' or are marked as 'manual'" do
15
+ cur1 = Dependency.create(name: "current dependency 1")
16
+ cur2 = Dependency.create(name: "current dependency 2")
17
+ man1 = Dependency.create(name: "manual dependency", manual: true)
18
+ Dependency.create(name: "old dependency 1")
19
+ Dependency.create(name: "old dependency 2")
20
+
21
+ current_gems = [
22
+ double(:gem1, save_as_dependency: cur1),
23
+ double(:gem2, save_as_dependency: cur2)
24
+ ]
25
+ Bundle.stub(:current_gems) { current_gems }
26
+
27
+ described_class.sync_with_bundler
28
+ Dependency.all.map(&:name).should =~ [cur1, cur2, man1].map(&:name)
29
+ end
30
+ end
31
+
32
+ describe ".create_non_bundler" do
33
+ it "should add a Dependency" do
34
+ expect do
35
+ described_class.create_non_bundler("MIT", "js_dep", "0.0.0")
36
+ end.to change(Dependency, :count).by(1)
37
+ end
38
+
39
+ it "should mark the dependency as manual" do
40
+ described_class.create_non_bundler("MIT", "js_dep", "0.0.0")
41
+ .should be_manual
42
+ end
43
+
44
+ it "should set the appropriate values" do
45
+ dep = described_class.create_non_bundler("GPL", "js_dep", "0.0.0")
46
+ dep.name.should == "js_dep"
47
+ dep.version.should == "0.0.0"
48
+ dep.license.name.should == "GPL"
49
+ dep.should_not be_approved
50
+ end
51
+
52
+ it "should complain if the dependency already exists" do
53
+ Dependency.create(name: "current dependency 1")
54
+ expect { described_class.create_non_bundler("GPL", "current dependency 1", "0.0.0") }
55
+ .to raise_error(LicenseFinder::Error)
56
+ end
57
+ end
58
+
59
+ describe ".destroy_non_bundler" do
60
+ it "should remove a non bundler Dependency" do
61
+ described_class.create_non_bundler("GPL", "a non-bundler dep", nil)
62
+ expect do
63
+ described_class.destroy_non_bundler("a non-bundler dep")
64
+ end.to change(Dependency, :count).by(-1)
65
+ end
66
+
67
+ it "should not remove a bundler Dependency" do
68
+ Dependency.create(name: "a bundler dep")
69
+ expect do
70
+ expect do
71
+ described_class.destroy_non_bundler("a bundler dep")
72
+ end.to raise_error(LicenseFinder::Error)
73
+ end.to_not change(Dependency, :count)
74
+ end
75
+ end
76
+
77
+ describe ".approve!" do
78
+ it "approves the dependency" do
79
+ dep = Dependency.named("current dependency")
80
+ dep.reload.should_not be_approved
81
+ described_class.approve!("current dependency")
82
+ dep.reload.should be_approved
83
+ end
84
+
85
+ it "should raise an error if it can't find the dependency" do
86
+ expect { described_class.approve!("non-existent dependency") }
87
+ .to raise_error(LicenseFinder::Error)
88
+ end
89
+ end
90
+
91
+ describe ".license!" do
92
+ it "adds a license for the dependency" do
93
+ dep = described_class.create_non_bundler("old license", "current dependency", nil)
94
+ dep.reload.license.name.should == "old license"
95
+ described_class.license!("current dependency", "a license")
96
+ dep.reload.license.name.should == "a license"
97
+ end
98
+
99
+ it "should raise an error if it can't find the dependency" do
100
+ expect { described_class.license!("non-existent dependency", "a license") }
101
+ .to raise_error(LicenseFinder::Error)
102
+ end
103
+ end
104
+
105
+ end
106
+ end
107
+
@@ -36,7 +36,7 @@ module LicenseFinder
36
36
  end
37
37
 
38
38
  context "when the gem has at least one bundler group" do
39
- before { dependency.stub(bundler_groups: [stub(name: "group")]) }
39
+ before { dependency.stub(bundler_groups: [double(name: "group")]) }
40
40
  it "should show the bundler group(s) in parens" do
41
41
  should have_text "(group)"
42
42
  end
@@ -52,7 +52,7 @@ module LicenseFinder
52
52
  end
53
53
 
54
54
  context "when the gem has at least one parent" do
55
- before { dependency.stub(parents: [stub(:name => "foo parent")]) }
55
+ before { dependency.stub(parents: [double(:name => "foo parent")]) }
56
56
  it "should include a parents section" do
57
57
  should have_text "Parents"
58
58
  should have_text "foo parent"
@@ -66,7 +66,7 @@ module LicenseFinder
66
66
  end
67
67
 
68
68
  context "when the gem has at least one child" do
69
- before { dependency.stub(children: [stub(:name => "foo child")]) }
69
+ before { dependency.stub(children: [double(:name => "foo child")]) }
70
70
 
71
71
  it "should include a Children section" do
72
72
  should have_text "Children"
@@ -1,35 +1,35 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module LicenseFinder
4
- describe LicenseFiles do
4
+ describe PossibleLicenseFiles do
5
5
  def fixture_path(fixture)
6
6
  Pathname.new(File.join(File.dirname(__FILE__), '..', '..', '..', 'spec', 'fixtures', fixture)).realpath.to_s
7
7
  end
8
8
 
9
- describe "#files" do
9
+ describe "#find" do
10
10
  it "is empty if there aren't any license files" do
11
11
  subject = described_class.new('/not/a/dir')
12
- subject.files.should == []
12
+ subject.find.should == []
13
13
  end
14
14
 
15
15
  it "includes files with names like LICENSE, License or COPYING" do
16
16
  subject = described_class.new(fixture_path('license_names'))
17
17
 
18
- subject.files.map(&:file_name).should =~
18
+ subject.find.map(&:file_name).should =~
19
19
  %w[COPYING.txt LICENSE Mit-License README.rdoc Licence.rdoc]
20
20
  end
21
21
 
22
22
  it "includes files deep in the hierarchy" do
23
23
  subject = described_class.new(fixture_path('nested_gem'))
24
24
 
25
- subject.files.map { |f| [f.file_name, f.file_path] }.should =~ [
25
+ subject.find.map { |f| [f.file_name, f.file_path] }.should =~ [
26
26
  %w[LICENSE vendor/LICENSE]
27
27
  ]
28
28
  end
29
29
 
30
30
  it "includes both files nested inside LICENSE directory and top level files" do
31
31
  subject = described_class.new(fixture_path('license_directory'))
32
- found_license_files = subject.files
32
+ found_license_files = subject.find
33
33
 
34
34
  found_license_files.map { |f| [f.file_name, f.file_path] }.should =~ [
35
35
  %w[BSD-2-Clause.txt LICENSE/BSD-2-Clause.txt],
@@ -43,7 +43,7 @@ module LicenseFinder
43
43
 
44
44
  it "handles non UTF8 encodings" do
45
45
  subject = described_class.new(fixture_path('utf8_gem'))
46
- expect { subject.files }.not_to raise_error
46
+ expect { subject.find }.not_to raise_error
47
47
  end
48
48
  end
49
49
  end
@@ -2,39 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  module LicenseFinder
4
4
  describe Dependency do
5
- let(:attributes) do
6
- {
7
- 'name' => "spec_name",
8
- 'version' => "2.1.3",
9
- 'license' => "GPLv2",
10
- 'approved' => false,
11
- 'notes' => 'some notes',
12
- 'homepage' => 'homepage',
13
- 'license_files' => ['/Users/pivotal/foo/lic1', '/Users/pivotal/bar/lic2'],
14
- 'bundler_groups' => ["test"]
15
- }
16
- end
17
-
18
- let(:config) { Configuration.new }
19
-
20
- before do
21
- LicenseFinder.stub(:config).and_return config
22
- config.whitelist = ["MIT", "other"]
23
- end
24
-
25
- describe ".destroy_obsolete" do
26
- it "destroys every dependency except for the ones provided as 'current'" do
27
- cur1 = Dependency.create(name: "current dependency 1")
28
- cur2 = Dependency.create(name: "current dependency 2")
29
- Dependency.create(name: "old dependency 1")
30
- Dependency.create(name: "old dependency 2")
5
+ describe '.unapproved' do
6
+ let(:config) { Configuration.new }
31
7
 
32
- Dependency.destroy_obsolete([cur1, cur2])
33
- Dependency.all.should =~ [cur1, cur2]
8
+ before do
9
+ LicenseFinder.stub(:config).and_return config
10
+ config.whitelist = ["MIT", "other"]
34
11
  end
35
- end
36
12
 
37
- describe '.unapproved' do
38
13
  it "should return all unapproved dependencies" do
39
14
  dependency = Dependency.create(name: "unapproved dependency", version: '0.0.1')
40
15
  dependency.approval = Approval.create(state: false)
@@ -53,6 +28,32 @@ module LicenseFinder
53
28
  end
54
29
  end
55
30
 
31
+ describe ".named" do
32
+ it "creates a new dependency" do
33
+ dep = described_class.named("never_seen")
34
+ dep.name.should == "never_seen"
35
+ dep.should_not be_new
36
+ end
37
+
38
+ it "returns an existing dependency" do
39
+ described_class.named("referenced_again")
40
+ dep = described_class.named("referenced_again")
41
+ dep.name.should == "referenced_again"
42
+ dep.should_not be_new
43
+ Dependency.count(name: "referenced_again").should == 1
44
+ end
45
+
46
+ it "always attaches an approval" do
47
+ described_class.named("referenced_again").reload.approval.should be
48
+ described_class.named("referenced_again").reload.approval.should be
49
+ end
50
+
51
+ it "attaches an approval to a dependency that is currently missing one" do
52
+ Dependency.create(name: "foo")
53
+ described_class.named("foo").reload.approval.should be
54
+ end
55
+ end
56
+
56
57
  describe '#approve!' do
57
58
  it "should update the database to show the dependency is approved" do
58
59
  dependency = Dependency.create(name: "foo", version: '0.0.1')
@@ -83,20 +84,6 @@ module LicenseFinder
83
84
  dependency.should_not be_approved
84
85
  end
85
86
  end
86
-
87
- describe "#set_license_manually" do
88
- let(:gem) do
89
- dependency = Dependency.new(name: "bob", version: '0.0.1')
90
- dependency.license = LicenseAlias.create(name: 'Original')
91
- dependency.save
92
- dependency
93
- end
94
-
95
- it "delegates to the license" do
96
- gem.license.should_receive(:set_manually).with('Updated')
97
- gem.set_license_manually('Updated')
98
- end
99
- end
100
87
  end
101
88
  end
102
89