Module: CapGitTools::TaskHelpers

Defined in:
lib/cap_git_tools/task_helpers.rb

Instance Method Summary collapse

Instance Method Details

#calculate_new_tagObject



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/cap_git_tools/task_helpers.rb', line 161

def calculate_new_tag
  # if capistrano :tag is already set, just use it        
  if exists?("tag")
    return fetch("tag")
  end
  
  # otherwise calculate, based on template
        
  tag_suffix = fetch("tag_template", "%{datetime}")
    
  tag_suffix.gsub!(/\%\{([^}]+)\}/) do 
    case $1
    when 'date'
      Time.now.localtime.strftime('%Y-%m-%d')
    when 'datetime'
      Time.now.localtime.strftime('%Y-%m-%d-%H%M')
    when 'what'
      (@__git_what = Capistrano::CLI.ui.ask("What does this release introduce? (this will be normalized and used in the tag for this release) ").gsub(/[ '"]+/, "_"))
    when 'who'
      `whoami`.chomp
    end
  end
    
  return "#{tag_prefix}-#{tag_suffix}"    
end

#current_branchObject

The branch that is currently checkout out in the local repository



76
77
78
79
80
# File 'lib/cap_git_tools/task_helpers.rb', line 76

def current_branch
  b = `git symbolic-ref -q HEAD`.sub(%r{^refs/heads/}, '').chomp
  b.empty? ? "HEAD" : b
  return b
end

#ensure_git_fetchObject

execute a ‘git fetch’, but mark in a private variable that we have, so we only do it once per cap execution.



20
21
22
23
24
25
# File 'lib/cap_git_tools/task_helpers.rb', line 20

def ensure_git_fetch
  unless @__git_fetched      
    local_sh "git fetch #{upstream_remote}"
    @__git_fetched = true
  end
end

#fetch_last_tag(pattern_prefix = self.tag_prefix) ⇒ Object

find the last (chronological) tag with given prefix. prefix can include shell-style wildcards like ‘*’. Defaults to last tag with current default tag_prefix.

Note: Will only work on git ‘full’ annotated tags (those signed or with -m message or -a) because git only stores dates for annotated tags. others will end up sorted lexicographically BEFORE any annotated tags.



121
122
123
124
125
126
127
128
129
130
# File 'lib/cap_git_tools/task_helpers.rb', line 121

def fetch_last_tag(pattern_prefix = self.tag_prefix)
  # make sure we've fetched to get latest from upstream. 
  ensure_git_fetch
  
  # crazy git command, yeah. Sort by tagged date descending, one line only, 
  # output refname:short, look for tags matching our pattern.  
  last_tag = `git for-each-ref --count=1 --sort='-taggerdate' --format='%(refname:short)' 'refs/tags/#{pattern_prefix}-*' 2>/dev/null`.chomp
  return nil if last_tag == ''
  return last_tag
end

#from_prefixObject



91
92
93
# File 'lib/cap_git_tools/task_helpers.rb', line 91

def from_prefix
  fetch("from_prefix", "staging")
end

#from_tagObject

mostly used by git:retag, calculate the tag we’ll be retagging FROM.

can set cap :from_tag. Or else find last tag matching from_prefix, which by default is “staging-*”



100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/cap_git_tools/task_helpers.rb', line 100

def from_tag
  t = nil
  if exists?("from_tag")
    t = fetch("from_tag")
  else
    t = fetch_last_tag(  self.from_prefix ) 
  
    if t.nil? || t.empty?
      abort("failed: can't find existing tag matching #{self.from_prefix}-*")
    end
  end
  return t
end

#guard_confirm_tag(new_tag) ⇒ Object

will prompt to confirm new tag, if :confirm_tag is true, otherwise no-op.



189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/cap_git_tools/task_helpers.rb', line 189

def guard_confirm_tag(new_tag)    
  if exists?("confirm_tag") && [true, "true"].include?( confirm_tag )      
    prompt = "Do you really want to deploy "
    prompt += new_tag
    prompt += " to #{stage}" if exists? :stage
    prompt += "?"
            
    unless Capistrano::CLI.ui.agree(prompt) 
      abort("exiting, user cancelled.")
    end
  end
end

#local_sh(cmd) ⇒ Object

execute locally as a shell command, echo’ing to output, as well as capturing error and aborting.



29
30
31
32
33
# File 'lib/cap_git_tools/task_helpers.rb', line 29

def local_sh(cmd)
  say_formatted("executing locally: #{cmd}")
  `#{cmd}`
  abort("failed: #{cmd}") unless $? == 0
end

#local_shaObject

current SHA fingerprint of local branch mentioned in :branch



83
84
85
# File 'lib/cap_git_tools/task_helpers.rb', line 83

def local_sha
  `git log --pretty=format:%H #{working_branch} -1`.chomp
end

#say_formatted(msg, options = {}) ⇒ Object

say with an indent in spaces



13
14
15
16
# File 'lib/cap_git_tools/task_helpers.rb', line 13

def say_formatted(msg, options = {})
  options.merge!(:indent => 4)
  Capistrano::CLI.ui.say(' ' * options[:indent] + msg )
end

#show_commit_log(from_tag, to_tag) ⇒ Object

show commit lot from commit-ish to commit-ish, using appropriate UI tool.

If you have cap :github_browser_compare set and the remote is github, use ‘open` to open in browser.

else if you have ENV set, pass to ‘git` (don’t know what this is for, inherited from gitflow)

else just use an ordinary command line git log



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/cap_git_tools/task_helpers.rb', line 142

def show_commit_log(from_tag, to_tag)
  if fetch("github_browser_compare", false ) && `git config remote.#{upstream_remote}.url` =~ /[email protected]:(.*)\/(.*).git/      
    # be awesome for github, use `open` in browser
    command = "open https://github.com/#{$1}/#{$2}/compare/#{from_tag}...#{to_tag}"
  elsif ENV['git_log_command'] && ENV['git_log_command'].strip != ''
    # use custom compare command if set
    command = "git #{ENV['git_log_command']} #{from_tag}..#{to_tag}"
  else
    # standard git log command
    command = "git log #{from_tag}..#{to_tag}"      
  end
  
  say_formatted "Displaying commits from #{from_tag} to #{to_tag}\n\n"
  say_formatted command + "\n\n"
  system command
  puts "" # newline
end

#tag_prefixObject



87
88
89
# File 'lib/cap_git_tools/task_helpers.rb', line 87

def tag_prefix
  fetch(:tag_prefix, fetch(:stage, "deploy"))
end

#upstream_remoteObject

How to refer to the upstream git repo configured in cap :repository? Will usually return ‘origin’, will sometimes return another remote, will occasionally return a raw git url when it’s not configured in remotes for some reason.

When using deploy_via copy, will find the remote if the repository only has one configured. If more than one remote is configured an error will be raised unless the ‘upstream_remote_name` variable is set specifying the correct remote.

Remote determination can be overridden manually for any deployment method by setting the remote to use in the ‘upstream_remote_name` variable.



47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/cap_git_tools/task_helpers.rb', line 47

def upstream_remote
  @__upstream_remote = begin
    if exists?('upstream_remote_name')
      fetch(:upstream_remote_name)
    elsif fetch(:deploy_via) == :copy
      upstream_remote_for_copy
    else
      git_url = fetch(:repository)        
      upstream_remote_by_url git_url
    end
  end
end

#upstream_remote_by_url(git_url) ⇒ Object



202
203
204
205
206
207
208
209
210
# File 'lib/cap_git_tools/task_helpers.rb', line 202

def upstream_remote_by_url(git_url)
  remote_info = 
    `git remote -v`.
    split("\n").
    collect {|line| line.split(/[\t ]/) }.
    find {|list| list[1] == git_url }

  remote_info ? remote_info[0] : git_url
end

#upstream_remote_for_copyObject



212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/cap_git_tools/task_helpers.rb', line 212

def upstream_remote_for_copy
  remotes = `git remote`.split("\n")
  remotes.size == 1 ? remotes[0] : abort(%Q{failed: upstream_remote: multiple possible upstream remotes

You are deploying via copy, and have multiple possible upstream remotes.

Please specify the correct remote to use by setting the 
:upstream_remote_name variable.

Available remotes:
  #{remotes.join("\n      ")}
  })
end

#working_branchObject

what branch we’re going to tag and deploy – if cap ‘branch’ is set, use that one, otherwise use current branch in checkout



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/cap_git_tools/task_helpers.rb', line 63

def working_branch
  @__git_working_branch ||= begin
    if exists?("branch")
      p fetch(:branch)
      fetch(:branch)
    else
      current_branch
    end
  end
  
end