git_reflow 0.8.9 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/multi-ruby-tests.yml +33 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +2 -0
  5. data/.ruby-version +1 -0
  6. data/Appraisals +1 -6
  7. data/CHANGELOG.md +466 -348
  8. data/Gemfile.lock +99 -72
  9. data/LICENSE +20 -20
  10. data/README.md +481 -0
  11. data/Rakefile +15 -8
  12. data/Workflow +3 -0
  13. data/_config.yml +1 -0
  14. data/bin/console +7 -7
  15. data/bin/setup +6 -6
  16. data/exe/git-reflow +20 -36
  17. data/git_reflow.gemspec +26 -30
  18. data/lib/git_reflow.rb +3 -15
  19. data/lib/git_reflow/config.rb +48 -13
  20. data/lib/git_reflow/git_helpers.rb +69 -22
  21. data/lib/git_reflow/git_server.rb +63 -63
  22. data/lib/git_reflow/git_server/base.rb +68 -68
  23. data/lib/git_reflow/git_server/bit_bucket.rb +101 -101
  24. data/lib/git_reflow/git_server/bit_bucket/pull_request.rb +84 -84
  25. data/lib/git_reflow/git_server/git_hub.rb +53 -41
  26. data/lib/git_reflow/git_server/git_hub/pull_request.rb +16 -14
  27. data/lib/git_reflow/git_server/pull_request.rb +4 -2
  28. data/lib/git_reflow/merge_error.rb +9 -9
  29. data/lib/git_reflow/rspec.rb +3 -2
  30. data/lib/git_reflow/rspec/command_line_helpers.rb +23 -6
  31. data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
  32. data/lib/git_reflow/rspec/workflow_helpers.rb +18 -0
  33. data/lib/git_reflow/sandbox.rb +16 -6
  34. data/lib/git_reflow/version.rb +1 -1
  35. data/lib/git_reflow/workflow.rb +304 -9
  36. data/lib/git_reflow/workflows/FlatMergeWorkflow +38 -0
  37. data/lib/git_reflow/workflows/core.rb +364 -238
  38. data/spec/fixtures/authentication_failure.json +3 -0
  39. data/spec/fixtures/awesome_workflow.rb +3 -7
  40. data/spec/fixtures/git/git_config +7 -7
  41. data/spec/fixtures/issues/comment.json.erb +27 -27
  42. data/spec/fixtures/issues/comments.json +29 -29
  43. data/spec/fixtures/issues/comments.json.erb +15 -15
  44. data/spec/fixtures/pull_requests/comment.json.erb +45 -45
  45. data/spec/fixtures/pull_requests/comments.json +47 -47
  46. data/spec/fixtures/pull_requests/comments.json.erb +15 -15
  47. data/spec/fixtures/pull_requests/commits.json +29 -29
  48. data/spec/fixtures/pull_requests/external_pull_request.json +145 -145
  49. data/spec/fixtures/pull_requests/pull_request.json +142 -142
  50. data/spec/fixtures/pull_requests/pull_request.json.erb +142 -142
  51. data/spec/fixtures/pull_requests/pull_request_branch_nonexistent_error.json +32 -0
  52. data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -32
  53. data/spec/fixtures/pull_requests/pull_requests.json +136 -136
  54. data/spec/fixtures/repositories/commit.json +53 -53
  55. data/spec/fixtures/repositories/commit.json.erb +53 -53
  56. data/spec/fixtures/repositories/commits.json.erb +13 -13
  57. data/spec/fixtures/repositories/statuses.json +31 -31
  58. data/spec/fixtures/users/user.json +32 -0
  59. data/spec/lib/git_reflow/git_helpers_spec.rb +115 -12
  60. data/spec/lib/git_reflow/git_server/bit_bucket_spec.rb +81 -81
  61. data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +10 -10
  62. data/spec/lib/git_reflow/git_server/git_hub_spec.rb +77 -3
  63. data/spec/lib/git_reflow/git_server/pull_request_spec.rb +9 -3
  64. data/spec/lib/git_reflow/git_server_spec.rb +101 -101
  65. data/spec/lib/git_reflow/sandbox_spec.rb +1 -1
  66. data/spec/lib/git_reflow/workflow_spec.rb +304 -59
  67. data/spec/lib/git_reflow/workflows/core_spec.rb +225 -67
  68. data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +71 -59
  69. data/spec/lib/git_reflow_spec.rb +2 -25
  70. data/spec/spec_helper.rb +3 -0
  71. data/spec/support/fixtures.rb +54 -54
  72. data/spec/support/github_helpers.rb +99 -109
  73. data/spec/support/mock_pull_request.rb +17 -17
  74. data/spec/support/web_mocks.rb +39 -39
  75. metadata +51 -74
  76. data/README.rdoc +0 -461
  77. data/circle.yml +0 -26
  78. data/lib/git_reflow/commands/deliver.rb +0 -10
  79. data/lib/git_reflow/commands/refresh.rb +0 -20
  80. data/lib/git_reflow/commands/review.rb +0 -13
  81. data/lib/git_reflow/commands/setup.rb +0 -11
  82. data/lib/git_reflow/commands/stage.rb +0 -9
  83. data/lib/git_reflow/commands/start.rb +0 -18
  84. data/lib/git_reflow/commands/status.rb +0 -7
  85. data/lib/git_reflow/os_detector.rb +0 -23
  86. data/lib/git_reflow/workflows/flat_merge.rb +0 -10
  87. data/spec/fixtures/workflow_with_super.rb +0 -8
