license_finder 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/CHANGELOG.rdoc +27 -3
  4. data/db/migrate/201307250917_add_license_manual_to_dependencies.rb +7 -0
  5. data/db/migrate/201307251004_data_fix_manual_licenses.rb +15 -0
  6. data/db/migrate/201307251107_reassociate_license.rb +23 -0
  7. data/db/migrate/201307251340_remove_manual_from_license_aliases.rb +7 -0
  8. data/features/cli.feature +1 -1
  9. data/features/html_report.feature +3 -2
  10. data/features/project_name.feature +10 -0
  11. data/features/set_license.feature +1 -0
  12. data/features/step_definitions/cli_steps.rb +3 -3
  13. data/features/step_definitions/project_name_steps.rb +3 -0
  14. data/features/step_definitions/set_license_steps.rb +9 -4
  15. data/features/step_definitions/shared_steps.rb +11 -2
  16. data/features/step_definitions/text_report_steps.rb +12 -2
  17. data/features/text_report.feature +7 -1
  18. data/files/dependency_breakdown.png +0 -0
  19. data/files/license_finder.yml +1 -0
  20. data/files/report_breakdown.png +0 -0
  21. data/lib/license_finder.rb +0 -5
  22. data/lib/license_finder/bundle.rb +22 -4
  23. data/lib/license_finder/bundled_gem.rb +17 -10
  24. data/lib/license_finder/bundled_gem_saver.rb +42 -30
  25. data/lib/license_finder/cli.rb +37 -5
  26. data/lib/license_finder/configuration.rb +13 -2
  27. data/lib/license_finder/dependency_manager.rb +21 -8
  28. data/lib/license_finder/reports/dependency_report.rb +1 -1
  29. data/lib/license_finder/reports/reporter.rb +4 -0
  30. data/lib/license_finder/tables/dependency.rb +9 -1
  31. data/lib/license_finder/tables/license_alias.rb +0 -4
  32. data/lib/license_finder/yml_to_sql.rb +1 -11
  33. data/lib/templates/html_report.erb +13 -3
  34. data/license_finder.gemspec +3 -4
  35. data/readme.md +25 -3
  36. data/release/gem_version.rb +3 -0
  37. data/{release.md → release/manual_instructions.md} +6 -0
  38. data/release/publish.sh +29 -0
  39. data/spec/lib/license_finder/bundle_spec.rb +16 -4
  40. data/spec/lib/license_finder/bundled_gem_saver_spec.rb +41 -38
  41. data/spec/lib/license_finder/bundled_gem_spec.rb +22 -4
  42. data/spec/lib/license_finder/cli_spec.rb +22 -0
  43. data/spec/lib/license_finder/configuration_spec.rb +34 -14
  44. data/spec/lib/license_finder/dependency_manager_spec.rb +61 -10
  45. data/spec/lib/license_finder/reporter_spec.rb +35 -1
  46. data/spec/lib/license_finder/tables/dependency_spec.rb +23 -0
  47. data/spec/lib/license_finder/tables/license_alias_spec.rb +0 -16
  48. data/spec/lib/license_finder/yml_to_sql_spec.rb +11 -3
  49. data/spec/lib/license_finder_spec.rb +2 -2
  50. data/spec/spec_helper.rb +3 -13
  51. metadata +21 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20f8ab76aa0c6a0b12a159a4e177648106c9cd7b
4
- data.tar.gz: e4a0d2d69fd8cbaeea45c300b676daa6b2a5399b
3
+ metadata.gz: 32345e0495c5fa4e7a83dbda58ee6a5143f4373c
4
+ data.tar.gz: 5507cdcaf0a114673a139c0096162979546c976a
5
5
  SHA512:
