Class: Inspec::Requirement

Inherits:
Object
  • Object
show all
Defined in:
lib/inspec/dependencies/requirement.rb

Overview

Inspec::Requirement represents a given profile dependency, where appropriate we delegate to Inspec::Profile directly.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, version_constraints, vendor_index, cwd, opts) ⇒ Requirement

Returns a new instance of Requirement.



36
37
38
39
40
41
42
43
# File 'lib/inspec/dependencies/requirement.rb', line 36

def initialize(name, version_constraints, vendor_index, cwd, opts)
  @name = name
  @version_requirement = Gem::Requirement.new(Array(version_constraints))
  @dep = Gem::Dependency.new(name, @version_requirement, :runtime)
  @vendor_index = vendor_index
  @opts = opts
  @cwd = cwd
end

Instance Attribute Details

#cwdObject (readonly)

rubocop:disable Metrics/ClassLength



11
12
13
# File 'lib/inspec/dependencies/requirement.rb', line 11

def cwd
  @cwd
end

#depObject (readonly)

rubocop:disable Metrics/ClassLength



11
12
13
# File 'lib/inspec/dependencies/requirement.rb', line 11

def dep
  @dep
end

#dependenciesObject



124
125
126
127
128
# File 'lib/inspec/dependencies/requirement.rb', line 124

def dependencies
  @dependencies ||= profile..dependencies.map do |r|
    Inspec::Requirement.(r, @vendor_index, cwd: @cwd)
  end
end

#nameObject (readonly)

rubocop:disable Metrics/ClassLength



11
12
13
# File 'lib/inspec/dependencies/requirement.rb', line 11

def name
  @name
end

#optsObject (readonly)

rubocop:disable Metrics/ClassLength



11
12
13
# File 'lib/inspec/dependencies/requirement.rb', line 11

def opts
  @opts
end

Class Method Details

.from_lock_entry(entry, cwd, vendor_index) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/inspec/dependencies/requirement.rb', line 21

def self.from_lock_entry(entry, cwd, vendor_index)
  req = new(entry['name'],
            entry['version_constraints'],
            vendor_index,
            cwd, { url: entry['resolved_source'] })

  locked_deps = []
  Array(entry['dependencies']).each do |dep_entry|
    locked_deps << Inspec::Requirement.from_lock_entry(dep_entry, cwd, vendor_index)
  end

  req.lock_deps(locked_deps)
  req
end

.from_metadata(dep, vendor_index, opts) ⇒ Object



14
15
16
17
18
19
# File 'lib/inspec/dependencies/requirement.rb', line 14

def self.(dep, vendor_index, opts)
  fail 'Cannot load empty dependency.' if dep.nil? || dep.empty?
  name = dep[:name] || fail('You must provide a name for all dependencies')
  version = dep[:version]
  new(name, version, vendor_index, opts[:cwd], opts.merge(dep))
end

Instance Method Details

#content_hashObject



84
85
86
87
88
89
90
# File 'lib/inspec/dependencies/requirement.rb', line 84

def content_hash
  @content_hash ||= begin
                      archive_path = @vendor_index.archive_entry_for(@name, source_url)
                      fail "No vendored archive path for #{self}, cannot take content hash" if archive_path.nil?
                      Digest::SHA256.hexdigest File.read(archive_path)
                    end
end

#fetcherObject



108
109
110
111
112
# File 'lib/inspec/dependencies/requirement.rb', line 108

def fetcher
  @fetcher ||= Inspec::Fetcher.resolve(source_url)
  fail "No fetcher for #{name} (options: #{opts})" if @fetcher.nil?
  @fetcher
end

#is_vendored?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/inspec/dependencies/requirement.rb', line 80

def is_vendored?
  @vendor_index.exists?(@name, source_url)
end

#local_pathObject



100
101
102
103
104
105
106
# File 'lib/inspec/dependencies/requirement.rb', line 100

def local_path
  @local_path ||= if fetcher.class == Fetchers::Local
                    File.expand_path(fetcher.target, @cwd)
                  else
                    @vendor_index.prefered_entry_for(@name, source_url)
                  end
end

#lock_deps(dep_array) ⇒ Object



76
77
78
# File 'lib/inspec/dependencies/requirement.rb', line 76

def lock_deps(dep_array)
  @dependencies = dep_array
end

#pathObject



134
135
136
# File 'lib/inspec/dependencies/requirement.rb', line 134

def path
  @path ||= pull
end

#profileObject



138
139
140
141
# File 'lib/inspec/dependencies/requirement.rb', line 138

def profile
  return nil if path.nil?
  @profile ||= Inspec::Profile.for_target(path, {})
end

#pullObject



114
115
116
117
118
119
120
121
122
# File 'lib/inspec/dependencies/requirement.rb', line 114

def pull
  # TODO(ssd): Dispatch on the class here is gross.  Seems like
  # Fetcher is missing an API we want.
  if fetcher.class == Fetchers::Local || @vendor_index.exists?(@name, source_url)
    local_path
  else
    @vendor_index.add(@name, source_url, fetcher.archive_path)
  end
end

#required_versionObject



45
46
47
# File 'lib/inspec/dependencies/requirement.rb', line 45

def required_version
  @version_requirement
end

#source_satisfies_spec?Boolean

Returns:

  • (Boolean)


53
54
55
56
57
# File 'lib/inspec/dependencies/requirement.rb', line 53

def source_satisfies_spec?
  name = profile..params[:name]
  version = profile..params[:version]
  @dep.match?(name, version)
end

#source_urlObject



92
93
94
95
96
97
98
# File 'lib/inspec/dependencies/requirement.rb', line 92

def source_url
  if opts[:path]
    "file://#{File.expand_path(opts[:path], @cwd)}"
  elsif opts[:url]
    opts[:url]
  end
end

#source_versionObject



49
50
51
# File 'lib/inspec/dependencies/requirement.rb', line 49

def source_version
  profile..params[:version]
end

#to_hashObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/inspec/dependencies/requirement.rb', line 59

def to_hash
  h = {
    'name' => name,
    'resolved_source' => source_url,
    'version_constraints' => @version_requirement.to_s,
  }

  if !dependencies.empty?
    h['dependencies'] = dependencies.map(&:to_hash)
  end

  if is_vendored?
    h['content_hash'] = content_hash
  end
  h
end

#to_sObject



130
131
132
# File 'lib/inspec/dependencies/requirement.rb', line 130

def to_s
  "#{dep} (#{source_url})"
end