@@ -1,84 +1,84 @@
1
- require 'git_reflow/git_server/pull_request'
2
-
3
- module GitReflow
4
- module GitServer
5
- class BitBucket
6
- class PullRequest < GitReflow::GitServer::PullRequest
7
- def initialize(attributes)
8
- self.number = attributes.id
9
- self.description = attributes.body || attributes.description
10
- self.html_url = "#{attributes.source.repository.links.html.href}/pull-request/#{self.number}"
11
- self.feature_branch_name = attributes.source.branch.name[/[^:]+$/]
12
- self.base_branch_name = attributes.destination.branch.name[/[^:]+$/]
13
- self.build = Build.new
14
- self.source_object = attributes
15
- end
16
-
17
- def self.create(options = {})
18
- self.new GitReflow.git_server.connection.repos.pull_requests.create(
19
- GitReflow.git_server.class.remote_user,
20
- GitReflow.git_server.class.remote_repo_name,
21
- title: options[:title],
22
- description: options[:body] || options[:description],
23
- source: {
24
- branch: { name: GitReflow.git_server.class.current_branch },
25
- repository: { full_name: "#{GitReflow.git_server.class.remote_user}/#{GitReflow.git_server.class.remote_repo_name}" }
26
- },
27
- destination: {
28
- branch: { name: options[:base] }
29
- },
30
- reviewers: [username: GitReflow.git_server.class.user])
31
- end
32
-
33
- def self.find_open(to: 'master', from: GitReflow.git_server.class.current_branch)
34
- begin
35
- matching_pull = GitReflow.git_server.connection.repos.pull_requests.all(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, limit: 1).select do |pr|
36
- pr.source.branch.name == from and
37
- pr.destination.branch.name == to
38
- end.first
39
-
40
- if matching_pull
41
- self.new matching_pull
42
- end
43
- rescue ::BitBucket::Error::NotFound => e
44
- GitReflow.git_server.say "No BitBucket repo found for #{GitReflow.git_server.class.remote_user}/#{GitReflow.git_server.class.remote_repo_name}", :error
45
- rescue ::BitBucket::Error::Forbidden => e
46
- GitReflow.git_server.say "You don't have API access to this repo", :error
47
- end
48
- end
49
-
50
- def commit_author
51
- # use the author of the pull request
52
- self.author.username
53
- end
54
-
55
- def comments
56
- GitReflow.git_server.connection.repos.pull_requests.comments.all(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, self.id)
57
- end
58
-
59
- def last_comment
60
- last_comment = comments.first
61
- return "" unless last_comment
62
- "#{last_comment.content.raw}"
63
- end
64
-
65
- def reviewers
66
- return [] unless comments.size > 0
67
- comments.map {|c| c.user.username }.uniq - [GitReflow.git_server.class.user]
68
- end
69
-
70
- def approvals
71
- approved = []
72
-
73
- GitReflow.git_server.connection.repos.pull_requests.activity(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, self.id).each do |activity|
74
- break unless activity.respond_to?(:approval) and activity.approval.user.username != GitReflow.git_server.class.user
75
- approved |= [activity.approval.user.username]
76
- end
77
-
78
- approved
79
- end
80
-
81
- end
82
- end
83
- end
84
- end
1
+ require 'git_reflow/git_server/pull_request'
2
+
3
+ module GitReflow
4
+ module GitServer
5
+ class BitBucket
6
+ class PullRequest < GitReflow::GitServer::PullRequest
7
+ def initialize(attributes)
8
+ self.number = attributes.id
9
+ self.description = attributes.body || attributes.description
10
+ self.html_url = "#{attributes.source.repository.links.html.href}/pull-request/#{self.number}"
11
+ self.feature_branch_name = attributes.source.branch.name[/[^:]+$/]
12
+ self.base_branch_name = attributes.destination.branch.name[/[^:]+$/]
13
+ self.build = Build.new
14
+ self.source_object = attributes
15
+ end
16
+
17
+ def self.create(options = {})
18
+ self.new GitReflow.git_server.connection.repos.pull_requests.create(
19
+ GitReflow.git_server.class.remote_user,
20
+ GitReflow.git_server.class.remote_repo_name,
21
+ title: options[:title],
22
+ description: options[:body] || options[:description],
23
+ source: {
24
+ branch: { name: GitReflow.git_server.class.current_branch },
25
+ repository: { full_name: "#{GitReflow.git_server.class.remote_user}/#{GitReflow.git_server.class.remote_repo_name}" }
26
+ },
27
+ destination: {
28
+ branch: { name: options[:base] }
29
+ },
30
+ reviewers: [username: GitReflow.git_server.class.user])
31
+ end
32
+
33
+ def self.find_open(to: 'master', from: GitReflow.git_server.class.current_branch)
34
+ begin
35
+ matching_pull = GitReflow.git_server.connection.repos.pull_requests.all(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, limit: 1).select do |pr|
36
+ pr.source.branch.name == from and
37
+ pr.destination.branch.name == to
38
+ end.first
39
+
40
+ if matching_pull
41
+ self.new matching_pull
42
+ end
43
+ rescue ::BitBucket::Error::NotFound => e
44
+ GitReflow.git_server.say "No BitBucket repo found for #{GitReflow.git_server.class.remote_user}/#{GitReflow.git_server.class.remote_repo_name}", :error
45
+ rescue ::BitBucket::Error::Forbidden => e
46
+ GitReflow.git_server.say "You don't have API access to this repo", :error
47
+ end
48
+ end
49
+
50
+ def commit_author
51
+ # use the author of the pull request
52
+ self.author.username
53
+ end
54
+
55
+ def comments
56
+ GitReflow.git_server.connection.repos.pull_requests.comments.all(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, self.id)
57
+ end
58
+
59
+ def last_comment
60
+ last_comment = comments.first
61
+ return "" unless last_comment
62
+ "#{last_comment.content.raw}"
63
+ end
64
+
65
+ def reviewers
66
+ return [] unless comments.size > 0
67
+ comments.map {|c| c.user.username }.uniq - [GitReflow.git_server.class.user]
68
+ end
69
+
70
+ def approvals
71
+ approved = []
72
+
73
+ GitReflow.git_server.connection.repos.pull_requests.activity(GitReflow.git_server.class.remote_user, GitReflow.git_server.class.remote_repo_name, self.id).each do |activity|
74
+ break unless activity.respond_to?(:approval) and activity.approval.user.username != GitReflow.git_server.class.user
75
+ approved |= [activity.approval.user.username]
76
+ end
77
+
78
+ approved
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+ end
@@ -9,7 +9,7 @@ module GitReflow
9
9
  extend GitHelpers
