Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: b4e8bfb88f
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 134 lines (111 sloc) 3.761 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
require 'shell'

module Garlic
  class Target
    attr_reader :garlic, :path, :name, :rails_repo_name, :tree_ish

    def initialize(garlic, options = {})
      @garlic = garlic
      @tree_ish = Repo.tree_ish(options) || 'origin/master'
      @rails_repo_name = options[:rails] || 'rails'
      @path = options[:path] or raise ArgumentError, "Target requires a :path"
      @path = File.expand_path(@path)
      @name = options[:name] || File.basename(@path)
      @prepare = options[:prepare]
      @run = options[:run]
    end
    
    def prepare
      puts "\nPreparing target #{name} (#{tree_ish})"
      install_rails
      runner.run(&@prepare) if @prepare
    end
    
    def run
      runner.run(&@run) if @run
    end
    
    def rails_sha
      read_sha('vendor/rails')
    end
    
    def shell
      unless @shell
        @shell = Shell.new
        @shell.verbose = false
        @shell.cd path
      end
      @shell
    end
    
  private
    def runner
      @runner ||= Target::Runner.new(self)
    end
    
    def read_sha(install_path)
      File.read(File.join(path, install_path, '.git_sha')) rescue nil
    end
    
    def write_sha(install_path, sha)
      File.open(File.join(path, install_path, '.git_sha'), 'w+') {|f| f << sha}
    end

    def install_rails
      rails_repo = garlic.repo(rails_repo_name)
      rails_repo.checkout(tree_ish)
      if File.exists?(path)
        puts "Rails app for #{name} exists"
      else
        puts "Creating rails app for #{name}..."
        `ruby #{rails_repo.path}/railties/bin/rails #{path}`
      end
      install_dependency(rails_repo, 'vendor/rails') { `rake rails:update` }
    end

    def install_dependency(repo, install_path = ".", options = {}, &block)
      repo = garlic.repo(repo) unless repo.is_a?(Repo)
      tree_ish = Repo.tree_ish(options)
      
      if options[:clone]
        if Repo.path?(install_path)
          puts "#{install_path} exists, and is a repo"
          cd(install_path) { `git fetch origin` }
        else
          puts "cloning #{repo.name} to #{install_path}"
          repo.clone_to(File.join(path, install_path))
        end
        cd(install_path) { `git checkout #{tree_ish || repo.head_sha}` }
      
      else
        if read_sha(install_path) == repo.head_sha
          puts "#{install_path} is up to date"
        else
          puts "#{install_path} needs update, exporting archive from #{repo.name}..."
          if tree_ish
            puts "Checking out #{tree_ish} of #{repo.name}"
            old_tree_ish = repo.head_sha
            repo.checkout(tree_ish) if tree_ish
          end
          
          repo.export_to(File.join(path, install_path))
          cd(path) { garlic.instance_eval(&block) } if block_given?
          write_sha(install_path, repo.head_sha)
          
          if tree_ish
            puts "Checking #{repo.name} back to where it was (#{old_tree_ish})"
            repo.checkout(old_tree_ish)
          end
        end
      end
    end
    
    
    class Runner
      attr_reader :target

      def initialize(target)
        @target = target
      end
      
      def run(&block)
        cd target.path do
          instance_eval(&block)
        end
      end
      
      def method_missing(method, *args, &block)
        target.garlic.send(method, *args, &block)
      end

      def respond_to?(method)
        super(method) || target.garlic.respond_to?(method)
      end

      def plugin(plugin, options = {}, &block)
        target.send(:install_dependency, plugin, "vendor/plugins/#{options[:as] || plugin}", options, &block)
      end

      def dependency(repo, dest, options = {}, &block)
        target.send(:install_dependency, repo, dest, options, &block)
      end
    end
  end
end
Something went wrong with that request. Please try again.