license_finder 6.6.0 → 6.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -189,6 +189,7 @@ require 'license_finder/packages/gradle_package'
189
189
  require 'license_finder/packages/cocoa_pods_package'
190
190
  require 'license_finder/packages/carthage_package'
191
191
  require 'license_finder/packages/rebar_package'
192
+ require 'license_finder/packages/erlangmk_package'
192
193
  require 'license_finder/packages/mix_package'
193
194
  require 'license_finder/packages/merged_package'
194
195
  require 'license_finder/packages/nuget_package'
@@ -163,6 +163,7 @@ require 'license_finder/package_managers/cocoa_pods'
163
163
  require 'license_finder/package_managers/carthage'
164
164
  require 'license_finder/package_managers/gradle'
165
165
  require 'license_finder/package_managers/rebar'
166
+ require 'license_finder/package_managers/erlangmk'
166
167
  require 'license_finder/package_managers/nuget'
167
168
  require 'license_finder/package_managers/dotnet'
168
169
  require 'license_finder/package_managers/dep'
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LicenseFinder
4
+ class Erlangmk < PackageManager
5
+ def package_management_command
6
+ 'make'
7
+ end
8
+
9
+ def package_management_command_with_path
10
+ "#{package_management_command} --directory=#{project_path} --no-print-directory"
11
+ end
12
+
13
+ # The IS_DEP=1 is added because not all erlang.mk-based projects are
14
+ # updated to a version that is compatible with LicenseFinder
15
+ def prepare_command
16
+ "#{package_management_command_with_path} IS_DEP=1 fetch-deps"
17
+ end
18
+
19
+ def possible_package_paths
20
+ [
21
+ project_path.join('Erlang.mk'),
22
+ project_path.join('erlang.mk')
23
+ ]
24
+ end
25
+
26
+ def current_packages
27
+ deps.map do |dep|
28
+ ErlangmkPackage.new(dep)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def deps
35
+ command = "#{package_management_command_with_path} QUERY='name fetch_method repo version absolute_path' query-deps"
36
+ stdout, stderr, status = Cmd.run(command)
37
+ if status.success?
38
+ dep_re = Regexp.new('^\s*DEP')
39
+ line_re = Regexp.new('^[_a-z0-9]+:')
40
+ stdout.each_line.map(&:strip).select { |line| !(line.start_with?('make') || line =~ dep_re) && line =~ line_re }
41
+ elsif stderr.include? "No rule to make target 'query-deps'"
42
+ # The stderr check happens because not all erlang.mk-based projects are
43
+ # updated to a version that is compatible with LicenseFinder
44
+ []
45
+ else
46
+ raise "Command '#{command}' failed to execute: #{stderr}"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -4,7 +4,7 @@ require 'license_finder/packages/go_package'
4
4
 
5
5
  module LicenseFinder
6
6
  class GoModules < PackageManager
7
- PACKAGES_FILE = 'go.sum'
7
+ PACKAGES_FILE = 'go.mod'
8
8
 
9
9
  class << self
10
10
  def takes_priority_over
@@ -12,12 +12,8 @@ module LicenseFinder
12
12
  end
13
13
  end
14
14
 
15
- def prepare_command
16
- 'GO111MODULE=on go mod tidy && GO111MODULE=on go mod vendor'
17
- end
18
-
19
15
  def active?
20
- sum_files?
16
+ mod_files?
21
17
  end
22
18
 
23
19
  def current_packages
@@ -33,19 +29,44 @@ module LicenseFinder
33
29
  private
34
30
 
35
31
  def packages_info
36
- info_output, stderr, _status = Cmd.run("GO111MODULE=on go list -m -f '{{.Path}},{{.Version}},{{.Dir}}' all")
37
- if stderr =~ Regexp.compile("can't compute 'all' using the vendor directory")
38
- info_output, _stderr, _status = Cmd.run("GO111MODULE=on go list -m -mod=mod -f '{{.Path}},{{.Version}},{{.Dir}}' all")
39
- end
32
+ Dir.chdir(project_path) do
33
+ # Explanations:
34
+ # * Only list dependencies (packages not listed in the project directory)
35
+ # (.DepOnly)
36
+ # * Ignore standard library packages
37
+ # (not .Standard)
38
+ # * Replacement modules are respected
39
+ # (or .Module.Replace .Module)
40
+ # * Module cache directory or (vendored) package directory
41
+ # (or $mod.Dir .Dir)
42
+ format_str = \
43
+ '{{ if and (.DepOnly) (not .Standard) }}'\
44
+ '{{ $mod := (or .Module.Replace .Module) }}'\
45
+ '{{ $mod.Path }},{{ $mod.Version }},{{ or $mod.Dir .Dir }}'\
46
+ '{{ end }}'
40
47
 