10
10
  include Sandbox
11
11
 
12
- attr_accessor :connection
12
+ attr_reader :connection
13
13
 
14
14
  def initialize(config_options = {})
15
15
  project_only = !!config_options.delete(:project_only)
@@ -84,56 +84,68 @@ module GitReflow
84
84
  end
85
85
 
86
86
  def authenticate(options = {silent: false})
87
+ self.class.user = options[:user]
88
+ if self.class.user.empty?
89
+ self.class.user = ask("Please enter your GitHub username: ")
90
+ end
91
+
87
92
  if connection and self.class.oauth_token.length > 0
88
- unless options[:silent]
89
- GitReflow.say "Your GitHub account was already setup with: "
90
- GitReflow.say "\tUser Name: #{self.class.user}"
91
- GitReflow.say "\tEndpoint: #{self.class.api_endpoint}"
92
- end
93
- else
94
93
  begin
95
- gh_user = options[:user] || ask("Please enter your GitHub username: ")
96
- gh_password = options[:password] || ask("Please enter your GitHub password (we do NOT store this): ") { |q| q.echo = false }
97
-
98
- @connection = ::Github.new do |config|
99
- config.basic_auth = "#{gh_user}:#{gh_password}"
100
- config.endpoint = GitServer::GitHub.api_endpoint
101
- config.site = GitServer::GitHub.site_url
102
- config.adapter = :net_http
94
+ connection.users.get
95
+ unless options[:silent]
96
+ GitReflow.say "Your GitHub account was already setup with: "
97
+ GitReflow.say "\tUser Name: #{self.class.user}"
98
+ GitReflow.say "\tEndpoint: #{self.class.api_endpoint}"
103
99
  end
