Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #9607: git-2.0.rb

File git-2.0.rb, 5.5 kB (added by garrydolley, 1 year ago)
Line 
1 require 'capistrano/recipes/deploy/scm/base'
2
3 module Capistrano
4   module Deploy
5     module SCM
6
7       # An SCM module for using Git as your source control tool with Capistrano
8       # 2.0.  If you are using Capistrano 1.x, use this plugin instead:
9       #
10       #   http://scie.nti.st/2007/3/16/capistrano-with-git-shared-repository
11       #
12       # Assumes you are using a shared Git repository.
13       #
14       # Parts of this plugin borrowed from Scott Chacon's version, which I
15       # found on the Capistrano mailing list but failed to be able to get
16       # working.
17       #
18       # FEATURES:
19       #
20       #   * Very simple, only requiring 2 lines in your deploy.rb.
21       #   * Can deploy different branches, tags, or any SHA1 easily.
22       #   * Supports prompting for password / passphrase upon checkout.
23       #     (I am amazed at how some plugins don't do this)
24       #   * Supports :scm_command, :scm_password, :scm_passphrase Capistrano
25       #     directives.
26       #
27       # REQUIREMENTS
28       # ------------
29       #
30       # Git is required to be installed on your remote machine(s), because a
31       # clone and checkout is done to get the code up there.  This is the way
32       # I prefer to deploy; there is no alternative to this, so :deploy_via
33       # is ignored.
34       #
35       # INSTALLATION
36       # ------------
37       #
38       # Place this file in:
39       #
40       #   $GEMPATH/capistrano-2.x.x/lib/capistrano/recipes/deploy/scm/
41       #
42       # CONFIGURATION
43       # -------------
44       #
45       # Use this plugin by adding the following line in your config/deploy.rb:
46       #
47       #   set :scm, :git
48       #
49       # Set <tt>:repository</tt> to the path of your Git repo:
50       #
51       #   set :repository, "someuser@somehost:/home/myproject"
52       #
53       # The above two options are required to be set, the ones below are
54       # optional.
55       #
56       # You may set <tt>:branch</tt>, which is the reference to the branch, tag,
57       # or any SHA1 you are deploying, for example:
58       #
59       #   set :branch, "origin/master"
60       #
61       # Otherwise, HEAD is assumed.  I strongly suggest you set this.  HEAD is
62       # not always the best assumption.
63       #
64       # The <tt>:git</tt> configuration variable, which (if specified) will be
65       # used as the full path to the git executable on the *remote* machine:
66       #
67       #   set :git, "/opt/local/bin/git"
68       #
69       # To set the full path to Git on your *local* machine, use the standard
70       # <tt>:scm_command</tt> variable:
71       #
72       #   set :scm_command, "/home/garry/bin/git"
73       #
74       # Set <tt>:scm_password</tt> to the password needed to clone your repo
75       # if you don't have password-less (public key) entry:
76       #
77       #   set :scm_password, "my_secret'
78       #
79       # Otherwise, you will be prompted for a password.
80       #
81       # <tt>:scm_passphrase</tt> is also supported.
82
83       class Git < Base
84         # Sets the default command name for this SCM on your *local* machine.
85         # Users may override this by setting the :scm_command variable.
86         default_command "git"
87
88         # When referencing "head", use the branch we want to deploy or, by
89         # default, Git's reference of HEAD (the latest changeset in the default
90         # branch, usually called "master").
91         def head
92           configuration[:branch] || 'HEAD'
93         end
94
95         # Performs a clone on the remote machine, then checkout on the branch
96         # you want to deploy.
97         def checkout(revision, destination)
98           git      = (configuration[:git] ? configuration[:git] : "git")
99
100           branch   = head
101
102           fail "No branch specified, use for example 'set :branch, \"origin/master\"' in your deploy.rb" unless branch
103
104           execute  = "#{git} clone #{configuration.repository} #{destination} && "
105           execute += "cd #{destination} && #{git} checkout -b deploy #{branch} "
106
107           execute
108         end
109
110         # Returns a string of diffs between two revisions
111         def diff(from, to=nil)
112           from << "..#{to}" if to
113           scm :diff, from
114         end
115
116         # Returns a log of changes between the two revisions (inclusive).
117         def log(from, to=nil)
118           scm :log, "#{from}..#{to}"
119         end
120
121         # Getting the actual commit id, in case we were passed a tag
122         # or partial sha or something - it will return the sha if you pass a sha, too
123         def query_revision(revision)
124           yield(scm('rev-parse', revision)).chomp
125         end
126
127         def command
128           cmd = configuration[:scm_command] || default_command
129         end
130
131         # Determines what the response should be for a particular bit of text
132         # from the SCM. Password prompts, connection requests, passphrases,
133         # etc. are handled here.
134         def handle_data(state, stream, text)
135                 logger.info "[#{stream}] #{text}"
136           case text
137           when /\bpassword.*:/i
138             # git is prompting for a password
139             unless pass = configuration[:scm_password]
140               pass = Capistrano::CLI.password_prompt
141             end
142             "#{pass}\n"
143           when %r{\(yes/no\)}
144             # git is asking whether or not to connect
145             "yes\n"
146           when /passphrase/i
147             # git is asking for the passphrase for the user's key
148             unless pass = configuration[:scm_passphrase]
149               pass = Capistrano::CLI.password_prompt
150             end
151             "#{pass}\n"
152           when /accept \(t\)emporarily/
153             # git is asking whether to accept the certificate
154             "t\n"
155           end
156         end
157       end
158     end
159   end
160 end