license_scout 1.3.16 → 2.0.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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +195 -0
  3. data/bin/license_scout +3 -59
  4. data/bin/mix_lock_json +0 -0
  5. data/bin/rebar_lock_json +0 -0
  6. data/lib/license_scout/cli.rb +99 -0
  7. data/lib/license_scout/collector.rb +25 -77
  8. data/lib/license_scout/config.rb +94 -0
  9. data/lib/license_scout/data/dependeny_manifest_v2_schema.json +62 -0
  10. data/lib/license_scout/data/exceptions.json +306 -0
  11. data/lib/license_scout/data/licenses.json +4653 -0
  12. data/lib/license_scout/dependency.rb +79 -7
  13. data/lib/license_scout/dependency_manager/base.rb +74 -42
  14. data/lib/license_scout/dependency_manager/berkshelf.rb +25 -50
  15. data/lib/license_scout/dependency_manager/bundler/_bundler_script.rb +1 -1
  16. data/lib/license_scout/dependency_manager/bundler.rb +47 -69
  17. data/lib/license_scout/dependency_manager/cpanm.rb +62 -112
  18. data/lib/license_scout/dependency_manager/dep.rb +29 -36
  19. data/lib/license_scout/dependency_manager/glide.rb +25 -36
  20. data/lib/license_scout/dependency_manager/godep.rb +27 -26
  21. data/lib/license_scout/dependency_manager/habitat.rb +126 -0
  22. data/lib/license_scout/dependency_manager/mix.rb +105 -0
  23. data/lib/license_scout/dependency_manager/npm.rb +30 -86
  24. data/lib/license_scout/dependency_manager/rebar.rb +26 -45
  25. data/lib/license_scout/dependency_manager.rb +19 -5
  26. data/lib/license_scout/exceptions.rb +2 -43
  27. data/lib/license_scout/license.rb +126 -0
  28. data/lib/license_scout/{license_file_analyzer.rb → log.rb} +4 -6
  29. data/lib/license_scout/reporter.rb +149 -55
  30. data/lib/license_scout/spdx.rb +123 -0
  31. data/lib/license_scout/version.rb +1 -1
  32. data/lib/license_scout.rb +2 -0
  33. data/native_parsers/mix_lock_json/README.md +21 -0
  34. data/native_parsers/mix_lock_json/lib/mix_lock_json.ex +20 -0
  35. data/native_parsers/mix_lock_json/mix.exs +31 -0
  36. data/native_parsers/mix_lock_json/mix.lock +3 -0
  37. data/{erl_src → native_parsers}/rebar_lock_json/rebar.lock +2 -2
  38. metadata +144 -67
  39. data/lib/license_scout/canonical_licenses/BSD-2-Clause.txt +0 -19
  40. data/lib/license_scout/canonical_licenses/BSD-3-Clause.txt +0 -27
  41. data/lib/license_scout/canonical_licenses/BSD-4-Clause.txt +0 -31
  42. data/lib/license_scout/canonical_licenses/Chef-MLSA.txt +0 -5
  43. data/lib/license_scout/canonical_licenses/ISC.txt +0 -14
  44. data/lib/license_scout/canonical_licenses/MIT.txt +0 -20
  45. data/lib/license_scout/dependency_manager/bundler/LICENSE.md +0 -23
  46. data/lib/license_scout/dependency_manager/json/README.md +0 -392
  47. data/lib/license_scout/dependency_manager/manual.rb +0 -67
  48. data/lib/license_scout/license_file_analyzer/any_matcher.rb +0 -37
  49. data/lib/license_scout/license_file_analyzer/definitions.rb +0 -219
  50. data/lib/license_scout/license_file_analyzer/header_matcher.rb +0 -34
  51. data/lib/license_scout/license_file_analyzer/matcher.rb +0 -46
  52. data/lib/license_scout/license_file_analyzer/template.rb +0 -45
  53. data/lib/license_scout/license_file_analyzer/templates/Apache2-short.txt +0 -11
  54. data/lib/license_scout/license_file_analyzer/templates/Apache2.txt +0 -170
  55. data/lib/license_scout/license_file_analyzer/templates/BSD-2-Clause-bullets.txt +0 -18
  56. data/lib/license_scout/license_file_analyzer/templates/BSD-2-Clause.txt +0 -19
  57. data/lib/license_scout/license_file_analyzer/templates/BSD-3-Clause-alt-format.txt +0 -24
  58. data/lib/license_scout/license_file_analyzer/templates/BSD-3-Clause.txt +0 -21
  59. data/lib/license_scout/license_file_analyzer/templates/BSD.txt +0 -24
  60. data/lib/license_scout/license_file_analyzer/templates/Chef-MLSA.txt +0 -5
  61. data/lib/license_scout/license_file_analyzer/templates/EPLICENSE.txt +0 -286
  62. data/lib/license_scout/license_file_analyzer/templates/GPL-2.0.txt +0 -339
  63. data/lib/license_scout/license_file_analyzer/templates/GPL-3.0.txt +0 -674
  64. data/lib/license_scout/license_file_analyzer/templates/ISC.txt +0 -2
  65. data/lib/license_scout/license_file_analyzer/templates/LGPL-3.0.txt +0 -165
  66. data/lib/license_scout/license_file_analyzer/templates/MIT.txt +0 -9
  67. data/lib/license_scout/license_file_analyzer/templates/MPL2.txt +0 -373
  68. data/lib/license_scout/license_file_analyzer/templates/Python-2.0.txt +0 -47
  69. data/lib/license_scout/license_file_analyzer/templates/Ruby.txt +0 -52
  70. data/lib/license_scout/license_file_analyzer/text.rb +0 -46
  71. data/lib/license_scout/net_fetcher.rb +0 -106
  72. data/lib/license_scout/options.rb +0 -47
  73. data/lib/license_scout/overrides.rb +0 -1123
  74. /data/{erl_src → native_parsers}/rebar_lock_json/README.md +0 -0
  75. /data/{erl_src → native_parsers}/rebar_lock_json/rebar.config +0 -0
  76. /data/{erl_src → native_parsers}/rebar_lock_json/src/rebar_lock_json.app.src +0 -0
  77. /data/{erl_src → native_parsers}/rebar_lock_json/src/rebar_lock_json.erl +0 -0
