git_reflow 0.8.6 → 0.8.7

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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +348 -348
  4. data/Gemfile.lock +13 -15
  5. data/LICENSE +20 -20
  6. data/README.rdoc +461 -461
  7. data/Rakefile +8 -8
  8. data/bin/console +7 -7
  9. data/bin/setup +6 -6
  10. data/circle.yml +5 -5
  11. data/exe/git-reflow +36 -36
  12. data/git_reflow.gemspec +1 -1
  13. data/lib/git_reflow/commands/deliver.rb +10 -10
  14. data/lib/git_reflow/commands/refresh.rb +20 -20
  15. data/lib/git_reflow/commands/review.rb +13 -13
  16. data/lib/git_reflow/commands/setup.rb +11 -11
  17. data/lib/git_reflow/commands/stage.rb +9 -9
  18. data/lib/git_reflow/commands/start.rb +22 -22
  19. data/lib/git_reflow/commands/status.rb +7 -7
  20. data/lib/git_reflow/config.rb +9 -9
  21. data/lib/git_reflow/git_server/base.rb +68 -68
  22. data/lib/git_reflow/git_server/bit_bucket/pull_request.rb +84 -84
  23. data/lib/git_reflow/git_server/bit_bucket.rb +101 -101
  24. data/lib/git_reflow/git_server/git_hub/pull_request.rb +4 -1
  25. data/lib/git_reflow/git_server/pull_request.rb +11 -2
  26. data/lib/git_reflow/git_server.rb +63 -63
  27. data/lib/git_reflow/logger.rb +49 -0
  28. data/lib/git_reflow/merge_error.rb +9 -9
  29. data/lib/git_reflow/os_detector.rb +23 -23
  30. data/lib/git_reflow/rspec/command_line_helpers.rb +12 -8
  31. data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
  32. data/lib/git_reflow/rspec.rb +2 -2
  33. data/lib/git_reflow/sandbox.rb +11 -6
  34. data/lib/git_reflow/version.rb +1 -1
  35. data/lib/git_reflow/workflow.rb +59 -59
  36. data/lib/git_reflow/workflows/core.rb +238 -238
  37. data/lib/git_reflow/workflows/flat_merge.rb +10 -10
  38. data/lib/git_reflow.rb +11 -0
  39. data/spec/fixtures/awesome_workflow.rb +7 -0
  40. data/spec/fixtures/git/git_config +7 -0
  41. data/spec/fixtures/issues/comment.json.erb +27 -0
  42. data/spec/fixtures/issues/comments.json +29 -0
  43. data/spec/fixtures/issues/comments.json.erb +15 -0
  44. data/spec/fixtures/pull_requests/comment.json.erb +45 -0
  45. data/spec/fixtures/pull_requests/comments.json +47 -0
  46. data/spec/fixtures/pull_requests/comments.json.erb +15 -0
  47. data/spec/fixtures/pull_requests/commits.json +29 -0
  48. data/spec/fixtures/pull_requests/external_pull_request.json +145 -0
  49. data/spec/fixtures/pull_requests/pull_request.json +142 -0
  50. data/spec/fixtures/pull_requests/pull_request.json.erb +142 -0
  51. data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -0
  52. data/spec/fixtures/pull_requests/pull_requests.json +136 -0
  53. data/spec/fixtures/repositories/commit.json +53 -0
  54. data/spec/fixtures/repositories/commit.json.erb +53 -0
  55. data/spec/fixtures/repositories/commits.json.erb +13 -0
  56. data/spec/fixtures/repositories/statuses.json +31 -0
  57. data/spec/fixtures/workflow_with_super.rb +8 -0
  58. data/spec/lib/git_reflow/config_spec.rb +74 -0
  59. data/spec/lib/git_reflow/git_helpers_spec.rb +182 -0
  60. data/spec/lib/git_reflow/git_server/bit_bucket_spec.rb +81 -0
  61. data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +587 -0
  62. data/spec/lib/git_reflow/git_server/git_hub_spec.rb +221 -0
  63. data/spec/lib/git_reflow/git_server/pull_request_spec.rb +524 -0
  64. data/spec/lib/git_reflow/git_server_spec.rb +101 -0
  65. data/spec/lib/git_reflow/logger_spec.rb +18 -0
  66. data/spec/lib/git_reflow/sandbox_spec.rb +15 -0
  67. data/spec/lib/git_reflow/workflow_spec.rb +59 -0
  68. data/spec/lib/git_reflow/workflows/core_spec.rb +665 -0
  69. data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +59 -0
  70. data/spec/lib/git_reflow_spec.rb +75 -0
  71. data/spec/spec_helper.rb +38 -0
  72. data/spec/support/fake_github.rb +128 -0
  73. data/spec/support/fixtures.rb +54 -0
  74. data/spec/support/github_helpers.rb +109 -0
  75. data/spec/support/mock_pull_request.rb +17 -0
  76. data/spec/support/web_mocks.rb +39 -0
  77. metadata +83 -6
