require_relative "cookbooks/version" module Vagrant module Cookbooks class Plugin < Vagrant.plugin("2") name "vagrant-cookbooks" description "Clone down Chef cookbooks" action_hook "vagrant_cookbooks" do |hook| # If LibrarianChef is configured cookbooks need to be cloned before. if defined?(VagrantPlugins::LibrarianChef) hook.before VagrantPlugins::LibrarianChef::Action::Install, Action else hook.before Vagrant::Action::Builtin::Provision, Action end end config "cookbooks" do Config end end class Config < Vagrant.plugin(2, :config) attr_accessor :git attr_accessor :path def initialize @git = UNSET_VALUE @path = UNSET_VALUE end def finalize! @git = "git@github.com:Shopify/cookbooks" if @git == UNSET_VALUE @path = ".vagrant/cookbooks" if @path == UNSET_VALUE end end class Action attr_reader :env, :app def initialize(app, env) @app = app @env = env end def call(env) if cookbooks? update_cookbooks else clone_cookbooks end end private def on_cookbooks_branch? cookbooks_branch != "master" end def cookbooks_branch system!("cd #{escape(cookbooks_path)} && git rev-parse --abbrev-ref HEAD") end def cookbooks? Dir.exists?(cookbooks_path) end def update_cookbooks if on_cookbooks_branch? env[:ui].warn "Cookbooks on branch `#{cookbooks_branch}`, skipping update" else env[:ui].info "Updating cookbooks" system!("cd #{escape(cookbooks_path)}; git fetch origin 2>&1; git rebase origin/master 2>&1") end end def clone_cookbooks env[:ui].info "Cloning cookbooks" system!("git clone git@github.com:Shopify/cookbooks #{escape(cookbooks_path)} 2>&1") end def escape(path) Shellwords.shellescape(path) end def system!(command, timeout = 60 * 5) result = nil Timeout.timeout(timeout) do result = `#{command}`.chomp end unless $?.success? env[:ui].error "Failed to execute: #{command}: #{result}" exit 1 end result rescue Timeout::Error env[:ui].error "Timed out executing: #{command}: #{result}" exit 1 end def cookbooks_path "#{cwd}/#{env[:machine].config.cookbooks.path}" end def cwd pwd = ENV["VAGRANT_CWD"] || Dir.pwd cwd = Pathname.new(pwd) raise "#{pwd} is not a directory" unless cwd.directory? cwd end end end end