git_reflow 0.8.10 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.ruby-version +1 -1
  4. data/Appraisals +1 -6
  5. data/CHANGELOG.md +426 -348
  6. data/Gemfile.lock +15 -19
  7. data/LICENSE +20 -20
  8. data/README.md +27 -7
  9. data/Rakefile +8 -8
  10. data/bin/console +7 -7
  11. data/bin/setup +6 -6
  12. data/circle.yml +5 -5
  13. data/exe/git-reflow +9 -30
  14. data/git_reflow.gemspec +1 -2
  15. data/lib/git_reflow/config.rb +22 -13
  16. data/lib/git_reflow/git_helpers.rb +69 -22
  17. data/lib/git_reflow/git_server/base.rb +68 -68
  18. data/lib/git_reflow/git_server/git_hub/pull_request.rb +15 -13
  19. data/lib/git_reflow/git_server/pull_request.rb +4 -2
  20. data/lib/git_reflow/merge_error.rb +9 -9
  21. data/lib/git_reflow/rspec/command_line_helpers.rb +9 -1
  22. data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
  23. data/lib/git_reflow/rspec/workflow_helpers.rb +18 -0
  24. data/lib/git_reflow/rspec.rb +1 -0
  25. data/lib/git_reflow/sandbox.rb +1 -0
  26. data/lib/git_reflow/version.rb +1 -1
  27. data/lib/git_reflow/workflow.rb +277 -9
  28. data/lib/git_reflow/workflows/FlatMergeWorkflow +38 -0
  29. data/lib/git_reflow/workflows/core.rb +208 -79
  30. data/lib/git_reflow.rb +3 -14
  31. data/spec/fixtures/awesome_workflow.rb +2 -6
  32. data/spec/fixtures/git/git_config +7 -7
  33. data/spec/fixtures/issues/comment.json.erb +27 -27
  34. data/spec/fixtures/issues/comments.json +29 -29
  35. data/spec/fixtures/issues/comments.json.erb +15 -15
  36. data/spec/fixtures/pull_requests/comment.json.erb +45 -45
  37. data/spec/fixtures/pull_requests/comments.json +47 -47
  38. data/spec/fixtures/pull_requests/comments.json.erb +15 -15
  39. data/spec/fixtures/pull_requests/commits.json +29 -29
  40. data/spec/fixtures/pull_requests/external_pull_request.json +145 -145
  41. data/spec/fixtures/pull_requests/pull_request.json +142 -142
  42. data/spec/fixtures/pull_requests/pull_request.json.erb +142 -142
  43. data/spec/fixtures/pull_requests/pull_request_branch_nonexistent_error.json +32 -0
  44. data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -32
  45. data/spec/fixtures/pull_requests/pull_requests.json +136 -136
  46. data/spec/fixtures/repositories/commit.json +53 -53
  47. data/spec/fixtures/repositories/commit.json.erb +53 -53
  48. data/spec/fixtures/repositories/commits.json.erb +13 -13
  49. data/spec/fixtures/repositories/statuses.json +31 -31
  50. data/spec/lib/git_reflow/git_helpers_spec.rb +115 -12
  51. data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +6 -6
  52. data/spec/lib/git_reflow/git_server/pull_request_spec.rb +9 -3
  53. data/spec/lib/git_reflow/workflow_spec.rb +190 -11
  54. data/spec/lib/git_reflow/workflows/core_spec.rb +224 -65
  55. data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +17 -6
  56. data/spec/lib/git_reflow_spec.rb +2 -25
  57. data/spec/spec_helper.rb +3 -0
  58. data/spec/support/github_helpers.rb +1 -1
  59. data/spec/support/mock_pull_request.rb +17 -17
  60. data/spec/support/web_mocks.rb +39 -39
  61. metadata +9 -28
  62. data/lib/git_reflow/commands/deliver.rb +0 -10
  63. data/lib/git_reflow/commands/refresh.rb +0 -20
  64. data/lib/git_reflow/commands/review.rb +0 -13
  65. data/lib/git_reflow/commands/setup.rb +0 -11
  66. data/lib/git_reflow/commands/stage.rb +0 -9
  67. data/lib/git_reflow/commands/start.rb +0 -18
  68. data/lib/git_reflow/commands/status.rb +0 -7
  69. data/lib/git_reflow/workflows/flat_merge.rb +0 -10
  70. data/spec/fixtures/workflow_with_super.rb +0 -8
