inspec 0.35.0 → 1.0.0.beta2

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +83 -2
  3. data/Gemfile +6 -0
  4. data/Rakefile +3 -55
  5. data/docs/README.md +20 -0
  6. data/docs/cli.rst +6 -0
  7. data/docs/dsl_inspec.md +245 -0
  8. data/docs/dsl_resource.md +93 -0
  9. data/docs/inspec_and_friends.md +102 -0
  10. data/docs/matchers.md +136 -0
  11. data/docs/plugin_kitchen_inspec.html.md +55 -0
  12. data/docs/profiles.md +271 -0
  13. data/docs/resources.rst +1 -1
  14. data/docs/shell.md +150 -0
  15. data/inspec.gemspec +1 -1
  16. data/lib/bundles/inspec-compliance/api.rb +28 -18
  17. data/lib/bundles/inspec-compliance/cli.rb +19 -27
  18. data/lib/fetchers/git.rb +4 -0
  19. data/lib/fetchers/local.rb +16 -1
  20. data/lib/fetchers/mock.rb +4 -0
  21. data/lib/fetchers/url.rb +40 -12
  22. data/lib/inspec/base_cli.rb +4 -0
  23. data/lib/inspec/cli.rb +6 -8
  24. data/lib/inspec/control_eval_context.rb +8 -0
  25. data/lib/inspec/dependencies/{vendor_index.rb → cache.rb} +5 -4
  26. data/lib/inspec/dependencies/dependency_set.rb +8 -14
  27. data/lib/inspec/dependencies/requirement.rb +10 -20
  28. data/lib/inspec/dependencies/resolver.rb +2 -2
  29. data/lib/inspec/dsl.rb +9 -0
  30. data/lib/inspec/fetcher.rb +1 -1
  31. data/lib/inspec/objects/test.rb +8 -2
  32. data/lib/inspec/plugins/fetcher.rb +11 -12
  33. data/lib/inspec/plugins/resource.rb +3 -0
  34. data/lib/inspec/profile.rb +60 -14
  35. data/lib/inspec/profile_context.rb +28 -7
  36. data/lib/inspec/resource.rb +17 -2
  37. data/lib/inspec/rspec_json_formatter.rb +80 -35
  38. data/lib/inspec/runner.rb +42 -18
  39. data/lib/inspec/shell.rb +5 -16
  40. data/lib/inspec/version.rb +1 -1
  41. data/lib/resources/apache_conf.rb +1 -1
  42. data/lib/resources/gem.rb +1 -0
  43. data/lib/resources/oneget.rb +1 -0
  44. data/lib/resources/os.rb +1 -1
  45. data/lib/resources/package.rb +3 -1
  46. data/lib/resources/pip.rb +1 -1
  47. data/lib/resources/ssl.rb +9 -11
  48. metadata +15 -15
  49. data/docs/dsl_inspec.rst +0 -259
  50. data/docs/dsl_resource.rst +0 -90
  51. data/docs/inspec_and_friends.rst +0 -85
  52. data/docs/matchers.rst +0 -137
  53. data/docs/profiles.rst +0 -169
  54. data/docs/readme.rst +0 -105
  55. data/docs/shell.rst +0 -130
  56. data/docs/template.rst +0 -51
@@ -58,6 +58,10 @@ module Inspec
58
58
  desc: 'Use colors in output.'
59
59
  option :attrs, type: :array,
60
60
  desc: 'Load attributes file (experimental)'
61
+ option :cache, type: :string,
62
+ desc: 'Use the given path for caching dependencies. (default: ~/.inspec/cache)'
63
+ option :create_lockfile, type: :boolean, default: true,
64
+ desc: 'Write out a lockfile based on this execution (unless one already exists)'
61
65
  end
62
66
 
63
67
  private
data/lib/inspec/cli.rb CHANGED
@@ -102,8 +102,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
102
102
  desc 'vendor', 'Download all dependencies and generate a lockfile'
103
103
  def vendor(path = nil)
104
104
  configure_logger(opts)
105
- profile = Inspec::Profile.for_target('./', opts)
106
- lockfile = profile.generate_lockfile(path)
105
+ profile = Inspec::Profile.for_target('./', opts.merge(cache: Inspec::Cache.new(path)))
106
+ lockfile = profile.generate_lockfile
107
107
  File.write('inspec.lock', lockfile.to_yaml)