100
+ return connection
101
+ rescue ::Github::Error::Unauthorized => e
102
+ GitReflow.logger.debug "[GitHub Error] Current oauth-token is invalid or expired..."
103
+ end
104
+ end
104
105
 
105
- @connection.connection_options = {headers: {"X-GitHub-OTP" => options[:two_factor_auth_code]}} if options[:two_factor_auth_code]
106
+ begin
107
+ gh_password = options[:password] || ask("Please enter your GitHub password (we do NOT store this): ") { |q| q.echo = false }
106
108
 
107
- previous_authorizations = @connection.oauth.all.select {|auth| auth.note == "git-reflow (#{run('hostname', loud: false).strip})" }
108
- if previous_authorizations.any?
109
- authorization = previous_authorizations.last
110
- GitReflow.say "You have previously setup git-reflow on this machine, but we can no longer find the stored token.", :error
111
- GitReflow.say "Please visit https://github.com/settings/tokens and delete the token for: git-reflow (#{run('hostname', loud: false).strip})", :notice
112
- raise "Setup could not be completed."
113
- else
114
- authorization = @connection.oauth.create scopes: ['repo'], note: "git-reflow (#{run('hostname', loud: false).strip})"
115
- end
109
+ @connection = ::Github.new do |config|
110
+ config.basic_auth = "#{self.class.user}:#{gh_password}"
111
+ config.endpoint = GitServer::GitHub.api_endpoint
112
+ config.site = GitServer::GitHub.site_url
113
+ config.adapter = :net_http
114
+ end
116
115
 