@@ -0,0 +1,38 @@
1
+ command(:deliver, arguments: { base: "master" }, flags: { merge_method: "merge" }, switches: { force: false, skip_lgtm: false }) do |**params|
2
+ params[:force] = params[:force] || params[:skip_lgtm]
3
+ begin
4
+ existing_pull_request = git_server.find_open_pull_request( from: current_branch, to: params[:base] )
5
+
6
+ if existing_pull_request.nil?
7
+ say "No pull request exists for #{remote_user}:#{current_branch}\nPlease submit your branch for review first with \`git reflow review\`", :deliver_halted
8
+ else
9
+
10
+ if existing_pull_request.good_to_merge?(force: params[:force])
11
+ # displays current status and prompts user for confirmation
12
+ self.status destination_branch: params[:base]
13
+ existing_pull_request.merge!(params)
14
+ else
15
+ say existing_pull_request.rejection_message, :deliver_halted
16
+ end
17
+
18
+ end
19
+
20
+ rescue Github::Error::UnprocessableEntity => e
21
+ say "Github Error: #{e.inspect}", :error
22
+ end
23
+ end
24
+ command_help(
25
+ :deliver,
26
+ summary: "deliver your feature branch",
27
+ arguments: {
28
+ base: "the branch to merge this feature into"
29
+ },
30
+ flags: {
31
+ merge_method: "how you want your feature branch merged ('merge', 'squash', 'rebase')"
32
+ },
33
+ switches: {
34
+ force: "skip the lgtm checks and deliver your feature branch",
35
+ skip_lgtm: "skip the lgtm checks and deliver your feature branch"
36
+ },
37
+ description: "merge your feature branch down to your base branch, and cleanup your feature branch"
38
+ )
@@ -1,4 +1,4 @@
1
- $: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../..')
1
+ $LOAD_PATH << File.expand_path(File.realpath(__dir__) + '/../..')
2
2
  require 'git_reflow/workflow'
3
3
 
4
4
  module GitReflow
@@ -6,86 +6,134 @@ module GitReflow
6
6
  # This class contains the core workflow for git-reflow. Going forward, this
7
7
  # will act as the base class for customizing and extending git-reflow.
8
8
  class Core
9
- include GitReflow::Workflow
9
+ include ::GitReflow::Workflow
10
+
11
+ # Reads and evaluates the provided file in the context of this class
12
+ #
13
+ # @param workflow_path [String] the path of the Workflow file to eval
14
+ def self.load_workflow(workflow_path)
15
+ return unless workflow_path.length > 0 and File.exists?(workflow_path)
16
+ ::GitReflow.logger.debug "Using workflow: #{workflow_path}"
17
+ self.load_raw_workflow(File.read(workflow_path))
18
+ end
19
+
20
+ # Evaluates the provided string in the context of this class
21
+ #
22
+ # @param workflow_string [String] the contents of a Workflow file to eval
23
+ def self.load_raw_workflow(workflow_string)
24
+ return if workflow_string.strip.empty?
25
+ ::GitReflow.logger.debug "Evaluating workflow..."
26
+ binding.eval(workflow_string)
27
+ end
10
28
 
11
29
  # Sets up the required git configurations that git-reflow depends on.
12
30
  #
13
- # @param local [Boolean] whether to configure git-reflow specific to the current project
14
- # @param enterprise [Boolean] whether to configure git-reflow for use with Github Enterprise
15
- command(:setup, defaults: {local: false, enterprise: false}) do |**params|
31
+ # @param [Hash] options the options to run setup with
32
+ # @option options [Boolean] :local (false) whether to configure git-reflow specific to the current project
33
+ # @option options [Boolean] :enterprise (false) whether to configure git-reflow for use with Github Enterprise
34
+ command(:setup, switches: { local: false, enterprise: false}) do |**params|
16
35
  reflow_options = { project_only: params[:local], enterprise: params[:enterprise] }
