license_finder 0.7.3 → 0.8.0

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 (73) hide show
  1. data/.gitignore +4 -3
  2. data/.travis.yml +1 -8
  3. data/bin/license_finder +31 -1
  4. data/db/migrate/201303290935_create_dependencies.rb +14 -0
  5. data/db/migrate/201303291155_create_licenses.rb +13 -0
  6. data/db/migrate/201303291402_create_approvals.rb +13 -0
  7. data/db/migrate/201303291456_create_ancestries.rb +9 -0
  8. data/db/migrate/201303291519_create_bundler_groups.rb +13 -0
  9. data/db/migrate/201303291720_move_manual_from_approvals_to_licenses.rb +11 -0
  10. data/db/migrate/201303291753_allow_null_license_names.rb +7 -0
  11. data/db/migrate/201304011027_allow_null_dependency_version.rb +7 -0
  12. data/db/migrate/201304020947_change_table_name_licenses_to_license_aliases.rb +5 -0
  13. data/features/approve_dependencies.feature +0 -45
  14. data/features/html_report.feature +1 -11
  15. data/features/license_finder.feature +13 -27
  16. data/features/license_finder_rake_task.feature +2 -1
  17. data/features/set_license.feature +2 -4
  18. data/features/step_definitions/license_finder_steps.rb +25 -0
  19. data/features/step_definitions/steps.rb +40 -26
  20. data/features/text_report.feature +2 -2
  21. data/files/license_finder.yml +1 -1
  22. data/lib/license_finder.rb +14 -6
  23. data/lib/license_finder/bundle.rb +4 -17
  24. data/lib/license_finder/bundle_syncer.rb +2 -3
  25. data/lib/license_finder/bundled_gem.rb +4 -47
  26. data/lib/license_finder/cli.rb +9 -16
  27. data/lib/license_finder/configuration.rb +55 -3
  28. data/lib/license_finder/dependency_report.rb +1 -1
  29. data/lib/license_finder/gem_saver.rb +69 -0
  30. data/lib/license_finder/html_report.rb +2 -2
  31. data/lib/license_finder/license.rb +60 -58
  32. data/lib/license_finder/license_files.rb +36 -0
  33. data/lib/license_finder/license_url.rb +8 -6
  34. data/lib/license_finder/platform.rb +32 -0
  35. data/lib/license_finder/possible_license_file.rb +1 -1
  36. data/lib/license_finder/tables.rb +7 -0
  37. data/lib/license_finder/tables/approval.rb +4 -0
  38. data/lib/license_finder/tables/bundler_group.rb +4 -0
  39. data/lib/license_finder/tables/dependency.rb +31 -0
  40. data/lib/license_finder/tables/license_alias.rb +22 -0
  41. data/lib/license_finder/yml_to_sql.rb +127 -0
  42. data/lib/tasks/license_finder.rake +3 -0
  43. data/lib/templates/html_report.erb +50 -32
  44. data/lib/templates/text_report.erb +3 -2
  45. data/license_finder.gemspec +14 -5
  46. data/readme.md +10 -50
  47. data/spec/lib/license_finder/bundle_spec.rb +22 -19
  48. data/spec/lib/license_finder/bundle_syncer_spec.rb +4 -10
  49. data/spec/lib/license_finder/bundled_gem_spec.rb +40 -108
  50. data/spec/lib/license_finder/cli_spec.rb +3 -3
  51. data/spec/lib/license_finder/configuration_spec.rb +53 -21
  52. data/spec/lib/license_finder/gem_saver_spec.rb +155 -0
  53. data/spec/lib/license_finder/html_report_spec.rb +32 -15
  54. data/spec/lib/license_finder/license_files_spec.rb +50 -0
  55. data/spec/lib/license_finder/tables/dependency_spec.rb +102 -0
  56. data/spec/lib/license_finder/tables/license_alias_spec.rb +54 -0
  57. data/spec/lib/license_finder/text_report_spec.rb +6 -4
  58. data/spec/lib/license_finder/yml_to_sql_spec.rb +99 -0
  59. data/spec/lib/license_finder_spec.rb +5 -5
  60. data/spec/spec_helper.rb +17 -1
  61. metadata +79 -32
  62. data/lib/license_finder/dependency.rb +0 -50
  63. data/lib/license_finder/persistence.rb +0 -1
  64. data/lib/license_finder/persistence/yaml.rb +0 -7
  65. data/lib/license_finder/persistence/yaml/configuration.rb +0 -34
  66. data/lib/license_finder/persistence/yaml/dependency.rb +0 -127
  67. data/lib/license_finder/source_syncer.rb +0 -40
  68. data/lib/templates/dependency.html.erb +0 -54
  69. data/spec/lib/license_finder/dependency_spec.rb +0 -188
  70. data/spec/lib/license_finder/persistence/yaml/dependency_spec.rb +0 -5
  71. data/spec/lib/license_finder/source_syncer_spec.rb +0 -37
  72. data/spec/support/shared_examples/persistence/configuration.rb +0 -28
  73. data/spec/support/shared_examples/persistence/dependency.rb +0 -138