@@ -1,238 +1,238 @@
1
- $: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../..')
2
- require 'git_reflow/workflow'
3
-
4
- module GitReflow
5
- module Workflows
6
- # This class contains the core workflow for git-reflow. Going forward, this
7
- # will act as the base class for customizing and extending git-reflow.
8
- class Core
9
- include GitReflow::Workflow
10
-
11
- # Sets up the required git configurations that git-reflow depends on.
12
- #
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|
16
- 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\` from the root of any project you want to setup differently.", :notice
22
- GitReflow.say "To adjust these settings globally, you can run \`git-reflow setup --global\`.", :notice
23
- GitReflow.run "touch #{GitReflow::Config::CONFIG_FILE_PATH}"
24
- GitReflow.say "Created #{GitReflow::Config::CONFIG_FILE_PATH} for git-reflow specific configurations.", :notice
25
- GitReflow::Config.add "include.path", GitReflow::Config::CONFIG_FILE_PATH, global: true
26
- GitReflow.say "Added #{GitReflow::Config::CONFIG_FILE_PATH} to include.path in $HOME/.gitconfig.", :notice
27
- end
28
-
29
- choose do |menu|
30
- menu.header = "Available remote Git Server services"
31
- menu.prompt = "Which service would you like to use for this project? "
32
-
33
- menu.choice('GitHub') { GitReflow::GitServer.connect reflow_options.merge({ provider: 'GitHub', silent: false }) }
34
- menu.choice('BitBucket (team-owned repos only)') { GitReflow::GitServer.connect reflow_options.merge({ provider: 'BitBucket', silent: false }) }
35
- end
36
-
37
- 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]
38
- GitReflow::Config.set "constants.approvalRegex", GitReflow::GitServer::PullRequest::DEFAULT_APPROVAL_REGEX, local: reflow_options[:project_only]
39
-
40
- if GitReflow::Config.get('core.editor').length <= 0
41
- GitReflow::Config.set('core.editor', GitReflow.default_editor, local: reflow_options[:project_only])
42
- GitReflow.say "Updated git's editor (via git config key 'core.editor') to: #{GitReflow.default_editor}.", :notice
43
- end
44
- end
45
-
46
- # Start a new feature branch
47
- #
48
- # @param feature_branch [String] the name of the branch to create your feature on
49
- # @option base [String] the name of the base branch you want to checkout your feature from
50
- command(:start, defaults: {base: 'master'}) do |**params|
51
- base_branch = params[:base]
52
- feature_branch = params[:feature_branch]
53
-
54
- if feature_branch.nil? or feature_branch.length <= 0
55
- GitReflow.say "usage: git-reflow start [new-branch-name]", :error
56
- else
57
- GitReflow.run_command_with_label "git checkout #{base_branch}"
58
- GitReflow.run_command_with_label "git pull origin #{base_branch}"
59
- GitReflow.run_command_with_label "git push origin #{base_branch}:refs/heads/#{feature_branch}"
60
- GitReflow.run_command_with_label "git checkout --track -b #{feature_branch} origin/#{feature_branch}"
61
- end
62
- end
63
-
64
- # Submit a feature branch for review
65
- #
66
- # @option base [String] the name of the base branch you want to merge your feature into
67
- # @option title [String] the title of your pull request
68
- # @option body [String] the body of your pull request
69
- command(:review, defaults: {base: 'master'}) do |**params|
70
- base_branch = params[:base]
71
- create_pull_request = true
72
-
73
- GitReflow.fetch_destination base_branch
74
- begin
75
- GitReflow.push_current_branch
76
-
77
- existing_pull_request = GitReflow.git_server.find_open_pull_request( from: GitReflow.current_branch, to: base_branch )
78
- if existing_pull_request
79
- say "A pull request already exists for these branches:", :notice
80
- existing_pull_request.display_pull_request_summary
81
- else
82
- unless params[:title] || params[:body]
83
- pull_request_msg_file = "#{GitReflow.git_root_dir}/.git/GIT_REFLOW_PR_MSG"
84
-
85
- File.open(pull_request_msg_file, 'w') do |file|
86
- file.write(params[:title] || GitReflow.pull_request_template || GitReflow.current_branch)
87
- end
88
-
89
- GitReflow.run("#{GitReflow.git_editor_command} #{pull_request_msg_file}", with_system: true)
90
-
91
- pr_msg = File.read(pull_request_msg_file).split(/[\r\n]|\r\n/).map(&:strip)
92
- title = pr_msg.shift
93
-
94
- File.delete(pull_request_msg_file)
95
-
96
- unless pr_msg.empty?
97
- pr_msg.shift if pr_msg.first.empty?
98
- end
99
-
100
- params[:title] = title
101
- params[:body] = "#{pr_msg.join("\n")}\n"
102
-
103
- say "\nReview your PR:\n"
104
- say "--------\n"
105
- say "Title:\n#{params[:title]}\n\n"
106
- say "Body:\n#{params[:body]}\n"
107
- say "--------\n"
108
-
109
- create_pull_request = ask("Submit pull request? (Y)") =~ /y/i
110
- end
111
-
112
- if create_pull_request
113
- pull_request = GitReflow.git_server.create_pull_request(title: params[:title] || params[:body],
114
- body: params[:body],
115
- head: "#{GitReflow.remote_user}:#{GitReflow.current_branch}",
116
- base: params[:base])
117
-
118
- say "Successfully created pull request ##{pull_request.number}: #{pull_request.title}\nPull Request URL: #{pull_request.html_url}\n", :success
119
- else
120
- say "Review aborted. No pull request has been created.", :review_halted
121
- end
122
- end
123
- rescue Github::Error::UnprocessableEntity => e
124
- say "Github Error: #{e.to_s}", :error
125
- rescue StandardError => e
126
- say "\nError: #{e.inspect}", :error
127
- end
128
- end
129
-
130
- # Checks the status of an existing pull request
131
- #
132
- # @option destination_branch [String] the branch you're merging your feature into ('master' is default)
133
- command(:status, defaults: {destination_branch: 'master'}) do |**params|
134
- pull_request = GitReflow.git_server.find_open_pull_request( :from => GitReflow.current_branch, :to => params[:destination_branch] )
135
-
136
- if pull_request.nil?
137
- say "No pull request exists for #{GitReflow.current_branch} -> #{params[:destination_branch]}", :notice
138
- say "Run 'git reflow review #{params[:destination_branch]}' to start the review process", :notice
139
- else
140
- say "Here's the status of your review:"
141
- pull_request.display_pull_request_summary
142
- end
143
- end
144
-
145
- command(:deploy) do |**params|
146
- destination_server = params[:destination_server] || 'default'
147
- deploy_command = GitReflow::Config.get("reflow.deploy-to-#{destination_server}-command", local: true)
148
-
149
- # first check is to allow for automated setup
150
- if deploy_command.empty?
151
- deploy_command = ask("Enter the command you use to deploy to #{destination_server} (leaving blank will skip deployment)")
152
- end
153
-
154
- # second check is to see if the user wants to skip
155
- if deploy_command.empty?
156
- say "Skipping deployment..."
157
- false
158
- else
159
- GitReflow::Config.set("reflow.deploy-to-#{destination_server}-command", deploy_command, local: true)
160
- run_command_with_label(deploy_command, with_system: true)
161
- end
162
- end
163
-
164
- # Merge and deploy a feature branch to a staging branch
165
- command(:stage) do |**params|
166
- feature_branch_name = GitReflow.current_branch
167
- staging_branch_name = GitReflow::Config.get('reflow.staging-branch', local: true)
168
-
169
- if staging_branch_name.empty?
170
- staging_branch_name = GitReflow.ask("What's the name of your staging branch? (default: 'staging') ")
171
- staging_branch_name = 'staging' if staging_branch_name.strip == ''
172
- GitReflow::Config.set('reflow.staging-branch', staging_branch_name, local: true)
173
- end
174
-
175
- GitReflow.run_command_with_label "git checkout #{staging_branch_name}"
176
- GitReflow.run_command_with_label "git pull origin #{staging_branch_name}"
177
-
178
- if GitReflow.run_command_with_label "git merge #{feature_branch_name}", with_system: true
179
- GitReflow.run_command_with_label "git push origin #{staging_branch_name}"
180
-
181
- staged = self.deploy(destination_server: :staging)
182
-
183
- if staged
184
- GitReflow.say "Deployed to Staging.", :success
185
- else
186
- GitReflow.say "There were issues deploying to staging.", :error
187
- end
188
- else
189
- GitReflow.say "There were issues merging your feature branch to staging.", :error
190
- end
191
- end
192
-
193
- # Deliver a feature branch to a base branch
194
- #
195
- # @option base [String] base branch to merge your feature branch into
196
- # @option force [Boolean] whether to force-deliver the feature branch, ignoring any QA checks
197
- command(:deliver, defaults: {base: 'master'}) do |**params|
198
- begin
199
- existing_pull_request = GitReflow.git_server.find_open_pull_request( from: GitReflow.current_branch, to: params[:base] )
200
-
201
- if existing_pull_request.nil?
202
- 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
203
- else
204
-
205
- if existing_pull_request.good_to_merge?(force: params[:force])
206
- # displays current status and prompts user for confirmation
207
- self.status destination_branch: params[:base]
208
- # TODO: change name of this in the merge! method
209
- params[:skip_lgtm] = params[:force] if params[:force]
210
- existing_pull_request.merge!(params)
211
- else
212
- say existing_pull_request.rejection_message, :deliver_halted
213
- end
214
-
215
- end
216
-
217
- rescue Github::Error::UnprocessableEntity => e
218
- say "Github Error: #{e.inspect}", :error
219
- end
220
- end
221
-
222
-
223
- # Updates and synchronizes your base branch and feature branch.
224
- #
225
- # Performs the following:
226
- # $ git checkout <base_branch>
227
- # $ git pull <remote_location> <base_branch>
228
- # $ git checkout <current_branch>
229
- # $ git pull origin <current_branch>
230
- # $ git merge <base_branch>
231
- # @param remote [String] the name of the remote repository to fetch updates from (origin by default)
232
- # @param base [String] the branch that you want to fetch updates from (master by default)
233
- command(:refresh, defaults: {remote: 'origin', base: 'master'}) do |**params|
234
- GitReflow.update_feature_branch(params)
235
- end
236
- end
237
- end
238
- end
1
+ $: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../..')
2
+ require 'git_reflow/workflow'
3
+
4
+ module GitReflow
5
+ module Workflows
6
+ # This class contains the core workflow for git-reflow. Going forward, this
7
+ # will act as the base class for customizing and extending git-reflow.
8
+ class Core
9
+ include GitReflow::Workflow
10
+
11
+ # Sets up the required git configurations that git-reflow depends on.
12
+ #
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|
16
+ 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\` from the root of any project you want to setup differently.", :notice
22
+ GitReflow.say "To adjust these settings globally, you can run \`git-reflow setup --global\`.", :notice
23
+ GitReflow.run "touch #{GitReflow::Config::CONFIG_FILE_PATH}"
24
+ GitReflow.say "Created #{GitReflow::Config::CONFIG_FILE_PATH} for git-reflow specific configurations.", :notice
25
+ GitReflow::Config.add "include.path", GitReflow::Config::CONFIG_FILE_PATH, global: true
26
+ GitReflow.say "Added #{GitReflow::Config::CONFIG_FILE_PATH} to include.path in $HOME/.gitconfig.", :notice
27
+ end
28
+
29
+ choose do |menu|
30
+ menu.header = "Available remote Git Server services"
31
+ menu.prompt = "Which service would you like to use for this project? "
32
+
33
+ menu.choice('GitHub') { GitReflow::GitServer.connect reflow_options.merge({ provider: 'GitHub', silent: false }) }
34
+ menu.choice('BitBucket (team-owned repos only)') { GitReflow::GitServer.connect reflow_options.merge({ provider: 'BitBucket', silent: false }) }
35
+ end
36
+
37
+ 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]
38
+ GitReflow::Config.set "constants.approvalRegex", GitReflow::GitServer::PullRequest::DEFAULT_APPROVAL_REGEX, local: reflow_options[:project_only]
39
+
40
+ if GitReflow::Config.get('core.editor').length <= 0
41
+ GitReflow::Config.set('core.editor', GitReflow.default_editor, local: reflow_options[:project_only])
42
+ GitReflow.say "Updated git's editor (via git config key 'core.editor') to: #{GitReflow.default_editor}.", :notice
43
+ end
44
+ end
45
+
46
+ # Start a new feature branch
47
+ #
48
+ # @param feature_branch [String] the name of the branch to create your feature on
49
+ # @option base [String] the name of the base branch you want to checkout your feature from
50
+ command(:start, defaults: {base: 'master'}) do |**params|
51
+ base_branch = params[:base]
52
+ feature_branch = params[:feature_branch]
53
+
54
+ if feature_branch.nil? or feature_branch.length <= 0
55
+ GitReflow.say "usage: git-reflow start [new-branch-name]", :error
56
+ else
57
+ GitReflow.run_command_with_label "git checkout #{base_branch}"
58
+ GitReflow.run_command_with_label "git pull origin #{base_branch}"
59
+ GitReflow.run_command_with_label "git push origin #{base_branch}:refs/heads/#{feature_branch}"
60
+ GitReflow.run_command_with_label "git checkout --track -b #{feature_branch} origin/#{feature_branch}"
61
+ end
62
+ end
63
+
64
+ # Submit a feature branch for review
65
+ #
66
+ # @option base [String] the name of the base branch you want to merge your feature into
67
+ # @option title [String] the title of your pull request
68
+ # @option body [String] the body of your pull request
69
+ command(:review, defaults: {base: 'master'}) do |**params|
70
+ base_branch = params[:base]
71
+ create_pull_request = true
72
+
73
+ GitReflow.fetch_destination base_branch
74
+ begin
75
+ GitReflow.push_current_branch
76
+
77
+ existing_pull_request = GitReflow.git_server.find_open_pull_request( from: GitReflow.current_branch, to: base_branch )
78
+ if existing_pull_request
79
+ say "A pull request already exists for these branches:", :notice
80
+ existing_pull_request.display_pull_request_summary
81
+ else
82
+ unless params[:title] || params[:body]
83
+ pull_request_msg_file = "#{GitReflow.git_root_dir}/.git/GIT_REFLOW_PR_MSG"
84
+
85
+ File.open(pull_request_msg_file, 'w') do |file|
86
+ file.write(params[:title] || GitReflow.pull_request_template || GitReflow.current_branch)
87
+ end
88
+
89
+ GitReflow.run("#{GitReflow.git_editor_command} #{pull_request_msg_file}", with_system: true)
90
+
91
+ pr_msg = File.read(pull_request_msg_file).split(/[\r\n]|\r\n/).map(&:strip)
92
+ title = pr_msg.shift
93
+
94
+ File.delete(pull_request_msg_file)
95
+
96
+ unless pr_msg.empty?
97
+ pr_msg.shift if pr_msg.first.empty?
98
+ end
99
+
100
+ params[:title] = title
101
+ params[:body] = "#{pr_msg.join("\n")}\n"
102
+
103
+ say "\nReview your PR:\n"
104
+ say "--------\n"
105
+ say "Title:\n#{params[:title]}\n\n"
106
+ say "Body:\n#{params[:body]}\n"
107
+ say "--------\n"
108
+
109
+ create_pull_request = ask("Submit pull request? (Y)") =~ /y/i
110
+ end
111
+
112
+ if create_pull_request
113
+ pull_request = GitReflow.git_server.create_pull_request(title: params[:title] || params[:body],
114
+ body: params[:body],
115
+ head: "#{GitReflow.remote_user}:#{GitReflow.current_branch}",
116
+ base: params[:base])
117
+
118
+ say "Successfully created pull request ##{pull_request.number}: #{pull_request.title}\nPull Request URL: #{pull_request.html_url}\n", :success
119
+ else
120
+ say "Review aborted. No pull request has been created.", :review_halted
121
+ end
122
+ end
123
+ rescue Github::Error::UnprocessableEntity => e
124
+ say "Github Error: #{e.to_s}", :error
125
+ rescue StandardError => e
126
+ say "\nError: #{e.inspect}", :error
127
+ end
128
+ end
129
+
130
+ # Checks the status of an existing pull request
131
+ #
132
+ # @option destination_branch [String] the branch you're merging your feature into ('master' is default)
133
+ command(:status, defaults: {destination_branch: 'master'}) do |**params|
134
+ pull_request = GitReflow.git_server.find_open_pull_request( :from => GitReflow.current_branch, :to => params[:destination_branch] )
135
+
136
+ if pull_request.nil?
137
+ say "No pull request exists for #{GitReflow.current_branch} -> #{params[:destination_branch]}", :notice
138
+ say "Run 'git reflow review #{params[:destination_branch]}' to start the review process", :notice
139
+ else
140
+ say "Here's the status of your review:"
141
+ pull_request.display_pull_request_summary
142
+ end
143
+ end
144
+
145
+ command(:deploy) do |**params|
146
+ destination_server = params[:destination_server] || 'default'
147
+ deploy_command = GitReflow::Config.get("reflow.deploy-to-#{destination_server}-command", local: true)
148
+
149
+ # first check is to allow for automated setup
150
+ if deploy_command.empty?
151
+ deploy_command = ask("Enter the command you use to deploy to #{destination_server} (leaving blank will skip deployment)")
152
+ end
153
+
154
+ # second check is to see if the user wants to skip
155
+ if deploy_command.empty?
156
+ say "Skipping deployment..."
157
+ false
158
+ else
159
+ GitReflow::Config.set("reflow.deploy-to-#{destination_server}-command", deploy_command, local: true)
160
+ run_command_with_label(deploy_command, with_system: true)
161
+ end
162
+ end
163
+
164
+ # Merge and deploy a feature branch to a staging branch
165
+ command(:stage) do |**params|
166
+ feature_branch_name = GitReflow.current_branch
167
+ staging_branch_name = GitReflow::Config.get('reflow.staging-branch', local: true)
168
+
169
+ if staging_branch_name.empty?
170
+ staging_branch_name = GitReflow.ask("What's the name of your staging branch? (default: 'staging') ")
171
+ staging_branch_name = 'staging' if staging_branch_name.strip == ''
172
+ GitReflow::Config.set('reflow.staging-branch', staging_branch_name, local: true)
173
+ end
174
+
175
+ GitReflow.run_command_with_label "git checkout #{staging_branch_name}"
176
+ GitReflow.run_command_with_label "git pull origin #{staging_branch_name}"
177
+
178
+ if GitReflow.run_command_with_label "git merge #{feature_branch_name}", with_system: true
179
+ GitReflow.run_command_with_label "git push origin #{staging_branch_name}"
180
+
181
+ staged = self.deploy(destination_server: :staging)
182
+
183
+ if staged
184
+ GitReflow.say "Deployed to Staging.", :success
185
+ else
186
+ GitReflow.say "There were issues deploying to staging.", :error
187
+ end
188
+ else
189
+ GitReflow.say "There were issues merging your feature branch to staging.", :error
190
+ end
191
+ end
192
+
193
+ # Deliver a feature branch to a base branch
194
+ #
195
+ # @option base [String] base branch to merge your feature branch into
196
+ # @option force [Boolean] whether to force-deliver the feature branch, ignoring any QA checks
197
+ command(:deliver, defaults: {base: 'master'}) do |**params|
198
+ begin
199
+ existing_pull_request = GitReflow.git_server.find_open_pull_request( from: GitReflow.current_branch, to: params[:base] )
200
+
201
+ if existing_pull_request.nil?
202
+ 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
203
+ else
204
+
205
+ if existing_pull_request.good_to_merge?(force: params[:force])
206
+ # displays current status and prompts user for confirmation
207
+ self.status destination_branch: params[:base]
208
+ # TODO: change name of this in the merge! method
209
+ params[:skip_lgtm] = params[:force] if params[:force]
210
+ existing_pull_request.merge!(params)
211
+ else
212
+ say existing_pull_request.rejection_message, :deliver_halted
213
+ end
214
+
215
+ end
216
+
217
+ rescue Github::Error::UnprocessableEntity => e
218
+ say "Github Error: #{e.inspect}", :error
219
+ end
220
+ end
221
+
222
+
223
+ # Updates and synchronizes your base branch and feature branch.
224
+ #
225
+ # Performs the following:
226
+ # $ git checkout <base_branch>
227
+ # $ git pull <remote_location> <base_branch>
228
+ # $ git checkout <current_branch>
229
+ # $ git pull origin <current_branch>
230
+ # $ git merge <base_branch>
231
+ # @param remote [String] the name of the remote repository to fetch updates from (origin by default)
232
+ # @param base [String] the branch that you want to fetch updates from (master by default)
233
+ command(:refresh, defaults: {remote: 'origin', base: 'master'}) do |**params|
234
+ GitReflow.update_feature_branch(params)
235
+ end
236
+ end
237
+ end
238
+ end
@@ -1,10 +1,10 @@
1
- class FlatMerge < GitReflow::Workflows::Core
2
- def self.deliver(**params)
3
- base_branch = params[:base] || 'master'
4
- params[:squash] = false
5
-
6
- super(**params)
7
- end
8
- end
9
-
10
- FlatMerge
1
+ class FlatMerge < GitReflow::Workflows::Core
2
+ def self.deliver(**params)
3
+ base_branch = params[:base] || 'master'
4
+ params[:squash] = false
5
+
6
+ super(**params)
7
+ end
8
+ end
9
+
10
+ FlatMerge
data/lib/git_reflow.rb CHANGED
@@ -20,18 +20,29 @@ require 'git_reflow/git_helpers'
20
20
  require 'git_reflow/git_server'
21
21
  require 'git_reflow/git_server/bit_bucket'
22
22
  require 'git_reflow/git_server/git_hub'
23
+ require 'git_reflow/logger'
23
24
  require 'git_reflow/merge_error'
24
25
  require 'git_reflow/os_detector'
25
26
  require 'git_reflow/sandbox'
26
27
  require 'git_reflow/workflow'
27
28
  require 'git_reflow/workflows/core'
28
29
 
30
+ # This is a work around to silence logger spam from hashie
31
+ # https://github.com/intridea/hashie/issues/394
32
+ require "hashie"
33
+ require "hashie/logger"
34
+ Hashie.logger = Logger.new(nil)
35
+
29
36
  module GitReflow
30
37
  include Sandbox
31
38
  include GitHelpers
32
39
 
33
40
  extend self
34
41
 
42
+ def logger(*args)
43
+ @logger ||= GitReflow::Logger.new(*args)
44
+ end
45
+
35
46
  def workflow
36
47
  Workflow.current
37
48
  end
@@ -0,0 +1,7 @@
1
+ class AwesomeWorkflow < GitReflow::Workflows::Core
2
+ def self.start(**args)
3
+ GitReflow.say "Awesome."
4
+ end
5
+ end
6
+
7
+ AwesomeWorkflow
@@ -0,0 +1,7 @@
1
+ [user]
2
+ name = Reenhanced
3
+ email = dev@reenhanced.com
4
+ [github]
5
+ user = reenhanced
6
+ token = 123456
7
+ oauth-token = 123456
@@ -0,0 +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
+ }
@@ -0,0 +1,29 @@
1
+ [
2
+ {
3
+ "id": 1,
4
+ "url": "https://api.github.com/repos/reenhanced/repo/issues/comments/1",
5
+ "html_url": "https://github.com/reenhanced/repo/issues/1#issuecomment-1",
6
+ "body": "Me too",
7
+ "user": {
8
+ "login": "reenhanced",
9
+ "id": 1,
10
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
11
+ "gravatar_id": "somehexcode",
12
+ "url": "https://api.github.com/users/reenhanced",
13
+ "html_url": "https://github.com/reenhanced",
14
+ "followers_url": "https://api.github.com/users/reenhanced/followers",
15
+ "following_url": "https://api.github.com/users/reenhanced/following{/other_user}",
16
+ "gists_url": "https://api.github.com/users/reenhanced/gists{/gist_id}",
17
+ "starred_url": "https://api.github.com/users/reenhanced/starred{/owner}{/repo}",
18
+ "subscriptions_url": "https://api.github.com/users/reenhanced/subscriptions",
19
+ "organizations_url": "https://api.github.com/users/reenhanced/orgs",
20
+ "repos_url": "https://api.github.com/users/reenhanced/repos",
21
+ "events_url": "https://api.github.com/users/reenhanced/events{/privacy}",
22
+ "received_events_url": "https://api.github.com/users/reenhanced/received_events",
23
+ "type": "User",
24
+ "site_admin": false
25
+ },
26
+ "created_at": "2011-04-14T16:00:49Z",
27
+ "updated_at": "2011-04-14T16:00:49Z"
28
+ }
29
+ ]
@@ -0,0 +1,15 @@
1
+ [
2
+ <% comment_json = [] %>
3
+ <% comments.each_with_index do |comment, index| %>
4
+ <% comment_json << Fixture.new('issues/comment.json.erb',
5
+ id: comment[:id] || index + 1,
6
+ author: comment[:author],
7
+ pull_request_number: pull_request_number,
8
+ repo_owner: repo_owner,
9
+ repo_name: repo_name,
10
+ body: comment[:body] || 'Hmmm...',
11
+ created_at: comment[:created_at] || '2011-04-14T16:00:49Z'
12
+ ).to_s %>
13
+ <% end %>
14
+ <%= comment_json.join(", ") %>
15
+ ]