117
- self.class.oauth_token = authorization.token
116
+ @connection.connection_options = {headers: {"X-GitHub-OTP" => options[:two_factor_auth_code]}} if options[:two_factor_auth_code]
118
117
 
119
- rescue ::Github::Error::Unauthorized => e
120
- if e.inspect.to_s.include?('two-factor')
121
- begin
122
- # dummy request to trigger a 2FA SMS since a HTTP GET won't do it
123
- @connection.oauth.create scopes: ['repo'], note: "thank Github for not making this straightforward"
124
- rescue ::Github::Error::Unauthorized
125
- ensure
126
- two_factor_code = ask("Please enter your two-factor authentication code: ")
127
- self.authenticate options.merge({user: gh_user, password: gh_password, two_factor_auth_code: two_factor_code})
128
- end
129
- else
130
- GitReflow.say "Github Authentication Error: #{e.inspect}", :error
118
+ previous_authorizations = @connection.oauth.all.select {|auth| auth.note == "git-reflow (#{run('hostname', loud: false).strip})" }
119
+ if previous_authorizations.any?
120
+ authorization = previous_authorizations.last
121
+ GitReflow.say "You have previously setup git-reflow on this machine, but we can no longer find the stored token.", :error
122
+ GitReflow.say "Please visit https://github.com/settings/tokens and delete the token for: git-reflow (#{run('hostname', loud: false).strip})", :notice
123
+ raise "Setup could not be completed."
124
+ else
125
+ authorization = @connection.oauth.create scopes: ['repo'], note: "git-reflow (#{run('hostname', loud: false).strip})"
126
+ end
127
+
128
+ self.class.oauth_token = authorization.token
129
+
130
+ rescue ::Github::Error::Unauthorized => e
131
+ if e.inspect.to_s.include?('two-factor')
132
+ begin
133
+ # dummy request to trigger a 2FA SMS since a HTTP GET won't do it
134
+ @connection.oauth.create scopes: ['repo'], note: "thank Github for not making this straightforward"
135
+ rescue ::Github::Error::Unauthorized
136
+ ensure
137
+ two_factor_code = ask("Please enter your two-factor authentication code: ")
138
+ self.authenticate options.merge({user: self.class.user, password: gh_password, two_factor_auth_code: two_factor_code})
131
139
  end
132
- rescue StandardError => e
133
- raise "We were unable to authenticate with Github."
134
140
  else
135
- GitReflow.say "Your GitHub account was successfully setup!", :success
141
+ GitReflow.say "Github Authentication Error: #{e.inspect}", :error
142
+ raise "Setup could not be completed."
136
143
  end
144
+ rescue StandardError => e
145
+ raise "We were unable to authenticate with Github."
146
+ else
147
+ GitReflow.say "Your GitHub account was successfully setup!", :success
148
+
137
149
  end
138
150
 
139
151
  @connection
@@ -38,7 +38,7 @@ module GitReflow
38
38
 
39
39
  def commit_author
40
40
  begin
41
- username, branch = base.label.split(':')
41
+ username, _ = base.label.split(':')
42
42
  first_commit = GitReflow.git_server.connection.pull_requests.commits(username, GitReflow.git_server.class.remote_repo_name, number.to_s).first
43
43
  "#{first_commit.commit.author.name} <#{first_commit.commit.author.email}>".strip
44
44
  rescue Github::Error::NotFound
@@ -47,7 +47,7 @@ module GitReflow
47
47
  end
48
48
 
49
49
  def reviewers
50
- (comment_authors + pull_request_reviews.map(&:user).map(&:login)).uniq
50
+ (comment_authors + pull_request_reviews.map(&:user).map(&:login)).uniq - [user.login]
51
51
  end
52
52
 
53
53
  def approvals
@@ -65,7 +65,7 @@ module GitReflow
65
65
  comments = GitReflow.git_server.connection.issues.comments.all GitReflow.remote_user, GitReflow.remote_repo_name, number: self.number