@@ -16,18 +16,90 @@
16
16
  #
17
17
 
18
18
  module LicenseScout
19
- Dependency = Struct.new(:name, :version, :license, :license_files, :dep_mgr_name) do
19
+ class Dependency
20
20
 
21
+ attr_reader :name
22
+
23
+ attr_reader :version
24
+
25
+ attr_reader :path
26
+
27
+ attr_reader :type
28
+
29
+ attr_reader :license
30
+
31
+ def initialize(name, version, path, type)
32
+ @name = name
33
+ @version = version
34
+ @path = path
35
+ @type = type
36
+
37
+ if path.nil?
38
+ @license = LicenseScout::License.new
39
+ elsif path =~ /^http/ || File.directory?(path)
40
+ @license = LicenseScout::License.new(path)
41
+ else
42
+ raise LicenseScout::Exceptions::MissingSourceDirectory.new("Could not find the source for '#{name}' in the following directories:\n\t * #{path}")
43
+ end
44
+
45
+ fallbacks = LicenseScout::Config.fallbacks.send(type.to_sym).select { |f| f["name"] =~ uid_regexp }
46
+ fallbacks.each do |fallback|
47
+ license.add_license(fallback["license_id"], "license_scout fallback", fallback["license_file"], force: true)
48
+ end
49
+ end
50
+
51
+ # @return [String] The UID for this dependency. Example: bundler (1.16.1)
52
+ def uid
53
+ "#{name} (#{version})"
54
+ end
55
+
56
+ # @return [Regexp] The regular expression that can be used to identify this dependency
57
+ def uid_regexp
58
+ Regexp.new("#{Regexp.escape(name)}(\s+\\(#{Regexp.escape(version)}\\))?")
59
+ end
60
+
61
+ def exceptions
62
+ @exceptions ||= LicenseScout::Config.exceptions.send(type.to_sym).select { |e| e["name"] =~ uid_regexp }
63
+ end
64
+
65
+ # Capture a license that was specified in metadata
66
+ #
67
+ # @param license_id [String] The license as specified in the metadata file
68
+ # @param source [String] Where we found the license info
69
+ # @param contents_url [String] Where we can find the contents of the license
70
+ #
71
+ # @return [void]
72
+ def add_license(license_id, source, contents_url = nil)
73
+ LicenseScout::Log.debug("[#{type}] Adding #{license_id} license for #{name} from #{source}")
74
+ license.add_license(license_id, source, contents_url, {})
75
+ end
76
+
77
+ # Determine if this dependency has an exception. Will match an exception for both the name and the name+version
78
+ def has_exception?
79
+ exceptions.any?
80
+ end
81
+
82
+ def exception_reason
83
+ if has_exception?
84
+ exceptions.first.dig("reason")
85
+ else
86
+ nil
87
+ end
88
+ end
89
+
90
+ # Be able to sort dependencies by type, then name, then version
91
+ def <=>(other)
92
+ "#{type}#{name}#{version}" <=> "#{other.type}#{other.name}#{other.version}"
93
+ end
94
+
95
+ # @return [Boolean] Whether or not this object is equal to another one. Used for Set uniqueness.
21
96
  def eql?(other)