@@ -9,7 +9,7 @@ Feature: Text Report
9
9
  | license | version |
10
10
  | MIT | 1.1.1 |
11
11
  When I run "license_finder"
12
- Then I should see the file "dependencies.txt" containing:
12
+ Then I should see the file "doc/dependencies.txt" containing:
13
13
  """
14
14
  descriptive_gem, 1.1.1, MIT
15
15
  """
@@ -21,7 +21,7 @@ Feature: Text Report
21
21
  | MIT | 1.1.1 |
22
22
  When I run "license_finder"
23
23
  And I run "license_finder"
24
- Then I should see the file "dependencies.txt" containing:
24
+ Then I should see the file "doc/dependencies.txt" containing:
25
25
  """
26
26
  descriptive_gem, 1.1.1, MIT
27
27
  """
@@ -5,4 +5,4 @@ whitelist:
5
5
  ignore_groups:
6
6
  #- test
7
7
  #- development
8
- dependencies_file_dir: './'
8
+ dependencies_file_dir: './doc/'
@@ -6,17 +6,15 @@ module LicenseFinder
6
6
  ROOT_PATH = Pathname.new(__FILE__).dirname
7
7
 
8
8
  DEPENDENCY_ATTRIBUTES = [
9
- "name", "source", "version", "license", "license_url", "approved", "notes",
9
+ "name", "version", "license", "license_url", "approved", "notes",
10
10
  "license_files", "bundler_groups", "summary",
11
- "description", "homepage", "children", "parents"
11
+ "description", "homepage", "children", "parents", "manual"
12
12
  ]
13
13
 
14
14
  autoload :Bundle, 'license_finder/bundle'
15
15
  autoload :BundledGem, 'license_finder/bundled_gem'
16
16
  autoload :CLI, 'license_finder/cli'
17
17
  autoload :Configuration, 'license_finder/configuration'
18
- autoload :Persistence, 'license_finder/persistence/yaml'
19
- autoload :Dependency, 'license_finder/dependency'
20
18
  autoload :License, 'license_finder/license'
21
19
  autoload :LicenseUrl, 'license_finder/license_url'
22
20
  autoload :PossibleLicenseFile, 'license_finder/possible_license_file'
@@ -25,10 +23,17 @@ module LicenseFinder
25
23
  autoload :TextReport, 'license_finder/text_report'
26
24
  autoload :Reporter, 'license_finder/reporter'
27
25
  autoload :BundleSyncer, 'license_finder/bundle_syncer'
28
- autoload :SourceSyncer, 'license_finder/source_syncer'
26
+ autoload :YmlToSql, 'license_finder/yml_to_sql'
27
+ autoload :Dependency, 'license_finder/tables/dependency'
28
+ autoload :Approval, 'license_finder/tables/approval'
29
+ autoload :LicenseAlias, 'license_finder/tables/license_alias'
30
+ autoload :BundlerGroup, 'license_finder/tables/bundler_group'
31
+ autoload :GemSaver, 'license_finder/gem_saver'
32
+ autoload :LicenseFiles, 'license_finder/license_files'
33
+ autoload :Platform, 'license_finder/platform'
29
34
 
30
35
  def self.config
31
- @config ||= Configuration.new
36
+ @config ||= Configuration.ensure_default
32
37
  end
33
38
 
34
39
  def self.load_rake_tasks
@@ -37,3 +42,6 @@ module LicenseFinder
37
42
  end
38
43
 