108
108
  end
109
109
 
@@ -213,13 +213,11 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
213
213
 
214
214
  def run_command(opts)
215
215
  runner = Inspec::Runner.new(opts)
216
- ctx = runner.create_context(opts)
217
- res = ctx.load(opts[:command])
216
+ res = runner.eval_with_virtual_profile(opts[:command])
217
+ runner.load
218
218
 
219
- return :ruby_eval, res if ctx.rules.empty?
220
-
221
- runner.register_rules(ctx)
222
- return :rspec_run, runner.run # rubocop:disable Style/RedundantReturn
219
+ return :ruby_eval, res if runner.all_rules.empty?
220
+ return :rspec_run, runner.run_tests # rubocop:disable Style/RedundantReturn
223
221
  end
224
222
  end
225
223
 
@@ -92,6 +92,14 @@ module Inspec
92
92
  res
93
93
  end
94
94
 
95
+ define_method :add_resource do |name, new_res|
96
+ resources_dsl.module_exec do
97
+ define_method name.to_sym do |*args|
98
+ new_res.new(@backend, name.to_s, *args)
99
+ end
100
+ end
101
+ end
102
+
95
103
  define_method :add_resources do |context|
96
104
  self.class.class_eval do
97
105
  include context.to_resources_dsl
@@ -4,7 +4,7 @@ require 'fileutils'
4
4
 
5
5
  module Inspec
6
6
  #
7
- # VendorIndex manages an on-disk cache of inspec profiles. The
7
+ # Inspec::Cache manages an on-disk cache of inspec profiles. The
8
8
  # cache can contain:
9
9
  #
10
10
  # - .tar.gz profile archives
@@ -16,7 +16,7 @@ module Inspec
16
16
  # sources.
17
17
  #
18
18
  #
19
- class VendorIndex
19
+ class Cache
20
20
  attr_reader :path
21
21
  def initialize(path = nil)
22
22
  @path = path || File.join(Dir.home, '.inspec', 'cache')
@@ -43,19 +43,20 @@ module Inspec
43
43
 
44
44
  #
45
45
  # For a given name and source_url, return true if the
46
- # profile exists in the VendorIndex.
46
+ # profile exists in the Cache.
47
47
  #
48
48
  # @param [String] name
49
49
  # @param [String] source_url
50
50
  # @return [Boolean]
51
51
  #
52
52
  def exists?(key)
53
+ return false if key.nil? || key.empty?
53
54
  path = base_path_for(key)
54
55
  File.directory?(path) || File.exist?("#{path}.tar.gz") || File.exist?("#{path}.zip")
55
56
  end
56
57
 
57
58
  #
58
- # Return the path to given profile in the vendor index.
59
+ # Return the path to given profile in the cache.
59
60
  #
60
61
  # The `source_url` parameter should be a URI-like string that
61
62
  # fully specifies the source of the exact version we want to pull
@@ -1,5 +1,4 @@
1
1
  # encoding: utf-8
2
- require 'inspec/dependencies/vendor_index'
3
2
  require 'inspec/dependencies/requirement'
4
3
  require 'inspec/dependencies/resolver'
5
4
 
@@ -7,9 +6,6 @@ module Inspec
7
6
  #
8
7
  # A DependencySet manages a list of dependencies for a profile.
9
8
  #
10
- # Currently this class is a thin wrapper interface to coordinate the
11
- # VendorIndex and the Resolver.
12
- #
13
9
  class DependencySet
14
10
  #
15
11
  # Return a dependency set given a lockfile.
@@ -18,22 +14,21 @@ module Inspec
18
14
  # @param cwd [String] Current working directory for relative path includes
19
15
  # @param vendor_path [String] Path to the vendor directory
20
16
  #
21
- def self.from_lockfile(lockfile, cwd, vendor_path, backend)
22
- vendor_index = VendorIndex.new(vendor_path)
17
+ def self.from_lockfile(lockfile, cwd, cache, backend)
23
18
  dep_tree = lockfile.deps.map do |dep|
24
- Inspec::Requirement.from_lock_entry(dep, cwd, vendor_index, backend)
19
+ Inspec::Requirement.from_lock_entry(dep, cwd, cache, backend)
25
20
  end
26
21
 
27
22
  dep_list = flatten_dep_tree(dep_tree)
