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,31 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'thegarage/gitx'
|
3
|
+
require 'thegarage/gitx/cli/base_command'
|
4
|
+
|
5
|
+
module Thegarage
|
6
|
+
module Gitx
|
7
|
+
module Cli
|
8
|
+
class StartCommand < BaseCommand
|
9
|
+
EXAMPLE_BRANCH_NAMES = %w( api-fix-invalid-auth desktop-cleanup-avatar-markup share-form-add-edit-link )
|
10
|
+
|
11
|
+
desc 'start', 'start a new git branch with latest changes from master'
|
12
|
+
def start(branch_name = nil)
|
13
|
+
until valid_new_branch_name?(branch_name)
|
14
|
+
branch_name = ask("What would you like to name your branch? (ex: #{EXAMPLE_BRANCH_NAMES.sample})")
|
15
|
+
end
|
16
|
+
|
17
|
+
run_cmd "git checkout #{Thegarage::Gitx::BASE_BRANCH}"
|
18
|
+
run_cmd 'git pull'
|
19
|
+
run_cmd "git checkout -b #{branch_name}"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def valid_new_branch_name?(branch)
|
25
|
+
remote_branches = Rugged::Branch.each_name(repo, :remote).to_a.map { |branch| branch.split('/').last }
|
26
|
+
branch =~ /^[A-Za-z0-9\-_]+$/ && !remote_branches.include?(branch)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'thegarage/gitx'
|
3
|
+
require 'thegarage/gitx/cli/base_command'
|
4
|
+
|
5
|
+
module Thegarage
|
6
|
+
module Gitx
|
7
|
+
module Cli
|
8
|
+
class TrackCommand < BaseCommand
|
9
|
+
desc 'track', 'set the current branch to track the remote branch with the same name'
|
10
|
+
def track
|
11
|
+
run_cmd "git branch --set-upstream-to origin/#{current_branch.name}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'thegarage/gitx'
|
3
|
+
require 'thegarage/gitx/cli/base_command'
|
4
|
+
|
5
|
+
module Thegarage
|
6
|
+
module Gitx
|
7
|
+
module Cli
|
8
|
+
class UpdateCommand < BaseCommand
|
9
|
+
desc 'update', 'Update the current branch with latest changes from the remote feature branch and master'
|
10
|
+
def update
|
11
|
+
say 'Updating '
|
12
|
+
say "#{current_branch.name} ", :green
|
13
|
+
say "with latest changes from "
|
14
|
+
say Thegarage::Gitx::BASE_BRANCH, :green
|
15
|
+
|
16
|
+
run_cmd "git pull origin #{current_branch.name}", :allow_failure => true
|
17
|
+
run_cmd "git pull origin #{Thegarage::Gitx::BASE_BRANCH}"
|
18
|
+
run_cmd 'git push origin HEAD'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/thegarage/gitx.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
Coveralls.wear!
|
1
3
|
require 'rubygems'
|
2
4
|
require 'bundler/setup'
|
3
5
|
require 'pry'
|
4
6
|
require 'webmock/rspec'
|
5
|
-
require '
|
7
|
+
require 'timecop'
|
6
8
|
|
7
9
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
8
10
|
# in spec/support/ and its subdirectories.
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/buildtag_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::BuildtagCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::BuildtagCommand.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 '#buildtag' do
|
20
|
+
let(:env_travis_branch) { nil }
|
21
|
+
let(:env_travis_pull_request) { nil }
|
22
|
+
let(:env_travis_build_number) { nil }
|
23
|
+
before do
|
24
|
+
ENV['TRAVIS_BRANCH'] = env_travis_branch
|
25
|
+
ENV['TRAVIS_PULL_REQUEST'] = env_travis_pull_request
|
26
|
+
ENV['TRAVIS_BUILD_NUMBER'] = env_travis_build_number
|
27
|
+
end
|
28
|
+
context 'when ENV[\'TRAVIS_BRANCH\'] is nil' do
|
29
|
+
it 'raises Unknown Branch error' do
|
30
|
+
expect { cli.buildtag }.to raise_error "Unknown branch. ENV['TRAVIS_BRANCH'] is required."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
context 'when the travis branch is master and the travis pull request is not false' do
|
34
|
+
let(:env_travis_branch) { 'master' }
|
35
|
+
let(:env_travis_pull_request) { '45' }
|
36
|
+
before do
|
37
|
+
expect(cli).to receive(:say).with("Skipping creation of tag for pull request: #{ENV['TRAVIS_PULL_REQUEST']}")
|
38
|
+
cli.buildtag
|
39
|
+
end
|
40
|
+
it 'tells us that it is skipping the creation of the tag' do
|
41
|
+
should meet_expectations
|
42
|
+
end
|
43
|
+
end
|
44
|
+
context 'when the travis branch is NOT master and is not a pull request' do
|
45
|
+
let(:env_travis_branch) { 'random-branch' }
|
46
|
+
let(:env_travis_pull_request) { 'false' }
|
47
|
+
before do
|
48
|
+
expect(cli).to receive(:say).with(/Cannot create build tag for branch: #{ENV['TRAVIS_BRANCH']}/)
|
49
|
+
cli.buildtag
|
50
|
+
end
|
51
|
+
it 'tells us that the branch is not supported' do
|
52
|
+
should meet_expectations
|
53
|
+
end
|
54
|
+
end
|
55
|
+
context 'when the travis branch is master and not a pull request' do
|
56
|
+
let(:env_travis_branch) { 'master' }
|
57
|
+
let(:env_travis_pull_request) { 'false' }
|
58
|
+
let(:env_travis_build_number) { '24' }
|
59
|
+
before do
|
60
|
+
Timecop.freeze(Time.utc(2013, 10, 30, 10, 21, 28)) do
|
61
|
+
expect(cli).to receive(:run_cmd).with("git tag build-master-2013-10-30-10-21-28 -a -m 'Generated tag from TravisCI build 24'").ordered
|
62
|
+
expect(cli).to receive(:run_cmd).with("git push origin build-master-2013-10-30-10-21-28").ordered
|
63
|
+
cli.buildtag
|
64
|
+
end
|
65
|
+
end
|
66
|
+
it 'creates a tag for the branch and push it to github' do
|
67
|
+
should meet_expectations
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/cleanup_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::CleanupCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::CleanupCommand.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 '#cleanup' do
|
20
|
+
before do
|
21
|
+
allow(cli).to receive(:say)
|
22
|
+
|
23
|
+
expect(cli).to receive(:merged_remote_branches).and_return(%w( merged-remote-feature ))
|
24
|
+
expect(cli).to receive(:merged_local_branches).and_return(%w( merged-local-feature ))
|
25
|
+
|
26
|
+
expect(cli).to receive(:run_cmd).with('git checkout master').ordered
|
27
|
+
expect(cli).to receive(:run_cmd).with('git pull').ordered
|
28
|
+
expect(cli).to receive(:run_cmd).with('git remote prune origin').ordered
|
29
|
+
expect(cli).to receive(:run_cmd).with('git push origin --delete merged-remote-feature').ordered
|
30
|
+
expect(cli).to receive(:run_cmd).with('git branch -d merged-local-feature').ordered
|
31
|
+
|
32
|
+
cli.cleanup
|
33
|
+
end
|
34
|
+
it 'runs expected commands' do
|
35
|
+
should meet_expectations
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/integrate_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::IntegrateCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::IntegrateCommand.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 '#integrate' do
|
20
|
+
let(:fake_update_command) { double('fake update command') }
|
21
|
+
before do
|
22
|
+
allow(Thegarage::Gitx::Cli::UpdateCommand).to receive(:new).and_return(fake_update_command)
|
23
|
+
end
|
24
|
+
context 'when target branch is ommitted' do
|
25
|
+
before do
|
26
|
+
expect(fake_update_command).to receive(:update)
|
27
|
+
|
28
|
+
expect(cli).to receive(:run_cmd).with("git branch -D staging", allow_failure: true).ordered
|
29
|
+
expect(cli).to receive(:run_cmd).with("git fetch origin").ordered
|
30
|
+
expect(cli).to receive(:run_cmd).with("git checkout staging").ordered
|
31
|
+
expect(cli).to receive(:run_cmd).with("git pull . feature-branch").ordered
|
32
|
+
expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
|
33
|
+
expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered
|
34
|
+
|
35
|
+
cli.integrate
|
36
|
+
end
|
37
|
+
it 'defaults to staging branch' do
|
38
|
+
should meet_expectations
|
39
|
+
end
|
40
|
+
end
|
41
|
+
context 'when target branch == prototype' do
|
42
|
+
before do
|
43
|
+
expect(fake_update_command).to receive(:update)
|
44
|
+
|
45
|
+
expect(cli).to receive(:run_cmd).with("git branch -D prototype", allow_failure: true).ordered
|
46
|
+
expect(cli).to receive(:run_cmd).with("git fetch origin").ordered
|
47
|
+
expect(cli).to receive(:run_cmd).with("git checkout prototype").ordered
|
48
|
+
expect(cli).to receive(:run_cmd).with("git pull . feature-branch").ordered
|
49
|
+
expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
|
50
|
+
expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered
|
51
|
+
|
52
|
+
cli.integrate 'prototype'
|
53
|
+
end
|
54
|
+
it 'runs expected commands' do
|
55
|
+
should meet_expectations
|
56
|
+
end
|
57
|
+
end
|
58
|
+
context 'when target branch != staging || prototype' do
|
59
|
+
it 'raises an error' do
|
60
|
+
|
61
|
+
expect { cli.integrate('some-other-branch') }.to raise_error(/Only aggregate branches are allowed for integration/)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/nuke_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::NukeCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::NukeCommand.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 '#nuke' do
|
20
|
+
context 'when target branch == prototype and --destination == master' do
|
21
|
+
let(:options) do
|
22
|
+
{
|
23
|
+
destination: good_branch
|
24
|
+
}
|
25
|
+
end
|
26
|
+
let(:good_branch) { 'master' }
|
27
|
+
let(:bad_branch) { 'prototype' }
|
28
|
+
let(:buildtag) { 'build-master-2013-10-01-01' }
|
29
|
+
before do
|
30
|
+
expect(cli).to receive(:yes?).and_return(true)
|
31
|
+
|
32
|
+
expect(cli).to receive(:current_build_tag).with(good_branch).and_return(buildtag)
|
33
|
+
|
34
|
+
expect(cli).to receive(:run_cmd).with("git checkout master").ordered
|
35
|
+
expect(cli).to receive(:run_cmd).with("git branch -D prototype", allow_failure: true).ordered
|
36
|
+
expect(cli).to receive(:run_cmd).with("git push origin --delete prototype", allow_failure: true).ordered
|
37
|
+
expect(cli).to receive(:run_cmd).with("git checkout -b prototype build-master-2013-10-01-01").ordered
|
38
|
+
expect(cli).to receive(:run_cmd).with("git push origin prototype").ordered
|
39
|
+
expect(cli).to receive(:run_cmd).with("git branch --set-upstream-to origin/prototype").ordered
|
40
|
+
expect(cli).to receive(:run_cmd).with("git checkout master").ordered
|
41
|
+
|
42
|
+
cli.nuke bad_branch
|
43
|
+
end
|
44
|
+
it 'runs expected commands' do
|
45
|
+
should meet_expectations
|
46
|
+
end
|
47
|
+
end
|
48
|
+
context 'when target branch == prototype and destination prompt == nil' do
|
49
|
+
let(:good_branch) { 'master' }
|
50
|
+
let(:bad_branch) { 'prototype' }
|
51
|
+
let(:buildtag) { 'build-master-2013-10-01-01' }
|
52
|
+
before do
|
53
|
+
expect(cli).to receive(:ask).and_return(good_branch)
|
54
|
+
expect(cli).to receive(:yes?).and_return(true)
|
55
|
+
|
56
|
+
expect(cli).to receive(:current_build_tag).with(good_branch).and_return(buildtag)
|
57
|
+
|
58
|
+
expect(cli).to receive(:run_cmd).with("git checkout master").ordered
|
59
|
+
expect(cli).to receive(:run_cmd).with("git branch -D prototype", allow_failure: true).ordered
|
60
|
+
expect(cli).to receive(:run_cmd).with("git push origin --delete prototype", allow_failure: true).ordered
|
61
|
+
expect(cli).to receive(:run_cmd).with("git checkout -b prototype build-master-2013-10-01-01").ordered
|
62
|
+
expect(cli).to receive(:run_cmd).with("git push origin prototype").ordered
|
63
|
+
expect(cli).to receive(:run_cmd).with("git branch --set-upstream-to origin/prototype").ordered
|
64
|
+
expect(cli).to receive(:run_cmd).with("git checkout master").ordered
|
65
|
+
|
66
|
+
cli.nuke 'prototype'
|
67
|
+
end
|
68
|
+
it 'defaults to prototype and should run expected commands' do
|
69
|
+
should meet_expectations
|
70
|
+
end
|
71
|
+
end
|
72
|
+
context 'when user does not confirm nuking the target branch' do
|
73
|
+
let(:buildtag) { 'build-master-2013-10-01-01' }
|
74
|
+
before do
|
75
|
+
expect(cli).to receive(:ask).and_return('master')
|
76
|
+
expect(cli).to receive(:yes?).and_return(false)
|
77
|
+
|
78
|
+
expect(cli).to receive(:current_build_tag).with('master').and_return(buildtag)
|
79
|
+
|
80
|
+
expect(cli).to_not receive(:run_cmd)
|
81
|
+
|
82
|
+
cli.nuke 'prototype'
|
83
|
+
end
|
84
|
+
it 'runs expected commands' do
|
85
|
+
should meet_expectations
|
86
|
+
end
|
87
|
+
end
|
88
|
+
context 'when no valid buildtag is found' do
|
89
|
+
let(:options) do
|
90
|
+
{
|
91
|
+
destination: good_branch
|
92
|
+
}
|
93
|
+
end
|
94
|
+
let(:good_branch) { 'master' }
|
95
|
+
let(:bad_branch) { 'prototype' }
|
96
|
+
let(:buildtags) { '' }
|
97
|
+
it 'raises error' do
|
98
|
+
expect(cli).to receive(:run_cmd).with("git fetch --tags").ordered
|
99
|
+
expect(cli).to receive(:run_cmd).with("git tag -l 'build-master-*'").and_return(buildtags).ordered
|
100
|
+
|
101
|
+
expect { cli.nuke('prototype') }.to raise_error(/No known good tag found for branch/)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/release_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::ReleaseCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::ReleaseCommand.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 '#release' do
|
20
|
+
context 'when user rejects release' do
|
21
|
+
before do
|
22
|
+
expect(cli).to receive(:yes?).and_return(false)
|
23
|
+
expect(cli).to_not receive(:run_cmd)
|
24
|
+
|
25
|
+
cli.release
|
26
|
+
end
|
27
|
+
it 'only runs update commands' do
|
28
|
+
should meet_expectations
|
29
|
+
end
|
30
|
+
end
|
31
|
+
context 'when user confirms release' do
|
32
|
+
let(:fake_update_command) { double('fake update command', update: nil) }
|
33
|
+
let(:fake_integrate_command) { double('fake integrate command') }
|
34
|
+
let(:fake_cleanup_command) { double('fake cleanup command', cleanup: nil) }
|
35
|
+
before do
|
36
|
+
expect(Thegarage::Gitx::Cli::UpdateCommand).to receive(:new).and_return(fake_update_command)
|
37
|
+
expect(Thegarage::Gitx::Cli::IntegrateCommand).to receive(:new).and_return(fake_integrate_command)
|
38
|
+
expect(Thegarage::Gitx::Cli::CleanupCommand).to receive(:new).and_return(fake_cleanup_command)
|
39
|
+
|
40
|
+
expect(fake_integrate_command).to receive(:integrate).with('staging')
|
41
|
+
|
42
|
+
expect(cli).to receive(:yes?).and_return(true)
|
43
|
+
|
44
|
+
expect(cli).to receive(:run_cmd).with("git checkout master").ordered
|
45
|
+
expect(cli).to receive(:run_cmd).with("git pull origin master").ordered
|
46
|
+
expect(cli).to receive(:run_cmd).with("git pull . feature-branch").ordered
|
47
|
+
expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
|
48
|
+
|
49
|
+
cli.release
|
50
|
+
end
|
51
|
+
it 'runs expected commands' do
|
52
|
+
should meet_expectations
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/review_request_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::ReviewRequestCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::ReviewRequestCommand.new(args, options, config) }
|
13
|
+
let(:repo) { double('fake repo', config: repo_config) }
|
14
|
+
let(:repo_config) do
|
15
|
+
{
|
16
|
+
'remote.origin.url' => 'https://github.com/thegarage/thegarage-gitx'
|
17
|
+
}
|
18
|
+
end
|
19
|
+
let(:branch) { double('fake branch', name: 'feature-branch') }
|
20
|
+
|
21
|
+
before do
|
22
|
+
allow(cli).to receive(:repo).and_return(repo)
|
23
|
+
allow(cli).to receive(:current_branch).and_return(branch)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#reviewrequest' do
|
27
|
+
let(:pull_request) do
|
28
|
+
{
|
29
|
+
'html_url' => 'https://path/to/new/pull/request',
|
30
|
+
'head' => {
|
31
|
+
'ref' => 'branch_name'
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
context 'when pull request does not exist' do
|
36
|
+
let(:authorization_token) { '123123' }
|
37
|
+
let(:changelog) { '* made some fixes' }
|
38
|
+
before do
|
39
|
+
expect(cli).to receive(:authorization_token).and_return(authorization_token)
|
40
|
+
expect(cli).to receive(:find_pull_request).and_return(nil)
|
41
|
+
expect(cli).to receive(:create_pull_request).and_return(pull_request)
|
42
|
+
expect(cli).to receive(:update)
|
43
|
+
expect(cli).to receive(:run_cmd).with("git log master...feature-branch --no-merges --pretty=format:'* %s%n%b'").and_return("2013-01-01 did some stuff").ordered
|
44
|
+
cli.reviewrequest
|
45
|
+
end
|
46
|
+
it 'creates github pull request' do
|
47
|
+
should meet_expectations
|
48
|
+
end
|
49
|
+
it 'runs expected commands' do
|
50
|
+
should meet_expectations
|
51
|
+
end
|
52
|
+
end
|
53
|
+
context 'when authorization_token is missing' do
|
54
|
+
let(:authorization_token) { nil }
|
55
|
+
it do
|
56
|
+
expect(cli).to receive(:authorization_token).and_return(authorization_token)
|
57
|
+
expect { cli.reviewrequest }.to raise_error(/token not found/)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
context 'when pull request already exists' do
|
61
|
+
let(:authorization_token) { '123123' }
|
62
|
+
before do
|
63
|
+
expect(cli).to receive(:authorization_token).and_return(authorization_token)
|
64
|
+
expect(cli).to receive(:find_pull_request).and_return(pull_request)
|
65
|
+
expect(cli).to_not receive(:create_pull_request)
|
66
|
+
|
67
|
+
cli.reviewrequest
|
68
|
+
end
|
69
|
+
it 'does not create new pull request' do
|
70
|
+
should meet_expectations
|
71
|
+
end
|
72
|
+
end
|
73
|
+
context 'when --assignee option passed' do
|
74
|
+
let(:options) do
|
75
|
+
{
|
76
|
+
assignee: 'johndoe'
|
77
|
+
}
|
78
|
+
end
|
79
|
+
let(:authorization_token) { '123123' }
|
80
|
+
before do
|
81
|
+
expect(cli).to receive(:authorization_token).and_return(authorization_token)
|
82
|
+
expect(cli).to receive(:find_pull_request).and_return(pull_request)
|
83
|
+
expect(cli).to receive(:assign_pull_request)
|
84
|
+
|
85
|
+
cli.reviewrequest
|
86
|
+
end
|
87
|
+
it 'calls assign_pull_request method' do
|
88
|
+
should meet_expectations
|
89
|
+
end
|
90
|
+
end
|
91
|
+
context 'when --open flag passed' do
|
92
|
+
let(:options) do
|
93
|
+
{
|
94
|
+
open: true
|
95
|
+
}
|
96
|
+
end
|
97
|
+
let(:authorization_token) { '123123' }
|
98
|
+
before do
|
99
|
+
expect(cli).to receive(:authorization_token).and_return(authorization_token)
|
100
|
+
expect(cli).to receive(:find_pull_request).and_return(pull_request)
|
101
|
+
expect(cli).to receive(:run_cmd).with("open #{pull_request['html_url']}").ordered
|
102
|
+
cli.reviewrequest
|
103
|
+
end
|
104
|
+
it 'runs open command with pull request url' do
|
105
|
+
should meet_expectations
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#authorization_token' do
|
111
|
+
context 'when github.user is not configured' do
|
112
|
+
it 'raises error' do
|
113
|
+
expect do
|
114
|
+
cli.send(:authorization_token)
|
115
|
+
end.to raise_error(/Github user not configured/)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
context 'when config.authorization_token is nil' do
|
119
|
+
let(:repo_config) do
|
120
|
+
{
|
121
|
+
'remote.origin.url' => 'https://github.com/thegarage/thegarage-gitx',
|
122
|
+
'github.user' => 'ryan@codecrate.com'
|
123
|
+
}
|
124
|
+
end
|
125
|
+
let(:github_password) { 'secretz' }
|
126
|
+
let(:authorization_token) { '123981239123' }
|
127
|
+
let(:expected_auth_body) do
|
128
|
+
JSON.dump({
|
129
|
+
scopes: ["repo"],
|
130
|
+
note: "The Garage Git eXtensions - thegarage/thegarage-gitx",
|
131
|
+
note_url: "https://github.com/thegarage/thegarage-gitx"
|
132
|
+
})
|
133
|
+
end
|
134
|
+
before do
|
135
|
+
stub_request(:post, "https://ryan@codecrate.com:secretz@api.github.com/authorizations").
|
136
|
+
with(:body => expected_auth_body).
|
137
|
+
to_return(:status => 200, :body => JSON.dump(token: authorization_token), :headers => {})
|
138
|
+
|
139
|
+
expect(cli).to receive(:ask).with('Github password for ryan@codecrate.com: ', {:echo => false}).and_return(github_password)
|
140
|
+
|
141
|
+
@auth_token = cli.send(:authorization_token)
|
142
|
+
end
|
143
|
+
it 'stores authorization_token in git config' do
|
144
|
+
expect(repo_config).to include('thegarage.gitx.githubauthtoken' => authorization_token)
|
145
|
+
end
|
146
|
+
it { expect(@auth_token).to eq authorization_token }
|
147
|
+
end
|
148
|
+
context 'when there is an existing authorization_token' do
|
149
|
+
let(:authorization_token) { '123981239123' }
|
150
|
+
let(:repo_config) do
|
151
|
+
{
|
152
|
+
'remote.origin.url' => 'https://github.com/thegarage/thegarage-gitx',
|
153
|
+
'github.user' => 'ryan@codecrate.com',
|
154
|
+
'thegarage.gitx.githubauthtoken' => authorization_token
|
155
|
+
}
|
156
|
+
end
|
157
|
+
before do
|
158
|
+
@auth_token = cli.send(:authorization_token)
|
159
|
+
end
|
160
|
+
it { expect(@auth_token).to eq authorization_token }
|
161
|
+
end
|
162
|
+
end
|
163
|
+
describe '#create_pull_request' do
|
164
|
+
context 'when there is an existing authorization_token' do
|
165
|
+
let(:authorization_token) { '123981239123' }
|
166
|
+
let(:repo_config) do
|
167
|
+
{
|
168
|
+
'remote.origin.url' => 'https://github.com/thegarage/thegarage-gitx',
|
169
|
+
'github.user' => 'ryan@codecrate.com',
|
170
|
+
'thegarage.gitx.githubauthtoken' => authorization_token
|
171
|
+
}
|
172
|
+
end
|
173
|
+
before do
|
174
|
+
stub_request(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/pulls").
|
175
|
+
to_return(:status => 200, :body => %q({"html_url": "http://github.com/repo/project/pulls/1"}), :headers => {})
|
176
|
+
|
177
|
+
expect(cli).to receive(:input_from_editor).and_return('scrubbed text')
|
178
|
+
cli.send(:create_pull_request, 'example-branch', 'changelog')
|
179
|
+
end
|
180
|
+
it 'should create github pull request' do
|
181
|
+
should meet_expectations
|
182
|
+
end
|
183
|
+
it 'should run expected commands' do
|
184
|
+
should meet_expectations
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thegarage/gitx/cli/share_command'
|
3
|
+
|
4
|
+
describe Thegarage::Gitx::Cli::ShareCommand do
|
5
|
+
let(:args) { [] }
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:config) do
|
8
|
+
{
|
9
|
+
pretend: true
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:cli) { Thegarage::Gitx::Cli::ShareCommand.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 '#share' do
|
20
|
+
before do
|
21
|
+
allow(cli).to receive(:say)
|
22
|
+
|
23
|
+
expect(cli).to receive(:run_cmd).with('git push origin feature-branch').ordered
|
24
|
+
expect(cli).to receive(:run_cmd).with('git branch --set-upstream-to origin/feature-branch').ordered
|
25
|
+
|
26
|
+
cli.share
|
27
|
+
end
|
28
|
+
it 'runs expected commands' do
|
29
|
+
should meet_expectations
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|