41
- info_output.split("\n")
48
+ # The module list flag (`-m`) is intentionally not used here. If the module
49
+ # dependency tree were followed, transitive dependencies that are never imported
50
+ # may be included.
51
+ #
52
+ # Instead, the owning module is listed for each imported package. This better
53
+ # matches the implementation of other Go package managers.
54
+ #
55
+ # TODO: Figure out a way to make the vendor directory work (i.e. remove the
56
+ # -mod=readonly flag). Each of the imported packages gets listed separatly,
57
+ # confusing the issue as to which package is the root of the module.
58
+ info_output, _stderr, _status = Cmd.run("GO111MODULE=on go list -mod=readonly -deps -f '#{format_str}' ./...")
59
+
60
+ # Since many packages may belong to a single module, #uniq is used to deduplicate
61
+ info_output.split("\n").uniq
62
+ end
42
63
  end
43
64
 
44
- def sum_files?
45
- sum_file_paths.any?
65
+ def mod_files?
66
+ mod_file_paths.any?
46
67
  end
47
68
 
48
- def sum_file_paths
69
+ def mod_file_paths
49
70
  Dir[project_path.join(PACKAGES_FILE)]
50
71
  end
51
72
 
@@ -96,7 +96,7 @@ module LicenseFinder
96
96
  raise "Command '#{command}' failed to execute: #{stderr}" unless status.success?
97
97
 
98
98
  packages_lines(stdout)
99
- .reject { |package_lines| package_lines.length == 1 } # in_umbrella: true dependencies
99
+ .reject { |package_lines| package_lines.length == 1 || package_lines.empty? } # in_umbrella: true dependencies
100
100
  .map { |package_lines| [package_lines[0].split(' ')[1], resolve_version(package_lines[1])] }
101
101
  end
102
102
 
@@ -90,29 +90,42 @@ module LicenseFinder
90
90
  end
91
91
 
92
92
  def prepare
93
- cmd = prepare_command
94
- stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(cmd) }
95
- return if status.success?
93
+ Dir.chdir(project_path) do
94
+ cmd = prepare_command
95
+ stdout, stderr, status = Cmd.run(cmd)
96
+ return if status.success?
96
97
 
97
- log_errors stderr
98
+ log_errors stderr
98
99
 
99
- if stderr.include?('-PackagesDirectory')
100
- logger.info cmd, 'trying fallback prepare command', color: :magenta
100
+ if stderr.include?('-PackagesDirectory')
101
+ logger.info cmd, 'trying fallback prepare command', color: :magenta
101
102
 
102
- cmd = "#{cmd} -PackagesDirectory ."
103
- stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(cmd) }
104
- return if status.success?
103
+ cmd = "#{cmd} -PackagesDirectory /#{Dir.home}/.nuget/packages"
104
+ stdout, stderr, status = Cmd.run(cmd)
105
+ return if status.success?
105
106
 
106
- log_errors_with_cmd(cmd, stderr)
107
- end
107
+ log_errors_with_cmd(cmd, stderr)
108
+ end
108
109
 
109
- error_message = "Prepare command '#{cmd}' failed\n#{stderr}"
110
- error_message += "\n#{stdout}\n" if !stdout.nil? && !stdout.empty?
111
- raise error_message unless @prepare_no_fail
110
+ error_message = "Prepare command '#{cmd}' failed\n#{stderr}"
111
+ error_message += "\n#{stdout}\n" if !stdout.nil? && !stdout.empty?
112
+ raise error_message unless @prepare_no_fail
113
+ end
112
114
  end
113
115
 
114
116
  def prepare_command
115
- "#{package_management_command} restore"
117
+ cmd = package_management_command
118
+ sln_files = Dir['*.sln']
119
+ cmds = []
120
+ if sln_files.count > 1
121
+ sln_files.each do |sln|
122
+ cmds << "#{cmd} restore #{sln}"
123
+ end
124
+ else
125
+ cmds << "#{cmd} restore"
126
+ end
127
+
128
+ cmds.join(' && ')
116
129
  end
117
130
 
118
131
  def installed?(logger = Core.default_logger)
@@ -5,23 +5,25 @@ module LicenseFinder
5
5
  def initialize(options = {})
6
6
  super
7
7
  @command = options[:rebar_command] || package_management_command
8
- @deps_path = Pathname(options[:rebar_deps_dir] || 'deps')
8
+ @deps_path = Pathname(options[:rebar_deps_dir] || File.join(project_path, '_build/default/lib'))
9
9
  end