39
44
  require 'license_finder/railtie' if defined?(Rails)
45
+ require 'license_finder/tables'
46
+
47
+ LicenseFinder::YmlToSql.convert_if_required
@@ -2,6 +2,10 @@ module LicenseFinder
2
2
  class Bundle
3
3
  attr_writer :ignore_groups
4
4
 
5
+ def self.current_gem_dependencies(bundler_definition=nil)
6
+ new(bundler_definition).gems.map(&:save_or_merge)
7
+ end
8
+
5
9
  def initialize(bundler_definition=nil)
6
10
  @definition = bundler_definition || Bundler::Definition.build(gemfile_path, lockfile_path, nil)
7
11
  end
@@ -15,8 +19,6 @@ module LicenseFinder
15
19
  BundledGem.new(spec, dependency)
16
20
  end
17
21
 
18
- setup_parent_child_relationships
19
-
20
22
  @gems
21
23
  end
22
24
 
@@ -27,21 +29,6 @@ module LicenseFinder
27
29
  @ignore_groups ||= LicenseFinder.config.ignore_groups
28
30
  end
29
31
 
30
- def setup_parent_child_relationships
31
- dependency_index = {}
32
-
33
- gems.each do |dep|
34
- dependency_index[dep.dependency_name] = dep
35
- end
36
-
37
- gems.each do |dep|
38
- dep.children.each do |child_dep|
39
- license_finder_dependency = dependency_index[child_dep]
40
- license_finder_dependency.parents << dep.dependency_name if license_finder_dependency
41
- end
42
- end
43
- end
44
-
45
32
  def dependencies
46
33
  @dependencies ||= definition.dependencies
47
34
  end
@@ -3,9 +3,8 @@ module LicenseFinder
3
3
  extend self
4
4
 
5
5
  def sync!
6
- source_dependencies = Bundle.new.gems.map(&:to_dependency)
7
- target_dependencies = Dependency.all.select {|d| d.source == "bundle" }
8
- SourceSyncer.new(source_dependencies, target_dependencies).sync!
6
+ current_dependencies = Bundle.current_gem_dependencies
7
+ Dependency.destroy_obsolete(current_dependencies)
9
8
  end
10
9
  end
11
10
  end
@@ -1,8 +1,6 @@
1
1
  module LicenseFinder
2
2
  class BundledGem
3
- LICENSE_FILE_NAMES = %w(LICENSE License Licence COPYING README Readme ReadMe)
4
-
5
- attr_reader :parents
3
+ attr_reader :parents, :spec, :bundler_dependency
6
4
 
7
5
  def initialize(spec, bundler_dependency = nil)
8
6
  @spec = spec
@@ -29,22 +27,6 @@ module LicenseFinder
29
27
  @children ||= @spec.dependencies.collect(&:name)
30
28
  end
31
29
 
32
- def to_dependency
33
- @dependency ||= LicenseFinder::Dependency.new(
34
- 'name' => @spec.name,
35
- 'version' => @spec.version.to_s,
36
- 'license' => determine_license,
37
- 'license_files' => license_files.map(&:file_path),
38
- 'source' => 'bundle',
39
- 'bundler_groups' => (@bundler_dependency.groups if @bundler_dependency),
40
- 'summary' => @spec.summary,
41
- 'description' => @spec.description,
42
- 'homepage' => @spec.homepage,
43
- 'children' => children,
44
- 'parents' => parents
45
- )
46
- end
47
-
48
30
  def determine_license
49
31
  return @spec.license if @spec.license
50
32
 
@@ -52,40 +34,15 @@ module LicenseFinder
52
34
  end
53
35
 
54
36
  def license_files
55
- paths_with_license_names = find_matching_files(LICENSE_FILE_NAMES)
56
- paths_for_license_files = paths_with_license_names.map do |path|
57
- File.directory?(path) ? paths_for_files_in_license_directory(path) : path
58
- end.flatten.uniq
59
- get_files_for_paths(paths_for_license_files)
60
- end
61
-
62
- def install_path
63
- @spec.full_gem_path
37
+ LicenseFiles.new(@spec.full_gem_path).files
64
38
  end
65
39
 
66
40
  def sort_order
67
41
  dependency_name.downcase
68
42
  end
69
43
 
