require 'pathname' require_relative 'slug/bucket' require_relative 'repo' require_relative 'shellable' module Hillary class Slug include Shellable attr_reader :branch, :version SlugArchiveError = Class.new(StandardError) class << self def build(path = File.expand_path('.'), version = Repo::Version.create!, options = {}) return unless version.sluggable? new(path, version, options).tap{|slug| slug.build} end end def initialize(path, version, options = {}) @path = path @version = version @logger = options[:logger] || Logger.new($stdout) @bucket = options[:bucket] || Bucket.new logger.formatter = proc{|_, _, _, msg| msg + "\n"} end def build if version.master? copy_slug else create_slug upload_slug end end def name "#{project_name}_slug_#{version.name}" end def canonical_name "#{project_name}_slug_#{version.sha}" end private attr_reader :logger, :bucket, :path def copy_slug logger.info("Copying #{bucket.name}:/#{canonical_storage_slug_file} to #{bucket.name}:/#{storage_slug_file}") bucket.copy(canonical_storage_slug_file, storage_slug_file) end def create_slug Dir.chdir(project_parent_directory) do logger.info("Creating slug #{canonical_slug_file}") shell("tar --exclude \".git\" --exclude \"vendor/bundle\" -zcvf #{canonical_slug_file} #{project_name}") end end def upload_slug logger.info("Uploading #{canonical_slug_file} to #{bucket.name}:/#{canonical_storage_slug_file}") bucket.write(canonical_storage_slug_file, project_parent_directory.join(canonical_slug_file)) end def slug_file "#{name}.tar.gz" end def storage_slug_file if version.master? if version.production? "production/#{slug_file}" else "rc/#{slug_file}" end elsif version.dev? "dev/#{slug_file}" end end def canonical_slug_file "#{canonical_name}.tar.gz" end def canonical_storage_slug_file "dev/#{canonical_slug_file}" end def project_directory Pathname.new(path).expand_path end def project_parent_directory project_directory.join('..').expand_path end def project_name project_directory.basename.to_s end end end