gitscape 1.1 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/gitscape +6 -3
- data/lib/gitscape/base.rb +147 -18
- data/lib/gitscape/version.rb +1 -1
- metadata +3 -3
data/bin/gitscape
CHANGED
@@ -7,15 +7,18 @@ rescue LoadError
|
|
7
7
|
require 'gitscape'
|
8
8
|
end
|
9
9
|
|
10
|
-
if ARGV.size <
|
10
|
+
if ARGV.size < 1
|
11
|
+
puts "*** Improper Usage ***"
|
11
12
|
puts "TODO: write usage help text"
|
12
13
|
exit(1)
|
13
14
|
else
|
14
15
|
case ARGV[0]
|
15
16
|
when "hotfix_start"
|
16
|
-
|
17
|
+
Gitscape::Base.new.hotfix_start ARGV[1]
|
17
18
|
when "hotfix_finish"
|
18
|
-
|
19
|
+
Gitscape::Base.new.hotfix_finish ARGV[1]
|
20
|
+
when "release_finish"
|
21
|
+
Gitscape::Base.new.release_finish ARGV[1].to_i
|
19
22
|
else
|
20
23
|
puts "Unknown command"
|
21
24
|
end
|
data/lib/gitscape/base.rb
CHANGED
@@ -21,11 +21,6 @@ class Gitscape::Base
|
|
21
21
|
@repo.branches.map { |b| b.full }
|
22
22
|
end
|
23
23
|
|
24
|
-
# Get the system's current git version
|
25
|
-
def git_version
|
26
|
-
@git_version ||= `git --version`.strip.split(" ").last
|
27
|
-
end
|
28
|
-
|
29
24
|
def checkout(branch_name)
|
30
25
|
begin
|
31
26
|
@repo.revparse(branch_name)
|
@@ -36,28 +31,52 @@ class Gitscape::Base
|
|
36
31
|
@repo.checkout(branch_name)
|
37
32
|
end
|
38
33
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
def git_working_copy_is_clean puts_changes=true
|
35
|
+
# Check if the working copy is clean, if not, exit
|
36
|
+
changes = `git status -uno --ignore-submodules=all --porcelain`
|
37
|
+
working_copy_clean = changes.length == 0
|
38
|
+
if !working_copy_clean && puts_changes
|
39
|
+
puts "Your working copy is not clean, either commit, stash, or reset your changes then try again."
|
40
|
+
puts changes
|
43
41
|
end
|
44
|
-
local_version = split_version(git_version)
|
45
|
-
min_version = split_version(min_version)
|
46
42
|
|
47
|
-
|
43
|
+
working_copy_clean
|
44
|
+
end
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
def live_current_version_number
|
47
|
+
current_branch = @repo.current_branch
|
48
|
+
live_branch = @repo.branch "live"
|
49
|
+
|
50
|
+
`git checkout #{live_branch.full}` unless current_branch == live_branch
|
51
|
+
|
52
|
+
version_file = File.new("version", "r")
|
53
|
+
live_current_version_number = version_file.read.delete("i").to_i
|
54
|
+
|
55
|
+
`git checkout #{current_branch}` unless current_branch == live_branch
|
56
|
+
|
57
|
+
live_current_version_number
|
53
58
|
end
|
54
59
|
|
60
|
+
def git_has_conflicts puts_conflicts=true
|
61
|
+
conflicts_status = `git status --porcelain | grep UU`
|
62
|
+
has_conflicts = conflicts_status.length > 0
|
63
|
+
|
64
|
+
puts conflicts_status if has_conflicts && puts_conflicts
|
65
|
+
|
66
|
+
has_conflicts
|
67
|
+
end
|
68
|
+
|
55
69
|
def hotfix_start(hotfix_branch_name=nil)
|
56
|
-
checkout "
|
70
|
+
checkout "live"
|
71
|
+
|
72
|
+
if hotfix_branch_name.length == 0
|
73
|
+
exception_message = "*** Improper Usage ***\nExpected Usage: hotfix_start <hotfix_branch_name>"
|
74
|
+
raise exception_message
|
75
|
+
end
|
57
76
|
|
58
77
|
hotfix_branch_name = "hotfix/#{hotfix_branch_name}"
|
59
78
|
puts "Creating hotfix branch '#{hotfix_branch_name}'..."
|
60
|
-
@repo.checkout(@repo.branch
|
79
|
+
@repo.checkout(@repo.branch(hotfix_branch_name).create)
|
61
80
|
end
|
62
81
|
|
63
82
|
def hotfix_finish(hotfix_branch_name=nil)
|
@@ -108,6 +127,95 @@ class Gitscape::Base
|
|
108
127
|
`git checkout #{previous_branch}`
|
109
128
|
end
|
110
129
|
|
130
|
+
def release_finish new_version_number=0
|
131
|
+
# Check if the working copy is clean, if not, exit
|
132
|
+
exit 1 unless git_working_copy_is_clean
|
133
|
+
|
134
|
+
# Get the right release_branch_name to merge
|
135
|
+
current_version_number = new_version_number - 1
|
136
|
+
if new_version_number == 0
|
137
|
+
current_version_number = live_current_version_number
|
138
|
+
new_version_number = current_version_number + 1
|
139
|
+
end
|
140
|
+
release_branch_name = "release/i#{new_version_number}"
|
141
|
+
release_branch = @repo.branch release_branch_name
|
142
|
+
|
143
|
+
# Get branch information for checks
|
144
|
+
branch_keys = ["name", "revision", "message"]
|
145
|
+
branch_values = `git branch -av`.scan(/^[ \*]*([^ \*]+) +([^ ]+) +(.*)$/)
|
146
|
+
branches = branch_values.map {|components| Hash[ branch_keys.zip components ] }
|
147
|
+
branch_revisions = Hash[ branches.map {|branch| [branch["name"], branch["revision"]] } ]
|
148
|
+
|
149
|
+
# Check if the required branches in sync
|
150
|
+
required_synced_branches = [ [release_branch_name, "remotes/origin/qa"], ["master", "remotes/origin/master"], ["live", "remotes/origin/live"] ]
|
151
|
+
required_synced_branches.each do |branch_pair|
|
152
|
+
if branch_revisions[ branch_pair[0] ] != branch_revisions[ branch_pair[0] ]
|
153
|
+
puts "*** ERROR: The #{branch_pair[0]} branch is not the same as the #{branch_pair[1]} branch.
|
154
|
+
\tPlease resolve this and try again."
|
155
|
+
exit 3
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Checkout live
|
160
|
+
`git checkout live`
|
161
|
+
|
162
|
+
# Record the revision of live used for the rollback tag
|
163
|
+
live_rollback_revision = `git log -n1 --oneline`.scan(/(^[^ ]+) .*$/).flatten[0]
|
164
|
+
|
165
|
+
merge_options = "--no-ff -s recursive -Xignore-space-change"
|
166
|
+
|
167
|
+
# Merge the release branch into live
|
168
|
+
`git merge #{merge_options} #{release_branch_name}`
|
169
|
+
|
170
|
+
# Error and conflict checking
|
171
|
+
if !$?.success? then exit 4 end
|
172
|
+
if git_has_conflicts then
|
173
|
+
puts "Merge conflicts when pulling #{release_branch_name} into live"
|
174
|
+
puts "Please bother Xavier if you see this message :)"
|
175
|
+
exit 2
|
176
|
+
end
|
177
|
+
|
178
|
+
# Ensure there is zero diff between what was tested on origin/qa and the new live
|
179
|
+
critical_diff = `git diff --stat live origin/qa`
|
180
|
+
if critical_diff.length > 0
|
181
|
+
puts "This live merge has code that was not on the qa branch."
|
182
|
+
puts critical_diff
|
183
|
+
puts "Run the command 'git reset --hard' to undo the merge, and raise this error with Phil and others involved to determine whether the release should happen."
|
184
|
+
exit 3
|
185
|
+
end
|
186
|
+
|
187
|
+
# Record the revision of live used for the release tag
|
188
|
+
live_release_revision = `git log -n1 --oneline`.scan(/(^[^ ]+) .*$/).flatten[0]
|
189
|
+
|
190
|
+
# Merge the release branch into master
|
191
|
+
`git checkout master`
|
192
|
+
`git merge #{merge_options} #{release_branch_name}`
|
193
|
+
|
194
|
+
# Error and conflict checking
|
195
|
+
if !$?.success? then exit 4 end
|
196
|
+
if git_has_conflicts then
|
197
|
+
puts "Merge conflicts when pulling #{release_branch_name} into master"
|
198
|
+
puts "Please bother Xavier if you see this message :)"
|
199
|
+
exit 2
|
200
|
+
end
|
201
|
+
|
202
|
+
# Tag the state of live for both release and rollback
|
203
|
+
`git tag rollback-to/i#{current_version_number} #{live_rollback_revision}`
|
204
|
+
if !$?.success? then
|
205
|
+
puts "=== WARNING: Failed to create rollback-to/i#{current_version_number} tag"
|
206
|
+
`git tag -d rollback-to/i#{current_version_number}`
|
207
|
+
end
|
208
|
+
|
209
|
+
`git tag live/i#{new_version_number}/release #{live_release_revision}`
|
210
|
+
if !$?.success? then
|
211
|
+
`git tag -d rollback-to/i#{current_version_number}`
|
212
|
+
`git tag -d live/i#{new_version_number}/release #{live_release_revision}`
|
213
|
+
exit 4
|
214
|
+
end
|
215
|
+
|
216
|
+
`git push origin live --tags`
|
217
|
+
`git push origin master`
|
218
|
+
end
|
111
219
|
|
112
220
|
# Returns true if the supplied Git commit hash or reference exists
|
113
221
|
def self.commit_exists?(commit_id)
|
@@ -140,6 +248,27 @@ class Gitscape::Base
|
|
140
248
|
EOH
|
141
249
|
end
|
142
250
|
|
251
|
+
# Get the system's current git version
|
252
|
+
def git_version
|
253
|
+
@git_version ||= `git --version`.strip.split(" ").last
|
254
|
+
end
|
255
|
+
|
256
|
+
# Check if the system's git version is at least as recent as the version specified
|
257
|
+
def git_version_at_least(min_version)
|
258
|
+
def split_version(v)
|
259
|
+
v.split(".").map { |x| x.to_i }
|
260
|
+
end
|
261
|
+
local_version = split_version(git_version)
|
262
|
+
min_version = split_version(min_version)
|
263
|
+
|
264
|
+
raise "Git version string must have 4 parts" if min_version.size != 4
|
265
|
+
|
266
|
+
4.times do |i|
|
267
|
+
return false unless local_version[i] >= min_version[i]
|
268
|
+
end
|
269
|
+
true
|
270
|
+
end
|
271
|
+
|
143
272
|
def self.result_ok?(result)
|
144
273
|
if result.nil? or result == 0
|
145
274
|
puts "done"
|
data/lib/gitscape/version.rb
CHANGED
metadata
CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
8
|
-
version: "1.
|
7
|
+
- 2
|
8
|
+
version: "1.2"
|
9
9
|
platform: ruby
|
10
10
|
authors:
|
11
11
|
- Jon Botelho
|
@@ -13,7 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date:
|
16
|
+
date: 2013-01-08 00:00:00 -05:00
|
17
17
|
default_executable:
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|