Fix recursive deps for path-based deps

Signed-off-by: Steven Danna <steve@chef.io>
This commit is contained in:
Steven Danna 2016-08-17 14:25:07 +01:00 committed by Christoph Hartmann
parent 306688fb97
commit 34ae3122e9
11 changed files with 141 additions and 60 deletions

View file

@ -10,8 +10,11 @@ module Fetchers
attr_reader :files attr_reader :files
def self.resolve(target) def self.resolve(target)
return nil unless File.exist?(target) if !File.exist?(target)
new(target) nil
else
new(target)
end
end end
def initialize(target) def initialize(target)

View file

@ -6,16 +6,17 @@ require 'logger'
require 'fileutils' require 'fileutils'
require 'molinillo' require 'molinillo'
require 'inspec/errors' require 'inspec/errors'
require 'inspec/requirement'
module Inspec module Inspec
class Resolver class Resolver
def self.resolve(requirements, vendor_index, cwd, opts = {}) def self.resolve(requirements, vendor_index, cwd, opts = {})
reqs = requirements.map do |req| reqs = requirements.map do |req|
Requirement.from_metadata(req, cwd: cwd) || req = Inspec::Requirement.from_metadata(req, cwd: cwd)
fail("Cannot initialize dependency: #{req}") req || fail("Cannot initialize dependency: #{req}")
end end
new(vendor_index, opts).resolve(reqs) new(vendor_index, opts.merge(cwd: cwd)).resolve(reqs)
end end
def initialize(vendor_index, opts = {}) def initialize(vendor_index, opts = {})
@ -23,6 +24,7 @@ module Inspec
@debug_mode = false # TODO: hardcoded for now, grab from options @debug_mode = false # TODO: hardcoded for now, grab from options
@vendor_index = vendor_index @vendor_index = vendor_index
@cwd = opts[:cwd] || './'
@resolver = Molinillo::Resolver.new(self, self) @resolver = Molinillo::Resolver.new(self, self)
@search_cache = {} @search_cache = {}
end end
@ -87,7 +89,9 @@ module Inspec
# @return [Array<Object>] the dependencies that are required by the given # @return [Array<Object>] the dependencies that are required by the given
# `specification`. # `specification`.
def dependencies_for(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 end
# Determines whether the given `requirement` is satisfied by the given # Determines whether the given `requirement` is satisfied by the given
@ -208,60 +212,6 @@ module Inspec
end end
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 class SupermarketDependency
def initialize(url, requirement) def initialize(url, requirement)
@url = url @url = url

44
lib/inspec/requirement.rb Normal file
View 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

View file

@ -0,0 +1,4 @@
# encoding: utf-8
include_controls 'profile_a'
include_controls 'profile_b'

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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