git_reflow 0.8.9 → 0.9.3

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 (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