17
- existing_git_include_paths = GitReflow::Config.get('include.path', all: true).split("\n")
18
-
19
- unless File.exist?(GitReflow::Config::CONFIG_FILE_PATH) or existing_git_include_paths.include?(GitReflow::Config::CONFIG_FILE_PATH)
20
- GitReflow.say "We'll walk you through setting up git-reflow's defaults for all your projects.", :notice
21
- GitReflow.say "In the future, you can run \`git-reflow setup --local\` from the root of any project you want to setup differently.", :notice
22
- GitReflow.run "touch #{GitReflow::Config::CONFIG_FILE_PATH}"
23
- GitReflow.say "Created #{GitReflow::Config::CONFIG_FILE_PATH} for git-reflow specific configurations.", :notice
24
- GitReflow::Config.add "include.path", GitReflow::Config::CONFIG_FILE_PATH, global: true
25
- GitReflow.say "Added #{GitReflow::Config::CONFIG_FILE_PATH} to include.path in $HOME/.gitconfig.", :notice
36
+ existing_git_include_paths = git_config.get('include.path', all: true).split("\n")
37
+
38
+ unless File.exist?(git_config::CONFIG_FILE_PATH) or existing_git_include_paths.include?(git_config::CONFIG_FILE_PATH)
39
+ say "We'll walk you through setting up git-reflow's defaults for all your projects.", :notice
40
+ say "In the future, you can run \`git-reflow setup --local\` from the root of any project you want to setup differently.", :notice
41
+ run "touch #{git_config::CONFIG_FILE_PATH}"
42
+ say "Created #{git_config::CONFIG_FILE_PATH} for git-reflow specific configurations.", :notice
43
+ git_config.add "include.path", git_config::CONFIG_FILE_PATH, global: true
44
+ say "Added #{git_config::CONFIG_FILE_PATH} to include.path in $HOME/.gitconfig.", :notice
26
45
  end
27
46
 
28
47
  choose do |menu|
29
48
  menu.header = "Available remote Git Server services"
30
49
  menu.prompt = "Which service would you like to use for this project? "
31
50
 
32
- menu.choice('GitHub') { GitReflow::GitServer.connect reflow_options.merge({ provider: 'GitHub', silent: false }) }
33
- menu.choice('BitBucket (team-owned repos only)') { GitReflow::GitServer.connect reflow_options.merge({ provider: 'BitBucket', silent: false }) }
51
+ menu.choice('GitHub') { ::GitReflow::GitServer.connect reflow_options.merge({ provider: 'GitHub', silent: false }) }
52
+ menu.choice('BitBucket (team-owned repos only)') { ::GitReflow::GitServer.connect reflow_options.merge({ provider: 'BitBucket', silent: false }) }
34
53
  end
35
54
 
36
- GitReflow::Config.set "constants.minimumApprovals", ask("Set the minimum number of approvals (leaving blank will require approval from all commenters): "), local: reflow_options[:project_only]
37
- GitReflow::Config.set "constants.approvalRegex", GitReflow::GitServer::PullRequest::DEFAULT_APPROVAL_REGEX, local: reflow_options[:project_only]
55
+ git_config.set "constants.minimumApprovals", ask("Set the minimum number of approvals (leaving blank will require approval from all commenters): "), local: reflow_options[:project_only]
56
+ git_config.set "constants.approvalRegex", ::GitReflow::GitServer::PullRequest::DEFAULT_APPROVAL_REGEX, local: reflow_options[:project_only]
38
57
 
39
- if GitReflow::Config.get('core.editor').length <= 0
40
- GitReflow::Config.set('core.editor', GitReflow.default_editor, local: reflow_options[:project_only])
41
- GitReflow.say "Updated git's editor (via git config key 'core.editor') to: #{GitReflow.default_editor}.", :notice
58
+ if git_config.get('core.editor').length <= 0
59
+ git_config.set('core.editor', default_editor, local: reflow_options[:project_only])
60
+ say "Updated git's editor (via git config key 'core.editor') to: #{default_editor}.", :notice
42
61
  end
43
62
  end
63
+ command_help(
64
+ :setup,
65
+ summary: "Connect your GitServer (e.g. GitHub) account to git-reflow",
66
+ switches: {
67
+ local: "setup GitReflow for the current project only",
68
+ enterprise: "setup GitReflow with a Github Enterprise account",
69
+ }
70
+ )
44
71
 
45
72
  # Start a new feature branch
46
73
  #
47
- # @param feature_branch [String] the name of the branch to create your feature on
48
- # @option base [String] the name of the base branch you want to checkout your feature from
49
- command(:start, defaults: {base: 'master'}) do |**params|
50
- base_branch = params[:base]
74
+ # @param [Hash] options the options to run start with
75
+ # @option options [String] :base ("master") the name of the base branch you want to checkout your feature from
76
+ # @option options [String] :feature_branch the name of the base branch you want to checkout your feature from
77
+ command(:start, arguments: { feature_branch: nil }, flags: { base: nil }) do |**params|
78
+ base_branch = params[:base] || default_base_branch
51
79
  feature_branch = params[:feature_branch]
