git_reflow 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -1
- data/Gemfile.lock +6 -5
- data/git_reflow.gemspec +4 -0
- data/lib/git_reflow/commands/deliver.rb +1 -6
- data/lib/git_reflow/commands/refresh.rb +2 -5
- data/lib/git_reflow/commands/review.rb +2 -10
- data/lib/git_reflow/commands/setup.rb +1 -23
- data/lib/git_reflow/commands/stage.rb +1 -23
- data/lib/git_reflow/commands/start.rb +3 -8
- data/lib/git_reflow/commands/status.rb +1 -2
- data/lib/git_reflow/config.rb +1 -1
- data/lib/git_reflow/git_server/git_hub/pull_request.rb +3 -3
- data/lib/git_reflow/rspec/command_line_helpers.rb +5 -0
- data/lib/git_reflow/version.rb +1 -1
- data/lib/git_reflow/workflow.rb +54 -0
- data/lib/git_reflow/workflows/core.rb +240 -0
- data/lib/git_reflow.rb +18 -117
- data/spec/lib/git_reflow/workflow_spec.rb +56 -0
- data/spec/lib/git_reflow/workflows/core_spec.rb +665 -0
- data/spec/lib/git_reflow_spec.rb +17 -526
- metadata +28 -4
- data/spec/lgtm_git_reflow_spec.rb +0 -522
data/lib/git_reflow.rb
CHANGED
@@ -8,143 +8,44 @@ require 'colorize'
|
|
8
8
|
|
9
9
|
require 'git_reflow/version.rb' unless defined?(GitReflow::VERSION)
|
10
10
|
require 'git_reflow/config'
|
11
|
+
require 'git_reflow/git_helpers'
|
11
12
|
require 'git_reflow/git_server'
|
12
|
-
require 'git_reflow/git_server/git_hub'
|
13
13
|
require 'git_reflow/git_server/bit_bucket'
|
14
|
+
require 'git_reflow/git_server/git_hub'
|
15
|
+
require 'git_reflow/merge_error'
|
14
16
|
require 'git_reflow/os_detector'
|
15
17
|
require 'git_reflow/sandbox'
|
16
|
-
require 'git_reflow/
|
17
|
-
require 'git_reflow/
|
18
|
+
require 'git_reflow/workflow'
|
19
|
+
require 'git_reflow/workflows/core'
|
18
20
|
|
19
21
|
module GitReflow
|
20
22
|
include Sandbox
|
21
23
|
include GitHelpers
|
24
|
+
|
22
25
|
extend self
|
23
26
|
|
24
|
-
def
|
25
|
-
|
27
|
+
def workflow
|
28
|
+
Workflow.current
|
26
29
|
end
|
27
30
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
if pull_request.nil?
|
32
|
-
say "\nNo pull request exists for #{current_branch} -> #{destination_branch}", :notice
|
33
|
-
say "Run 'git reflow review #{destination_branch}' to start the review process", :notice
|
34
|
-
else
|
35
|
-
say "Here's the status of your review:"
|
36
|
-
pull_request.display_pull_request_summary
|
37
|
-
end
|
31
|
+
def default_editor
|
32
|
+
"#{ENV['EDITOR'] || 'vi'}".freeze
|
38
33
|
end
|
39
34
|
|
40
|
-
def
|
41
|
-
|
42
|
-
create_pull_request = true
|
43
|
-
|
44
|
-
fetch_destination options[:base]
|
45
|
-
|
46
|
-
begin
|
47
|
-
push_current_branch
|
48
|
-
|
49
|
-
existing_pull_request = git_server.find_open_pull_request( from: current_branch, to: options[:base] )
|
50
|
-
if existing_pull_request
|
51
|
-
say "A pull request already exists for these branches:", :notice
|
52
|
-
existing_pull_request.display_pull_request_summary
|
53
|
-
else
|
54
|
-
unless options[:title] || options[:body]
|
55
|
-
pull_request_msg_file = "#{GitReflow.git_root_dir}/.git/GIT_REFLOW_PR_MSG"
|
56
|
-
|
57
|
-
File.open(pull_request_msg_file, 'w') do |file|
|
58
|
-
file.write(options[:title] || GitReflow.pull_request_template || GitReflow.current_branch)
|
59
|
-
end
|
60
|
-
|
61
|
-
GitReflow.run("#{GitReflow.git_editor_command} #{pull_request_msg_file}", with_system: true)
|
62
|
-
|
63
|
-
pr_msg = File.read(pull_request_msg_file).split(/[\r\n]|\r\n/).map(&:strip)
|
64
|
-
title = pr_msg.shift
|
65
|
-
|
66
|
-
File.delete(pull_request_msg_file)
|
67
|
-
|
68
|
-
unless pr_msg.empty?
|
69
|
-
pr_msg.shift if pr_msg.first.empty?
|
70
|
-
end
|
71
|
-
|
72
|
-
options[:title] = title
|
73
|
-
options[:body] = "#{pr_msg.join("\n")}\n"
|
74
|
-
|
75
|
-
say "\nReview your PR:\n"
|
76
|
-
say "--------\n"
|
77
|
-
say "Title:\n#{options[:title]}\n\n"
|
78
|
-
say "Body:\n#{options[:body]}\n"
|
79
|
-
say "--------\n"
|
80
|
-
|
81
|
-
create_pull_request = ask("Submit pull request? (Y)") =~ /y/i
|
82
|
-
end
|
83
|
-
|
84
|
-
if create_pull_request
|
85
|
-
pull_request = git_server.create_pull_request(title: options[:title] || options[:body],
|
86
|
-
body: options[:body],
|
87
|
-
head: "#{remote_user}:#{current_branch}",
|
88
|
-
base: options[:base])
|
89
|
-
|
90
|
-
say "Successfully created pull request ##{pull_request.number}: #{pull_request.title}\nPull Request URL: #{pull_request.html_url}\n", :success
|
91
|
-
else
|
92
|
-
say "Review aborted. No pull request has been created.", :review_halted
|
93
|
-
end
|
94
|
-
end
|
95
|
-
rescue Github::Error::UnprocessableEntity => e
|
96
|
-
say "Github Error: #{e.to_s}", :error
|
97
|
-
rescue StandardError => e
|
98
|
-
say "\nError: #{e.inspect}", :error
|
99
|
-
end
|
35
|
+
def git_server
|
36
|
+
@git_server ||= GitServer.connect provider: GitReflow::Config.get('reflow.git-server').strip, silent: true
|
100
37
|
end
|
101
38
|
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
-
begin
|
106
|
-
existing_pull_request = git_server.find_open_pull_request( from: current_branch, to: options[:base] )
|
107
|
-
|
108
|
-
if existing_pull_request.nil?
|
109
|
-
say "No pull request exists for #{remote_user}:#{current_branch}\nPlease submit your branch for review first with \`git reflow review\`", :deliver_halted
|
110
|
-
else
|
111
|
-
|
112
|
-
if existing_pull_request.good_to_merge?(force: options[:skip_lgtm])
|
113
|
-
# displays current status and prompts user for confirmation
|
114
|
-
self.status options[:base]
|
115
|
-
existing_pull_request.merge!(options)
|
116
|
-
else
|
117
|
-
say existing_pull_request.rejection_message, :deliver_halted
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
rescue Github::Error::UnprocessableEntity => e
|
122
|
-
errors = JSON.parse(e.response_message[:body])
|
123
|
-
error_messages = errors["errors"].collect {|error| "GitHub Error: #{error["message"].gsub(/^base\s/, '')}" unless error["message"].nil?}.compact.join("\n")
|
124
|
-
say "Github Error: #{error_messages}", :error
|
125
|
-
end
|
39
|
+
def respond_to?(method_sym, include_all = false)
|
40
|
+
(workflow and workflow.respond_to?(method_sym, include_all)) || super(method_sym, include_all)
|
126
41
|
end
|
127
42
|
|
128
|
-
def
|
129
|
-
|
130
|
-
|
131
|
-
# first check is to allow for automated setup
|
132
|
-
if deploy_command.empty?
|
133
|
-
deploy_command = ask("Enter the command you use to deploy to #{destination_server} (leaving blank will skip deployment)")
|
134
|
-
end
|
135
|
-
|
136
|
-
# second check is to see if the user wants to skip
|
137
|
-
if deploy_command.empty?
|
138
|
-
say "Skipping deployment..."
|
139
|
-
false
|
43
|
+
def method_missing(method_sym, *arguments, &block)
|
44
|
+
if workflow and workflow.respond_to? method_sym
|
45
|
+
workflow.send method_sym, *arguments, &block
|
140
46
|
else
|
141
|
-
|
142
|
-
run_command_with_label(deploy_command, with_system: true)
|
47
|
+
super
|
143
48
|
end
|
144
49
|
end
|
145
50
|
|
146
|
-
def git_server
|
147
|
-
@git_server ||= GitServer.connect provider: GitReflow::Config.get('reflow.git-server').strip, silent: true
|
148
|
-
end
|
149
|
-
|
150
51
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GitReflow::Workflow do
|
4
|
+
|
5
|
+
class DummyWorkflow
|
6
|
+
include GitReflow::Workflow
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:workflow) { DummyWorkflow }
|
10
|
+
let(:loader) { double() }
|
11
|
+
|
12
|
+
describe ".current" do
|
13
|
+
subject { GitReflow::Workflow.current }
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow(GitReflow::Workflow).to receive(:load).and_return(loader)
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when no workflow has been set" do
|
20
|
+
before { allow(GitReflow::Config).to receive(:get).with("reflow.workflow").and_return('') }
|
21
|
+
specify { expect( subject ).to eql(GitReflow::Workflows::Core) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe ".command" do
|
26
|
+
it "creates a class method for a bogus command" do
|
27
|
+
class DummyWorkflow
|
28
|
+
include GitReflow::Workflow
|
29
|
+
end
|
30
|
+
workflow.command :bogus do
|
31
|
+
"Woohoo"
|
32
|
+
end
|
33
|
+
|
34
|
+
expect(DummyWorkflow.bogus).to eql("Woohoo")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "creates a method for a bogus command with arguments" do
|
38
|
+
workflow.command :bogus, arguments: [:feature_branch] do |**params|
|
39
|
+
"Woohoo #{params[:feature_branch]}!"
|
40
|
+
end
|
41
|
+
|
42
|
+
expect(DummyWorkflow.bogus(feature_branch: "donuts")).to eql("Woohoo donuts!")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "creates a class method for a bogus command with default options" do
|
46
|
+
workflow.command :bogus, arguments: [:feature_branch], defaults: {decoration: 'sprinkles'} do |**params|
|
47
|
+
donut_excitement = "Woohoo #{params[:feature_branch]}"
|
48
|
+
donut_excitement += " with #{params[:decoration]}" if params[:decoration]
|
49
|
+
"#{donut_excitement}!"
|
50
|
+
end
|
51
|
+
|
52
|
+
expect(DummyWorkflow.bogus(feature_branch: "donuts")).to eql("Woohoo donuts with sprinkles!")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|