require 'minimart/inventory_requirement/git_requirement' module Minimart module InventoryRequirement # This class is used to parse any Git requirements specified in the inventory # and build Minimart::Inventory::GitRequirements from them. class GitRequirementsBuilder # @return [String] the name of the cookbook defined by this requirement. attr_reader :name # @return [String] the location to fetch this cookbook from. attr_reader :location # @return [Array] a listing of branches to checkout when fetching this cookbook. attr_reader :branches # @return [Array] a listing of tags to checkout when fetching this cookbook. attr_reader :tags # @return [Array] a listing of refs to checkout when fetching this cookbook. attr_reader :refs # @param [String] name The name of the cookbook defined by this requirement. # @param [Hash] reqs # * 'git' [Hash] The git specific requirements for this cookbook # * 'branches' [Array] A listing of branches to checkout when fetching this cookbook. # * 'branch' [String] A single branch to checkout when fetching this cookbook. # * 'tags' [Array] A listing of tags to checkout when fetching this cookbook. # * 'tag' [String] A single tag to checkout when fetching this cookbook. # * 'refs' [Array] A listing of ref to checkout when fetching this cookbook. # * 'ref' [String] A single ref to checkout when fetching this cookbook. def initialize(name, reqs) @name = name git_reqs = reqs.fetch('git', {}) @location = git_reqs['location'] @branches = raw_location_type_requirement(%w[branches branch], git_reqs) @tags = raw_location_type_requirement(%w[tags tag], git_reqs) @refs = raw_location_type_requirement(%w[refs ref], git_reqs) validate_requirements(git_reqs) end # Build the git requirements. # @return [Array] def build from_branches + from_tags + from_refs end private def from_branches branches.map { |b| build_requirement(:branch, b) } end def from_tags tags.map { |t| build_requirement(:tag, t) } end def from_refs refs.map { |r| build_requirement(:ref, r) } end def build_requirement(type, value) InventoryRequirement::GitRequirement.new(name, {type => value}.merge(location: location)) end def raw_location_type_requirement(location_types, requirements) location_types.inject([]) do |memo, type| if requirements[type] req = requirements[type] req = [req] if req.is_a?(String) memo.concat(req) end memo end end def validate_requirements(reqs) return if reqs.nil? || reqs.empty? validate_location validate_commitish end def validate_location return unless location.nil? || location.empty? raise Minimart::Error::InvalidInventoryError, "'#{name}' specifies Git requirements, but does not have a location." end def validate_commitish return unless branches.empty? && tags.empty? && refs.empty? raise Minimart::Error::InvalidInventoryError, "'#{name}' specified Git requirements, but does not provide a branch|tag|ref" end end end end