6
- metadata.gz: 822abefcd6d88446a2d178890691ebd0e696cc3572be07d70ff809b1fce088cc2b5eea9b6bfda8e390400f78f8cf69567e702001707696e5d3c55e2c4bb7e175
7
- data.tar.gz: 42f08fc6c49d0ff7a408864e5c5fb7d49ca8119d4ec7832c573a1ed6eb59d13f50d02874c30a4baa6e967fdf4de1d59287536a017d48d9c0db411cf62d33c4b1
6
+ metadata.gz: b316183dfd5bbd79cf034576ff69d596429a688ff202478a0d4a33fce7817c1df6bdf9f25e8a821299f66b8251c622851357d39ffa023ab738b8f36c4ee0bfbb
7
+ data.tar.gz: b5e87ed9886cdaf35a3a96d645710c1d1bdeac6a3def4de49428a54850e8d73e737861f7c4bdbae479240f3fc982a12300bc0747c34878b9316dfb1df9ddab32
@@ -9,7 +9,6 @@ rvm:
9
9
 
10
10
  matrix:
11
11
  allow_failures:
12
- - rvm: jruby-19mode
13
12
  - rvm: rbx-19mode
14
13
  - rvm: ruby-head
15
14
  - rvm: jruby-head
@@ -2,10 +2,34 @@
2
2
 
3
3
  * Features
4
4
 
5
- * Can maintain whitelisted licenses from command line
6
- * Improve New BSD license detection
5
+ * Projects now have a title which can be configured from CLI
6
+ * JRuby officially supported. Test suite works against jruby, removed
7
+ warnings
8
+ * Internal clean-up of database behavior
9
+ * Updated documentation with breakdown of HTML report
7
10
 