22
- other.is_a?(self.class) && other.hash == hash
97
+ other.kind_of?(self.class) && other.hash == hash
23
98
  end
24
99
 
25
- # hash code for when Dependency is used as a key in a Hash or member of a
26
- # Set. The implementation is somewhat naive, but will work fine if you
27
- # don't go too crazy mixing different types.
100
+ # @return [Integer] A hashcode that can be used to idenitfy this object. Used for Set uniqueness.
28
101
  def hash
29
- [dep_mgr_name, name, version, license].hash
102
+ [type, name, version].hash
30
103
  end
31
-
32
104
  end
33
105
  end
@@ -15,58 +15,90 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
+ require "licensee"
18
19
  require "license_scout/dependency"
19
- require "license_scout/license_file_analyzer"
20
20
 
21
21
  module LicenseScout
22
+ # The DependencyManager module (or more accurately, implementations of it) are responsible for recognizing
23
+ # when a dependency manager such as Bundler, Rebar, Berkshelf, etc is managing dependencies for source code
24
+ # in the given directory.
22
25
  module DependencyManager
23
26
  class Base
24
27
 
25
- POSSIBLE_LICENSE_FILES = %w{
26
- LICENSE
27
- LICENSE.txt
28
- LICENSE.TXT
29
- LICENSE.md
30
- LICENSE.mkd
31
- LICENSE.rdoc
32
- License
33
- License.text
34
- License.txt
35
- License.md
36
- License.rdoc
37
- Licence.rdoc
38
- Licence.md
39
- license
40
- LICENCE
41
- licence
42
- license.md
43
- licence.md
44
- APACHE.LICENSE
45
- MIT-LICENSE
46
- MIT-LICENSE.txt
47
- LICENSE.MIT
48
- LICENSE-MIT
49
- LICENSE-MIT.txt
50
- LGPL-2.1
51
- COPYING.txt
52
- COPYING
53
- BSD_LICENSE
54
- LICENSE.BSD
55
- UNLICENSE
56
- }.freeze
28
+ attr_reader :directory
57
29
 
58
- attr_reader :project_dir
59
- attr_reader :options
30
+ # @param directory [String] The fully-qualified path to the directory to be inspected
31
+ def initialize(directory)
32
+ @directory = directory
33
+ @deps = nil
34
+ end
35
+
36
+ # The unique name of this Dependency Manager. In general, the name should follow the `<TYPE>_<NAME` pattern where:
37
+ # * <TYPE> is the value of DependencyManager#type
38
+ # * <NAME> is the name of the dependency manager.
39
+ #
40
+ # @example Go's various package managers
41
+ # Name Reference
42
+ # -------- -----------------------------------------------
43
+ # go_dep [`godep`](https://github.com/tools/godep)
44
+ # go_godep [`dep`](https://github.com/golang/dep)
45
+ # go_glide [`glide`](https://github.com/Masterminds/glide)
46
+ #
47
+ # @return [String]
48
+ def name
49
+ raise LicenseScout::Exceptions::Error.new("All DependencyManagers must have a `#name` method")
50
+ end
51
+
52
+ # The "type" of dependencies this manager manages. This can be the language, tool, etc.
53
+ #
54
+ # @return [String]
55
+ def type
56
+ raise LicenseScout::Exceptions::Error.new("All DependencyManagers must have a `#type` method")
57
+ end
58
+
59
+ # A human-readable description of the files/folders that indicate this dependency manager is in use.
60
+ #
61
+ # @return [String]
62
+ def signature
63
+ raise LicenseScout::Exceptions::Error.new("All DependencyManagers must have a `#signature` method")
64
+ end
65
+
66
+ # Whether or not we were able to detect that this dependency manager is currently in use in our directory
67
+ #
68
+ # @return [Boolean]
69
+ def detected?
70
+ raise LicenseScout::Exceptions::Error.new("All DependencyManagers must have a `#detected?` method")
71
+ end
60
72
 
