mirror of
https://github.com/inspec/inspec
synced 2024-11-23 05:03:07 +00:00
Fix recursive deps for path-based deps
Signed-off-by: Steven Danna <steve@chef.io>
This commit is contained in:
parent
306688fb97
commit
34ae3122e9
11 changed files with 141 additions and 60 deletions
|
@ -10,8 +10,11 @@ module Fetchers
|
|||
attr_reader :files
|
||||
|
||||
def self.resolve(target)
|
||||
return nil unless File.exist?(target)
|
||||
new(target)
|
||||
if !File.exist?(target)
|
||||
nil
|
||||
else
|
||||
new(target)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(target)
|
||||
|
|
|
@ -6,16 +6,17 @@ require 'logger'
|
|||
require 'fileutils'
|
||||
require 'molinillo'
|
||||
require 'inspec/errors'
|
||||
require 'inspec/requirement'
|
||||
|
||||
module Inspec
|
||||
class Resolver
|
||||
def self.resolve(requirements, vendor_index, cwd, opts = {})
|
||||
reqs = requirements.map do |req|
|
||||
Requirement.from_metadata(req, cwd: cwd) ||
|
||||
fail("Cannot initialize dependency: #{req}")
|
||||
req = Inspec::Requirement.from_metadata(req, cwd: cwd)
|
||||
req || fail("Cannot initialize dependency: #{req}")
|
||||
end
|
||||
|
||||
new(vendor_index, opts).resolve(reqs)
|
||||
new(vendor_index, opts.merge(cwd: cwd)).resolve(reqs)
|
||||
end
|
||||
|
||||
def initialize(vendor_index, opts = {})
|
||||
|
@ -23,6 +24,7 @@ module Inspec
|
|||
@debug_mode = false # TODO: hardcoded for now, grab from options
|
||||
|
||||
@vendor_index = vendor_index
|
||||
@cwd = opts[:cwd] || './'
|
||||
@resolver = Molinillo::Resolver.new(self, self)
|
||||
@search_cache = {}
|
||||
end
|
||||
|
@ -87,7 +89,9 @@ module Inspec
|
|||
# @return [Array<Object>] the dependencies that are required by the given
|
||||
# `specification`.
|
||||
def dependencies_for(specification)
|
||||
specification.profile.metadata.dependencies
|
||||
specification.profile.metadata.dependencies.map do |r|
|
||||
Inspec::Requirement.from_metadata(r, cwd: @cwd)
|
||||
end
|
||||
end
|
||||
|
||||
# Determines whether the given `requirement` is satisfied by the given
|
||||
|
@ -208,60 +212,6 @@ module Inspec
|
|||
end
|
||||
end
|
||||
|
||||
class Requirement
|
||||
attr_reader :name, :dep, :cwd, :opts
|
||||
def initialize(name, dep, cwd, opts)
|
||||
@name = name
|
||||
@dep = Gem::Dependency.new(name, Gem::Requirement.new(Array(dep)), :runtime)
|
||||
@opts = opts
|
||||
@cwd = cwd
|
||||
end
|
||||
|
||||
def matches_spec?(spec)
|
||||
params = spec.profile.metadata.params
|
||||
@dep.match?(params[:name], params[:version])
|
||||
end
|
||||
|
||||
def pull
|
||||
case
|
||||
when @opts[:path] then pull_path(@opts[:path])
|
||||
else
|
||||
# TODO: should default to supermarket
|
||||
fail 'You must specify the source of the dependency (for now...)'
|
||||
end
|
||||
end
|
||||
|
||||
def path
|
||||
@path || pull
|
||||
end
|
||||
|
||||
def profile
|
||||
return nil if path.nil?
|
||||
@profile ||= Inspec::Profile.for_target(path, {})
|
||||
end
|
||||
|
||||
def self.from_metadata(dep, 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, opts[:cwd], dep)
|
||||
end
|
||||
|
||||
def to_s
|
||||
@dep.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pull_path(path)
|
||||
abspath = File.absolute_path(path, @cwd)
|
||||
fail "Dependency path doesn't exist: #{path}" unless File.exist?(abspath)
|
||||
fail "Dependency path isn't a folder: #{path}" unless File.directory?(abspath)
|
||||
@path = abspath
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class SupermarketDependency
|
||||
def initialize(url, requirement)
|
||||
@url = url
|
||||
|
|
44
lib/inspec/requirement.rb
Normal file
44
lib/inspec/requirement.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
# encoding: utf-8
|
||||
module Inspec
|
||||
class Requirement
|
||||
attr_reader :name, :dep, :cwd, :opts
|
||||
def initialize(name, version_constraints, cwd, opts)
|
||||
@name = name
|
||||
@dep = Gem::Dependency.new(name,
|
||||
Gem::Requirement.new(Array(version_constraints)),
|
||||
:runtime)
|
||||
@opts = opts
|
||||
@cwd = cwd
|
||||
end
|
||||
|
||||
def matches_spec?(spec)
|
||||
params = spec.profile.metadata.params
|
||||
@dep.match?(params[:name], params[:version])
|
||||
end
|
||||
|
||||
def pull
|
||||
case
|
||||
when @opts[:path]
|
||||
File.expand_path(@opts[:path], @cwd)
|
||||
else
|
||||
fail 'You must specify the source of the dependency (for now...)'
|
||||
end
|
||||
end
|
||||
|
||||
def path
|
||||
@path ||= pull
|
||||
end
|
||||
|
||||
def profile
|
||||
return nil if path.nil?
|
||||
@profile ||= Inspec::Profile.for_target(path, {})
|
||||
end
|
||||
|
||||
def self.from_metadata(dep, 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, opts[:cwd], opts.merge(dep))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# encoding: utf-8
|
||||
|
||||
include_controls 'profile_a'
|
||||
include_controls 'profile_b'
|
|
@ -0,0 +1,12 @@
|
|||
name: inheritance
|
||||
title: InSpec example inheritance
|
||||
maintainer: Chef Software, Inc.
|
||||
copyright: Chef Software, Inc.
|
||||
copyright_email: support@chef.io
|
||||
license: Apache 2 license
|
||||
version: 1.0.0
|
||||
depends:
|
||||
- name: profile_a
|
||||
path: ../profile_a
|
||||
- name: profile_b
|
||||
path: ../profile_b
|
|
@ -0,0 +1,21 @@
|
|||
# encoding: utf-8
|
||||
# copyright: 2015, The Authors
|
||||
# license: All rights reserved
|
||||
|
||||
title 'sample section'
|
||||
include_controls 'profile_c'
|
||||
|
||||
# you can also use plain tests
|
||||
describe file('/tmp') do
|
||||
it { should be_directory }
|
||||
end
|
||||
|
||||
# you add controls here
|
||||
control 'tmp-1.0' do # A unique ID for this control
|
||||
impact 0.7 # The criticality, if this control fails.
|
||||
title 'Create /tmp directory' # A human-readable title
|
||||
desc 'An optional description...'
|
||||
describe file('/tmp') do # The actual test
|
||||
it { should be_directory }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
name: profile_a
|
||||
title: InSpec Profile
|
||||
maintainer: The Authors
|
||||
copyright: The Authors
|
||||
copyright_email: you@example.com
|
||||
license: All Rights Reserved
|
||||
summary: An InSpec Compliance Profile
|
||||
version: 0.1.0
|
||||
depends:
|
||||
- name: profile_c
|
||||
path: ../profile_c
|
|
@ -0,0 +1,20 @@
|
|||
# encoding: utf-8
|
||||
# copyright: 2015, The Authors
|
||||
# license: All rights reserved
|
||||
|
||||
title 'sample section'
|
||||
|
||||
# you can also use plain tests
|
||||
describe file('/tmp') do
|
||||
it { should be_directory }
|
||||
end
|
||||
|
||||
# you add controls here
|
||||
control 'tmp-1.0' do # A unique ID for this control
|
||||
impact 0.7 # The criticality, if this control fails.
|
||||
title 'Create /tmp directory' # A human-readable title
|
||||
desc 'An optional description...'
|
||||
describe file('/tmp') do # The actual test
|
||||
it { should be_directory }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
name: profile_b
|
||||
title: InSpec Profile
|
||||
maintainer: The Authors
|
||||
copyright: The Authors
|
||||
copyright_email: you@example.com
|
||||
license: All Rights Reserved
|
||||
summary: An InSpec Compliance Profile
|
||||
version: 0.1.0
|
|
@ -0,0 +1,8 @@
|
|||
name: profile_c
|
||||
title: InSpec Profile
|
||||
maintainer: The Authors
|
||||
copyright: The Authors
|
||||
copyright_email: you@example.com
|
||||
license: All Rights Reserved
|
||||
summary: An InSpec Compliance Profile
|
||||
version: 0.1.0
|
Loading…
Reference in a new issue