thegarage-gitx 1.5.5.pre1 → 2.0.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Guardfile +8 -0
- data/README.md +2 -0
- data/bin/git-buildtag +3 -2
- data/bin/git-cleanup +4 -2
- data/bin/git-integrate +3 -2
- data/bin/git-nuke +3 -2
- data/bin/git-release +3 -2
- data/bin/git-reviewrequest +3 -2
- data/bin/git-share +3 -2
- data/bin/git-start +3 -2
- data/bin/git-track +3 -2
- data/bin/git-update +3 -2
- data/lib/thegarage/gitx/cli/base_command.rb +74 -0
- data/lib/thegarage/gitx/cli/buildtag_command.rb +39 -0
- data/lib/thegarage/gitx/cli/cleanup_command.rb +36 -0
- data/lib/thegarage/gitx/cli/integrate_command.rb +40 -0
- data/lib/thegarage/gitx/cli/nuke_command.rb +64 -0
- data/lib/thegarage/gitx/cli/release_command.rb +31 -0
- data/lib/thegarage/gitx/cli/review_request_command.rb +203 -0
- data/lib/thegarage/gitx/cli/share_command.rb +17 -0
- data/lib/thegarage/gitx/cli/start_command.rb +31 -0
- data/lib/thegarage/gitx/cli/track_command.rb +16 -0
- data/lib/thegarage/gitx/cli/update_command.rb +23 -0
- data/lib/thegarage/gitx/version.rb +1 -1
- data/lib/thegarage/gitx.rb +0 -2
- data/spec/spec_helper.rb +3 -1
- data/spec/thegarage/gitx/cli/buildtag_command_spec.rb +71 -0
- data/spec/thegarage/gitx/cli/cleanup_command_spec.rb +38 -0
- data/spec/thegarage/gitx/cli/integrate_command_spec.rb +65 -0
- data/spec/thegarage/gitx/cli/nuke_command_spec.rb +105 -0
- data/spec/thegarage/gitx/cli/release_command_spec.rb +56 -0
- data/spec/thegarage/gitx/cli/review_request_command_spec.rb +188 -0
- data/spec/thegarage/gitx/cli/share_command_spec.rb +32 -0
- data/spec/thegarage/gitx/cli/start_command_spec.rb +61 -0
- data/spec/thegarage/gitx/cli/track_command_spec.rb +31 -0
- data/spec/thegarage/gitx/cli/update_command_spec.rb +33 -0
- data/thegarage-gitx.gemspec +3 -0
- metadata +76 -11
- data/lib/thegarage/gitx/cli.rb +0 -117
- data/lib/thegarage/gitx/git.rb +0 -210
- data/lib/thegarage/gitx/github.rb +0 -185
- data/spec/thegarage/gitx/cli_spec.rb +0 -257
- data/spec/thegarage/gitx/git_spec.rb +0 -231
- data/spec/thegarage/gitx/github_spec.rb +0 -91
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/start_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::StartCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::StartCommand.new(args, options, config) }
|
13
|
+
let(:branch) { double('fake branch', name: 'feature-branch') }
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow(cli).to receive(:current_branch).and_return(branch)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#start' do
|
20
|
+
context 'when user inputs branch that is valid' do
|
21
|
+
before do
|
22
|
+
expect(cli).to receive(:run_cmd).with('git checkout master').ordered
|
23
|
+
expect(cli).to receive(:run_cmd).with('git pull').ordered
|
24
|
+
expect(cli).to receive(:run_cmd).with('git checkout -b new-branch').ordered
|
25
|
+
|
26
|
+
cli.start 'new-branch'
|
27
|
+
end
|
28
|
+
it do
|
29
|
+
should meet_expectations
|
30
|
+
end
|
31
|
+
end
|
32
|
+
context 'when user does not input a branch name' do
|
33
|
+
before do
|
34
|
+
expect(cli).to receive(:ask).and_return('another-new-branch')
|
35
|
+
|
36
|
+
expect(cli).to receive(:run_cmd).with('git checkout master').ordered
|
37
|
+
expect(cli).to receive(:run_cmd).with('git pull').ordered
|
38
|
+
expect(cli).to receive(:run_cmd).with('git checkout -b another-new-branch').ordered
|
39
|
+
|
40
|
+
cli.start
|
41
|
+
end
|
42
|
+
it 'prompts user to enter a new branch name' do
|
43
|
+
should meet_expectations
|
44
|
+
end
|
45
|
+
end
|
46
|
+
context 'when user inputs an invalid branch name' do
|
47
|
+
before do
|
48
|
+
expect(cli).to receive(:ask).and_return('another-new-branch')
|
49
|
+
|
50
|
+
expect(cli).to receive(:run_cmd).with('git checkout master').ordered
|
51
|
+
expect(cli).to receive(:run_cmd).with('git pull').ordered
|
52
|
+
expect(cli).to receive(:run_cmd).with('git checkout -b another-new-branch').ordered
|
53
|
+
|
54
|
+
cli.start 'a bad_branch-name?'
|
55
|
+
end
|
56
|
+
it 'prompts user to enter a new branch name' do
|
57
|
+
should meet_expectations
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/track_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::TrackCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::TrackCommand.new(args, options, config) }
|
13
|
+
let(:branch) { double('fake branch', name: 'feature-branch') }
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow(cli).to receive(:current_branch).and_return(branch)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#track' do
|
20
|
+
before do
|
21
|
+
allow(cli).to receive(:say)
|
22
|
+
|
23
|
+
expect(cli).to receive(:run_cmd).with('git branch --set-upstream-to origin/feature-branch').ordered
|
24
|
+
|
25
|
+
cli.track
|
26
|
+
end
|
27
|
+
it 'runs expected commands' do
|
28
|
+
should meet_expectations
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/update_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::UpdateCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::UpdateCommand.new(args, options, config) }
|
13
|
+
let(:branch) { double('fake branch', name: 'feature-branch') }
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow(cli).to receive(:current_branch).and_return(branch)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#update' do
|
20
|
+
before do
|
21
|
+
allow(cli).to receive(:say)
|
22
|
+
|
23
|
+
expect(cli).to receive(:run_cmd).with('git pull origin feature-branch', allow_failure: true).ordered
|
24
|
+
expect(cli).to receive(:run_cmd).with('git pull origin master').ordered
|
25
|
+
expect(cli).to receive(:run_cmd).with('git push origin HEAD').ordered
|
26
|
+
|
27
|
+
cli.update
|
28
|
+
end
|
29
|
+
it 'runs expected commands' do
|
30
|
+
should meet_expectations
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/thegarage-gitx.gemspec
CHANGED
@@ -28,4 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "pry", '>= 0'
|
29
29
|
spec.add_development_dependency "webmock", '>= 0'
|
30
30
|
spec.add_development_dependency "timecop", "~> 0.6.3"
|
31
|
+
spec.add_development_dependency "guard"
|
32
|
+
spec.add_development_dependency "guard-rspec"
|
33
|
+
spec.add_development_dependency "coveralls"
|
31
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thegarage-gitx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Sonnek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rugged
|
@@ -136,6 +136,48 @@ dependencies:
|
|
136
136
|
- - ~>
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: 0.6.3
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: guard
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: guard-rspec
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: coveralls
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - '>='
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
139
181
|
description: Git eXtensions for common development workflow
|
140
182
|
email:
|
141
183
|
- ryan.sonnek@gmail.com
|
@@ -160,6 +202,7 @@ files:
|
|
160
202
|
- .ruby-version
|
161
203
|
- .travis.yml
|
162
204
|
- Gemfile
|
205
|
+
- Guardfile
|
163
206
|
- LICENSE.txt
|
164
207
|
- README.md
|
165
208
|
- Rakefile
|
@@ -175,17 +218,32 @@ files:
|
|
175
218
|
- bin/git-update
|
176
219
|
- bin/git-wtf
|
177
220
|
- lib/thegarage/gitx.rb
|
178
|
-
- lib/thegarage/gitx/cli.rb
|
179
|
-
- lib/thegarage/gitx/
|
180
|
-
- lib/thegarage/gitx/
|
221
|
+
- lib/thegarage/gitx/cli/base_command.rb
|
222
|
+
- lib/thegarage/gitx/cli/buildtag_command.rb
|
223
|
+
- lib/thegarage/gitx/cli/cleanup_command.rb
|
224
|
+
- lib/thegarage/gitx/cli/integrate_command.rb
|
225
|
+
- lib/thegarage/gitx/cli/nuke_command.rb
|
226
|
+
- lib/thegarage/gitx/cli/release_command.rb
|
227
|
+
- lib/thegarage/gitx/cli/review_request_command.rb
|
228
|
+
- lib/thegarage/gitx/cli/share_command.rb
|
229
|
+
- lib/thegarage/gitx/cli/start_command.rb
|
230
|
+
- lib/thegarage/gitx/cli/track_command.rb
|
231
|
+
- lib/thegarage/gitx/cli/update_command.rb
|
181
232
|
- lib/thegarage/gitx/runner.rb
|
182
233
|
- lib/thegarage/gitx/string_extensions.rb
|
183
234
|
- lib/thegarage/gitx/version.rb
|
184
235
|
- spec/spec_helper.rb
|
185
236
|
- spec/support/meet_expectations_matcher.rb
|
186
|
-
- spec/thegarage/gitx/
|
187
|
-
- spec/thegarage/gitx/
|
188
|
-
- spec/thegarage/gitx/
|
237
|
+
- spec/thegarage/gitx/cli/buildtag_command_spec.rb
|
238
|
+
- spec/thegarage/gitx/cli/cleanup_command_spec.rb
|
239
|
+
- spec/thegarage/gitx/cli/integrate_command_spec.rb
|
240
|
+
- spec/thegarage/gitx/cli/nuke_command_spec.rb
|
241
|
+
- spec/thegarage/gitx/cli/release_command_spec.rb
|
242
|
+
- spec/thegarage/gitx/cli/review_request_command_spec.rb
|
243
|
+
- spec/thegarage/gitx/cli/share_command_spec.rb
|
244
|
+
- spec/thegarage/gitx/cli/start_command_spec.rb
|
245
|
+
- spec/thegarage/gitx/cli/track_command_spec.rb
|
246
|
+
- spec/thegarage/gitx/cli/update_command_spec.rb
|
189
247
|
- thegarage-gitx.gemspec
|
190
248
|
homepage: ''
|
191
249
|
licenses:
|
@@ -214,6 +272,13 @@ summary: Utility scripts for Git to increase productivity for common operations
|
|
214
272
|
test_files:
|
215
273
|
- spec/spec_helper.rb
|
216
274
|
- spec/support/meet_expectations_matcher.rb
|
217
|
-
- spec/thegarage/gitx/
|
218
|
-
- spec/thegarage/gitx/
|
219
|
-
- spec/thegarage/gitx/
|
275
|
+
- spec/thegarage/gitx/cli/buildtag_command_spec.rb
|
276
|
+
- spec/thegarage/gitx/cli/cleanup_command_spec.rb
|
277
|
+
- spec/thegarage/gitx/cli/integrate_command_spec.rb
|
278
|
+
- spec/thegarage/gitx/cli/nuke_command_spec.rb
|
279
|
+
- spec/thegarage/gitx/cli/release_command_spec.rb
|
280
|
+
- spec/thegarage/gitx/cli/review_request_command_spec.rb
|
281
|
+
- spec/thegarage/gitx/cli/share_command_spec.rb
|
282
|
+
- spec/thegarage/gitx/cli/start_command_spec.rb
|
283
|
+
- spec/thegarage/gitx/cli/track_command_spec.rb
|
284
|
+
- spec/thegarage/gitx/cli/update_command_spec.rb
|
data/lib/thegarage/gitx/cli.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
require 'English'
|
2
|
-
require "thor"
|
3
|
-
require 'rest_client'
|
4
|
-
require 'thegarage/gitx'
|
5
|
-
require 'thegarage/gitx/git'
|
6
|
-
require 'thegarage/gitx/github'
|
7
|
-
require 'thegarage/gitx/runner'
|
8
|
-
|
9
|
-
module Thegarage
|
10
|
-
module Gitx
|
11
|
-
class CLI < Thor
|
12
|
-
include Thor::Actions
|
13
|
-
add_runtime_options!
|
14
|
-
|
15
|
-
method_option :trace, :type => :boolean, :aliases => '-v'
|
16
|
-
def initialize(*args)
|
17
|
-
super(*args)
|
18
|
-
RestClient.proxy = ENV['HTTPS_PROXY'] if ENV.has_key?('HTTPS_PROXY')
|
19
|
-
RestClient.log = Logger.new(STDOUT) if options[:trace]
|
20
|
-
end
|
21
|
-
|
22
|
-
desc "reviewrequest", "Create or update a pull request on github"
|
23
|
-
method_option :description, :type => :string, :aliases => '-d', :desc => 'pull request description'
|
24
|
-
method_option :assignee, :type => :string, :aliases => '-a', :desc => 'pull request assignee'
|
25
|
-
method_option :open, :type => :boolean, :aliases => '-o', :desc => 'open the pull request in a web browser'
|
26
|
-
# @see http://developer.github.com/v3/pulls/
|
27
|
-
def reviewrequest
|
28
|
-
fail 'Github authorization token not found' unless github.authorization_token
|
29
|
-
|
30
|
-
branch = git.current_branch.name
|
31
|
-
pull_request = github.find_pull_request(branch)
|
32
|
-
if pull_request.nil?
|
33
|
-
git.update
|
34
|
-
changelog = runner.run_cmd "git log #{Thegarage::Gitx::BASE_BRANCH}...#{branch} --no-merges --pretty=format:'* %s%n%b'"
|
35
|
-
pull_request = github.create_pull_request(branch, changelog, options)
|
36
|
-
say 'Pull request created: '
|
37
|
-
say pull_request['html_url'], :green
|
38
|
-
end
|
39
|
-
github.assign_pull_request(pull_request, options[:assignee]) if options[:assignee]
|
40
|
-
|
41
|
-
runner.run_cmd "open #{pull_request['html_url']}" if options[:open]
|
42
|
-
end
|
43
|
-
|
44
|
-
desc 'update', 'Update the current branch with latest changes from the remote feature branch and master'
|
45
|
-
def update
|
46
|
-
git.update
|
47
|
-
end
|
48
|
-
|
49
|
-
desc 'cleanup', 'Cleanup branches that have been merged into master from the repo'
|
50
|
-
def cleanup
|
51
|
-
git.cleanup
|
52
|
-
end
|
53
|
-
|
54
|
-
desc 'track', 'set the current branch to track the remote branch with the same name'
|
55
|
-
def track
|
56
|
-
git.track
|
57
|
-
end
|
58
|
-
|
59
|
-
desc 'start', 'start a new git branch with latest changes from master'
|
60
|
-
def start(branch_name = nil)
|
61
|
-
until git.valid_new_branch_name?(branch_name)
|
62
|
-
example_branch = %w{ api-fix-invalid-auth desktop-cleanup-avatar-markup share-form-add-edit-link }.sample
|
63
|
-
branch_name = ask("What would you like to name your branch? (ex: #{example_branch})")
|
64
|
-
end
|
65
|
-
|
66
|
-
git.start branch_name
|
67
|
-
end
|
68
|
-
|
69
|
-
desc 'share', 'Share the current branch in the remote repository'
|
70
|
-
def share
|
71
|
-
git.share
|
72
|
-
end
|
73
|
-
|
74
|
-
desc 'integrate', 'integrate the current branch into one of the aggregate development branches'
|
75
|
-
def integrate(target_branch = 'staging')
|
76
|
-
git.integrate target_branch
|
77
|
-
end
|
78
|
-
|
79
|
-
desc 'nuke', 'nuke the specified aggregate branch and reset it to a known good state'
|
80
|
-
method_option :destination, :type => :string, :aliases => '-d', :desc => 'destination branch to reset to'
|
81
|
-
def nuke(bad_branch)
|
82
|
-
good_branch = options[:destination] || ask("What branch do you want to reset #{bad_branch} to? (default: #{bad_branch})")
|
83
|
-
good_branch = bad_branch if good_branch.length == 0
|
84
|
-
|
85
|
-
last_known_good_tag = git.current_build_tag(good_branch)
|
86
|
-
return unless yes?("Reset #{bad_branch} to #{last_known_good_tag}? (y/n)", :green)
|
87
|
-
|
88
|
-
git.nuke bad_branch, last_known_good_tag
|
89
|
-
end
|
90
|
-
|
91
|
-
desc 'release', 'release the current branch to production'
|
92
|
-
def release
|
93
|
-
return unless yes?("Release #{git.current_branch.name} to production? (y/n)", :green)
|
94
|
-
git.release
|
95
|
-
end
|
96
|
-
|
97
|
-
desc 'buildtag', 'create a tag for the current Travis-CI build and push it back to origin'
|
98
|
-
def buildtag
|
99
|
-
git.buildtag
|
100
|
-
end
|
101
|
-
|
102
|
-
private
|
103
|
-
|
104
|
-
def github
|
105
|
-
@github ||= Thegarage::Gitx::Github.new(git.repo, shell)
|
106
|
-
end
|
107
|
-
|
108
|
-
def git
|
109
|
-
@git ||= Thegarage::Gitx::Git.new(shell, runner)
|
110
|
-
end
|
111
|
-
|
112
|
-
def runner
|
113
|
-
@runner ||= Thegarage::Gitx::Runner.new(shell, options)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
data/lib/thegarage/gitx/git.rb
DELETED
@@ -1,210 +0,0 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require 'rugged'
|
3
|
-
|
4
|
-
module Thegarage
|
5
|
-
module Gitx
|
6
|
-
class Git
|
7
|
-
AGGREGATE_BRANCHES = %w( staging prototype )
|
8
|
-
RESERVED_BRANCHES = %w( HEAD master next_release ) + AGGREGATE_BRANCHES
|
9
|
-
TAGGABLE_BRANCHES = %w( master staging )
|
10
|
-
|
11
|
-
attr_accessor :shell, :runner, :repo
|
12
|
-
|
13
|
-
def initialize(shell, runner, path = Dir.pwd)
|
14
|
-
@shell = shell
|
15
|
-
@runner = runner
|
16
|
-
root_path = Rugged::Repository.discover(path)
|
17
|
-
@repo = Rugged::Repository.new(root_path)
|
18
|
-
end
|
19
|
-
|
20
|
-
def update
|
21
|
-
shell.say 'Updating '
|
22
|
-
shell.say "#{current_branch.name} ", :green
|
23
|
-
shell.say "with latest changes from "
|
24
|
-
shell.say Thegarage::Gitx::BASE_BRANCH, :green
|
25
|
-
|
26
|
-
runner.run_cmd "git pull origin #{current_branch.name}", :allow_failure => true
|
27
|
-
runner.run_cmd "git pull origin #{Thegarage::Gitx::BASE_BRANCH}"
|
28
|
-
runner.run_cmd 'git push origin HEAD'
|
29
|
-
end
|
30
|
-
|
31
|
-
def track
|
32
|
-
runner.run_cmd "git branch --set-upstream-to origin/#{current_branch.name}"
|
33
|
-
end
|
34
|
-
|
35
|
-
def share
|
36
|
-
runner.run_cmd "git push origin #{current_branch.name}"
|
37
|
-
track
|
38
|
-
end
|
39
|
-
|
40
|
-
def valid_new_branch_name?(branch)
|
41
|
-
remote_branches = Rugged::Branch.each_name(repo, :remote).to_a.map { |branch| branch.split('/').last }
|
42
|
-
branch =~ /^[A-Za-z0-9\-_]+$/ && !remote_branches.include?(branch)
|
43
|
-
end
|
44
|
-
|
45
|
-
def start(branch_name)
|
46
|
-
runner.run_cmd "git checkout #{Thegarage::Gitx::BASE_BRANCH}"
|
47
|
-
runner.run_cmd 'git pull'
|
48
|
-
runner.run_cmd "git checkout -b #{branch_name}"
|
49
|
-
end
|
50
|
-
|
51
|
-
def cleanup
|
52
|
-
runner.run_cmd "git checkout #{Thegarage::Gitx::BASE_BRANCH}"
|
53
|
-
runner.run_cmd "git pull"
|
54
|
-
runner.run_cmd 'git remote prune origin'
|
55
|
-
|
56
|
-
shell.say "Deleting branches that have been merged into "
|
57
|
-
shell.say Thegarage::Gitx::BASE_BRANCH, :green
|
58
|
-
branches(:merged => true, :remote => true).each do |branch|
|
59
|
-
runner.run_cmd "git push origin --delete #{branch}" unless aggregate_branch?(branch)
|
60
|
-
end
|
61
|
-
branches(:merged => true).each do |branch|
|
62
|
-
runner.run_cmd "git branch -d #{branch}" unless aggregate_branch?(branch)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def integrate(target_branch = 'staging')
|
67
|
-
update
|
68
|
-
|
69
|
-
branch = current_branch.name
|
70
|
-
integrate_branch(branch, target_branch)
|
71
|
-
runner.run_cmd "git checkout #{branch}"
|
72
|
-
end
|
73
|
-
|
74
|
-
def current_build_tag(branch)
|
75
|
-
last_build_tag = build_tags_for_branch(branch).last
|
76
|
-
raise "No known good tag found for branch: #{branch}. Verify tag exists via `git tag -l 'build-#{branch}-*'`" unless last_build_tag
|
77
|
-
last_build_tag
|
78
|
-
end
|
79
|
-
|
80
|
-
# reset the specified aggregate branch to the same set of commits as the destination branch
|
81
|
-
def nuke(outdated_branch, target_reference)
|
82
|
-
return if outdated_branch == target_reference
|
83
|
-
fail "Only aggregate branches are allowed to be reset: #{AGGREGATE_BRANCHES}" unless aggregate_branch?(outdated_branch)
|
84
|
-
return if migrations_need_to_be_reverted?
|
85
|
-
|
86
|
-
shell.say "Resetting "
|
87
|
-
shell.say "#{outdated_branch} ", :green
|
88
|
-
shell.say "branch to "
|
89
|
-
shell.say target_reference, :green
|
90
|
-
|
91
|
-
runner.run_cmd "git checkout #{Thegarage::Gitx::BASE_BRANCH}"
|
92
|
-
runner.run_cmd "git branch -D #{outdated_branch}", :allow_failure => true
|
93
|
-
runner.run_cmd "git push origin --delete #{outdated_branch}", :allow_failure => true
|
94
|
-
runner.run_cmd "git checkout -b #{outdated_branch} #{target_reference}"
|
95
|
-
runner.run_cmd "git push origin #{outdated_branch}"
|
96
|
-
runner.run_cmd "git branch --set-upstream-to origin/#{outdated_branch}"
|
97
|
-
runner.run_cmd "git checkout #{Thegarage::Gitx::BASE_BRANCH}"
|
98
|
-
end
|
99
|
-
|
100
|
-
# lookup the current branch of the repo
|
101
|
-
def current_branch
|
102
|
-
repo.branches.find(&:head?)
|
103
|
-
end
|
104
|
-
|
105
|
-
def release
|
106
|
-
branch = current_branch.name
|
107
|
-
assert_not_protected_branch!(branch, 'release')
|
108
|
-
update
|
109
|
-
|
110
|
-
runner.run_cmd "git checkout #{Thegarage::Gitx::BASE_BRANCH}"
|
111
|
-
runner.run_cmd "git pull origin #{Thegarage::Gitx::BASE_BRANCH}"
|
112
|
-
runner.run_cmd "git pull . #{branch}"
|
113
|
-
runner.run_cmd "git push origin HEAD"
|
114
|
-
integrate('staging')
|
115
|
-
cleanup
|
116
|
-
end
|
117
|
-
|
118
|
-
def buildtag
|
119
|
-
branch = ENV['TRAVIS_BRANCH']
|
120
|
-
pull_request = ENV['TRAVIS_PULL_REQUEST']
|
121
|
-
|
122
|
-
raise "Unknown branch. ENV['TRAVIS_BRANCH'] is required." unless branch
|
123
|
-
|
124
|
-
if pull_request != 'false'
|
125
|
-
shell.say "Skipping creation of tag for pull request: #{pull_request}"
|
126
|
-
elsif !TAGGABLE_BRANCHES.include?(branch)
|
127
|
-
shell.say "Cannot create build tag for branch: #{branch}. Only #{TAGGABLE_BRANCHES} are supported."
|
128
|
-
else
|
129
|
-
label = "Generated tag from TravisCI build #{ENV['TRAVIS_BUILD_NUMBER']}"
|
130
|
-
create_build_tag(branch, label)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
private
|
135
|
-
|
136
|
-
def assert_not_protected_branch!(branch, action)
|
137
|
-
raise "Cannot #{action} reserved branch" if RESERVED_BRANCHES.include?(branch) || aggregate_branch?(branch)
|
138
|
-
end
|
139
|
-
|
140
|
-
# retrieve a list of branches
|
141
|
-
def branches(options = {})
|
142
|
-
branches = []
|
143
|
-
args = []
|
144
|
-
args << '-r' if options[:remote]
|
145
|
-
args << "--merged #{options[:merged].is_a?(String) ? options[:merged] : ''}" if options[:merged]
|
146
|
-
output = `git branch #{args.join(' ')}`.split("\n")
|
147
|
-
output.each do |branch|
|
148
|
-
branch = branch.gsub(/\*/, '').strip.split(' ').first
|
149
|
-
branch = branch.split('/').last if options[:remote]
|
150
|
-
branches << branch unless RESERVED_BRANCHES.include?(branch)
|
151
|
-
end
|
152
|
-
branches.uniq
|
153
|
-
end
|
154
|
-
|
155
|
-
# integrate a branch into a destination aggregate branch
|
156
|
-
# blow away the local aggregate branch to ensure pulling into most recent "clean" branch
|
157
|
-
def integrate_branch(branch, destination_branch)
|
158
|
-
assert_not_protected_branch!(branch, 'integrate') unless aggregate_branch?(destination_branch)
|
159
|
-
raise "Only aggregate branches are allowed for integration: #{AGGREGATE_BRANCHES}" unless aggregate_branch?(destination_branch) || destination_branch == Thegarage::Gitx::BASE_BRANCH
|
160
|
-
shell.say "Integrating "
|
161
|
-
shell.say "#{branch} ", :green
|
162
|
-
shell.say "into "
|
163
|
-
shell.say destination_branch, :green
|
164
|
-
|
165
|
-
refresh_branch_from_remote destination_branch
|
166
|
-
runner.run_cmd "git pull . #{branch}"
|
167
|
-
runner.run_cmd "git push origin HEAD"
|
168
|
-
runner.run_cmd "git checkout #{branch}"
|
169
|
-
end
|
170
|
-
|
171
|
-
# nuke local branch and pull fresh version from remote repo
|
172
|
-
def refresh_branch_from_remote(destination_branch)
|
173
|
-
runner.run_cmd "git branch -D #{destination_branch}", :allow_failure => true
|
174
|
-
runner.run_cmd "git fetch origin"
|
175
|
-
runner.run_cmd "git checkout #{destination_branch}"
|
176
|
-
end
|
177
|
-
|
178
|
-
def aggregate_branch?(branch)
|
179
|
-
AGGREGATE_BRANCHES.include?(branch)
|
180
|
-
end
|
181
|
-
|
182
|
-
def create_build_tag(branch, label)
|
183
|
-
timestamp = Time.now.utc.strftime '%Y-%m-%d-%H-%M-%S'
|
184
|
-
git_tag = "build-#{branch}-#{timestamp}"
|
185
|
-
runner.run_cmd "git tag #{git_tag} -a -m '#{label}'"
|
186
|
-
runner.run_cmd "git push origin #{git_tag}"
|
187
|
-
end
|
188
|
-
|
189
|
-
def build_tags_for_branch(branch)
|
190
|
-
runner.run_cmd "git fetch --tags"
|
191
|
-
build_tags = runner.run_cmd("git tag -l 'build-#{branch}-*'").split
|
192
|
-
build_tags.sort
|
193
|
-
end
|
194
|
-
|
195
|
-
def migrations_need_to_be_reverted?
|
196
|
-
return false unless File.exists?('db/migrate')
|
197
|
-
outdated_migrations = runner.run_cmd("git diff #{head_branch}...#{outdated_branch} --name-only db/migrate").split
|
198
|
-
return false if outdated_migrations.empty?
|
199
|
-
|
200
|
-
shell.say "#{outdated_branch} contains migrations that may need to be reverted. Ensure any reversable migrations are reverted on affected databases before nuking.", :red
|
201
|
-
shell.say 'Example commands to revert outdated migrations:'
|
202
|
-
outdated_migrations.reverse.each do |migration|
|
203
|
-
version = File.basename(migration).split('_').first
|
204
|
-
shell.say "rake db:migrate:down VERSION=#{version}"
|
205
|
-
end
|
206
|
-
!yes?("Are you sure you want to nuke #{outdated_branch}? (y/n) ", :green)
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|