66
66
  review_comments = GitReflow.git_server.connection.pull_requests.comments.all GitReflow.remote_user, GitReflow.remote_repo_name, number: self.number
67
67
 
68
- review_comments.to_a + comments.to_a
68
+ (review_comments.to_a + comments.to_a).select { |c| c.user.login != user.login }
69
69
  end
70
70
 
71
71
  def last_comment
@@ -80,33 +80,38 @@ module GitReflow
80
80
  if self.class.minimum_approvals.to_i == 0
81
81
  super
82
82
  else
83
- approvals.size >= self.class.minimum_approvals.to_i and !last_comment.match(self.class.approval_regex).nil?
83
+ approvals.size >= self.class.minimum_approvals.to_i and (
84
+ last_comment.empty? ||
85
+ !last_comment.match(self.class.approval_regex).nil?
86
+ )
84
87
  end
85
88
  end
86
89
 
87
90
  def merge!(options = {})
88
91
 
89
92
  # fallback to default merge process if user "forces" merge
90
- if(options[:skip_lgtm])
93
+ if(options[:force])
91
94
  super options
92
95
  else
93
96
  if deliver?
94
97
  GitReflow.say "Merging pull request ##{self.number}: '#{self.title}', from '#{self.feature_branch_name}' into '#{self.base_branch_name}'", :notice
95
98
 
99
+ merge_method = options[:merge_method] || GitReflow::Config.get("reflow.merge-method")
100
+ merge_method = "squash" if "#{merge_method}".length < 1
101
+ merge_message_file = GitReflow.merge_message_path(merge_method: merge_method)
102
+
96
103
  unless options[:title] || options[:message]
97
104
  # prompts user for commit_title and commit_message
98
- squash_merge_message_file = "#{GitReflow.git_root_dir}/.git/SQUASH_MSG"
99
-
100
- File.open(squash_merge_message_file, 'w') do |file|
105
+ File.open(merge_message_file, 'w') do |file|
101
106
  file.write("#{self.title}\n#{self.commit_message_for_merge}\n")
102
107
  end
103
108
 
104
- GitReflow.run("#{GitReflow.git_editor_command} #{squash_merge_message_file}", with_system: true)
105
- merge_message = File.read(squash_merge_message_file).split(/[\r\n]|\r\n/).map(&:strip)
109
+ GitReflow.run("#{GitReflow.git_editor_command} #{merge_message_file}", with_system: true)
110
+ merge_message = File.read(merge_message_file).split(/[\r\n]|\r\n/).map(&:strip)
106
111
 
107
112
  title = merge_message.shift
108
113
 
109
- File.delete(squash_merge_message_file)
114
+ File.delete(merge_message_file)
110
115
 
111
116
  unless merge_message.empty?
112
117
  merge_message.shift if merge_message.first.empty?
@@ -124,9 +129,6 @@ module GitReflow
124
129
 
125
130
  options[:body] = "#{options[:message]}\n" if options[:body].nil? and "#{options[:message]}".length > 0
126
131
 