8
- === 0.8.2 / 2012-07-09
11
+ * Bugfixes
12
+
13
+ * dependencies.db is no longer modified after license_finder runs and finds
14
+ no changes
15
+ * Fix more CLI grammar/syntax errors
16
+ * HTML report now works when served over https (PR #36 - bwalding)
17
+ * dependencies.txt is now dependencies.csv (It was always a csv in spirit)
18
+
19
+ === 0.9.0 / 2013-07-16
20
+
21
+ * Features
22
+
23
+ * Clarify CLI options and commands in help output
24
+ * Can manage whitelisted licenses from command line
25
+ * Improved New BSD license detection
26
+
27
+ * Bugfixes
28
+
29
+ * Fix CLI grammar errors
30
+ * Using license_finder in a non-RVM environment now works (Issue #35)
31
+
32
+ === 0.8.2 / 2013-07-09
9
33
 
10
34
  * Features
11
35
 
@@ -0,0 +1,7 @@
1
+ Sequel.migration do
2
+ change do
3
+ alter_table(:dependencies) do
4
+ add_column :license_manual, TrueClass
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ Sequel.migration do
2
+ up do
3
+ DB << <<EOS
4
+ UPDATE dependencies
5
+ SET license_manual = 1
6
+ WHERE id
7
+ IN
8
+ (SELECT d.id
9
+ FROM dependencies d
10
+ INNER JOIN license_aliases l
11
+ ON d.license_id = l.id
12
+ WHERE l.manual = 1)
13
+ EOS
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ Sequel.migration do
2
+ up do
3
+ DB << <<EOS
4
+ UPDATE dependencies
5
+ SET license_id =
6
+ (SELECT la.id
7
+ FROM
8
+ license_aliases la,
9
+ license_aliases la_orig
10
+ WHERE
11
+ la.name = la_orig.name AND
12
+ la_orig.id = license_id
13
+ LIMIT 1)
14
+ EOS
15
+
16
+ DB << <<CLEANUP
17
+ DELETE
18
+ FROM license_aliases
19
+ WHERE
20
+ id NOT IN (SELECT license_id FROM dependencies)
21
+ CLEANUP
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ Sequel.migration do
2
+ change do
3
+ alter_table(:license_aliases) do
4
+ drop_column :manual
5
+ end
6
+ end
7
+ end
@@ -16,7 +16,7 @@ Feature: License Finder command line executable
16
16
 
17
17
  Scenario: Auditing an application with whitelisted licenses
18
18
  Given I have an app with license finder that depends on a MIT licensed gem
19
- When I whitelist MIT and 'other' and New BSD licenses
19
+ When I whitelist MIT and 'other' and New BSD and Apache 2.0 licenses
20
20
  Then it should exit with status code 0
21
21
  And I should see all gems approved for use
22
22
 
@@ -9,7 +9,8 @@ Feature: HTML Report
9
9
  Scenario: Dependency details listed in HTML report
10
10
  And my app depends on a gem with specific details
11
11
  When I run license_finder
12
- Then I should see my specific gem details listed in the html
12
+ Then I should see the project name my_app in the html
13
+ And I should see my specific gem details listed in the html
13
14
 
14
15
  Scenario: Approval status of dependencies indicated in HTML report
15
16
  And my app depends on MIT and GPL licensed gems
@@ -19,5 +20,5 @@ Feature: HTML Report
19
20
 
20
21
  Scenario: Dependency summary
21
22
  And my app depends on MIT and GPL licensed gems
22
- When I whitelist MIT and 'other' and New BSD licenses
23
+ When I whitelist MIT and 'other' and New BSD and Apache 2.0 licenses
23
24
  Then I should see only see GPL liceneses as unapproved in the html
@@ -0,0 +1,10 @@
1
+ Feature: Project names
2
+ As a developer
3
+ I want to assign a name for my project
4
+ So that license audit reports indicate their associated project
5
+
6
+ Scenario: Specifying a project name
7
+ Given I have an app with license finder
8
+ When I set the project name to new_project
9
+ And I run license_finder
10
+ Then I should see the project name new_project in the html
@@ -7,3 +7,4 @@ Feature: Set a dependency's license through a command line interface
7
7
  Given I have an app with license finder that depends on an other licensed gem
8
8
  When I set that gems license to MIT from the command line
9
9
  Then I should see that other gems license set to MIT
10
+ And I see other licensed gems have not changed licenses
@@ -23,7 +23,7 @@ Given(/^I have a project that depends on mime\-types with a manual license type$
23
23
  end
24
24
 
25
25
  When(/^I run license_finder help on a specific command$/) do
26
- @output = @user.execute_command "license_finder dependencies help add"
26
+ @output = @user.execute_command "license_finder ignored_bundler_groups help add"
27
27
  end
28
28
 
29
29
  When(/^I run license_finder help$/) do
@@ -32,7 +32,7 @@ end
32
32
 
33
33
  Then(/^it creates a config directory with the license_finder config$/) do
34
34
  File.should be_exists(@user.app_path('config'))
35
- text = "---\nwhitelist:\n#- MIT\n#- Apache 2.0\nignore_groups:\n#- test\n#- development\ndependencies_file_dir: './doc/'\n"
35
+ text = "---\nwhitelist:\n#- MIT\n#- Apache 2.0\nignore_groups:\n#- test\n#- development\ndependencies_file_dir: './doc/'\nproject_name: # project name\n"
36
36
  File.read(@user.app_path('config/license_finder.yml')).should == text.gsub(/^\s+/, "")
37
37
  end
38
38
 
@@ -53,7 +53,7 @@ Then(/^the mime\-types license remains set with my manual license type$/) do
53
53
  end
54
54
 
55
55
  Then(/^I should see the correct subcommand usage instructions$/) do
56
- @output.should include 'license_finder dependencies add LICENSE'
56
+ @output.should include 'license_finder ignored_bundler_groups add GROUP'
57
57
  end
58
58
 
59
59
  Then(/^I should the correct default usage instructions$/) do
@@ -0,0 +1,3 @@
1
+ When(/^I set the project name to (\w+)$/) do |project_name|
2
+ @user.execute_command "license_finder project_name set #{project_name}"
3
+ end
@@ -2,15 +2,20 @@ Given(/^I have an app with license finder that depends on an other licensed gem$
2
2
  @user = ::DSL::User.new
3
3
  @user.create_nonrails_app
4
4
  @user.add_license_finder_to_rakefile
5
- @user.add_dependency_to_app 'other_gem', :license => 'other'
5
+ @user.add_dependency_to_app 'other_gem', version: '1.0', license: 'other'
6
+ @user.add_dependency_to_app 'control_gem', version: '1.0', license: 'other'
6
7
  end
7
8
 
8
9
  When(/^I set that gems license to MIT from the command line$/) do
9
- @output = @user.execute_command 'license_finder --quiet'
10
- @output = @user.execute_command 'license_finder license MIT other_gem'
10
+ @user.execute_command 'license_finder --quiet'
11
+ @user.execute_command 'license_finder license MIT other_gem'
11
12
  @output = @user.execute_command 'license_finder --quiet'
12
13
  end
13
14
 
14
15
  Then(/^I should see that other gems license set to MIT$/) do
15
- @output.should include 'other_gem'
16
+ @output.should include 'other_gem, 1.0, MIT'
17
+ end
18
+
19
+ Then(/^I see other licensed gems have not changed licenses$/) do
20
+ @output.should include 'control_gem, 1.0, other'
16
21
  end
@@ -14,11 +14,20 @@ When(/^I run license_finder$/) do
14
14
  @output = @user.execute_command "license_finder --quiet"
15
15
  end
16
16
 
17
- When(/^I whitelist MIT and 'other' and New BSD licenses$/) do
18
- @user.configure_license_finder_whitelist ["MIT","other","New BSD"]
17
+ When(/^I whitelist MIT and 'other' and New BSD and Apache 2.0 licenses$/) do
18
+ @user.configure_license_finder_whitelist ["MIT","other","New BSD","Apache 2.0"]
19
19
  @output = @user.execute_command "license_finder --quiet"
20
20
  end
21
21
 
22
+ Then(/^I should see the project name (\w+) in the html$/) do |project_name|
23
+ html = File.read(@user.dependencies_html_path)
24
+ page = Capybara.string(html)
25
+ title = page.find("h1")
26
+
27
+ title.should have_content project_name
28
+ end
29
+
30
+
22
31
  module DSL
23
32
  class User
24
33
  def create_nonrails_app
@@ -4,6 +4,16 @@ Given(/^I have an app with license finder that depends on a gem with license and
4
4
  @user.add_dependency_to_app('info_gem', license: 'MIT', version: '1.1.1')
5
5
  end
6
6
 
7
- Then(/^I should see those version and license details in the dependencies\.txt file$/) do
8
- File.read(@user.app_path("doc/dependencies.txt")).should include "info_gem, 1.1.1, MIT"
7
+ Given(/^I have a dependencies\.txt file$/) do
8
+ Dir.mkdir(@user.app_path("doc"))
9
+ File.open(@user.app_path("doc/dependencies.txt"), 'w+') { |file| file.puts("Legacy text file") }
10
+ end
11
+
12
+ Then(/^I should see those version and license details in the dependencies\.csv file$/) do
13
+ File.read(@user.app_path("doc/dependencies.csv")).should include "info_gem, 1.1.1, MIT"
14
+ end
15
+
16
+ Then(/^I should see dependencies\.txt replaced by dependencies\.csv$/) do
17
+ File.exists?(@user.app_path("doc/dependencies.txt")).should be_false
18
+ File.exists?(@user.app_path("doc/dependencies.csv")).should be_true
9
19
  end
@@ -6,4 +6,10 @@ Feature: Text Report
6
6
  Scenario: Viewing dependencies
7
7
  Given I have an app with license finder that depends on a gem with license and version details
8
8
  When I run license_finder
9
- Then I should see those version and license details in the dependencies.txt file
9
+ Then I should see those version and license details in the dependencies.csv file
10
+
11
+ Scenario: Cleaning up old versions of text report
12
+ Given I have an app with license finder
13
+ And I have a dependencies.txt file
14
+ When I run license_finder
15
+ Then I should see dependencies.txt replaced by dependencies.csv
@@ -6,3 +6,4 @@ ignore_groups:
6
6
  #- test
7
7
  #- development
8
8
  dependencies_file_dir: './doc/'
9
+ project_name: # project name
@@ -34,10 +34,6 @@ module LicenseFinder
34
34
  @config ||= Configuration.ensure_default
35
35
  end
36
36
 
37
- def self.current_gems
38
- @current_gems ||= Bundle.current_gems
39
- end
40
-
41
37
  def self.load_rake_tasks
42
38
  load 'tasks/license_finder.rake'
43
39
  end
@@ -45,5 +41,4 @@ end
45
41
 
46
42
  require 'license_finder/railtie' if defined?(Rails)
47
43
  require 'license_finder/tables'
48
-
49
44
  LicenseFinder::YmlToSql.convert_if_required
@@ -4,23 +4,33 @@ module LicenseFinder
4
4
  class Bundle
5
5
  attr_writer :ignore_groups
6
6
 
7
- def self.current_gems(bundler_definition=nil)
8
- new(bundler_definition).gems
7
+ def self.current_gems(config, bundler_definition=nil)
8
+ new(config, bundler_definition).gems
9
9
  end
10
10
 
11
- def initialize(bundler_definition=nil)
11
+ def initialize(config=nil, bundler_definition=nil)
12
12
  @definition = bundler_definition || Bundler::Definition.build(gemfile_path, lockfile_path, nil)
13
+ @config ||= config
13
14
  end
14
15
 
15
16
  def gems
16
17
  return @gems if @gems
17
18
 
19
+ gem_names_cache = {}
20
+
18
21
  @gems ||= definition.specs_for(included_groups).map do |spec|
19
22
  dependency = dependencies.detect { |dep| dep.name == spec.name }
20
23
 
24
+ formatted_name = format_name(spec)
25
+ gem_names_cache[format_name(spec)] = true
26
+
21
27
  BundledGem.new(spec, dependency)
22
28
  end
23
29
 
30
+ @gems.each do |gem|
31
+ gem.children = children_for(gem, gem_names_cache)
32
+ end
33
+
24
34
  @gems
25
35
  end
26
36
 
@@ -28,7 +38,7 @@ module LicenseFinder
28
38
  attr_reader :definition
29
39
 
30
40
  def ignore_groups
31
- @ignore_groups ||= LicenseFinder.config.ignore_groups
41
+ @ignore_groups ||= @config.ignore_groups
32
42
  end
33
43
 
34
44
  def dependencies
@@ -46,5 +56,13 @@ module LicenseFinder
46
56
  def lockfile_path
47
57
  gemfile_path.dirname.join('Gemfile.lock')
48
58
  end
59
+
60
+ def children_for(gem, cache)
61
+ gem.spec.dependencies.map(&:name).select { |name| cache[name] }
62
+ end
63
+
64
+ def format_name(gem)
65
+ gem.name.split(" ")[0]
66
+ end
49
67
  end
50
68
  end
@@ -1,10 +1,11 @@
1
1
  module LicenseFinder
2
2
  class BundledGem
3
- attr_reader :parents, :spec, :bundler_dependency
3
+ attr_reader :parents, :spec, :bundler_dependency, :children
4
4
 
5
5
  def initialize(spec, bundler_dependency = nil)
6
6
  @spec = spec
7
7
  @bundler_dependency = bundler_dependency
8
+ @children = []
8
9
  end
9
10
 
10
11
  def name
@@ -23,26 +24,32 @@ module LicenseFinder
23
24
  @spec.version.to_s
24
25
  end
25
26
 
26
- def children
27
- @children ||= @spec.dependencies.collect(&:name)
27
+ def groups
28
+ @groups ||= bundler_dependency ? bundler_dependency.groups : []
28
29
  end
29
30
 
30
- def determine_license
31
- return @spec.license if @spec.license
31
+ def license
32
+ @license ||= determine_license
33
+ end
32
34
 
33
- license_files.map(&:license).compact.first || 'other'
35
+ def sort_order
36
+ dependency_name.downcase
34
37
  end
35
38
 
36
39
  def license_files
37
40
  PossibleLicenseFiles.new(@spec.full_gem_path).find
38
41
  end
39
42
 
40
- def sort_order
41
- dependency_name.downcase
43
+ def children=(childs)
44
+ @children = childs
42
45
  end
43
46
 
44
- def save_as_dependency
45
- BundledGemSaver.find_or_create_by_name(@spec.name, self).save
47
+ private
48
+
49
+ def determine_license
50
+ return @spec.license if @spec.license
51
+
52
+ license_files.map(&:license).compact.first || 'other'
46
53
  end
47
54
  end
48
55
  end
@@ -2,15 +2,21 @@ module LicenseFinder
2
2
  class BundledGemSaver
3
3
  extend Forwardable
4
4
  def_delegators :spec, :name, :version, :summary, :description, :homepage
5
- def_delegators :bundled_gem, :bundler_dependency, :determine_license, :children
5
+ def_delegators :bundled_gem, :bundler_dependency, :license, :children, :groups
6
6
 
7
7
  attr_reader :dependency, :bundled_gem
8
8
 
9
- def self.find_or_create_by_name(name, bundled_gem)
10
- dependency = Dependency.named(name)
9
+ def self.find_or_create_by_name(bundled_gem)
10
+ dependency = Dependency.named(bundled_gem.spec.name)
11
11
  new(dependency, bundled_gem)
12
12
  end
13
13
 
14
+ def self.save_gems(current_gems)
15
+ current_gems.map do |bundled_gem|
16
+ BundledGemSaver.find_or_create_by_name(bundled_gem).save
17
+ end
18
+ end
19
+
14
20
  def initialize(dependency, bundled_gem)
15
21
  @bundled_gem = bundled_gem
16
22
  @dependency = dependency
@@ -19,8 +25,8 @@ module LicenseFinder
19
25
  def save
20
26
  DB.transaction do
21
27
  apply_dependency_definition
22
- refresh_bundler_groups
23
- refresh_children
28
+ sync_bundler_groups
29
+ sync_children
24
30
  apply_better_license
25
31
  end
26
32
  dependency
@@ -38,7 +44,6 @@ module LicenseFinder
38
44
  dependency.summary = summary
39
45
  dependency.description = description
40
46
  dependency.homepage = homepage
41
- dependency.license ||= LicenseAlias.create(name: determine_license)
42
47
  dependency.save
43
48
  end
44
49
  end
@@ -47,42 +52,49 @@ module LicenseFinder
47
52
  return dependency.version != version.to_s ||
48
53
  dependency.summary != summary ||
49
54
  dependency.description != description ||
50
- dependency.homepage != homepage ||
51
- dependency.license.name != determine_license
55
+ dependency.homepage != homepage
52
56
  end
53
57
 
54
- def refresh_bundler_groups
55
- dependency.remove_all_bundler_groups
56
- if bundler_dependency
57
- bundler_dependency.groups.each { |group|
58
- dependency.add_bundler_group BundlerGroup.find_or_create(name: group.to_s)
59
- }
58
+ def sync_bundler_groups
59
+ existing_groups = dependency.bundler_groups
60
+ new_groups = groups.map(&:to_s)
61
+
62
+ existing_groups.reverse.each do |group|
63
+ unless new_groups.include?(group.name)
64
+ dependency.remove_bundler_group(group)
65
+ end
60
66
  end
61
- end
62
67
 
63
- def refresh_children
64
- dependency.remove_all_children
65
- children.each do |child|
66
- if child_required?(child)
67
- dependency.add_child Dependency.named(child)
68
+ new_groups.each do |group|
69
+ unless existing_groups.map(&:name).include? group
70
+ dependency.add_bundler_group BundlerGroup.find_or_create(name: group)
68
71
  end
69
72
  end
70
73
  end
71
74
 
72
- def child_required?(child)
73
- current_gem_names.include?(child)
74
- end
75
+ def sync_children
76
+ existing_children = dependency.children
77
+ new_children = children
78
+
79
+ existing_children.reverse.each do |child|
80
+ unless new_children.include?(child.name)
81
+ dependency.remove_child(child)
82
+ end
83
+ end
75
84
 
76
- def current_gem_names
77
- @current_gem_names ||= LicenseFinder.current_gems.map { |gem| gem.name.split(" ")[0] }
85
+ new_children.each do |child|
86
+ unless existing_children.map(&:name).include?(child)
87
+ dependency.add_child Dependency.named(child)
88
+ end
89
+ end
78
90
  end
79
91
 
80
92
  def apply_better_license
81
- if dependency.license && !dependency.license.manual && determine_license != 'other'
82
- new_name = determine_license
83
- unless new_name == dependency.license.name
84
- dependency.license.name = new_name
85
- dependency.license.save
93
+ if !dependency.license_manual
94
+ bundled_license = license
95
+ if dependency.license.nil? || bundled_license != dependency.license.name
96
+ dependency.license = LicenseAlias.find_or_create(name: bundled_license)
97
+ dependency.save
86
98
  end
87
99
  end
88
100
  end