28
- new(cwd, vendor_path, dep_list, backend)
23
+ new(cwd, cache, dep_list, backend)
29
24
  end
30
25
 
31
- def self.from_array(dependencies, cwd, vendor_path, backend)
26
+ def self.from_array(dependencies, cwd, cache, backend)
32
27
  dep_list = {}
33
28
  dependencies.each do |d|
34
29
  dep_list[d.name] = d
35
30
  end
36
- new(cwd, vendor_path, dep_list, backend)
31
+ new(cwd, cache, dep_list, backend)
37
32
  end
38
33
 
39
34
  # This is experimental code to test the working of the
@@ -58,9 +53,9 @@ module Inspec
58
53
  # @param cwd [String] current working directory for relative path includes
59
54
  # @param vendor_path [String] path which contains vendored dependencies
60
55
  # @return [dependencies] this
61
- def initialize(cwd, vendor_path, dep_list, backend)
56
+ def initialize(cwd, cache, dep_list, backend)
62
57
  @cwd = cwd
63
- @vendor_path = vendor_path
58
+ @cache = cache
64
59
  @dep_list = dep_list
65
60
  @backend = backend
66
61
  end
@@ -91,8 +86,7 @@ module Inspec
91
86
  #
92
87
  def vendor(dependencies)
93
88
  return nil if dependencies.nil? || dependencies.empty?
94
- @vendor_index ||= VendorIndex.new(@vendor_path)
95
- @dep_list = Resolver.resolve(dependencies, @vendor_index, @cwd, @backend)
89
+ @dep_list = Resolver.resolve(dependencies, @cache, @cwd, @backend)
96
90
  end
97
91
  end
98
92
  end
@@ -9,31 +9,31 @@ module Inspec
9
9
  # appropriate we delegate to Inspec::Profile directly.
10
10
  #
11
11
  class Requirement
12
- def self.from_metadata(dep, vendor_index, opts)
12
+ def self.from_metadata(dep, cache, opts)
13
13
  fail 'Cannot load empty dependency.' if dep.nil? || dep.empty?
14
- new(dep[:name], dep[:version], vendor_index, opts[:cwd], opts.merge(dep))
14
+ new(dep[:name], dep[:version], cache, opts[:cwd], opts.merge(dep))
15
15
  end
16
16
 
17
- def self.from_lock_entry(entry, cwd, vendor_index, backend)
17
+ def self.from_lock_entry(entry, cwd, cache, backend)
18
18
  req = new(entry[:name],
19
19
  entry[:version_constraints],
20
- vendor_index,
20
+ cache,
21
21
  cwd,
22
22
  entry[:resolved_source].merge(backend: backend))
23
23
 
24
24
  locked_deps = []
25
25
  Array(entry[:dependencies]).each do |dep_entry|
26
- locked_deps << Inspec::Requirement.from_lock_entry(dep_entry, cwd, vendor_index, backend)
26
+ locked_deps << Inspec::Requirement.from_lock_entry(dep_entry, cwd, cache, backend)
27
27
  end
28
28
  req.lock_deps(locked_deps)
29
29
  req
30
30
  end
31
31
 
32
32
  attr_reader :cwd, :opts, :required_version
33
- def initialize(name, version_constraints, vendor_index, cwd, opts)
33
+ def initialize(name, version_constraints, cache, cwd, opts)
34
34
  @name = name
35
35
  @required_version = Gem::Requirement.new(Array(version_constraints))
36
- @vendor_index = vendor_index
36
+ @cache = cache
37
37
  @backend = opts[:backend]
38
38
  @opts = opts
39
39
  @cwd = cwd
@@ -74,7 +74,6 @@ module Inspec
74
74
  h['dependencies'] = dependencies.map(&:to_hash)
75
75
  end
76
76
 
77
- h['content_hash'] = content_hash if content_hash
78
77
  h
79
78
  end
80
79
 
@@ -82,15 +81,6 @@ module Inspec
82
81
  @dependencies = dep_array
83
82
  end
84
83
 
85
- def content_hash
86
- @content_hash ||= begin
87
- archive_path = @vendor_index.archive_entry_for(fetcher.cache_key) || fetcher.archive_path
88
- if archive_path && File.file?(archive_path)
89
- Digest::SHA256.hexdigest File.read(archive_path)
90
- end
91
- end
92
- end
93
-
94
84
  def fetcher