61
- def initialize(project_dir, options)
62
- @project_dir = project_dir
63
- @options = options
73
+ # The command to run to install dependency if one or more is missing
74
+ #
75
+ # @return [String]
76
+ def install_command
77
+ raise LicenseScout::Exceptions::Error.new("All DependencyManagers must have a `#install_command` method")
64
78
  end
65
79
 
66
- def create_dependency(dep_name, version, license, license_files, dep_mgr_name = name)
67
- # add name of the dependency manager `name` to the dependency we are
68
- # creating.
69
- Dependency.new(dep_name, version, license, license_files, dep_mgr_name)
80
+ # Implementation's of this method in sub-classes are the methods that are responsible for all
81
+ # the heavy-lifting when it comes to determining the dependencies (and their licenses).
82
+ # They should return an array of `LicenseScout::Dependency`.
83
+ #
84
+ # @return [Array<LicenseScout::Dependency>]
85
+ def dependencies
86
+ []
87
+ end
88
+
89
+ private
90
+
91
+ # A helper that allows you to quickly create a new Dependency (with the type)
92
+ #
93
+ # @param name [String] The name of the dependency
94
+ # @param version [String] The version of the dependency
95
+ # @param path [String] The path to the dependency on the local system
96
+ #
97
+ # @return [LicenseScout::Dependency]
98
+ # @api private
99
+ def new_dependency(name, version, path)
100
+ LicenseScout::Log.debug("[#{type}] Found #{name} #{version}#{" #{path}" unless path.nil?}")
101
+ Dependency.new(name, version, path, type)
70
102
  end
71
103
  end
72
104
  end
@@ -25,14 +25,16 @@ module LicenseScout
25
25
  "chef_berkshelf"
26
26
  end
27
27
 
28
- def berkshelf_available?
29
- begin
30
- require "berkshelf"
31
- rescue LoadError
32
- return false
33
- end
28
+ def type
29
+ "chef_cookbook"
30
+ end
34
31
 
35
- true
32
+ def signature
33
+ "Berksfile and Berksfile.lock files"
34
+ end
35
+
36
+ def install_command
37
+ "berks install"
36
38
  end
37
39
 
38
40
  def detected?
@@ -41,13 +43,12 @@ module LicenseScout
41
43
 
42
44
  def dependencies
43
45
  unless berkshelf_available?
44
- raise LicenseScout::Exceptions::Error.new "Project at '#{project_dir}' is a Berkshelf project but berkshelf gem is not available in your bundle. Add berkshelf to your bundle in order to collect licenses for this project."
46
+ raise LicenseScout::Exceptions::Error.new("Project at '#{directory}' is a Berkshelf project but berkshelf gem is not available in your bundle. Add berkshelf to your bundle in order to collect licenses for this project.")
45
47
  end
46
48
 
47
- dependencies = []
48
- cookbook_dependencies = nil
49
+ cookbook_dependencies = []
49
50
 
50
- Dir.chdir(project_dir) do
51
+ Dir.chdir(directory) do
51
52
  berksfile = ::Berkshelf::Berksfile.from_file("./Berksfile")
52
53
 
53
54
  # Berkshelf should not give an error when there are cookbooks in the
@@ -59,56 +60,30 @@ module LicenseScout
59
60
  cookbook_dependencies = berksfile.list
60
61
  end
61
62
 
62
- cookbook_dependencies.each do |dep|
63
- dependency_name = dep.name
64
- dependency_version = dep.cached_cookbook.version
65
-
66
- dependency_license_files = auto_detect_license_files(dep.cached_cookbook.path.to_s)
67
-
68
- # Check license override and license_files override separately since
69
- # only one might be set in the overrides.
70
- dependency_license = options.overrides.license_for(name, dependency_name, dependency_version) || dep.cached_cookbook.license
71
-
72
- override_license_files = options.overrides.license_files_for(name, dependency_name, dependency_version)
73
- cookbook_path = dep.cached_cookbook.path.to_s
63
+ cookbook_dependencies.map do |dep|
64
+ new_dependency(dep.name, dep.cached_cookbook.version, dep.cached_cookbook.path.to_s)
65
+ end.compact
66
+ end
74
67
 
75
- if override_license_files.empty?
76
- dependency_license_files = auto_detect_license_files(cookbook_path)
77
- else
78
- dependency_license_files = override_license_files.resolve_locations(cookbook_path)
79
- end
68
+ private
80
69
 
81
- dependencies << create_dependency(
82
- dependency_name,
83
- dependency_version,
84
- dependency_license,
85
- dependency_license_files
86
- )
70
+ def berkshelf_available?
71
+ begin
72
+ require "berkshelf"
73
+ rescue LoadError
74
+ return false
87
75
  end
88
76
 
89
- dependencies
77
+ true
90
78
  end
91
79
 
92
- private
93
-
94
80
  def berksfile_path
95
- File.join(project_dir, "Berksfile")
81
+ File.join(directory, "Berksfile")
96
82
  end
97
83
 
98
84
  def lockfile_path
99
- File.join(project_dir, "Berksfile.lock")
85
+ File.join(directory, "Berksfile.lock")
100
86
  end
101
-
102
- def auto_detect_license_files(cookbook_path)
103
- unless File.exist?(cookbook_path)
104
- raise LicenseScout::Exceptions::InaccessibleDependency.new "Autodetected cookbook path '#{cookbook_path}' does not exist"
105
- end
106
-
107
- Dir.glob("#{cookbook_path}/*").select do |f|
108
- POSSIBLE_LICENSE_FILES.include?(File.basename(f))
109
- end
110
- end
111
-
112
87
  end
113
88
  end
114
89
  end
@@ -30,7 +30,7 @@
30
30
  require "bundler/setup"
31
31
 
32
32
  # We're only using things that are in the stdlib.
33
- require "json" unless defined?(JSON)
33
+ require "json"
34
34
 
35
35
  dependencies = []
36
36
 
@@ -16,13 +16,11 @@
16
16
  #
17
17
 
18
18
  require "license_scout/dependency_manager/base"
19
- require "license_scout/net_fetcher"
20
- require "license_scout/exceptions"
21
19
 
22
20
  require "bundler"
23
- require "mixlib/shellout" unless defined?(Mixlib::ShellOut)
24
- require "ffi_yajl" unless defined?(FFI_Yajl)
25
- require "pathname" unless defined?(Pathname)
21
+ require "mixlib/shellout"
22
+ require "ffi_yajl"
23
+ require "pathname"
26
24
 
27
25
  module LicenseScout
28
26
  module DependencyManager
@@ -32,6 +30,18 @@ module LicenseScout
32
30
  "ruby_bundler"
33
31
  end
34
32
 
33
+ def type
34
+ "ruby"
35
+ end
36
+
37
+ def signature
38
+ "Gemfile and Gemfile.lock files"
39
+ end
40
+
41
+ def install_command
42
+ "bundle install"
43
+ end
44
+
35
45
  def detected?
36
46
  # We check the existence of both Gemfile and Gemfile.lock. We need both
37
47
  # of them to be able to get a concrete set of dependencies which we can
@@ -42,13 +52,40 @@ module LicenseScout
42
52
  File.exist?(gemfile_path) && File.exist?(lockfile_path)
43
53
  end
44
54
 
55
+ def dependencies
56
+ dependency_data.map do |gem_data|
57
+ dep_name = gem_data["name"]
58
+ dep_version = gem_data["version"]
59
+
60
+ dep_path = if dep_name == "bundler"
61
+ # Bundler is weird. It inserts itself as a dependency, but is a
62
+ # special case, so rubygems cannot correctly report the license.
63
+ # Additionally, rubygems reports the gem path as a path inside
64
+ # bundler's lib/ dir, so we have to munge it.
65
+ "https://github.com/bundler/bundler"
66
+ elsif dep_name == "json"
67
+ # json is different weird. When project is using the json that is prepackaged with
68
+ # Ruby, its included not as a full fledged gem but an *.rb file at:
69
+ # /opt/opscode/embedded/lib/ruby/2.2.0/json.rb
70
+ # Because of this its license is reported as nil and its license files can not be
71
+ # found. That is why we need to provide them manually here.
72
+ "https://github.com/flori/json"
73
+ else
74
+ gem_data["path"]
75
+ end
76
+
77
+ new_dependency(dep_name, dep_version, dep_path)
78
+ end.compact
79
+ end
80
+
81
+ private
82
+
45
83
  def dependency_data
46
84
  bundler_script = File.join(File.dirname(__FILE__), "bundler/_bundler_script.rb")
47
85
 
48
- Dir.chdir(project_dir) do
86
+ Dir.chdir(directory) do
49
87
  json_dep_data = with_clean_env do
50
- ruby_bin_path = options.ruby_bin || "ruby"
51
- s = Mixlib::ShellOut.new("#{ruby_bin_path} #{bundler_script}", environment: options.environment)
88
+ s = Mixlib::ShellOut.new("#{LicenseScout::Config.ruby_bin} #{bundler_script}", environment: LicenseScout::Config.environment)
52
89
  s.run_command
53
90
  s.error!
54
91
  s.stdout
@@ -57,55 +94,6 @@ module LicenseScout
57
94
  end
58
95
  end
59
96
 
60
- def dependencies
61
- dependencies = []
62
- dependency_data.each do |gem_data|
63
- dependency_name = gem_data["name"]
64
- dependency_version = gem_data["version"]
65
- dependency_license = nil
66
- dependency_license_files = []
67
-
68
- if dependency_name == "bundler"
69
- # Bundler is weird. It inserts itself as a dependency, but is a
70
- # special case, so rubygems cannot correctly report the license.
71
- # Additionally, rubygems reports the gem path as a path inside
72
- # bundler's lib/ dir, so we have to munge it.
73
- dependency_license = "MIT"
74
- dependency_license_files = [File.join(File.dirname(__FILE__), "bundler/LICENSE.md")]
75
- elsif dependency_name == "json"
76
- # json is different weird. When project is using the json that is prepackaged with
77
- # Ruby, its included not as a full fledged gem but an *.rb file at:
78
- # /opt/opscode/embedded/lib/ruby/2.2.0/json.rb
79
- # Because of this its license is reported as nil and its license files can not be
80
- # found. That is why we need to provide them manually here.
81
- dependency_license = "Ruby"
82
- dependency_license_files = [File.join(File.dirname(__FILE__), "json/README.md")]
83
- else
84
- # Check license override and license_files override separately since
85
- # only one might be set in the overrides.
86
- dependency_license = options.overrides.license_for(name, dependency_name, dependency_version) || gem_data["license"]
87
-
88
- override_license_files = options.overrides.license_files_for(name, dependency_name, dependency_version)
89
- if override_license_files.empty?
90
- dependency_license_files = auto_detect_license_files(gem_data["path"])
91
- else
92
- dependency_license_files = override_license_files.resolve_locations(gem_data["path"])
93
- end
94
- end
95
-
96
- dependencies << create_dependency(
97
- dependency_name,
98
- dependency_version,
99
- dependency_license,
100
- dependency_license_files
101
- )
102
- end
103
-
104
- dependencies
105
- end
106
-
107
- private
108
-
109
97
  #
110
98
  # Execute the given command, removing any Ruby-specific environment
111
99
  # variables. This is an "enhanced" version of +Bundler.with_clean_env+,
@@ -142,22 +130,12 @@ module LicenseScout
142
130
  ENV.replace(original.to_hash)
143
131
  end
144
132
 
145
- def auto_detect_license_files(gem_path)
146
- unless File.exist?(gem_path)
147
- raise LicenseScout::Exceptions::InaccessibleDependency.new "Autodetected gem path '#{gem_path}' does not exist"
148
- end
149
-
150
- Dir.glob("#{gem_path}/*").select do |f|
151
- POSSIBLE_LICENSE_FILES.include?(File.basename(f))
152
- end
153
- end
154
-
155
133
  def gemfile_path
156
- File.join(project_dir, "Gemfile")
134
+ File.join(directory, "Gemfile")
157
135
  end
158
136
 
159
137
  def lockfile_path
160
- File.join(project_dir, "Gemfile.lock")
138
+ File.join(directory, "Gemfile.lock")
161
139
  end
162
140
 
163
141
  end