70
- private
71
-
72
- def find_matching_files(names)
73
- Dir.glob(File.join(install_path, '**', "*{#{names.join(',')}}*"))
74
- end
75
-
76
- def get_file_for_path(path)
77
- PossibleLicenseFile.new(install_path, path)
78
- end
79
-
80
- def paths_for_files_in_license_directory(path)
81
- entries_in_directory = Dir::entries(path).reject { |p| p.match(/^(\.){1,2}$/) }
82
- entries_in_directory.map { |entry_name| File.join(path, entry_name) }
83
- end
84
-
85
- def get_files_for_paths(paths_for_license_files)
86
- paths_for_license_files.map do |path|
87
- get_file_for_path(path)
88
- end
44
+ def save_or_merge
45
+ GemSaver.find_or_initialize_by_name(@spec.name, self).save
89
46
  end
90
47
  end
91
48
  end
@@ -2,13 +2,16 @@ module LicenseFinder
2
2
  module CLI
3
3
  extend self
4
4
 
5
+ @@run_complete = false
6
+
5
7
  def check_for_action_items
6
- create_default_configuration
7
8
  BundleSyncer.sync!
9
+ @@run_complete = true
8
10
  generate_reports
9
11
 
10
12
  unapproved = Dependency.unapproved
11
13
 
14
+ puts "\r" + " "*24
12
15
  if unapproved.count == 0
13
16
  puts "All gems are approved for use"
14
17
  else
@@ -19,18 +22,18 @@ module LicenseFinder
19
22
  end
20
23
 
21
24
  def execute!(options={})
22
- create_default_configuration
23
-
24
25
  if options.empty?
25
26
  check_for_action_items
26
27
  else
27
- dependency = Dependency.find_by_name(options[:dependency])
28
+ dependency = Dependency.first(name: options[:dependency])
28
29
 
30
+ @@run_complete = true
31
+ puts "\r" + " "*24
29
32
  if options[:approve]
30
33
  dependency.approve!
31
34
  puts "The #{dependency.name} has been approved!\n\n"
32
35
  elsif options[:license]
33
- dependency.update_attributes :license => options[:license]
36
+ dependency.set_license_manually options[:license]
34
37
  puts "The #{dependency.name} has been marked as using #{options[:license]} license!\n\n"
35
38
  end
36
39
 
@@ -40,17 +43,7 @@ module LicenseFinder
40
43
 
41
44
  private
42
45
  def generate_reports
43
- LicenseFinder::Reporter.write_reports
44
- end
45
-
46
- def create_default_configuration
47
- unless File.exists?(LicenseFinder.config.config_file_path)
48
- FileUtils.mkdir_p(File.join('.', 'config'))
49
- FileUtils.cp(
50
- File.join(File.dirname(__FILE__), '..', '..', 'files', 'license_finder.yml'),
51
- LicenseFinder.config.config_file_path
52
- )
53
- end
46
+ Reporter.write_reports
54
47
  end
55
48
  end
56
49
  end
@@ -1,7 +1,58 @@
1
1
  module LicenseFinder
2
- class Configuration < LicenseFinder::Persistence::Configuration
2
+ class Configuration
3
+ attr_accessor :whitelist, :ignore_groups, :dependencies_dir
4
+
5
+ def self.config_file_path
6
+ File.join('.', 'config', 'license_finder.yml')
7
+ end
8
+
9
+ def self.ensure_default
10
+ make_config_file unless File.exists?(config_file_path)
11
+ new
12
+ end
13
+
14
+ def self.make_config_file
15
+ FileUtils.mkdir_p(File.join('.', 'config'))
16
+ FileUtils.cp(
17
+ File.join(File.dirname(__FILE__), '..', '..', 'files', 'license_finder.yml'),
18
+ config_file_path
19
+ )
20
+ end
21
+
22
+ def initialize(config={})
23
+ if File.exists?(config_file_path)
24
+ yaml = File.read(config_file_path)
25
+ config = YAML.load(yaml).merge config
26
+ end
27
+
28
+ @whitelist = config['whitelist'] || []
29
+ @ignore_groups = (config["ignore_groups"] || []).map(&:to_sym)
30
+ @dependencies_dir = config['dependencies_file_dir'] || './doc/'
31
+ FileUtils.mkdir_p(@dependencies_dir)
32
+ end
33
+
34
+ def config_file_path
35
+ self.class.config_file_path
36
+ end
37
+
38
+ def database_path
39
+ File.expand_path(File.join(dependencies_dir, "dependencies.db"))
40
+ end
41
+
42
+ def dependencies_yaml
43
+ File.join(dependencies_dir, "dependencies.yml")
44
+ end
45
+
46
+ def dependencies_text
47
+ File.join(dependencies_dir, "dependencies.txt")
48
+ end
49
+
50
+ def dependencies_html
51
+ File.join(dependencies_dir, "dependencies.html")
52
+ end
53
+
3
54
  def ignore_groups
