etsy-deployinator 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +368 -0
- data/Rakefile +16 -0
- data/bin/deployinator-tailer.rb +78 -0
- data/deployinator.gemspec +31 -0
- data/lib/deployinator.rb +114 -0
- data/lib/deployinator/app.rb +204 -0
- data/lib/deployinator/base.rb +58 -0
- data/lib/deployinator/config.rb +7 -0
- data/lib/deployinator/controller.rb +147 -0
- data/lib/deployinator/helpers.rb +610 -0
- data/lib/deployinator/helpers/deploy.rb +68 -0
- data/lib/deployinator/helpers/dsh.rb +42 -0
- data/lib/deployinator/helpers/git.rb +348 -0
- data/lib/deployinator/helpers/plugin.rb +50 -0
- data/lib/deployinator/helpers/stack-tail.rb +32 -0
- data/lib/deployinator/helpers/version.rb +62 -0
- data/lib/deployinator/helpers/view.rb +67 -0
- data/lib/deployinator/logging.rb +16 -0
- data/lib/deployinator/plugin.rb +7 -0
- data/lib/deployinator/stack-tail.rb +34 -0
- data/lib/deployinator/static/css/diff_style.css +283 -0
- data/lib/deployinator/static/css/highlight.css +235 -0
- data/lib/deployinator/static/css/style.css +1223 -0
- data/lib/deployinator/static/js/flot/jquery.flot.min.js +1 -0
- data/lib/deployinator/static/js/flot/jquery.flot.selection.js +299 -0
- data/lib/deployinator/static/js/jquery-1.8.3.min.js +2 -0
- data/lib/deployinator/static/js/jquery-ui-1.8.24.min.js +5 -0
- data/lib/deployinator/static/js/jquery.timed_bar.js +36 -0
- data/lib/deployinator/tasks/initialize.rake +84 -0
- data/lib/deployinator/tasks/tests.rake +22 -0
- data/lib/deployinator/templates/deploys_status.mustache +42 -0
- data/lib/deployinator/templates/generic_single_push.mustache +64 -0
- data/lib/deployinator/templates/index.mustache +12 -0
- data/lib/deployinator/templates/layout.mustache +604 -0
- data/lib/deployinator/templates/log.mustache +24 -0
- data/lib/deployinator/templates/log_table.mustache +90 -0
- data/lib/deployinator/templates/messageboxes.mustache +29 -0
- data/lib/deployinator/templates/run_logs.mustache +15 -0
- data/lib/deployinator/templates/scroll_control.mustache +8 -0
- data/lib/deployinator/templates/stream.mustache +13 -0
- data/lib/deployinator/version.rb +3 -0
- data/lib/deployinator/views/deploys_status.rb +22 -0
- data/lib/deployinator/views/index.rb +14 -0
- data/lib/deployinator/views/layout.rb +48 -0
- data/lib/deployinator/views/log.rb +12 -0
- data/lib/deployinator/views/log_table.rb +35 -0
- data/lib/deployinator/views/run_logs.rb +32 -0
- data/templates/app.rb.erb +7 -0
- data/templates/config.ru.erb +10 -0
- data/templates/helper.rb.erb +15 -0
- data/templates/stack.rb.erb +17 -0
- data/templates/template.mustache +1 -0
- data/templates/view.rb.erb +7 -0
- data/test/unit/helpers_dsh_test.rb +40 -0
- data/test/unit/helpers_test.rb +77 -0
- data/test/unit/version_test.rb +104 -0
- metadata +245 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
module Deployinator
|
2
|
+
module Helpers
|
3
|
+
# Public: helper methods to interact with deploy processes
|
4
|
+
module DeployHelpers
|
5
|
+
|
6
|
+
# Public: get a list of all currently running deploys
|
7
|
+
#
|
8
|
+
# Returns an array of hashes of the form {:stack => stackname, :stage
|
9
|
+
# => stagename}
|
10
|
+
def get_list_of_deploys
|
11
|
+
ret = []
|
12
|
+
raw = `pgrep -d, -l -f Deployinator`.strip.split(",")
|
13
|
+
raw.each do |deploy|
|
14
|
+
deploy = deploy.strip
|
15
|
+
if deploy =~ /Deployinator - deploy (\S+?):(\S+?)$/
|
16
|
+
ret << {:stack => $1, :stage => $2}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
ret
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# Public: stop a running deploy indentified by stack and stage
|
24
|
+
#
|
25
|
+
# Parameters:
|
26
|
+
# stack - name of the stack
|
27
|
+
# stage - name of the stage
|
28
|
+
#
|
29
|
+
# Returns true if the deploy was stopped and false on error
|
30
|
+
def stop_deploy(stack, stage)
|
31
|
+
if deployname = get_deploy_process_title(stack,stage)
|
32
|
+
return system("pkill -f '#{deployname}'")
|
33
|
+
end
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
# Public: get the activity status of the deploy for a certain stack
|
38
|
+
# and stage
|
39
|
+
#
|
40
|
+
# Parameters:
|
41
|
+
# stack - name of the stack
|
42
|
+
# stage - name of the stage
|
43
|
+
#
|
44
|
+
# Returns true for a running deploy or false for a deploy that
|
45
|
+
# is not running
|
46
|
+
def is_deploy_active?(stack, stage)
|
47
|
+
if deployname = get_deploy_process_title(stack,stage)
|
48
|
+
return system("pgrep -f '#{deployname}'")
|
49
|
+
end
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
53
|
+
# Public: get the process title for the deployment process of a
|
54
|
+
# specific stage in a stack
|
55
|
+
#
|
56
|
+
# Parameters:
|
57
|
+
# stack - name of the stack
|
58
|
+
# stage - name of the stage
|
59
|
+
#
|
60
|
+
# Returns the title as a string or nil on error
|
61
|
+
def get_deploy_process_title(stack=nil, stage=nil)
|
62
|
+
return nil if (stack.nil? or stage.nil?)
|
63
|
+
"Deployinator - deploy #{stack}:#{stage}"
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Deployinator
|
2
|
+
module Helpers
|
3
|
+
module DshHelpers
|
4
|
+
def dsh_fanout
|
5
|
+
@dsh_fanout || 30
|
6
|
+
end
|
7
|
+
|
8
|
+
def run_dsh(groups, cmd, &block)
|
9
|
+
groups = [groups] unless groups.is_a?(Array)
|
10
|
+
dsh_groups = groups.map {|group| "-g #{group} "}.join("")
|
11
|
+
run_cmd(%Q{ssh #{Deployinator.default_user}@#{Deployinator.deploy_host} dsh #{dsh_groups} -r ssh -F #{dsh_fanout} "#{cmd}"}, &block)[:stdout]
|
12
|
+
end
|
13
|
+
|
14
|
+
# run dsh against a given host or array of hosts
|
15
|
+
def run_dsh_hosts(hosts, cmd, extra_opts='', &block)
|
16
|
+
hosts = [hosts] unless hosts.is_a?(Array)
|
17
|
+
if extra_opts.length > 0
|
18
|
+
run_cmd %Q{ssh #{Deployinator.default_user}@#{Deployinator.deploy_host} 'dsh -m #{hosts.join(',')} -r ssh -F #{dsh_fanout} #{extra_opts} -- "#{cmd}"'}, &block
|
19
|
+
else
|
20
|
+
run_cmd %Q{ssh #{Deployinator.default_user}@#{Deployinator.deploy_host} 'dsh -m #{hosts.join(',')} -r ssh -F #{dsh_fanout} -- "#{cmd}"'}, &block
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_dsh_extra(dsh_group, cmd, extra_opts, &block)
|
25
|
+
# runs dsh to a single group with extra args to dsh
|
26
|
+
run_cmd(%Q{ssh #{Deployinator.default_user}@#{Deployinator.deploy_host} dsh -g #{dsh_group} -r ssh #{extra_opts} -F #{dsh_fanout} "#{cmd}"}, &block)[:stdout]
|
27
|
+
end
|
28
|
+
|
29
|
+
def hosts_for(group)
|
30
|
+
@hosts_for ||= {}
|
31
|
+
@hosts_for[group] ||= begin
|
32
|
+
dsh_file = "/home/#{Deployinator.default_user}/.dsh/group/#{group}"
|
33
|
+
hosts = `ssh #{Deployinator.default_user}@#{Deployinator.deploy_host} cat #{dsh_file}`.chomp
|
34
|
+
if $?.nil? || $?.exitstatus != 0
|
35
|
+
raise "DSH hosts file at #{Deployinator.deploy_host}:#{dsh_file} is likely missing!"
|
36
|
+
end
|
37
|
+
hosts.split("\n").delete_if { |x| x.lstrip[0..0] == "#" }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,348 @@
|
|
1
|
+
require 'enumerator'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module Deployinator
|
5
|
+
module Helpers
|
6
|
+
# Public: module containing helper methods for interacting with git
|
7
|
+
# repositories and extracting information from them.
|
8
|
+
module GitHelpers
|
9
|
+
|
10
|
+
# Where we cache the current head rev. stack name wil be appended
|
11
|
+
@@rev_head_cache = "/tmp/rev_head_cache"
|
12
|
+
|
13
|
+
# How many seconds the head rev cache is good for
|
14
|
+
@@rev_head_cache_ttl = 15
|
15
|
+
|
16
|
+
def build_git_cmd(cmd, extra_cmd)
|
17
|
+
unless extra_cmd.nil? or extra_cmd.empty?
|
18
|
+
"#{extra_cmd} '#{cmd}'"
|
19
|
+
else
|
20
|
+
cmd
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Public: method to get the short rev of a git commit and create a
|
25
|
+
# version tag from it. The tag is then dumped into a version text file.
|
26
|
+
#
|
27
|
+
# stack - String representing the stack, which determines where the
|
28
|
+
# version file should be located
|
29
|
+
# version_dir - String (or Array of Strings) representing the
|
30
|
+
# directories to contain the version file
|
31
|
+
# extra_cmd - String representing an additional command to prepend to
|
32
|
+
# the version echo command (default: "")
|
33
|
+
# path - String containing the base path where the version file is
|
34
|
+
# located (default: nil)
|
35
|
+
# rev - String containing the rev to parse for the short SHA id
|
36
|
+
# (default: "HEAD")
|
37
|
+
#
|
38
|
+
#
|
39
|
+
# Returns STDOUT of the echo command
|
40
|
+
def git_bump_version(stack, version_dir, extra_cmd="", path=nil, rev="HEAD", tee_cmd="tee")
|
41
|
+
unless version_dir.kind_of?(Array)
|
42
|
+
version_dir = [version_dir]
|
43
|
+
end
|
44
|
+
|
45
|
+
ts = Time.now.strftime("%Y%m%d-%H%M%S-%Z")
|
46
|
+
|
47
|
+
path ||= git_checkout_path(checkout_root, stack)
|
48
|
+
|
49
|
+
cmd = "cd #{path} && git rev-parse --short=#{Deployinator.git_sha_length} #{rev}"
|
50
|
+
cmd = build_git_cmd(cmd, extra_cmd)
|
51
|
+
sha1 = run_cmd(cmd)[:stdout]
|
52
|
+
|
53
|
+
version = "#{sha1.chomp}-#{ts}"
|
54
|
+
|
55
|
+
fullpaths = ""
|
56
|
+
version_dir.each do |dir|
|
57
|
+
fullpath = File.join(dir, "version.txt")
|
58
|
+
fullpaths << fullpath + " "
|
59
|
+
end
|
60
|
+
|
61
|
+
log_and_stream "Setting #{fullpaths} to #{version}"
|
62
|
+
|
63
|
+
cmd = "cd #{path} && echo #{version} | #{tee_cmd} #{fullpaths}"
|
64
|
+
cmd = build_git_cmd(cmd, extra_cmd)
|
65
|
+
run_cmd cmd
|
66
|
+
|
67
|
+
return version
|
68
|
+
end
|
69
|
+
|
70
|
+
# Public: git helper method to get the path to checkout the git repo to
|
71
|
+
#
|
72
|
+
# checkout_root - the directory base for the repo location
|
73
|
+
# stack - String representing the stack, which determines where the
|
74
|
+
# version file should be located
|
75
|
+
#
|
76
|
+
# Returns path to checkout git repo to
|
77
|
+
def git_checkout_path(checkout_root, stack)
|
78
|
+
if (git_info_for_stack[stack.intern].has_key?(:checkout_dir))
|
79
|
+
dir = git_info_for_stack[stack.intern][:checkout_dir].to_s
|
80
|
+
else
|
81
|
+
dir = stack.to_s
|
82
|
+
end
|
83
|
+
File.join(checkout_root, dir)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Public: git helper method to bring a local repo up to date with the
|
87
|
+
# remote
|
88
|
+
#
|
89
|
+
# stack - the stack we want to update the repo for
|
90
|
+
# extra_cmd - a command that can be prepended before the actual command
|
91
|
+
# path - the path to the repo. This is also passed to the block as
|
92
|
+
# an argument if one is provided
|
93
|
+
# branch - the branch to checkout after the fetch
|
94
|
+
#
|
95
|
+
# Returns nothing
|
96
|
+
def git_freshen_clone(stack, extra_cmd="", path=nil, branch="master")
|
97
|
+
path ||= git_checkout_path(checkout_root, stack)
|
98
|
+
cmd = "cd #{path} && git fetch --quiet origin +refs/heads/#{branch}:refs/remotes/origin/#{branch} && git reset --hard origin/#{branch} 2>&1"
|
99
|
+
cmd = build_git_cmd(cmd, extra_cmd)
|
100
|
+
run_cmd cmd
|
101
|
+
yield "#{path}" if block_given?
|
102
|
+
end
|
103
|
+
|
104
|
+
# Public: wrapper function which can be used to clone a non-existing repo
|
105
|
+
# or freshen an existing one. It tests if the path exists and fetches
|
106
|
+
# remotes if that's the case. Otherwise the repo is checked out at the
|
107
|
+
# given path.
|
108
|
+
#
|
109
|
+
# Examples:
|
110
|
+
# git_freshen_or_clone("web", etsy_qa, "/var/etsy/", "master")
|
111
|
+
#
|
112
|
+
# stack - the stack to refresh or clone the repo for
|
113
|
+
# extra_cmd - cmd to prepend before the actual command
|
114
|
+
# checkout_root - the directory base for the repo location
|
115
|
+
# branch - the branch the repo should be on (currently only used
|
116
|
+
# when the repo is refreshed). (default: master)
|
117
|
+
# read_write - boolean; True means clone the repo read/write
|
118
|
+
#
|
119
|
+
# Returns stdout of the respective git command.
|
120
|
+
def git_freshen_or_clone(stack, extra_cmd, checkout_root, branch="master", read_write=false)
|
121
|
+
path = git_checkout_path(checkout_root, stack)
|
122
|
+
is_git = is_git_repo(path, extra_cmd)
|
123
|
+
if is_git == :true
|
124
|
+
log_and_stream "</br>Refreshing repo #{stack} at #{path}</br>"
|
125
|
+
git_freshen_clone(stack, extra_cmd, path, branch)
|
126
|
+
elsif is_git == :missing
|
127
|
+
log_and_stream "</br>Cloning branch #{branch} of #{stack} repo into #{path}</br>"
|
128
|
+
git_clone(stack, git_url(stack, "git", read_write), extra_cmd, checkout_root, branch)
|
129
|
+
else
|
130
|
+
log_and_stream "</br><span class=\"stderr\">The path for #{stack} at #{path} exists but is not a git repo.</span></br>"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Public: Filters a range of commits and either returns all commit shas that
|
135
|
+
# only include the filter_file, or the inverse list of shas.
|
136
|
+
#
|
137
|
+
# stack - the stack to refresh or clone the repo for
|
138
|
+
# extra_cmd - cmd to prepend before the actual command
|
139
|
+
# old_rev - the git sha representing an older rev.
|
140
|
+
# new_rev - the git sha representing a newer rev.
|
141
|
+
# path - optional parameter to overide the path to the git repo.
|
142
|
+
# filter_files - filepaths relative to the root of the git repo to use as the filter
|
143
|
+
# including - Should the returned list of filters include the filter_file commits, or all other commits
|
144
|
+
#
|
145
|
+
# Returns an array of shas
|
146
|
+
def git_filter_shas(stack, extra_cmd, old_rev, new_rev, path=nil, filter_files=[], including=false)
|
147
|
+
path ||= git_checkout_path(checkout_root, stack)
|
148
|
+
including_shas = []
|
149
|
+
excluding_shas = []
|
150
|
+
cmd = "cd #{path} && git log --no-merges --name-only --pretty=format:%H #{old_rev}..#{new_rev}"
|
151
|
+
cmd = build_git_cmd(cmd, extra_cmd)
|
152
|
+
committers = run_cmd(cmd)[:stdout]
|
153
|
+
committers.split(/\n\n/).each { |commit|
|
154
|
+
lines = commit.split(/\n/)
|
155
|
+
commit_sha = lines.shift
|
156
|
+
has_filter_file = false
|
157
|
+
filter_files.each { |filter_file|
|
158
|
+
if !has_filter_file && lines.include?(filter_file)
|
159
|
+
has_filter_file = true
|
160
|
+
end
|
161
|
+
}
|
162
|
+
if has_filter_file
|
163
|
+
including_shas.push(commit_sha)
|
164
|
+
#add to the exclude shas list as well if there are more than one file
|
165
|
+
excluding_shas.push(commit_sha) unless lines.length == 1
|
166
|
+
else
|
167
|
+
excluding_shas.push(commit_sha)
|
168
|
+
end
|
169
|
+
}
|
170
|
+
if including
|
171
|
+
return including_shas
|
172
|
+
else
|
173
|
+
return excluding_shas
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Public: Handles get and store of the head rev from a local
|
178
|
+
# file cache. Call this instead of get_git_head_rev.
|
179
|
+
#
|
180
|
+
# Paramaters:
|
181
|
+
# stack - name of the stack for the repo
|
182
|
+
# branch - name of the branch to test
|
183
|
+
#
|
184
|
+
# Returns the rev as a string
|
185
|
+
def git_head_rev(stack, branch="master")
|
186
|
+
filename = "#{@@rev_head_cache}_#{stack}"
|
187
|
+
head_rev = get_from_cache(filename, @@rev_head_cache_ttl)
|
188
|
+
|
189
|
+
unless head_rev
|
190
|
+
head_rev = get_git_head_rev(stack, branch)
|
191
|
+
File.open(filename, 'w') {|f| f.write(head_rev) }
|
192
|
+
end
|
193
|
+
|
194
|
+
return head_rev
|
195
|
+
end
|
196
|
+
|
197
|
+
# Public: get the short sha of the remote HEAD rev of a stack repo.
|
198
|
+
# Beware that a true git short rev can also be longer than git_sha_length chars and
|
199
|
+
# this way of retrieving it is no guarantee to get a unique short rev.
|
200
|
+
# But the alternative is cloning the repo and do a git rev-parse --short
|
201
|
+
#
|
202
|
+
# Parameters:
|
203
|
+
# stack - name of the stack for the repo
|
204
|
+
# branch - name of the branch to test (default: master)
|
205
|
+
#
|
206
|
+
# Returns the rev as a string
|
207
|
+
def get_git_head_rev(stack, branch='master', protocol='git')
|
208
|
+
cmd = %x{git ls-remote -h #{git_url(stack, protocol)} #{branch} | cut -c1-#{Deployinator.git_sha_length}}.chomp
|
209
|
+
end
|
210
|
+
|
211
|
+
# Public: helper method which wraps git clone
|
212
|
+
#
|
213
|
+
# Examples:
|
214
|
+
# git_clone('web', 'git@github.com:web.git)
|
215
|
+
#
|
216
|
+
# stack - the stack to clone
|
217
|
+
# repo_url - the remote url of the repo to clone
|
218
|
+
# extra_cmd - command to prepend before the actual command
|
219
|
+
# checkout_root - base directory to clone into
|
220
|
+
# branch - Git branch to checkout. Defaults to 'master'.
|
221
|
+
#
|
222
|
+
# Returns nothing
|
223
|
+
def git_clone(stack, repo_url, extra_cmd="", checkout_root=checkout_root, branch='master')
|
224
|
+
path = git_checkout_path(checkout_root, stack)
|
225
|
+
cmd = "git clone #{repo_url} -b #{branch} #{path}"
|
226
|
+
cmd = build_git_cmd(cmd, extra_cmd)
|
227
|
+
run_cmd cmd
|
228
|
+
end
|
229
|
+
|
230
|
+
# Public: helper method to build github urls
|
231
|
+
#
|
232
|
+
# Example:
|
233
|
+
# git_url('web', 'git', false)
|
234
|
+
#
|
235
|
+
# stack - the stack whose github url we want
|
236
|
+
# protocol - 'https', 'http' or 'git'
|
237
|
+
# read_write - if true then we give back a git url we can push to
|
238
|
+
#
|
239
|
+
# Returns string
|
240
|
+
def git_url(stack, protocol="git", read_write=false)
|
241
|
+
stack = stack.intern
|
242
|
+
repo = git_info_for_stack[stack][:repository]
|
243
|
+
github_host = which_github_host(stack)
|
244
|
+
repo += ".git" if protocol != "git"
|
245
|
+
if (read_write)
|
246
|
+
return "git@#{github_host}:#{git_info_for_stack[stack][:user]}/#{repo}"
|
247
|
+
else
|
248
|
+
return "#{protocol}://#{github_host}/#{git_info_for_stack[stack][:user]}/#{repo}"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# Public: helper method to determine which github hostname to use
|
253
|
+
#
|
254
|
+
# Example:
|
255
|
+
# which_github_host('statsd')
|
256
|
+
#
|
257
|
+
# stack - the stack for the github host we are looking for
|
258
|
+
#
|
259
|
+
# Returns string
|
260
|
+
def which_github_host(stack)
|
261
|
+
github_host = git_info_for_stack[stack][:host]
|
262
|
+
github_host || Deployinator.github_host
|
263
|
+
end
|
264
|
+
|
265
|
+
def git_info_for_stack
|
266
|
+
if Deployinator.git_info_for_stack
|
267
|
+
Deployinator.git_info_for_stack
|
268
|
+
else
|
269
|
+
{}
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# Public: determines whether a given filesystem path is a git repo
|
274
|
+
#
|
275
|
+
# path - the path to the directory to test
|
276
|
+
# extra_cmd - optional extra_cmd to prepend to the testing command
|
277
|
+
# (default: "")
|
278
|
+
#
|
279
|
+
# Examples
|
280
|
+
# is_git_repo('/home/dev/repo')
|
281
|
+
# is_git_repo('/home/dev/repo', 'ssh dev@deployhost')
|
282
|
+
#
|
283
|
+
# Returns :true if it is a git repo,
|
284
|
+
# :false if the path exists but is not a git repo,
|
285
|
+
# :missing if the path doesn't exist
|
286
|
+
def is_git_repo(path, extra_cmd="")
|
287
|
+
cmd = "#{extra_cmd} test"
|
288
|
+
is_dir = system("#{cmd} -d #{path}")
|
289
|
+
is_file = system("#{cmd} -f #{path}")
|
290
|
+
is_git = system("#{cmd} -d #{path}/.git")
|
291
|
+
|
292
|
+
# check possibilities
|
293
|
+
if is_dir
|
294
|
+
return :true if is_git
|
295
|
+
return :false
|
296
|
+
elsif is_file
|
297
|
+
return :false
|
298
|
+
else
|
299
|
+
return :missing
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
# Public: determine whether we want to use the github diff based on the
|
304
|
+
# existence of the stack key in the github info dict
|
305
|
+
#
|
306
|
+
# Returns true for existing keys and false otherwise
|
307
|
+
def use_github_diff
|
308
|
+
git_info_for_stack.has_key? @stack.to_sym
|
309
|
+
end
|
310
|
+
|
311
|
+
def github_list_committers(github_commits_param)
|
312
|
+
commits = {}
|
313
|
+
unless github_commits_param.nil?
|
314
|
+
github_commits_param.each do |c|
|
315
|
+
name = c["commit"]["committer"]["name"]
|
316
|
+
sha = c["sha"]
|
317
|
+
message = c["commit"]["message"]
|
318
|
+
commits[sha] = { :name => name, :message => message}
|
319
|
+
end
|
320
|
+
end
|
321
|
+
return commits
|
322
|
+
end
|
323
|
+
|
324
|
+
# Public: list the files that changes between 2 revs
|
325
|
+
#
|
326
|
+
# Parameters:
|
327
|
+
# rev1: string of the older rev
|
328
|
+
# rev2: string of the newer rev
|
329
|
+
# ssh_cmd: string ssh cmd to get to a host where you've got this repo checked out
|
330
|
+
# extra: string any extra cmds like cd that you need to do on the remote host to get to your checkout
|
331
|
+
# quiet: boolean - if true we make no additional output and just return the files
|
332
|
+
#
|
333
|
+
# Returns:
|
334
|
+
# Array of files names changed between these revs
|
335
|
+
def git_show_changed_files(rev1, rev2, ssh_cmd, extra=nil, quiet=false)
|
336
|
+
cmd = %Q{git log --name-only --pretty=oneline --full-index #{rev1}..#{rev2} | grep -vE '^[0-9a-f]{40} ' | sort | uniq}
|
337
|
+
extra = "#{extra} &&" unless extra.nil?
|
338
|
+
if quiet
|
339
|
+
list_of_touched_files = %x{#{ssh_cmd} "#{extra} #{cmd}"}
|
340
|
+
else
|
341
|
+
list_of_touched_files = run_cmd(%Q{#{ssh_cmd} "#{extra} #{cmd}"})[:stdout]
|
342
|
+
end
|
343
|
+
return list_of_touched_files.split("\n")
|
344
|
+
end
|
345
|
+
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|