95
85
  @fetcher ||= Inspec::Fetcher.resolve(opts)
96
86
  fail "No fetcher for #{name} (options: #{opts})" if @fetcher.nil?
@@ -99,7 +89,7 @@ module Inspec
99
89
 
100
90
  def dependencies
101
91
  @dependencies ||= profile.metadata.dependencies.map do |r|
102
- Inspec::Requirement.from_metadata(r, @vendor_index, cwd: @cwd, backend: @backend)
92
+ Inspec::Requirement.from_metadata(r, @cache, cwd: @cwd, backend: @backend)
103
93
  end
104
94
  end
105
95
 
@@ -109,10 +99,10 @@ module Inspec
109
99
 
110
100
  def profile
111
101
  opts = @opts.dup
112
- opts[:cache] = @vendor_index
102
+ opts[:cache] = @cache
113
103
  opts[:backend] = @backend
114
104
  if !@dependencies.nil?
115
- opts[:dependencies] = Inspec::DependencySet.from_array(@dependencies, @cwd, @vendor_index, @backend)
105
+ opts[:dependencies] = Inspec::DependencySet.from_array(@dependencies, @cwd, @cache, @backend)
116
106
  end
117
107
  @profile ||= Inspec::Profile.for_target(opts, opts)
118
108
  end
@@ -23,9 +23,9 @@ module Inspec
23
23
  # implementation of the fetcher being used.
24
24
  #
25
25
  class Resolver
26
- def self.resolve(dependencies, vendor_index, working_dir, backend)
26
+ def self.resolve(dependencies, cache, working_dir, backend)
27
27
  reqs = dependencies.map do |dep|
28
- req = Inspec::Requirement.from_metadata(dep, vendor_index, cwd: working_dir, backend: backend)
28
+ req = Inspec::Requirement.from_metadata(dep, cache, cwd: working_dir, backend: backend)
29
29
  req || fail("Cannot initialize dependency: #{req}")
30
30
  end
31
31
  new.resolve(reqs)
data/lib/inspec/dsl.rb CHANGED
@@ -18,6 +18,15 @@ module Inspec::DSL
18
18
  alias require_rules require_controls
19
19
  alias include_rules include_controls
20
20
 
21
+ def require_resource(options = {})
22
+ fail 'You must specify a specific resource name when calling require_resource()' if options[:resource].nil?
23
+
24
+ from_profile = options[:profile] || profile_name
25
+ target_name = options[:as] || options[:resource]
26
+ res = resource_class(from_profile, options[:resource])
27
+ add_resource(target_name, res)
28
+ end
29
+
21
30
  def self.load_spec_files_for_profile(bind_context, opts, &block)
22
31
  dependencies = opts[:dependencies]
23
32
  profile_id = opts[:profile_id]
@@ -16,7 +16,7 @@ module Inspec
16
16
  end
17
17
  end
18
18
 
19
- NON_FETCHER_KEYS = [:name, :version_constraint, :cwd, :backend, :cache].freeze
19
+ NON_FETCHER_KEYS = [:name, :version_constraint, :cwd, :backend, :cache, :sha256].freeze
20
20
  def fetcher_specified?(target)
21
21
  # Only set a default for Hash-based (i.e. from
22
22
  # inspec.yml/inspec.lock) targets
@@ -66,8 +66,14 @@ module Inspec
66
66
  res, xtra = describe_chain
67
67
  itsy = xtra.nil? ? 'it' : 'its(' + xtra.to_s.inspect + ')'
68
68
  naughty = @negated ? '_not' : ''
