class Kitchen::Provisioner::Chef::Policyfile

@author Fletcher Nichol <fnichol@nichol.ca>
Chef cookbook resolver that uses Policyfiles to calculate dependencies.

def self.load!(logger: Kitchen.logger)

Parameters:
  • logger (Kitchen::Logger) -- a logger to use for output, defaults
def self.load!(logger: Kitchen.logger)
  # intentionally left blank
end

def chef_license(license)

Return `"--chef-license #{license}"` when `license` is not nil or empty and the empty string otherwise.
def chef_license(license)
  (license.nil? || license.empty?) ? "" : "--chef-license #{license}"
end

def cli_path

Other tags:
    Api: - private
def cli_path
  @cli_path ||= which("chef-cli") || which("chef") || no_cli_found_error
end

def compile

generate the policyfile lock.
Runs `chef install` to determine the correct cookbook set and
def compile
  if File.exist?(lockfile)
    info("Installing cookbooks for Policyfile #{policyfile} using `#{cli_path} install`")
  else
    info("Policy lock file doesn't exist, running `#{cli_path} install` for Policyfile #{policyfile}...")
  end
  run_command("#{cli_path} install #{escape_path(policyfile)} #{chef_license(license)}")
  if always_update
    info("Updating policy lock using `#{cli_path} update`")
    run_command("#{cli_path} update #{escape_path(policyfile)} #{chef_license(license)}")
  end
end

def escape_path(path)

Other tags:
    Api: - private

Returns:
  • (String) -

Parameters:
  • path (String) -- Path to escape
def escape_path(path)
  if /mswin|mingw/.match?(RbConfig::CONFIG["host_os"])
    # I know what you're thinking: "just use Shellwords.escape". That
    # method produces incorrect results on Windows with certain input
    # which would be a metacharacter in Sh but is not for one or more of
    # Windows command line parsing libraries. This covers the 99% case of
    # spaces in the path without breaking other stuff.
    if /[ \t\n\v"]/.match?(path)
      "\"#{path.gsub(/[ \t\n\v\"\\]/) { |m| "\\" + m[0] }}\""
    else
      path
    end
  else
    Shellwords.escape(path)
  end
end

def initialize(policyfile, path, license: nil, logger: Kitchen.logger, always_update: false, policy_group: nil)

Parameters:
  • logger (Kitchen::Logger) -- a logger to use for output, defaults
  • path (String) -- path in which to vendor the resulting
  • policyfile (String) -- path to a Policyfile
def initialize(policyfile, path, license: nil, logger: Kitchen.logger, always_update: false, policy_group: nil)
  @policyfile    = policyfile
  @path          = path
  @logger        = logger
  @always_update = always_update
  @policy_group  = policy_group
  @license       = license
end

def lockfile

Returns:
  • (String) -
def lockfile
  policyfile.gsub(/\.rb\Z/, ".lock.json")
end

def no_cli_found_error

Other tags:
    Api: - private
def no_cli_found_error
  @logger.fatal("The `chef` or `chef-cli` executables cannot be found in your " \
                "PATH. Ensure you have installed Chef Workstation " \
                "from https://www.chef.io/downloads/ and that your PATH " \
                "setting includes the path to the `chef` or `chef-cli` commands.")
  raise UserError, "Could not find the chef or chef-cli executables in your PATH."
end

def resolve

in the desired path.
Performs the cookbook resolution and vendors the resulting cookbooks
def resolve
  if policy_group
    info("Exporting cookbook dependencies from Policyfile #{path} with policy_group #{policy_group} using `#{cli_path} export`...")
    run_command("#{cli_path} export #{escape_path(policyfile)} #{escape_path(path)} --policy_group #{policy_group} --force #{chef_license(license)}")
  else
    info("Exporting cookbook dependencies from Policyfile #{path} using `#{cli_path} export`...")
    run_command("#{cli_path} export #{escape_path(policyfile)} #{escape_path(path)} --force #{chef_license(license)}")
  end
end