52
80
 
53
81
  if feature_branch.nil? or feature_branch.length <= 0
54
- GitReflow.say "usage: git-reflow start [new-branch-name]", :error
82
+ say "usage: git-reflow start [new-branch-name]", :error
55
83
  else
56
- GitReflow.run_command_with_label "git checkout #{base_branch}"
57
- GitReflow.run_command_with_label "git pull origin #{base_branch}"
58
- GitReflow.run_command_with_label "git push origin #{base_branch}:refs/heads/#{feature_branch}"
59
- GitReflow.run_command_with_label "git checkout --track -b #{feature_branch} origin/#{feature_branch}"
84
+ run_command_with_label "git checkout #{base_branch}"
85
+ run_command_with_label "git pull origin #{base_branch}"
86
+ run_command_with_label "git push origin #{base_branch}:refs/heads/#{feature_branch}"
87
+ run_command_with_label "git checkout --track -b #{feature_branch} origin/#{feature_branch}"
60
88
  end
61
89
  end
90
+ command_help(
91
+ :start,
92
+ summary: "This will create a new feature branch and setup remote tracking",
93
+ arguments: { new_feature_branch: "name of the new feature branch" },
94
+ flags: { base: "name of a branch you want to branch off of" },
95
+ description: <<LONGTIME
96
+ Performs the following:\n
97
+ \t$ git checkout <base_branch>\n
98
+ \t$ git pull origin <base_branch>\n
99
+ \t$ git push origin <base_branch>:refs/heads/[new_feature_branch]\n
100
+ \t$ git checkout --track -b [new_feature_branch] origin/[new_feature_branch]\n
101
+ LONGTIME
102
+ )
62
103
 
63
104
  # Submit a feature branch for review
64
105
  #
65
- # @option base [String] the name of the base branch you want to merge your feature into
66
- # @option title [String] the title of your pull request
67
- # @option body [String] the body of your pull request
68
- command(:review, defaults: {base: 'master'}) do |**params|
69
- base_branch = params[:base]
106
+ # @param [Hash] options the options to run review with
107
+ # @option options [String] :base (GitReflow::Config.get('reflow.base-branch') or "master") the name of the base branch you want to merge your feature into
108
+ # @option options [String] :title (<current-branch-name>) the title of your pull request
109
+ # @option options [String] :message ("") the body of your pull request
110
+ command(:review, arguments: { base: nil }, flags: { title: nil, message: nil }) do |**params|
111
+ base_branch = params[:base] || default_base_branch
70
112
  create_pull_request = true
71
113
 
72
- GitReflow.fetch_destination base_branch
114
+ fetch_destination base_branch
73
115
  begin
74
- GitReflow.push_current_branch
116
+ push_current_branch
75
117
 
76
- existing_pull_request = GitReflow.git_server.find_open_pull_request( from: GitReflow.current_branch, to: base_branch )
118
+ existing_pull_request = git_server.find_open_pull_request( from: current_branch, to: base_branch )
77
119
  if existing_pull_request
78
120
  say "A pull request already exists for these branches:", :notice
79
121
  existing_pull_request.display_pull_request_summary
80
122
  else
81
- unless params[:title] || params[:body]
82
- pull_request_msg_file = "#{GitReflow.git_root_dir}/.git/GIT_REFLOW_PR_MSG"
123
+ unless params[:title] || params[:message]
124
+ pull_request_msg_file = "#{git_root_dir}/.git/GIT_REFLOW_PR_MSG"
83
125
 
84
126
  File.open(pull_request_msg_file, 'w') do |file|
85
- file.write(params[:title] || GitReflow.pull_request_template || GitReflow.current_branch)
127
+ begin
128
+ pr_message = params[:title] || pull_request_template || current_branch
129
+ file.write(pr_message)
130
+ rescue StandardError => e
131
+ logger.error "Unable to parse PR template (#{pull_request_msg_file}): #{e.inspect}"
132
+ file.write(params[:title] || current_branch)
133
+ end
86
134
  end
87
135
 
88
- GitReflow.run("#{GitReflow.git_editor_command} #{pull_request_msg_file}", with_system: true)
136
+ run("#{git_editor_command} #{pull_request_msg_file}", with_system: true)
89
137
 
