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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +348 -348
- data/Gemfile.lock +13 -15
- data/LICENSE +20 -20
- data/README.rdoc +461 -461
- data/Rakefile +8 -8
- data/bin/console +7 -7
- data/bin/setup +6 -6
- data/circle.yml +5 -5
- data/exe/git-reflow +36 -36
- data/git_reflow.gemspec +1 -1
- data/lib/git_reflow/commands/deliver.rb +10 -10
- data/lib/git_reflow/commands/refresh.rb +20 -20
- data/lib/git_reflow/commands/review.rb +13 -13
- data/lib/git_reflow/commands/setup.rb +11 -11
- data/lib/git_reflow/commands/stage.rb +9 -9
- data/lib/git_reflow/commands/start.rb +22 -22
- data/lib/git_reflow/commands/status.rb +7 -7
- data/lib/git_reflow/config.rb +9 -9
- data/lib/git_reflow/git_server/base.rb +68 -68
- data/lib/git_reflow/git_server/bit_bucket/pull_request.rb +84 -84
- data/lib/git_reflow/git_server/bit_bucket.rb +101 -101
- data/lib/git_reflow/git_server/git_hub/pull_request.rb +4 -1
- data/lib/git_reflow/git_server/pull_request.rb +11 -2
- data/lib/git_reflow/git_server.rb +63 -63
- data/lib/git_reflow/logger.rb +49 -0
- data/lib/git_reflow/merge_error.rb +9 -9
- data/lib/git_reflow/os_detector.rb +23 -23
- data/lib/git_reflow/rspec/command_line_helpers.rb +12 -8
- data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
- data/lib/git_reflow/rspec.rb +2 -2
- data/lib/git_reflow/sandbox.rb +11 -6
- data/lib/git_reflow/version.rb +1 -1
- data/lib/git_reflow/workflow.rb +59 -59
- data/lib/git_reflow/workflows/core.rb +238 -238
- data/lib/git_reflow/workflows/flat_merge.rb +10 -10
- data/lib/git_reflow.rb +11 -0
- data/spec/fixtures/awesome_workflow.rb +7 -0
- data/spec/fixtures/git/git_config +7 -0
- data/spec/fixtures/issues/comment.json.erb +27 -0
- data/spec/fixtures/issues/comments.json +29 -0
- data/spec/fixtures/issues/comments.json.erb +15 -0
- data/spec/fixtures/pull_requests/comment.json.erb +45 -0
- data/spec/fixtures/pull_requests/comments.json +47 -0
- data/spec/fixtures/pull_requests/comments.json.erb +15 -0
- data/spec/fixtures/pull_requests/commits.json +29 -0
- data/spec/fixtures/pull_requests/external_pull_request.json +145 -0
- data/spec/fixtures/pull_requests/pull_request.json +142 -0
- data/spec/fixtures/pull_requests/pull_request.json.erb +142 -0
- data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -0
- data/spec/fixtures/pull_requests/pull_requests.json +136 -0
- data/spec/fixtures/repositories/commit.json +53 -0
- data/spec/fixtures/repositories/commit.json.erb +53 -0
- data/spec/fixtures/repositories/commits.json.erb +13 -0
- data/spec/fixtures/repositories/statuses.json +31 -0
- data/spec/fixtures/workflow_with_super.rb +8 -0
- data/spec/lib/git_reflow/config_spec.rb +74 -0
- data/spec/lib/git_reflow/git_helpers_spec.rb +182 -0
- data/spec/lib/git_reflow/git_server/bit_bucket_spec.rb +81 -0
- data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +587 -0
- data/spec/lib/git_reflow/git_server/git_hub_spec.rb +221 -0
- data/spec/lib/git_reflow/git_server/pull_request_spec.rb +524 -0
- data/spec/lib/git_reflow/git_server_spec.rb +101 -0
- data/spec/lib/git_reflow/logger_spec.rb +18 -0
- data/spec/lib/git_reflow/sandbox_spec.rb +15 -0
- data/spec/lib/git_reflow/workflow_spec.rb +59 -0
- data/spec/lib/git_reflow/workflows/core_spec.rb +665 -0
- data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +59 -0
- data/spec/lib/git_reflow_spec.rb +75 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/fake_github.rb +128 -0
- data/spec/support/fixtures.rb +54 -0
- data/spec/support/github_helpers.rb +109 -0
- data/spec/support/mock_pull_request.rb +17 -0
- data/spec/support/web_mocks.rb +39 -0
- metadata +83 -6
@@ -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
|
@@ -1,101 +1,101 @@
|
|
1
|
-
require 'bitbucket_rest_api'
|
2
|
-
require 'git_reflow/git_helpers'
|
3
|
-
|
4
|
-
module GitReflow
|
5
|
-
module GitServer
|
6
|
-
class BitBucket < Base
|
7
|
-
require_relative 'bit_bucket/pull_request'
|
8
|
-
|
9
|
-
attr_accessor :connection
|
10
|
-
|
11
|
-
def initialize(config_options = {})
|
12
|
-
project_only = !!config_options.delete(:project_only)
|
13
|
-
|
14
|
-
# We remove any existing setup first, then setup our required config settings
|
15
|
-
GitReflow::Config.unset('reflow.local-projects', value: "#{self.class.remote_user}/#{self.class.remote_repo_name}")
|
16
|
-
GitReflow::Config.add('reflow.local-projects', "#{self.class.remote_user}/#{self.class.remote_repo_name}") if project_only
|
17
|
-
GitReflow::Config.set('reflow.git-server', 'BitBucket', local: project_only)
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.connection
|
21
|
-
if api_key_setup?
|
22
|
-
@connection ||= ::BitBucket.new login: remote_user, password: api_key
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.api_endpoint
|
27
|
-
endpoint = GitReflow::Config.get("bitbucket.endpoint", local: project_only?)
|
28
|
-
(endpoint.length > 0) ? endpoint : ::BitBucket::Configuration::DEFAULT_ENDPOINT
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.site_url
|
32
|
-
site_url = GitReflow::Config.get("bitbucket.site", local: project_only?)
|
33
|
-
(site_url.length > 0) ? site_url : 'https://bitbucket.org'
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.api_key
|
37
|
-
GitReflow::Config.get("bitbucket.api-key", reload: true, local: project_only?)
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.api_key=(key)
|
41
|
-
GitReflow::Config.set("bitbucket.api-key", key, local: project_only?)
|
42
|
-
end
|
43
|
-
def self.api_key_setup?
|
44
|
-
(self.api_key.length > 0)
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.user
|
48
|
-
GitReflow::Config.get('bitbucket.user', local: project_only?)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.user=(bitbucket_user)
|
52
|
-
GitReflow::Config.set('bitbucket.user', bitbucket_user, local: project_only?)
|
53
|
-
end
|
54
|
-
|
55
|
-
def authenticate(options = {silent: false})
|
56
|
-
begin
|
57
|
-
if connection and self.class.api_key_setup?
|
58
|
-
unless options[:silent]
|
59
|
-
GitReflow.say "\nYour BitBucket account was already setup with:"
|
60
|
-
GitReflow.say "\tUser Name: #{self.class.user}"
|
61
|
-
end
|
62
|
-
else
|
63
|
-
self.class.user = options[:user] || ask("Please enter your BitBucket username: ")
|
64
|
-
GitReflow.say "\nIn order to connect your BitBucket account,"
|
65
|
-
GitReflow.say "you'll need to generate an API key for your team"
|
66
|
-
GitReflow.say "Visit #{self.class.site_url}/account/user/#{self.class.remote_user}/api-key/, to generate it\n"
|
67
|
-
self.class.api_key = ask("Please enter your team's API key: ")
|
68
|
-
connection.repos.all(self.class.remote_user).count
|
69
|
-
GitReflow.say "Connected to BitBucket\!", :success
|
70
|
-
end
|
71
|
-
rescue ::BitBucket::Error::Unauthorized => e
|
72
|
-
GitReflow::Config.unset('bitbucket.api-key', local: self.class.project_only?)
|
73
|
-
GitReflow.say "Invalid API key for team #{self.class.remote_user}.", :error
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def connection
|
78
|
-
@connection ||= self.class.connection
|
79
|
-
end
|
80
|
-
|
81
|
-
def get_build_status(sha)
|
82
|
-
# BitBucket does not currently support build status via API
|
83
|
-
# for updates: https://bitbucket.org/site/master/issue/8548/better-ci-integration-add-a-build-status
|
84
|
-
return nil
|
85
|
-
end
|
86
|
-
|
87
|
-
def colorized_build_description(state, description)
|
88
|
-
""
|
89
|
-
end
|
90
|
-
|
91
|
-
def create_pull_request(options = {})
|
92
|
-
PullRequest.create(options)
|
93
|
-
end
|
94
|
-
|
95
|
-
def find_open_pull_request(options = {})
|
96
|
-
PullRequest.find_open(options)
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
1
|
+
require 'bitbucket_rest_api'
|
2
|
+
require 'git_reflow/git_helpers'
|
3
|
+
|
4
|
+
module GitReflow
|
5
|
+
module GitServer
|
6
|
+
class BitBucket < Base
|
7
|
+
require_relative 'bit_bucket/pull_request'
|
8
|
+
|
9
|
+
attr_accessor :connection
|
10
|
+
|
11
|
+
def initialize(config_options = {})
|
12
|
+
project_only = !!config_options.delete(:project_only)
|
13
|
+
|
14
|
+
# We remove any existing setup first, then setup our required config settings
|
15
|
+
GitReflow::Config.unset('reflow.local-projects', value: "#{self.class.remote_user}/#{self.class.remote_repo_name}")
|
16
|
+
GitReflow::Config.add('reflow.local-projects', "#{self.class.remote_user}/#{self.class.remote_repo_name}") if project_only
|
17
|
+
GitReflow::Config.set('reflow.git-server', 'BitBucket', local: project_only)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.connection
|
21
|
+
if api_key_setup?
|
22
|
+
@connection ||= ::BitBucket.new login: remote_user, password: api_key
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.api_endpoint
|
27
|
+
endpoint = GitReflow::Config.get("bitbucket.endpoint", local: project_only?)
|
28
|
+
(endpoint.length > 0) ? endpoint : ::BitBucket::Configuration::DEFAULT_ENDPOINT
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.site_url
|
32
|
+
site_url = GitReflow::Config.get("bitbucket.site", local: project_only?)
|
33
|
+
(site_url.length > 0) ? site_url : 'https://bitbucket.org'
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.api_key
|
37
|
+
GitReflow::Config.get("bitbucket.api-key", reload: true, local: project_only?)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.api_key=(key)
|
41
|
+
GitReflow::Config.set("bitbucket.api-key", key, local: project_only?)
|
42
|
+
end
|
43
|
+
def self.api_key_setup?
|
44
|
+
(self.api_key.length > 0)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.user
|
48
|
+
GitReflow::Config.get('bitbucket.user', local: project_only?)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.user=(bitbucket_user)
|
52
|
+
GitReflow::Config.set('bitbucket.user', bitbucket_user, local: project_only?)
|
53
|
+
end
|
54
|
+
|
55
|
+
def authenticate(options = {silent: false})
|
56
|
+
begin
|
57
|
+
if connection and self.class.api_key_setup?
|
58
|
+
unless options[:silent]
|
59
|
+
GitReflow.say "\nYour BitBucket account was already setup with:"
|
60
|
+
GitReflow.say "\tUser Name: #{self.class.user}"
|
61
|
+
end
|
62
|
+
else
|
63
|
+
self.class.user = options[:user] || ask("Please enter your BitBucket username: ")
|
64
|
+
GitReflow.say "\nIn order to connect your BitBucket account,"
|
65
|
+
GitReflow.say "you'll need to generate an API key for your team"
|
66
|
+
GitReflow.say "Visit #{self.class.site_url}/account/user/#{self.class.remote_user}/api-key/, to generate it\n"
|
67
|
+
self.class.api_key = ask("Please enter your team's API key: ")
|
68
|
+
connection.repos.all(self.class.remote_user).count
|
69
|
+
GitReflow.say "Connected to BitBucket\!", :success
|
70
|
+
end
|
71
|
+
rescue ::BitBucket::Error::Unauthorized => e
|
72
|
+
GitReflow::Config.unset('bitbucket.api-key', local: self.class.project_only?)
|
73
|
+
GitReflow.say "Invalid API key for team #{self.class.remote_user}.", :error
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def connection
|
78
|
+
@connection ||= self.class.connection
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_build_status(sha)
|
82
|
+
# BitBucket does not currently support build status via API
|
83
|
+
# for updates: https://bitbucket.org/site/master/issue/8548/better-ci-integration-add-a-build-status
|
84
|
+
return nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def colorized_build_description(state, description)
|
88
|
+
""
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_pull_request(options = {})
|
92
|
+
PullRequest.create(options)
|
93
|
+
end
|
94
|
+
|
95
|
+
def find_open_pull_request(options = {})
|
96
|
+
PullRequest.find_open(options)
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -118,6 +118,9 @@ module GitReflow
|
|
118
118
|
|
119
119
|
options[:body] = "#{options[:message]}\n" if options[:body].nil? and "#{options[:message]}".length > 0
|
120
120
|
|
121
|
+
merge_method = options[:merge_method] || GitReflow::Config.get("reflow.merge-method")
|
122
|
+
merge_method = "squash" if "#{merge_method}".length < 1
|
123
|
+
|
121
124
|
merge_response = GitReflow::GitServer::GitHub.connection.pull_requests.merge(
|
122
125
|
"#{GitReflow.git_server.class.remote_user}",
|
123
126
|
"#{GitReflow.git_server.class.remote_repo_name}",
|
@@ -126,7 +129,7 @@ module GitReflow
|
|
126
129
|
"commit_title" => "#{options[:title]}",
|
127
130
|
"commit_message" => "#{options[:body]}",
|
128
131
|
"sha" => "#{self.head.sha}",
|
129
|
-
"
|
132
|
+
"merge_method" => merge_method
|
130
133
|
}
|
131
134
|
)
|
132
135
|
|
@@ -196,11 +196,20 @@ module GitReflow
|
|
196
196
|
GitReflow.update_current_branch
|
197
197
|
GitReflow.fetch_destination(self.base_branch_name)
|
198
198
|
|
199
|
-
message
|
199
|
+
message = commit_message_for_merge
|
200
|
+
merge_method = options[:merge_method] || GitReflow::Config.get("reflow.merge-method")
|
201
|
+
merge_method = "squash" if "#{merge_method}".length < 1
|
202
|
+
|
200
203
|
|
201
204
|
GitReflow.run_command_with_label "git checkout #{self.base_branch_name}"
|
202
205
|
GitReflow.run_command_with_label "git pull origin #{self.base_branch_name}"
|
203
|
-
|
206
|
+
|
207
|
+
case merge_method
|
208
|
+
when /squash/i
|
209
|
+
GitReflow.run_command_with_label "git merge --squash #{self.feature_branch_name}"
|
210
|
+
else
|
211
|
+
GitReflow.run_command_with_label "git merge #{self.feature_branch_name}"
|
212
|
+
end
|
204
213
|
|
205
214
|
GitReflow.append_to_squashed_commit_message(message) if message.length > 0
|
206
215
|
|
@@ -1,63 +1,63 @@
|
|
1
|
-
module GitReflow
|
2
|
-
module GitServer
|
3
|
-
autoload :Base, 'git_reflow/git_server/base'
|
4
|
-
autoload :GitHub, 'git_reflow/git_server/git_hub'
|
5
|
-
autoload :PullRequest, 'git_reflow/git_server/pull_request'
|
6
|
-
|
7
|
-
extend self
|
8
|
-
|
9
|
-
class ConnectionError < StandardError; end
|
10
|
-
|
11
|
-
def connect(options = {})
|
12
|
-
options ||= {}
|
13
|
-
options[:provider] = 'GitHub' if "#{options[:provider]}".length <= 0
|
14
|
-
begin
|
15
|
-
provider_name = options[:provider]
|
16
|
-
provider = provider_class_for(options.delete(:provider)).new(options)
|
17
|
-
provider.authenticate(options.keep_if {|key, value| key == :silent })
|
18
|
-
provider
|
19
|
-
rescue ConnectionError => e
|
20
|
-
GitReflow.say "Error connecting to #{provider_name}: #{e.message}", :error
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def connection
|
25
|
-
return nil unless current_provider
|
26
|
-
current_provider.connection
|
27
|
-
end
|
28
|
-
|
29
|
-
def current_provider
|
30
|
-
provider = "#{GitReflow::Config.get('reflow.git-server', local: true) || GitReflow::Config.get('reflow.git-server')}"
|
31
|
-
if provider.length > 0
|
32
|
-
begin
|
33
|
-
provider_class_for(provider)
|
34
|
-
rescue ConnectionError => e
|
35
|
-
GitReflow.say e.message, :error
|
36
|
-
nil
|
37
|
-
end
|
38
|
-
else
|
39
|
-
GitReflow.say "Reflow hasn't been setup yet. Run 'git reflow setup' to continue", :notice
|
40
|
-
nil
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def can_connect_to?(provider)
|
45
|
-
GitReflow::GitServer.const_defined?(provider)
|
46
|
-
end
|
47
|
-
|
48
|
-
def create_pull_request(options = {})
|
49
|
-
raise "#{self.class.to_s}#create_pull_request method must be implemented"
|
50
|
-
end
|
51
|
-
|
52
|
-
def find_open_pull_request(options = {})
|
53
|
-
raise "#{self.class.to_s}#find_open_pull_request method must be implemented"
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def provider_class_for(provider)
|
59
|
-
raise ConnectionError, "GitServer not setup for \"#{provider}\"" unless self.can_connect_to?(provider)
|
60
|
-
GitReflow::GitServer.const_get(provider)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
1
|
+
module GitReflow
|
2
|
+
module GitServer
|
3
|
+
autoload :Base, 'git_reflow/git_server/base'
|
4
|
+
autoload :GitHub, 'git_reflow/git_server/git_hub'
|
5
|
+
autoload :PullRequest, 'git_reflow/git_server/pull_request'
|
6
|
+
|
7
|
+
extend self
|
8
|
+
|
9
|
+
class ConnectionError < StandardError; end
|
10
|
+
|
11
|
+
def connect(options = {})
|
12
|
+
options ||= {}
|
13
|
+
options[:provider] = 'GitHub' if "#{options[:provider]}".length <= 0
|
14
|
+
begin
|
15
|
+
provider_name = options[:provider]
|
16
|
+
provider = provider_class_for(options.delete(:provider)).new(options)
|
17
|
+
provider.authenticate(options.keep_if {|key, value| key == :silent })
|
18
|
+
provider
|
19
|
+
rescue ConnectionError => e
|
20
|
+
GitReflow.say "Error connecting to #{provider_name}: #{e.message}", :error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def connection
|
25
|
+
return nil unless current_provider
|
26
|
+
current_provider.connection
|
27
|
+
end
|
28
|
+
|
29
|
+
def current_provider
|
30
|
+
provider = "#{GitReflow::Config.get('reflow.git-server', local: true) || GitReflow::Config.get('reflow.git-server')}"
|
31
|
+
if provider.length > 0
|
32
|
+
begin
|
33
|
+
provider_class_for(provider)
|
34
|
+
rescue ConnectionError => e
|
35
|
+
GitReflow.say e.message, :error
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
else
|
39
|
+
GitReflow.say "Reflow hasn't been setup yet. Run 'git reflow setup' to continue", :notice
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def can_connect_to?(provider)
|
45
|
+
GitReflow::GitServer.const_defined?(provider)
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_pull_request(options = {})
|
49
|
+
raise "#{self.class.to_s}#create_pull_request method must be implemented"
|
50
|
+
end
|
51
|
+
|
52
|
+
def find_open_pull_request(options = {})
|
53
|
+
raise "#{self.class.to_s}#find_open_pull_request method must be implemented"
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def provider_class_for(provider)
|
59
|
+
raise ConnectionError, "GitServer not setup for \"#{provider}\"" unless self.can_connect_to?(provider)
|
60
|
+
GitReflow::GitServer.const_get(provider)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'git_reflow/config'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module GitReflow
|
5
|
+
class Logger < ::Logger
|
6
|
+
DEFAULT_LOG_FILE = "/tmp/git-reflow.log"
|
7
|
+
COLORS = {
|
8
|
+
"FATAL" => :red,
|
9
|
+
"ERROR" => :red,
|
10
|
+
"WARN" => :orange,
|
11
|
+
"INFO" => :yellow,
|
12
|
+
"DEBUG" => :white,
|
13
|
+
}
|
14
|
+
|
15
|
+
def initialize(*args)
|
16
|
+
log_file = args.shift || log_file_path
|
17
|
+
args.unshift(log_file)
|
18
|
+
super(*args)
|
19
|
+
@formatter = SimpleFormatter.new
|
20
|
+
end
|
21
|
+
|
22
|
+
# Simple formatter which only displays the message.
|
23
|
+
class SimpleFormatter < ::Logger::Formatter
|
24
|
+
# This method is invoked when a log event occurs
|
25
|
+
def call(severity, timestamp, progname, msg)
|
26
|
+
if $stdout.tty?
|
27
|
+
"#{severity.colorize(COLORS[severity])}: #{String === msg ? msg : msg.inspect}\n"
|
28
|
+
else
|
29
|
+
"#{severity}: #{String === msg ? msg : msg.inspect}\n"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def log_file_path
|
37
|
+
return @log_file_path if "#{@log_file_path}".length > 0
|
38
|
+
|
39
|
+
configured_log_file_path = GitReflow::Config.get('reflow.log_file_path')
|
40
|
+
|
41
|
+
if configured_log_file_path.length > 0
|
42
|
+
@log_file_path = configured_log_file_path
|
43
|
+
else
|
44
|
+
@log_file_path = DEFAULT_LOG_FILE
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -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,23 +1,23 @@
|
|
1
|
-
# Thanks to http://stackoverflow.com/questions/170956/how-can-i-find-which-operating-system-my-ruby-program-is-running-on
|
2
|
-
# and to Thoughtbot: https://github.com/thoughtbot/cocaine/blob/master/lib/cocaine/os_detector.rb
|
3
|
-
module GitReflow
|
4
|
-
class OSDetector
|
5
|
-
def windows?
|
6
|
-
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
7
|
-
end
|
8
|
-
|
9
|
-
def mac?
|
10
|
-
(/darwin/ =~ RUBY_PLATFORM) != nil
|
11
|
-
end
|
12
|
-
|
13
|
-
def unix?
|
14
|
-
!OS.windows?
|
15
|
-
end
|
16
|
-
|
17
|
-
def linux?
|
18
|
-
OS.unix? and not OS.mac?
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
OS = OSDetector.new
|
23
|
-
end
|
1
|
+
# Thanks to http://stackoverflow.com/questions/170956/how-can-i-find-which-operating-system-my-ruby-program-is-running-on
|
2
|
+
# and to Thoughtbot: https://github.com/thoughtbot/cocaine/blob/master/lib/cocaine/os_detector.rb
|
3
|
+
module GitReflow
|
4
|
+
class OSDetector
|
5
|
+
def windows?
|
6
|
+
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def mac?
|
10
|
+
(/darwin/ =~ RUBY_PLATFORM) != nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def unix?
|
14
|
+
!OS.windows?
|
15
|
+
end
|
16
|
+
|
17
|
+
def linux?
|
18
|
+
OS.unix? and not OS.mac?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
OS = OSDetector.new
|
23
|
+
end
|