127
- merge_method = options[:merge_method] || GitReflow::Config.get("reflow.merge-method")
128
- merge_method = "squash" if "#{merge_method}".length < 1
129
-
130
132
  merge_response = GitReflow::GitServer::GitHub.connection.pull_requests.merge(
131
133
  "#{GitReflow.git_server.class.remote_user}",
132
134
  "#{GitReflow.git_server.class.remote_repo_name}",
@@ -158,6 +158,8 @@ module GitReflow
158
158
  end
159
159
 
160
160
  def commit_message_for_merge
161
+ return GitReflow.merge_commit_template unless GitReflow.merge_commit_template.nil?
162
+
161
163
  message = ""
162
164
 
163
165
  if "#{self.description}".length > 0
@@ -204,14 +206,14 @@ module GitReflow
204
206
  GitReflow.run_command_with_label "git checkout #{self.base_branch_name}"
205
207
  GitReflow.run_command_with_label "git pull origin #{self.base_branch_name}"
206
208
 
207
- case merge_method
209
+ case merge_method.to_s
208
210
  when /squash/i
209
211
  GitReflow.run_command_with_label "git merge --squash #{self.feature_branch_name}"
210
212
  else
211
213
  GitReflow.run_command_with_label "git merge #{self.feature_branch_name}"
212
214
  end
213
215
 
214
- GitReflow.append_to_squashed_commit_message(message) if message.length > 0
216
+ GitReflow.append_to_merge_commit_message(message) if message.length > 0
215
217
 
216
218
  if GitReflow.run_command_with_label 'git commit', with_system: true
217
219
  GitReflow.say "Pull request ##{self.number} successfully merged.", :success
@@ -1,9 +1,9 @@
1
- module GitReflow
2
- module GitServer
3
- class MergeError < StandardError
4
- def initialize(msg="Merge failed")
5
- super(msg)
6
- end
7
- end
8
- end
9
- end
1
+ module GitReflow
2
+ module GitServer
3
+ class MergeError < StandardError
4
+ def initialize(msg="Merge failed")
5
+ super(msg)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,2 +1,3 @@
1
- require_relative 'rspec/command_line_helpers'
2
- require_relative 'rspec/stub_helpers'
1
+ require_relative 'rspec/command_line_helpers'
2
+ require_relative 'rspec/stub_helpers'
3
+ require_relative 'rspec/workflow_helpers'
@@ -2,11 +2,12 @@ require "highline"
2
2
 
3
3
  module GitReflow
4
4
  module RSpec
5
+ # @nodoc
5
6
  module CommandLineHelpers
6
-
7
7
  def stub_command_line
8
8
  $commands_ran = []
9
9
  $stubbed_commands = {}
10
+ $stubbed_runners = Set.new
10
11
  $output = []
11
12
  $says = []
12
13
 
@@ -33,6 +34,7 @@ module GitReflow
33
34
  end
34
35
 
35
36
  def stub_run_for(module_to_stub)
37
+ $stubbed_runners << module_to_stub
36
38
  allow(module_to_stub).to receive(:run) do |command, options|
37
39
  options = { loud: true, blocking: true }.merge(options || {})
38
40
  $commands_ran << Hashie::Mash.new(command: command, options: options)
@@ -52,16 +54,31 @@ module GitReflow
52
54
  $says = []
53
55
  end
54
56
 
55
- def stub_command(command, return_value)
57
+ def stub_command(command:, return_value: "", options: {})
56
58
  $stubbed_commands[command] = return_value
57
- allow(GitReflow::Sandbox).to receive(:run).with(command).and_return(return_value)
59
+ $stubbed_runners.each do |runner|
60
+ allow(runner).to receive(:run).with(command, options) do |command, options|
61
+ options = { loud: true, blocking: true }.merge(options || {})
62
+ $commands_ran << Hashie::Mash.new(command: command, options: options)
63
+ $stubbed_commands[command] = return_value
64
+ raise GitReflow::Sandbox::CommandError.new(return_value, "\"#{command}\" failed to run.") if options[:raise]
65
+ end
66
+ end
67
+ end
68
+
69
+ def stub_command_line_inputs_for(module_to_stub, inputs)
70
+ allow(module_to_stub).to receive(:ask) do |terminal, question|
71
+ return_value = inputs[question]
72
+ question = ""
73
+ return_value
74
+ end
58
75
  end
59
76
 
60
77
  def stub_command_line_inputs(inputs)
61
78
  allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
62
- return_value = inputs[question]
63
- question = ""
64
- return_value
79
+ return_value = inputs[question]
80
+ question = ""
81
+ return_value
65
82
  end
66
83
  end
67
84