90
138
  pr_msg = File.read(pull_request_msg_file).split(/[\r\n]|\r\n/).map(&:strip)
91
139
  title = pr_msg.shift
@@ -97,22 +145,30 @@ module GitReflow
97
145
  end
98
146
 
99
147
  params[:title] = title
100
- params[:body] = "#{pr_msg.join("\n")}\n"
148
+ params[:message] = "#{pr_msg.join("\n")}\n"
101
149
 
102
150
  say "\nReview your PR:\n"
103
151
  say "--------\n"
104
152
  say "Title:\n#{params[:title]}\n\n"
105
- say "Body:\n#{params[:body]}\n"
153
+ say "Body:\n#{params[:message]}\n"
106
154
  say "--------\n"
107
155
 
108
156
  create_pull_request = ask("Submit pull request? (Y)") =~ /y/i
109
157
  end
110
158
 
111
159
  if create_pull_request
112
- pull_request = GitReflow.git_server.create_pull_request(title: params[:title] || params[:body],
113
- body: params[:body],
114
- head: "#{GitReflow.remote_user}:#{GitReflow.current_branch}",
115
- base: params[:base])
160
+ begin
161
+ retries ||= 0
162
+ pull_request = git_server.create_pull_request(
163
+ title: params[:title] || params[:message],
164
+ body: params[:message],
165
+ head: "#{remote_user}:#{current_branch}",
166
+ base: base_branch
167
+ )
168
+ rescue Github::Error::UnprocessableEntity
169
+ retry if (retries += 1) < 3
170
+ raise
171
+ end
116
172
 
117
173
  say "Successfully created pull request ##{pull_request.number}: #{pull_request.title}\nPull Request URL: #{pull_request.html_url}\n", :success
118
174
  else
@@ -125,25 +181,49 @@ module GitReflow
125
181
  say "\nError: #{e.inspect}", :error
126
182
  end
127
183
  end
184
+ command_help(
185
+ :review,
186
+ summary: "Pushes your latest feature branch changes to your remote repo and creates a pull request",
187
+ arguments: {
188
+ base: "the branch you want to merge your feature branch into"
189
+ },
190
+ flags: {
191
+ title: "the title of the Pull Request we'll create",
192
+ message: "the body of the Pull Request we'll create"
193
+ }
194
+ )
128
195
 
129
196
  # Checks the status of an existing pull request
130
197
  #
131
- # @option destination_branch [String] the branch you're merging your feature into ('master' is default)
132
- command(:status, defaults: {destination_branch: 'master'}) do |**params|
133
- pull_request = GitReflow.git_server.find_open_pull_request( :from => GitReflow.current_branch, :to => params[:destination_branch] )
198
+ # @param [Hash] options the options to run review with
199
+ # @option options [String] :destination_branch ("master") the branch you're merging your feature into
200
+ command(:status, arguments: { destination_branch: nil }) do |**params|
201
+ base_branch = params[:destination_branch] || default_base_branch
202
+ pull_request = git_server.find_open_pull_request( :from => current_branch, :to => base_branch )
134
203
 
135
204
  if pull_request.nil?
136
- say "No pull request exists for #{GitReflow.current_branch} -> #{params[:destination_branch]}", :notice
137
- say "Run 'git reflow review #{params[:destination_branch]}' to start the review process", :notice
205
+ say "No pull request exists for #{current_branch} -> #{base_branch}", :notice
206
+ say "Run 'git reflow review #{base_branch}' to start the review process", :notice
138
207
  else
139
208
  say "Here's the status of your review:"
140
209
  pull_request.display_pull_request_summary
141
210
  end
142
211
  end
143
-
144
- command(:deploy) do |**params|
145
- destination_server = params[:destination_server] || 'default'
146
- deploy_command = GitReflow::Config.get("reflow.deploy-to-#{destination_server}-command", local: true)
212
+ command_help(
213
+ :status,
214
+ summary: "Display information about the status of your feature in the review process",
215
+ arguments: {
216
+ destination_branch: "the branch to merge your feature into"
217
+ }
218
+ )
219
+
220
+ # Deploys the current branch to a specified server
221
+ #
222
+ # @param [Hash] options the options to run review with
223
+ # @option options [String] :destination_server ("default") the environment server to deploy to (pulled from `git config "reflow.deploy-to-#{destination_server}-command")
224
+ command(:deploy, arguments: { destination_server: "default" }) do |**params|
225
+ destination_server = params[:destination_server] || "default"
226
+ deploy_command = git_config.get("reflow.deploy-to-#{destination_server}-command", local: true)
147
227
 