10
10
 
11
11
  def current_packages
12
- rebar_ouput.map do |name, version_type, version_value, homepage|
12
+ rebar_deps.map do |name, version|
13
+ licenses, homepage = dep_info(name)
13
14
  RebarPackage.new(
14
15
  name,
15
- "#{version_type}: #{version_value}",
16
+ version,
16
17
  install_path: @deps_path.join(name),
17
18
  homepage: homepage,
19
+ spec_licenses: licenses.nil? ? [] : [licenses],
18
20
  logger: logger
19
21
  )
20
22
  end
21
23
  end
22
24
 
23
25
  def package_management_command
24
- 'rebar'
26
+ 'rebar3'
25
27
  end
26
28
 
27
29
  def possible_package_paths
@@ -30,15 +32,34 @@ module LicenseFinder
30
32
 
31
33
  private
32
34
 
33
- def rebar_ouput
34
- command = "#{@command} list-deps"
35
+ def rebar_deps
36
+ command = "#{@command} tree"
35
37
  stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(command) }
36
38
  raise "Command '#{command}' failed to execute: #{stderr}" unless status.success?
37
39
 
38
40
  stdout
39
41
  .each_line
40
- .reject { |line| line.start_with?('=') }
41
- .map { |line| line.split(' ') }
42
+ .reject { |line| line.start_with?('=') || line.include?('project app') }
43
+ .map do |line|
44
+ matches = line.match(/(?<name>\w+)─(?<version>[\S.]+)\s*/)
45
+ [matches[:name], matches[:version]] if matches
46
+ end.compact
47
+ end
48
+
49
+ def dep_info(name)
50
+ command = "#{@command} pkgs #{name}"
51
+ stdout, _, status = Cmd.run(command)
52
+ return [nil, nil] unless status.success?
53
+
54
+ licenses = nil
55
+ homepage = nil
56
+
57
+ stdout.scan(/Licenses: (?<licenses>.+)|(?<homepage>(https|http).*)/) do |pkg_licenses, pkg_homepage|
58
+ licenses ||= pkg_licenses
59
+ homepage ||= pkg_homepage
60
+ end
61
+
62
+ [licenses, homepage]
42
63
  end
43
64
  end
44
65
  end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+
5
+ class InvalidErlangmkPackageError < ArgumentError
6
+ end
7
+
8
+ module LicenseFinder
9
+ class ErlangmkPackage < Package
10
+ attr_reader :dep_parent,
11
+ :dep_name,
12
+ :dep_fetch_method,
13
+ :dep_repo_unformatted,
14
+ :dep_version_unformatted,
15
+ :dep_absolute_path
16
+
17
+ def initialize(dep_string_from_query_deps)
18
+ @dep_parent,
19
+ @dep_name,
20
+ @dep_fetch_method,
21
+ @dep_repo_unformatted,
22
+ @dep_version_unformatted,
23
+ @dep_absolute_path = dep_string_from_query_deps.split
24
+
25
+ raise_invalid(dep_string_from_query_deps) unless all_parts_valid?
26
+
27
+ super(
28
+ dep_name,
29
+ dep_version,
30
+ homepage: dep_repo,
31
+ install_path: dep_absolute_path
32
+ )
33
+ end
34
+
35
+ def package_manager
36
+ 'Erlangmk'
37
+ end
38
+
39
+ def dep_version
40
+ @dep_version ||= begin
41
+ version_prefix_re = Regexp.new('^v')
42
+ dep_version_unformatted.sub(version_prefix_re, '')
43
+ end
44
+ end
45
+
46
+ def dep_repo
47
+ @dep_repo ||= dep_repo_unformatted
48
+ .chomp('.git')
49
+ .sub('git@github.com:', 'https://github.com/')
50
+ end
51
+
52
+ def raise_invalid(dep_string)
53
+ invalid_dep_message = "'#{dep_string}' does not look like a valid Erlank.mk dependency"
54
+ valid_dep_example = "A valid dependency example: 'lager: goldrush git https://github.com/DeadZen/goldrush.git 0.1.9 /absolute/path/to/dep'"
55
+ raise(InvalidErlangmkPackageError, "#{invalid_dep_message}. #{valid_dep_example}")
56
+ end
57
+
58
+ def all_parts_valid?
59
+ dep_part_valid?(dep_parent) &&
60
+ dep_part_valid?(dep_name) &&
61
+ set?(dep_fetch_method) &&
62
+ dep_repo_valid? &&
63
+ dep_version_valid? &&
64
+ set?(dep_absolute_path)
65
+ end
66
+
67
+ private
68
+
69
+ def dep_part_valid?(dep_part)
70
+ set?(dep_part) &&
71
+ word?(dep_part)
72
+ end
73
+
74
+ def set?(dep_part)
75
+ !dep_part.nil? &&
76
+ !dep_part.empty?
77
+ end
78
+
79
+ def word?(dep_part)
80
+ dep = dep_part.chomp(':')
81
+ dep =~ word_re
82
+ end
83
+
84
+ def word_re
85
+ @word_re ||= Regexp.new('^\w+$')
86
+ end
87
+
88
+ def dep_repo_valid?
89
+ set?(dep_repo_unformatted) &&
90
+ URI.parse(dep_repo)
91
+ end
92
+
93
+ def dep_version_valid?
94
+ return false unless set?(dep_version_unformatted)
95
+
96
+ if dep_version =~ version_re
97
+ Gem::Version.correct?(dep_version)
98
+ else
99
+ dep_version =~ word_re
100
+ end
101
+ end
102
+
103
+ def version_re
104
+ @version_re ||= Regexp.new('\d+\.\d+\.\d+')
105
+ end
106
+ end
107
+ end
@@ -8,9 +8,16 @@ module LicenseFinder
8
8
  INVALID_LICENSES = ['', 'UNKNOWN'].to_set