4
- super.map &:to_sym
55
+ @ignore_groups.map &:to_sym
5
56
  end
6
57
 
7
58
  def whitelisted?(license_name)
@@ -10,9 +61,10 @@ module LicenseFinder
10
61
  end
11
62
 
12
63
  private
64
+
13
65
  def whitelisted_licenses
14
66
  whitelist.map do |license_name|
15
- LicenseFinder::License.find_by_name(license_name) || license_name
67
+ License.find_by_name(license_name) || license_name
16
68
  end.compact
17
69
  end
18
70
  end
@@ -16,7 +16,7 @@ module LicenseFinder
16
16
 
17
17
  def to_s
18
18
  filename = File.join(File.dirname(__FILE__), '..', 'templates', "#{self.class.underscored_name}.erb")
19
- template = ERB.new(File.read(filename))
19
+ template = ERB.new(File.read(filename), 0, '-')
20
20
  template.result(binding)
21
21
  end
22
22
 
@@ -0,0 +1,69 @@
1
+ module LicenseFinder
2
+ class GemSaver
3
+ extend Forwardable
4
+ def_delegators :spec, :name, :version, :summary, :description, :homepage
5
+ def_delegators :bundled_gem, :bundler_dependency, :determine_license, :children
6
+
7
+ def self.find_or_initialize_by_name(name, bundled_gem)
8
+ dependency = Dependency.find_or_create(name: name) do |d|
9
+ d.approval = Approval.create
10
+ end
11
+ new(dependency, bundled_gem)
12
+ end
13
+
14
+ def initialize(dependency, bundled_gem)
15
+ @bundled_gem = bundled_gem
16
+ @dependency = dependency
17
+ end
18
+
19
+ def save
20
+ DB.transaction do
21
+ apply_dependency_definition
22
+ refresh_bundler_groups
23
+ refresh_children
24
+ apply_better_license
25
+ end
26
+ dependency
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :dependency, :bundled_gem
32
+
33
+ def spec
34
+ bundled_gem.spec
35
+ end
36
+
37
+ def apply_dependency_definition
38
+ dependency.version = version.to_s
39
+ dependency.summary = summary
40
+ dependency.description = description
41
+ dependency.homepage = homepage
42
+ dependency.license ||= LicenseAlias.create(name: determine_license)
43
+ dependency.save
44
+ end
45
+
46
+ def refresh_bundler_groups
47
+ dependency.remove_all_bundler_groups
48
+ if bundler_dependency
49
+ bundler_dependency.groups.each { |group|
50
+ dependency.add_bundler_group BundlerGroup.find_or_create(name: group.to_s)
51
+ }
52
+ end
53
+ end
54
+
55
+ def refresh_children
56
+ dependency.remove_all_children
57
+ children.each do |child|
58
+ dependency.add_child Dependency.find_or_create(name: child.to_s)
59
+ end
60
+ end
61
+
62
+ def apply_better_license
63
+ if dependency.license && !dependency.license.manual && determine_license != 'other'
64
+ dependency.license.name = determine_license
65
+ dependency.license.save
66
+ end
67
+ end
68
+ end
69
+ end
@@ -4,11 +4,11 @@ module LicenseFinder
4
4
  class HtmlReport < DependencyReport
5
5
  private
6
6
  def unapproved_dependencies
7
- dependencies.reject(&:approved)
7
+ dependencies.reject(&:approved?)
8
8
  end
9
9
 
10
10
  def grouped_dependencies
11
- dependencies.group_by(&:license).sort_by { |_, group| group.size }.reverse
11
+ dependencies.group_by {|dep| dep.license.name }.sort_by { |_, group| group.size }.reverse
12
12
  end
13
13
  end