148
228
  # first check is to allow for automated setup
149
229
  if deploy_command.empty?
@@ -155,50 +235,65 @@ module GitReflow
155
235
  say "Skipping deployment..."
156
236
  false
157
237
  else
158
- GitReflow::Config.set("reflow.deploy-to-#{destination_server}-command", deploy_command, local: true)
238
+ git_config.set("reflow.deploy-to-#{destination_server}-command", deploy_command, local: true)
159
239
  run_command_with_label(deploy_command, with_system: true)
160
240
  end
161
241
  end
242
+ command_help(
243
+ :deploy,
244
+ summary: "Deploys the current branch to a specified server",
245
+ arguments: {
246
+ destination_server: 'the environment to deploy to (from: `git config "reflow.deploy-to-#{destination_server}-command"`)'
247
+ }
248
+ )
162
249
 
163
250
  # Merge and deploy a feature branch to a staging branch
164
251
  command(:stage) do |**params|
165
- feature_branch_name = GitReflow.current_branch
166
- staging_branch_name = GitReflow::Config.get('reflow.staging-branch', local: true)
252
+ feature_branch_name = current_branch
253
+ staging_branch_name = git_config.get('reflow.staging-branch', local: true)
167
254
 
168
255
  if staging_branch_name.empty?
169
- staging_branch_name = GitReflow.ask("What's the name of your staging branch? (default: 'staging') ")
256
+ staging_branch_name = ask("What's the name of your staging branch? (default: 'staging') ")
170
257
  staging_branch_name = 'staging' if staging_branch_name.strip == ''
171
- GitReflow::Config.set('reflow.staging-branch', staging_branch_name, local: true)
258
+ git_config.set('reflow.staging-branch', staging_branch_name, local: true)
172
259
  end
173
260
 
174
- GitReflow.run_command_with_label "git checkout #{staging_branch_name}"
175
- GitReflow.run_command_with_label "git pull origin #{staging_branch_name}"
261
+ run_command_with_label "git checkout #{staging_branch_name}"
262
+ run_command_with_label "git pull origin #{staging_branch_name}"
176
263
 
177
- if GitReflow.run_command_with_label "git merge #{feature_branch_name}", with_system: true
178
- GitReflow.run_command_with_label "git push origin #{staging_branch_name}"
264
+ if run_command_with_label "git merge #{feature_branch_name}", with_system: true
265
+ run_command_with_label "git push origin #{staging_branch_name}"
179
266
 
180
267
  staged = self.deploy(destination_server: :staging)
181
268
 
182
269
  if staged
183
- GitReflow.say "Deployed to Staging.", :success
270
+ say "Deployed to Staging.", :success
184
271
  else
185
- GitReflow.say "There were issues deploying to staging.", :error
272
+ say "There were issues deploying to staging.", :error
186
273
  end
187
274
  else
188
- GitReflow.say "There were issues merging your feature branch to staging.", :error
275
+ say "There were issues merging your feature branch to staging.", :error
189
276
  end
190
277
  end
278
+ command_help(
279
+ :stage,
280
+ summary: "Merge and deploy a feature branch to a staging branch"
281
+ )
191
282
 
192
283
  # Deliver a feature branch to a base branch
193
284
  #
194
- # @option base [String] base branch to merge your feature branch into
195
- # @option force [Boolean] whether to force-deliver the feature branch, ignoring any QA checks
196
- command(:deliver, defaults: {base: 'master'}) do |**params|
285
+ # @param [Hash] options the options to run review with
286
+ # @option options [String] :base ("master") the base branch to merge your feature branch into
287
+ # @option options [String] :force (false) whether to force-deliver the feature branch, ignoring any QA checks
288
+ command(:deliver, arguments: { base: nil }, flags: { merge_method: "squash" }, switches: { force: false, skip_lgtm: false }) do |**params|
289
+ params[:force] = params[:force] || params[:skip_lgtm]
290
+ params[:base] ||= default_base_branch
291
+
197
292
  begin
198
- existing_pull_request = GitReflow.git_server.find_open_pull_request( from: GitReflow.current_branch, to: params[:base] )
293
+ existing_pull_request = git_server.find_open_pull_request( from: current_branch, to: params[:base] )
199
294
 
200
295
  if existing_pull_request.nil?