69
- xpect = defined?(@expectation) ? expectation.inspect+' ' : ''
70
- format("%sdescribe %s do\n %s { should%s %s %s}\nend",
69
+ xpect = defined?(@expectation) ? expectation.inspect : ''
70
+ if matcher == 'match'
71
+ # without this, xpect values like / \/zones\// will not be parsed properly
72
+ xpect = "(#{xpect})"
73
+ elsif xpect != ''
74
+ xpect = ' ' + xpect
75
+ end
76
+ format("%sdescribe %s do\n %s { should%s %s%s }\nend",
71
77
  vars, res, itsy, naughty, matcher, xpect)
72
78
  end
73
79
 
@@ -24,6 +24,10 @@ module Inspec
24
24
  Inspec::Fetcher
25
25
  end
26
26
 
27
+ def writable?
28
+ false
29
+ end
30
+
27
31
  #
28
32
  # The path to the archive on disk. This can be passed to a
29
33
  # FileProvider to get access to the files in the fetched
@@ -56,6 +60,13 @@ module Inspec
56
60
  fail "Fetcher #{self} does not implement `resolved_source()`. This is required for terminal fetchers."
57
61
  end
58
62
 
63
+ #
64
+ # The unique key based on the content of the remote archive.
65
+ #
66
+ def cache_key
67
+ fail "Fetcher #{self} does not implement `cache_key()`. This is required for terminal fetchers."
68
+ end
69
+
59
70
  #
60
71
  # relative_target is provided to keep compatibility with 3rd
61
72
  # party plugins.
@@ -69,18 +80,6 @@ module Inspec
69
80
  file_provider = Inspec::FileProvider.for_path(archive_path)
70
81
  file_provider.relative_provider
71
82
  end
72
-
73
- #
74
- # A string based on the components of the resolved source,
75
- # suitable for constructing per-source file names.
76
- #
77
- def cache_key
78
- key = ''
79
- resolved_source.each do |k, v|
80
- key << "#{k}:#{v}"
81
- end
82
- Digest::SHA256.hexdigest key
83
- end
84
83
  end
85
84
  end
86
85
  end
@@ -72,6 +72,9 @@ module Inspec
72
72
  end
73
73
 
74
74
  # rubocop:enable Lint/NestedMethodDefinition
75
+ if __resource_registry.key?(name)
76
+ Inspec::Log.warn("Overwriting resource #{name}. To reference a specific version of #{name} use the resource() method")
77
+ end
75
78
  __resource_registry[name] = cl
76
79
  end
77
80
  end
@@ -13,7 +13,7 @@ require 'inspec/backend'
13
13
  require 'inspec/rule'
14
14
  require 'inspec/log'
15
15
  require 'inspec/profile_context'
16
- require 'inspec/dependencies/vendor_index'
16
+ require 'inspec/dependencies/cache'
17
17
  require 'inspec/dependencies/lockfile'
18
18
  require 'inspec/dependencies/dependency_set'
19
19
 
@@ -21,19 +21,44 @@ module Inspec
21
21
  class Profile # rubocop:disable Metrics/ClassLength
22
22
  extend Forwardable
23
23
 
24
+ #
25
+ # TODO: This function is getting pretty gross.
26
+ #
24
27
  def self.resolve_target(target, cache = nil)
25
- cache ||= VendorIndex.new
28
+ cache ||= Cache.new
26
29
  fetcher = Inspec::Fetcher.resolve(target)
30
+
27
31
  if fetcher.nil?
28
32
  fail("Could not fetch inspec profile in #{target.inspect}.")
29
33
  end
30
34
 
31
- if cache.exists?(fetcher.cache_key)
35
+ cache_key = if target.is_a?(Hash)
36
+ target[:sha256] || target[:ref] || fetcher.cache_key
37
+ else
38
+ fetcher.cache_key
39
+ end
40
+
41
+ if cache.exists?(cache_key)
32
42
  Inspec::Log.debug "Using cached dependency for #{target}"
33
- cache.prefered_entry_for(fetcher.cache_key)
43
+ [cache.prefered_entry_for(cache_key), false]
34
44
  else
35
45
  fetcher.fetch(cache.base_path_for(fetcher.cache_key))
36
- fetcher.archive_path
46
+ if target.respond_to?(:key?) && target.key?(:sha256)
47
+ if fetcher.resolved_source[:sha256] != target[:sha256]
48
+ fail <<EOF
49
+ The remote source #{fetcher} no longer has the requested content:
50
+
51
+ Request Content Hash: #{target[:sha256]}
52
+ Actual Content Hash: #{fetcher.resolved_source[:sha256]}
53
+
54
+ For URL, supermarket, compliance, and other sources that do not
55
+ provide versioned artifacts, this likely means that the remote source
56
+ has changed since your lockfile was generated.
57
+ EOF
58
+ end
59
+ end
60
+
61
+ [fetcher.archive_path, fetcher.writable?]
37
62
  end
38
63
  end
39
64
 
@@ -48,7 +73,8 @@ module Inspec
48
73
  end
49
74
 
50
75
  def self.for_target(target, opts = {})
51
- for_path(resolve_target(target, opts[:cache]), opts.merge(target: target))
76
+ path, writable = resolve_target(target, opts[:cache])
77
+ for_path(path, opts.merge(target: target, writable: writable))
52
78
  end
53
79
 
54
80
  attr_reader :source_reader, :backend, :runner_context
@@ -62,10 +88,13 @@ module Inspec
62
88
  @logger = options[:logger] || Logger.new(nil)
63
89
  @locked_dependencies = options[:dependencies]
64
90
  @controls = options[:controls] || []
91
+ @writable = options[:writable] || false
65
92
  @profile_id = options[:id]
93
+ @cache = options[:cache] || Cache.new
66
94
  @backend = options[:backend] || Inspec::Backend.create(options)
67
95
  @source_reader = source_reader
68
96
  @tests_collected = false
97
+ @libraries_loaded = false
69
98
  Metadata.finalize(@source_reader.metadata, @profile_id)
70
99
  @runner_context = options[:profile_context] || Inspec::ProfileContext.for_profile(self,
71
100
  @backend,
@@ -80,6 +109,10 @@ module Inspec
80
109
  metadata.params[:version]
81
110
  end
82
111
 
112
+ def writable? # rubocop:disable Style/TrivialAccessors
113
+ @writable
114
+ end
115
+
83
116
  #
84
117
  # Is this profile is supported on the current platform of the
85
118
  # backend machine and the current inspec version.
@@ -125,6 +158,8 @@ module Inspec
125
158
  end
126
159
 
127
160
  def load_libraries
161
+ return @runner_context if @libraries_loaded
162
+
128
163
  locked_dependencies.each do |d|
129
164
  c = d.load_libraries
130
165
  @runner_context.add_resources(c)
@@ -135,6 +170,7 @@ module Inspec
135
170
  end
136
171
 
137
172
  @runner_context.load_libraries(libs)
173
+ @libraries_loaded = true
138
174
  @runner_context
139
175
  end
140
176
 
@@ -142,19 +178,29 @@ module Inspec
142
178
  "Inspec::Profile<#{name}>"
143
179
  end
144
180
 
145
- def info
146
- res = params.dup
181
+ # return info using uncached params
182
+ def info!
183
+ info(load_params.dup)
184
+ end
185
+
186
+ def info(res = params.dup)
147
187
  # add information about the controls
148
- controls = res[:controls].map do |id, rule|
188
+ res[:controls] = res[:controls].map do |id, rule|
149
189
  next if id.to_s.empty?
150
190
  data = rule.dup
151
191
  data.delete(:checks)
152
192
  data[:impact] ||= 0.5
153
193
  data[:impact] = 1.0 if data[:impact] > 1.0
154
194
  data[:impact] = 0.0 if data[:impact] < 0.0
155
- [id, data]
195
+ data[:id] = id
196
+ data
197
+ end.compact
198
+
199
+ # resolve hash structure in groups
200
+ res[:groups] = res[:groups].map do |id, group|
201
+ group[:id] = id
202
+ group
156
203
  end
157
- res[:controls] = Hash[controls.compact]
158
204
 
159
205
  # add information about the required attributes
160
206
  res[:attributes] = res[:attributes].map(&:to_hash) unless res[:attributes].nil? || res[:attributes].empty?
@@ -329,14 +375,14 @@ module Inspec
329
375
  # @param vendor_path [String] Path to the on-disk vendor dir
330
376
  # @return [Inspec::Lockfile]
331
377
  #
332
- def generate_lockfile(vendor_path = nil)
333
- res = Inspec::DependencySet.new(cwd, vendor_path, nil, @backend)
378
+ def generate_lockfile
379
+ res = Inspec::DependencySet.new(cwd, @cache, nil, @backend)
334
380
  res.vendor(metadata.dependencies)
335
381
  Inspec::Lockfile.from_dependency_set(res)
336
382
  end
337
383
 
338
384
  def load_dependencies
339
- Inspec::DependencySet.from_lockfile(lockfile, cwd, nil, @backend)
385
+ Inspec::DependencySet.from_lockfile(lockfile, cwd, @cache, @backend)
340
386
  end
341
387
 
342
388
  private