14
14
  end
@@ -1,84 +1,86 @@
1
- module LicenseFinder::License
2
- class << self
3
- def all
4
- @all ||= []
5
- end
1
+ module LicenseFinder
2
+ module License
3
+ class << self
4
+ def all
5
+ @all ||= []
6
+ end
6
7
 
7
- def find_by_name(license_name)
8
- all.detect { |l| l.names.map(&:downcase).include? license_name.to_s.downcase }
8
+ def find_by_name(license_name)
9
+ all.detect { |l| l.names.map(&:downcase).include? license_name.to_s.downcase }
10
+ end
9
11
  end
10
- end
11
12
 
12
- class Text
13
- def initialize(text)
14
- @text = normalized(text)
15
- end
13
+ class Text
14
+ def initialize(text)
15
+ @text = normalized(text)
16
+ end
16
17
 
17
- def to_s
18
- @text
19
- end
18
+ def to_s
19
+ @text
20
+ end
20
21
 
21
- private
22
+ private
22
23
 
23
- def normalized(text)
24
- text.gsub(/\s+/, ' ').gsub(/['`"]{1,2}/, "\"")
24
+ def normalized(text)
25
+ text.gsub(/\s+/, ' ').gsub(/['`"]{1,2}/, "\"")
26
+ end
25
27
  end
26
- end
27
28
 
28
- class Base
29
- class << self
30
- attr_accessor :license_url, :alternative_names
29
+ class Base
30
+ class << self
31
+ attr_accessor :license_url, :alternative_names
31
32
 
32
- def inherited(descendant)
33
- LicenseFinder::License.all << descendant
34
- end
33
+ def inherited(descendant)
34
+ License.all << descendant
35
+ end
35
36
 
36
- def names
37
- ([demodulized_name, pretty_name] + self.alternative_names).uniq
38
- end
37
+ def names
38
+ ([demodulized_name, pretty_name] + self.alternative_names).uniq
39
+ end
39
40
 
40
- def alternative_names
41
- @alternative_names ||= []
42
- end
41
+ def alternative_names
42
+ @alternative_names ||= []
43
+ end
43
44
 
44
- def demodulized_name
45
- name.gsub(/^.*::/, '')
46
- end
45
+ def demodulized_name
46
+ name.gsub(/^.*::/, '')
47
+ end
47
48
 
48
- def slug
49
- demodulized_name.downcase
50
- end
49
+ def slug
50
+ demodulized_name.downcase
51
+ end
51
52
 
52
- def pretty_name
53
- demodulized_name
54
- end
53
+ def pretty_name
54
+ demodulized_name
55
+ end
55
56
 
56
- def license_text
57
- unless defined?(@license_text)
58
- template = File.join(LicenseFinder::ROOT_PATH, "data", "licenses", "#{demodulized_name}.txt").to_s
57
+ def license_text
58
+ unless defined?(@license_text)
59
+ template = File.join(ROOT_PATH, "data", "licenses", "#{demodulized_name}.txt").to_s
59
60
 
60
- @license_text = Text.new(File.read(template)).to_s if File.exists?(template)
61
+ @license_text = Text.new(File.read(template)).to_s if File.exists?(template)
62
+ end
63
+ @license_text
61
64
  end
62
- @license_text
63
- end
64
65
 
65
- def license_regex
66
- /#{Regexp.escape(license_text).gsub(/<[^<>]+>/, '(.*)')}/ if license_text
66
+ def license_regex
67
+ /#{Regexp.escape(license_text).gsub(/<[^<>]+>/, '(.*)')}/ if license_text
68
+ end
67
69
  end
68
- end
69
70
 
70
- def initialize(text)
71
- self.text = text
72
- end
71
+ def initialize(text)
72
+ self.text = text
73
+ end
73
74
 
74
- attr_reader :text
75
+ attr_reader :text
75
76
 
76
- def text=(text)
77
- @text = Text.new(text).to_s
78
- end
77
+ def text=(text)
78
+ @text = Text.new(text).to_s
79
+ end
79
80
 
80
- def matches?
81
- !!(text =~ self.class.license_regex if self.class.license_regex)
81
+ def matches?
82
+ !!(text =~ self.class.license_regex if self.class.license_regex)
83
+ end
82
84
  end
83
85
  end
84
86
  end