201
- say "No pull request exists for #{GitReflow.remote_user}:#{GitReflow.current_branch}\nPlease submit your branch for review first with \`git reflow review\`", :deliver_halted
296
+ say "No pull request exists for #{remote_user}:#{current_branch}\nPlease submit your branch for review first with \`git reflow review\`", :deliver_halted
202
297
  else
203
298
 
204
299
  if existing_pull_request.good_to_merge?(force: params[:force])
@@ -215,21 +310,55 @@ module GitReflow
215
310
  say "Github Error: #{e.inspect}", :error
216
311
  end
217
312
  end
313
+ command_help(
314
+ :deliver,
315
+ summary: "deliver your feature branch",
316
+ arguments: {
317
+ base: "the branch to merge this feature into"
318
+ },
319
+ flags: {
320
+ merge_method: "how you want your feature branch merged ('squash', 'merge', 'rebase')"
321
+ },
322
+ switches: {
323
+ force: "skip the lgtm checks and deliver your feature branch",
324
+ skip_lgtm: "skip the lgtm checks and deliver your feature branch"
325
+ },
326
+ description: "merge your feature branch down to your base branch, and cleanup your feature branch"
327
+ )
218
328
 
219
329
 
220
330
  # Updates and synchronizes your base branch and feature branch.
221
- #
331
+ #
222
332
  # Performs the following:
223
333
  # $ git checkout <base_branch>
224
334
  # $ git pull <remote_location> <base_branch>
225
335
  # $ git checkout <current_branch>
226
336
  # $ git pull origin <current_branch>
227
337
  # $ git merge <base_branch>
228
- # @param remote [String] the name of the remote repository to fetch updates from (origin by default)
229
- # @param base [String] the branch that you want to fetch updates from (master by default)
230
- command(:refresh, defaults: {remote: 'origin', base: 'master'}) do |**params|
231
- GitReflow.update_feature_branch(params)
338
+ #
339
+ # @param [Hash] options the options to run review with
340
+ # @option options [String] :remote ("origin") the name of the remote repository to fetch updates from
341
+ # @option options [String] :base ("master") the branch that you want to fetch updates from
342
+ command(:refresh, flags: { remote: 'origin', base: nil}) do |**params|
343
+ params[:base] ||= default_base_branch
344
+ update_feature_branch(params)
232
345
  end
346
+ command_help(
347
+ :refresh,
348
+ summary: "Updates and synchronizes your base branch and feature branch.",
349
+ flags: {
350
+ base: "branch to merge into",
351
+ remote: "remote repository name to fetch updates from",
352
+ },
353
+ description: <<LONGTIME
354
+ Performs the following:\n
355
+ \t$ git checkout <base_branch>\n
356
+ \t$ git pull <remote_location> <base_branch>\n
357
+ \t$ git checkout <current_branch>\n
358
+ \t$ git pull origin <current_branch>\n
359
+ \t$ git merge <base_branch>\n
360
+ LONGTIME
361
+ )
233
362
  end
234
363
  end
235
364
  end
data/lib/git_reflow.rb CHANGED
@@ -6,13 +6,6 @@ require 'httpclient'
6
6
  require 'json'
7
7
  require 'colorize'
8
8
 
9
- # XXX: work around logger spam from hashie (required by github api)
10
- # https://github.com/intridea/hashie/issues/394
11
- require "hashie"
12
- require "hashie/logger"
13
- Hashie.logger = Logger.new(nil)
14
-
15
-
16
9
  require 'github_api'
17
10
  require 'git_reflow/version.rb' unless defined?(GitReflow::VERSION)
18
11
  require 'git_reflow/config'
@@ -46,20 +39,16 @@ module GitReflow
46
39
  Workflow.current
47
40
  end
48
41
 
49
- def default_editor
50
- "#{ENV['EDITOR'] || 'vi'}".freeze
51
- end
52
-
53
42
  def git_server
54
43
  @git_server ||= GitServer.connect provider: GitReflow::Config.get('reflow.git-server').strip, silent: true
55
44
  end
56
45
 
57
- def respond_to?(method_sym, include_all = false)
58
- (workflow and workflow.respond_to?(method_sym, include_all)) || super(method_sym, include_all)
46
+ def respond_to_missing?(method_sym, include_all = false)
47
+ (workflow && workflow.respond_to?(method_sym, include_all)) || super(method_sym, include_all)
59
48
  end
60
49
 
61
50
  def method_missing(method_sym, *arguments, &block)