9
9
 
10
10
  def self.license_names_from_spec(spec)
11
- license = spec['license'].to_s.strip
11
+ license_names = spec['license'].to_s.strip.split(' or ')
12
+ has_unrecognized_license = false
12
13
 
13
- return [license] unless INVALID_LICENSES.include?(license)
14
+ license_names.each do |license_name|
15
+ license = License.find_by_name(license_name.strip)
16
+
17
+ has_unrecognized_license ||= license.unrecognized_matcher?
18
+ end
19
+
20
+ return license_names if !license_names.empty? && !has_unrecognized_license
14
21
 
15
22
  spec
16
23
  .fetch('classifiers', [])
@@ -4,7 +4,7 @@ module LicenseFinder
4
4
  class Scanner
5
5
  PACKAGE_MANAGERS = [
6
6
  GoModules, GoDep, GoWorkspace, Go15VendorExperiment, Glide, Gvt, Govendor, Trash, Dep, Bundler, NPM, Pip,
7
- Yarn, Bower, Maven, Gradle, CocoaPods, Rebar, Nuget, Carthage, Mix, Conan, Sbt, Cargo, Dotnet, Composer, Pipenv
7
+ Yarn, Bower, Maven, Gradle, CocoaPods, Rebar, Erlangmk, Nuget, Carthage, Mix, Conan, Sbt, Cargo, Dotnet, Composer, Pipenv
8
8
  ].freeze
9
9
 
10
10
  class << self
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: license_finder
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.6.0
4
+ version: 6.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Collins
@@ -27,7 +27,7 @@ authors:
27
27
  autorequire:
28
28
  bindir: bin
29
29
  cert_chain: []
30
- date: 2020-06-22 00:00:00.000000000 Z
30
+ date: 2020-08-13 00:00:00.000000000 Z
31
31
  dependencies:
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: bundler
@@ -392,6 +392,7 @@ files:
392
392
  - lib/license_finder/license/templates/LGPL.txt
393
393
  - lib/license_finder/license/templates/LGPL2_1.txt
394
394
  - lib/license_finder/license/templates/MIT.txt
395
+ - lib/license_finder/license/templates/MPL1_1.txt
395
396
  - lib/license_finder/license/templates/MPL2.txt
396
397
  - lib/license_finder/license/templates/NewBSD.txt
397
398
  - lib/license_finder/license/templates/OFL.txt
@@ -414,6 +415,7 @@ files:
414
415
  - lib/license_finder/package_managers/conan.rb
415
416
  - lib/license_finder/package_managers/dep.rb
416
417
  - lib/license_finder/package_managers/dotnet.rb
418
+ - lib/license_finder/package_managers/erlangmk.rb
417
419
  - lib/license_finder/package_managers/glide.rb
418
420
  - lib/license_finder/package_managers/go_15vendorexperiment.rb
419
421
  - lib/license_finder/package_managers/go_dep.rb
@@ -449,6 +451,7 @@ files:
449
451
  - lib/license_finder/packages/cocoa_pods_package.rb
450
452
  - lib/license_finder/packages/composer_package.rb
451
453
  - lib/license_finder/packages/conan_package.rb
454
+ - lib/license_finder/packages/erlangmk_package.rb
452
455
  - lib/license_finder/packages/go_package.rb
453
456
  - lib/license_finder/packages/gradle_package.rb
454
457
  - lib/license_finder/packages/manual_package.rb