62
- if workflow and workflow.respond_to? method_sym
51
+ if workflow && workflow.respond_to?(method_sym, false)
63
52
  workflow.send method_sym, *arguments, &block
64
53
  else
65
54
  super
@@ -1,7 +1,3 @@
1
- class AwesomeWorkflow < GitReflow::Workflows::Core
2
- def self.start(**args)
3
- GitReflow.say "Awesome."
4
- end
1
+ command :start do
2
+ say "Awesome."
5
3
  end
6
-
7
- AwesomeWorkflow
@@ -1,7 +1,7 @@
1
- [user]
2
- name = Reenhanced
3
- email = dev@reenhanced.com
4
- [github]
5
- user = reenhanced
6
- token = 123456
7
- oauth-token = 123456
1
+ [user]
2
+ name = Reenhanced
3
+ email = dev@reenhanced.com
4
+ [github]
5
+ user = reenhanced
6
+ token = 123456
7
+ oauth-token = 123456
@@ -1,27 +1,27 @@
1
- {
2
- "id": <%= id || 1 %>,
3
- "url": "https://api.github.com/repos/<%= repo_owner %>/<%= repo_name %>/issues/comments/<%= pull_request_number %>",
4
- "html_url": "https://github.com/<%= repo_owner %>/<%= repo_name %>/issues/<%= pull_request_number %>#issuecomment-1",
5
- "body": "<%= body || "Hmmm..." %>",
6
- "user": {
7
- "login": "<%= author %>",
8
- "id": 1,
9
- "avatar_url": "https://github.com/images/error/octocat_happy.gif",
10
- "gravatar_id": "somehexcode",
11
- "url": "https://api.github.com/users/<%= author %>",
12
- "html_url": "https://github.com/<%= author %>",
13
- "followers_url": "https://api.github.com/users/<%= author %>/followers",
14
- "following_url": "https://api.github.com/users/<%= author %>/following{/other_user}",
15
- "gists_url": "https://api.github.com/users/<%= author %>/gists{/gist_id}",
16
- "starred_url": "https://api.github.com/users/<%= author %>/starred{/owner}{/repo}",
17
- "subscriptions_url": "https://api.github.com/users/<%= author %>/subscriptions",
18
- "organizations_url": "https://api.github.com/users/<%= author %>/orgs",
19
- "repos_url": "https://api.github.com/users/<%= author %>/repos",
20
- "events_url": "https://api.github.com/users/<%= author %>/events{/privacy}",
21
- "received_events_url": "https://api.github.com/users/<%= author %>/received_events",
22
- "type": "User",
23
- "site_admin": false
24
- },
25
- "created_at": "<%= created_at %>",
26
- "updated_at": "2011-04-14T16:00:49Z"
27
- }
1
+ {
2
+ "id": <%= id || 1 %>,
3
+ "url": "https://api.github.com/repos/<%= repo_owner %>/<%= repo_name %>/issues/comments/<%= pull_request_number %>",
4
+ "html_url": "https://github.com/<%= repo_owner %>/<%= repo_name %>/issues/<%= pull_request_number %>#issuecomment-1",
5
+ "body": "<%= body || "Hmmm..." %>",
6
+ "user": {
7
+ "login": "<%= author %>",
8
+ "id": 1,
9
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
10
+ "gravatar_id": "somehexcode",
11
+ "url": "https://api.github.com/users/<%= author %>",
12
+ "html_url": "https://github.com/<%= author %>",
13
+ "followers_url": "https://api.github.com/users/<%= author %>/followers",
14
+ "following_url": "https://api.github.com/users/<%= author %>/following{/other_user}",
15
+ "gists_url": "https://api.github.com/users/<%= author %>/gists{/gist_id}",
16
+ "starred_url": "https://api.github.com/users/<%= author %>/starred{/owner}{/repo}",
17
+ "subscriptions_url": "https://api.github.com/users/<%= author %>/subscriptions",
18
+ "organizations_url": "https://api.github.com/users/<%= author %>/orgs",
19
+ "repos_url": "https://api.github.com/users/<%= author %>/repos",
20
+ "events_url": "https://api.github.com/users/<%= author %>/events{/privacy}",
21
+ "received_events_url": "https://api.github.com/users/<%= author %>/received_events",
22
+ "type": "User",
23
+ "site_admin": false
24
+ },
25
+ "created_at": "<%= created_at %>",
26
+ "updated_at": "2011-04-14T16:00:49Z"
27
+ }