git_reflow 0.3.5 → 0.4.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6033d9ac0481348f75d715588d5ae35f451b53e8
4
+ data.tar.gz: 6865bb6dfdad09ada836eb0e5cb08a2f8bc7b29f
5
+ SHA512:
6
+ metadata.gz: 1054c1140b333a61c70030757b5a713b2d23a876c2912d6d18887c4d946e7e8b8e92f4277529bf8075ed9112e6b701ed79a2102fe51759d7a415229b5414d189
7
+ data.tar.gz: 9720ebbd2a3ee378cc830940de30170b58ed1fe970264f45807fad418f03413d40faf8099ff947bfd9bf7e2f77d436eaa0b6dc554c6d83cc4d0be58e331231bb
data/.gitignore CHANGED
@@ -1 +1,3 @@
1
1
  pkg/*
2
+ **/.DS_Store
3
+ .rspec
data/Gemfile.lock CHANGED
@@ -1,10 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- git_reflow (0.3.5)
4
+ git_reflow (0.4.0)
5
5
  colorize (= 0.6.0)
6
- github_api (= 0.10.2)
7
- gli (= 2.8.1)
6
+ github_api (= 0.12.1)
7
+ gli (= 2.12.2)
8
8
  highline
9
9
  httpclient
10
10
  json_pure
@@ -13,48 +13,78 @@ GEM
13
13
  remote: https://rubygems.org/
14
14
  specs:
15
15
  addressable (2.3.5)
16
+ byebug (3.5.1)
17
+ columnize (~> 0.8)
18
+ debugger-linecache (~> 1.2)
19
+ slop (~> 3.6)
20
+ coderay (1.1.0)
16
21
  colorize (0.6.0)
17
- faraday (0.8.8)
18
- multipart-post (~> 1.2.0)
19
- git (1.2.5)
20
- github_api (0.10.2)
21
- addressable
22
- faraday (~> 0.8.7)
23
- hashie (>= 1.2)
24
- multi_json (~> 1.4)
25
- nokogiri (~> 1.6.0)
22
+ columnize (0.8.9)
23
+ crack (0.4.2)
24
+ safe_yaml (~> 1.0.0)
25
+ debugger-linecache (1.2.0)
26
+ descendants_tracker (0.0.4)
27
+ thread_safe (~> 0.3, >= 0.3.1)
28
+ diff-lcs (1.2.5)
29
+ faraday (0.9.0)
30
+ multipart-post (>= 1.2, < 3)
31
+ github_api (0.12.1)
32
+ addressable (~> 2.3)
33
+ descendants_tracker (~> 0.0.4)
34
+ faraday (~> 0.8, < 0.10)
35
+ hashie (>= 3.2)
36
+ multi_json (>= 1.7.5, < 2.0)
37
+ nokogiri (~> 1.6.3)
26
38
  oauth2
27
- gli (2.8.1)
28
- hashie (2.0.5)
29
- highline (1.6.20)
30
- httpauth (0.2.0)
31
- httpclient (2.3.4.1)
32
- jeweler (1.8.4)
33
- bundler (~> 1.0)
34
- git (>= 1.2.5)
35
- rake
36
- rdoc
39
+ gli (2.12.2)
40
+ hashie (3.3.1)
41
+ highline (1.6.21)
42
+ httpclient (2.4.0)
37
43
  json (1.7.5)
38
44
  json_pure (1.8.1)
39
- jwt (0.1.8)
40
- multi_json (>= 1.5)
41
- mini_portile (0.5.1)
42
- multi_json (1.8.4)
45
+ jwt (1.0.0)
46
+ method_source (0.8.2)
47
+ mini_portile (0.6.0)
48
+ multi_json (1.10.1)
43
49
  multi_xml (0.5.5)
44
- multipart-post (1.2.0)
45
- nokogiri (1.6.0)
46
- mini_portile (~> 0.5.0)
47
- oauth2 (0.9.2)
48
- faraday (~> 0.8)
49
- httpauth (~> 0.2)
50
- jwt (~> 0.1.4)
51
- multi_json (~> 1.0)
50
+ multipart-post (2.0.0)
51
+ nokogiri (1.6.3.1)
52
+ mini_portile (= 0.6.0)
53
+ oauth2 (1.0.0)
54
+ faraday (>= 0.8, < 0.10)
55
+ jwt (~> 1.0)
56
+ multi_json (~> 1.3)
52
57
  multi_xml (~> 0.5)
53
58
  rack (~> 1.2)
59
+ pry (0.10.1)
60
+ coderay (~> 1.1.0)
61
+ method_source (~> 0.8.1)
62
+ slop (~> 3.4)
63
+ pry-byebug (2.0.0)
64
+ byebug (~> 3.4)
65
+ pry (~> 0.10)
54
66
  rack (1.5.2)
55
67
  rake (0.9.2.2)
56
68
  rdoc (3.12)
57
69
  json (~> 1.4)
70
+ rspec (3.0.0)
71
+ rspec-core (~> 3.0.0)
72
+ rspec-expectations (~> 3.0.0)
73
+ rspec-mocks (~> 3.0.0)
74
+ rspec-core (3.0.3)
75
+ rspec-support (~> 3.0.0)
76
+ rspec-expectations (3.0.3)
77
+ diff-lcs (>= 1.2.0, < 2.0)
78
+ rspec-support (~> 3.0.0)
79
+ rspec-mocks (3.0.3)
80
+ rspec-support (~> 3.0.0)
81
+ rspec-support (3.0.3)
82
+ safe_yaml (1.0.1)
83
+ slop (3.6.0)
84
+ thread_safe (0.3.4)
85
+ webmock (1.17.4)
86
+ addressable (>= 2.2.7)
87
+ crack (>= 0.3.2)
58
88
 
59
89
  PLATFORMS
60
90
  ruby
@@ -62,6 +92,8 @@ PLATFORMS
62
92
  DEPENDENCIES
63
93
  bundler
64
94
  git_reflow!
65
- jeweler
95
+ pry-byebug
66
96
  rake
67
97
  rdoc
98
+ rspec (~> 3.0.0)
99
+ webmock
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
+ #!/usr/bin/env rake
1
2
  require 'rake'
2
3
  require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ Dir[File.join(File.dirname(__FILE__),'lib/tasks/*.rake')].each { |f| load f }
7
+
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task :default => [:spec]
data/git_reflow.gemspec CHANGED
@@ -16,21 +16,22 @@ spec = Gem::Specification.new do |s|
16
16
  s.has_rdoc = true
17
17
  s.extra_rdoc_files = ['README.rdoc']
18
18
  s.bindir = 'bin'
19
-
20
19
  s.require_paths << 'lib'
21
20
  s.rdoc_options << '--title' << 'git_reflow' << '--main' << 'README.rdoc' << '-ri'
22
21
 
23
22
  s.add_development_dependency('bundler')
23
+ s.add_development_dependency('pry-byebug')
24
24
  s.add_development_dependency('rake')
25
25
  s.add_development_dependency('rdoc')
26
- s.add_development_dependency('jeweler')
26
+ s.add_development_dependency('rspec', '~> 3.0.0')
27
+ s.add_development_dependency('webmock')
27
28
 
28
29
  s.add_dependency('colorize', '0.6.0')
29
- s.add_dependency('gli', '2.8.1')
30
+ s.add_dependency('gli', '2.12.2')
30
31
  s.add_dependency('highline')
31
32
  s.add_dependency('httpclient')
32
33
  s.add_dependency('json_pure')
33
- s.add_dependency('github_api', '0.10.2')
34
+ s.add_dependency('github_api', '0.12.1')
34
35
 
35
36
  s.post_install_message = "You need to setup your GitHub OAuth token\nPlease run 'git-reflow setup'"
36
37
  end
@@ -4,6 +4,13 @@ command :setup do |c|
4
4
  c.switch [:l, :local], default_value: false, desc: 'setup GitReflow for the current project only'
5
5
  c.switch [:e, :enterprise], default_value: false, desc: 'setup GitReflow with a Github Enterprise account'
6
6
  c.action do |global_options, options, args|
7
- GitReflow.setup({ project_only: options[:local], enterprise: options[:enterprise] })
7
+ reflow_options = { project_only: options[:local], enterprise: options[:enterprise] }
8
+ choose do |menu|
9
+ menu.header = "Available remote Git Server services:"
10
+ menu.prompt = "Which service would you like to use for this project? "
11
+
12
+ menu.choice('GitHub') { GitReflow::GitServer.connect reflow_options.merge({ provider: 'GitHub', silent: false }) }
13
+ menu.choice('BitBucket') { say("Coming soon...") }
14
+ end
8
15
  end
9
16
  end
@@ -2,7 +2,7 @@ desc 'Start will create a new feature branch and setup remote tracking'
2
2
  long_desc <<LONGTIME
3
3
  Performs the following:\n
4
4
  \t$ git pull origin <current_branch>\n
5
- \t$ git push origin master:refs/heads/[new_feature_branch]\n
5
+ \t$ git push origin <current_branch>:refs/heads/[new_feature_branch]\n
6
6
  \t$ git checkout --track -b [new_feature_branch] origin/[new_feature_branch]\n
7
7
  LONGTIME
8
8
  arg_name '[new-feature-branch-name] - name of the new feature branch'
@@ -18,7 +18,7 @@ command :start do |c|
18
18
  raise "usage: git-reflow start [new-branch-name]"
19
19
  else
20
20
  `git pull origin #{GitReflow.current_branch}`
21
- `git push origin master:refs/heads/#{args[0]}`
21
+ `git push origin #{GitReflow.current_branch}:refs/heads/#{args[0]}`
22
22
  `git checkout --track -b #{args[0]} origin/#{args[0]}`
23
23
  end
24
24
  end
@@ -0,0 +1,23 @@
1
+ module GitReflow
2
+ module Config
3
+ extend self
4
+
5
+ def get(key)
6
+ if cached_key_value = instance_variable_get(:"@#{key.tr('.-', '_')}")
7
+ cached_key_value
8
+ else
9
+ new_value = GitReflow::Sandbox.run "git config --get #{key}", loud: false
10
+ instance_variable_set(:"@#{key.tr('.-', '_')}", new_value)
11
+ end
12
+ end
13
+
14
+ def set(key, value, options = { local: false })
15
+ value = value.strip
16
+ if options.delete(:local)
17
+ GitReflow::Sandbox.run "git config --replace-all #{key} \"#{value}\"", loud: false
18
+ else
19
+ GitReflow::Sandbox.run "git config --global --replace-all #{key} \"#{value}\"", loud: false
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,65 @@
1
+ require 'git_reflow/config'
2
+ require 'git_reflow/sandbox'
3
+
4
+ module GitReflow
5
+ module GitHelpers
6
+ include Sandbox
7
+
8
+ def remote_user
9
+ return "" unless "#{GitReflow::Config.get('remote.origin.url')}".length > 0
10
+ GitReflow::Config.get('remote.origin.url')[/[\/:](\w|-|\.)+/i][1..-1]
11
+ end
12
+
13
+ def remote_repo_name
14
+ return "" unless "#{GitReflow::Config.get('remote.origin.url')}".length > 0
15
+ GitReflow::Config.get('remote.origin.url')[/\/(\w|-|\.)+$/i][1..-5]
16
+ end
17
+
18
+ def current_branch
19
+ run("git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g'", loud: false).strip
20
+ end
21
+
22
+ def get_first_commit_message
23
+ run('git log --pretty=format:"%s" --no-merges -n 1', loud: false).strip
24
+ end
25
+
26
+ def push_current_branch
27
+ run_command_with_label "git push origin #{current_branch}"
28
+ end
29
+
30
+ def fetch_destination(destination_branch)
31
+ run_command_with_label "git fetch origin #{destination_branch}"
32
+ end
33
+
34
+ def update_destination(destination_branch)
35
+ origin_branch = current_branch
36
+ run_command_with_label "git checkout #{destination_branch}"
37
+ run_command_with_label "git pull origin #{destination_branch}"
38
+ run_command_with_label "git checkout #{origin_branch}"
39
+ end
40
+
41
+ def merge_feature_branch(feature_branch_name, options = {})
42
+ options[:destination_branch] ||= 'master'
43
+
44
+ message = "#{options[:message]}"
45
+
46
+ if "#{options[:pull_request_number]}".length > 0
47
+ message << "\nCloses ##{options[:pull_request_number]}\n"
48
+ end
49
+
50
+ if lgtm_authors = Array(options[:lgtm_authors]) and lgtm_authors.any?
51
+ message << "\nLGTM given by: @#{lgtm_authors.join(', @')}\n"
52
+ end
53
+
54
+ run_command_with_label "git checkout #{options[:destination_branch]}"
55
+ run_command_with_label "git merge --squash #{feature_branch_name}"
56
+
57
+ append_to_squashed_commit_message(message) if message.length > 0
58
+ end
59
+
60
+ def append_to_squashed_commit_message(message = '')
61
+ run "echo \"#{message}\" | cat - .git/SQUASH_MSG > ./tmp_squash_msg"
62
+ run 'mv ./tmp_squash_msg .git/SQUASH_MSG'
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,88 @@
1
+ require 'git_reflow/config'
2
+
3
+ module GitReflow
4
+ class GitServer::Base
5
+ @@connection = nil
6
+ @@project_only = false
7
+
8
+ def initialize(options)
9
+ @@project_only = !!options.delete(:project_only)
10
+
11
+ site_url = self.class.site_url
12
+ api_endpoint = self.class.api_endpoint
13
+
14
+ self.class.site_url = site_url
15
+ self.class.api_endpoint = api_endpoint
16
+
17
+ authenticate
18
+ end
19
+
20
+ def authenticate
21
+ raise "#{self.class.to_s}#authenticate method must be implemented"
22
+ end
23
+
24
+ def find_pull_request(options)
25
+ raise "#{self.class.to_s}#find_pull_request(options) method must be implemented"
26
+ end
27
+
28
+ def self.connection
29
+ raise "#{self.class.to_s}.connection method must be implemented"
30
+ end
31
+
32
+ def self.user
33
+ raise "#{self.class.to_s}.user method must be implemented"
34
+ end
35
+
36
+ def self.oauth_token
37
+ raise "#{self.class.to_s}.oauth_token method must be implemented"
38
+ end
39
+
40
+ def self.oauth_token=(oauth_token)
41
+ raise "#{self.class.to_s}.oauth_token= method must be implemented"
42
+ end
43
+
44
+ def self.api_endpoint
45
+ raise "#{self.class.to_s}.api_endpoint method must be implemented"
46
+ end
47
+
48
+ def self.api_endpoint=(api_endpoint, options = {local: false})
49
+ raise "#{self.class.to_s}.api_endpoint= method must be implemented"
50
+ end
51
+
52
+ def self.site_url
53
+ raise "#{self.class.to_s}.site_url method must be implemented"
54
+ end
55
+
56
+ def self.site_url=(site_url, options = {local: false})
57
+ raise "#{self.class.to_s}.site_url= method must be implemented"
58
+ end
59
+
60
+ def connection
61
+ @connection ||= self.class.connection
62
+ end
63
+
64
+ def pull_request_comments(pull_request)
65
+ raise "#{self.class.to_s}#pull_request_comments(pull_request) method must be implemented"
66
+ end
67
+
68
+ def has_pull_request_comments?(pull_request)
69
+ pull_request_comments(pull_request).count > 0
70
+ end
71
+
72
+ def get_build_status sha
73
+ raise "#{self.class.to_s}#get_build_status(sha) method must be implemented"
74
+ end
75
+
76
+ def colorized_build_description status
77
+ raise "#{self.class.to_s}#colorized_build_description(status) method must be implemented"
78
+ end
79
+
80
+ def find_authors_of_open_pull_request_comments(pull_request)
81
+ raise "#{self.class.to_s}#find_authors_of_open_pull_request_comments(pull_request) method must be implemented"
82
+ end
83
+
84
+ def get_commited_time(commit_sha)
85
+ raise "#{self.class.to_s}#get_commited_time(commit_sha) method must be implemented"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,184 @@
1
+ require 'github_api'
2
+ require 'git_reflow/git_helpers'
3
+
4
+ module GitReflow
5
+ module GitServer
6
+ class GitHub < Base
7
+ include GitHelpers
8
+
9
+ attr_accessor :connection
10
+
11
+ @@project_only = false
12
+ @@using_enterprise = false
13
+
14
+ def initialize(config_options = {})
15
+ @@project_only = !!config_options.delete(:project_only)
16
+ @@using_enterprise = !!config_options.delete(:enterprise)
17
+
18
+ gh_site_url = self.class.site_url
19
+ gh_api_endpoint = self.class.api_endpoint
20
+
21
+ if @@using_enterprise
22
+ gh_site_url = ask("Please enter your Enterprise site URL (e.g. https://github.company.com):")
23
+ gh_api_endpoint = ask("Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):")
24
+ end
25
+
26
+ self.class.site_url = gh_site_url
27
+ self.class.api_endpoint = gh_api_endpoint
28
+
29
+ if @@project_only
30
+ GitReflow::Config.set('reflow.git-server', 'GitHub', local: true)
31
+ else
32
+ GitReflow::Config.set('reflow.git-server', 'GitHub')
33
+ end
34
+ end
35
+
36
+ def authenticate(options = {silent: false})
37
+ if connection
38
+ unless options[:silent]
39
+ puts "Your GitHub account was already setup with: "
40
+ puts "\tUser Name: #{self.class.user}"
41
+ puts "\tEndpoint: #{self.class.api_endpoint}"
42
+ end
43
+ else
44
+ begin
45
+ gh_user = ask("Please enter your GitHub username: ")
46
+ gh_password = ask("Please enter your GitHub password (we do NOT store this): ") { |q| q.echo = false }
47
+
48
+ @connection = ::Github.new do |config|
49
+ config.basic_auth = "#{gh_user}:#{gh_password}"
50
+ config.endpoint = GitServer::GitHub.api_endpoint
51
+ config.site = GitServer::GitHub.site_url
52
+ config.adapter = :net_http
53
+ config.ssl = {:verify => false}
54
+ end
55
+
56
+ previous_authorizations = @connection.oauth.all.select {|auth| auth.note == "git-reflow (#{run('hostname', loud: false).strip})" }
57
+ if previous_authorizations.any?
58
+ authorization = previous_authorizations.last
59
+ else
60
+ authorization = @connection.oauth.create scopes: ['repo'], note: "git-reflow (#{run('hostname', loud: false).strip})"
61
+ end
62
+
63
+ oauth_token = authorization.token
64
+
65
+ self.class.oauth_token = oauth_token
66
+ puts "\nYour GitHub account was successfully setup!"
67
+
68
+ rescue StandardError => e
69
+ puts "\nInvalid username or password: #{e.inspect}"
70
+ else
71
+ puts "\nYour GitHub account was successfully setup!"
72
+ end
73
+ end
74
+
75
+ @connection
76
+ end
77
+
78
+ def create_pull_request(options = {})
79
+ pull_request = connection.pull_requests.create(remote_user, remote_repo_name,
80
+ title: options[:title],
81
+ body: options[:body],
82
+ head: "#{remote_user}:#{current_branch}",
83
+ base: options[:base])
84
+ end
85
+
86
+ def find_pull_request(options = {})
87
+ connection.pull_requests.all(remote_user, remote_repo_name, base: options[:to], head: "#{remote_user}:#{options[:from]}", :state => 'open').first
88
+ end
89
+
90
+ def self.connection
91
+ if self.oauth_token.length > 0
92
+ @connection ||= ::Github.new do |config|
93
+ config.oauth_token = GitServer::GitHub.oauth_token
94
+ config.endpoint = GitServer::GitHub.api_endpoint
95
+ config.site = GitServer::GitHub.site_url
96
+ end
97
+ end
98
+ end
99
+
100
+ def self.user
101
+ GitReflow::Config.get('github.user')
102
+ end
103
+
104
+ def self.oauth_token
105
+ GitReflow::Config.get('github.oauth-token')
106
+ end
107
+
108
+ def self.oauth_token=(oauth_token, options = {})
109
+ GitReflow::Config.set('github.oauth-token', oauth_token, local: @@project_only)
110
+ oauth_token
111
+ end
112
+
113
+ def self.api_endpoint
114
+ endpoint = GitReflow::Config.get('github.endpoint')
115
+ (endpoint.length > 0) ? endpoint : ::Github::Configuration.new.endpoint
116
+ end
117
+
118
+ def self.api_endpoint=(api_endpoint)
119
+ GitReflow::Config.set("github.endpoint", api_endpoint, local: @@project_only)
120
+ api_endpoint
121
+ end
122
+
123
+ def self.site_url
124
+ site_url = GitReflow::Config.get('github.site')
125
+ (site_url.length > 0) ? site_url : ::Github::Configuration.new.site
126
+ end
127
+
128
+ def self.site_url=(site_url)
129
+ GitReflow::Config.set("github.site", site_url, local: @@project_only)
130
+ site_url
131
+ end
132
+
133
+ def connection
134
+ @connection ||= self.class.connection
135
+ end
136
+
137
+ def pull_request_comments(pull_request)
138
+ comments = connection.issues.comments.all remote_user, remote_repo_name, number: pull_request.number
139
+ review_comments = connection.pull_requests.comments.all remote_user, remote_repo_name, number: pull_request.number
140
+
141
+ review_comments.to_a + comments.to_a
142
+ end
143
+
144
+ def get_build_status sha
145
+ connection.repos.statuses.all(remote_user, remote_repo_name, sha).first
146
+ end
147
+
148
+ def colorized_build_description status
149
+ colorized_statuses = { pending: :yellow, success: :green, error: :red, failure: :red }
150
+ status.description.colorize( colorized_statuses[status.state.to_sym] )
151
+ end
152
+
153
+ def find_authors_of_open_pull_request_comments(pull_request)
154
+ # first we'll gather all the authors that have commented on the pull request
155
+ pull_last_committed_at = get_commited_time(pull_request.head.sha)
156
+ comment_authors = comment_authors_for_pull_request(pull_request)
157
+ lgtm_authors = comment_authors_for_pull_request(pull_request, :with => LGTM, :after => pull_last_committed_at)
158
+
159
+ comment_authors - lgtm_authors
160
+ end
161
+
162
+ def comment_authors_for_pull_request(pull_request, options = {})
163
+ all_comments = pull_request_comments(pull_request)
164
+ comment_authors = []
165
+
166
+ all_comments.each do |comment|
167
+ next if options[:after] and Time.parse(comment.created_at) < options[:after]
168
+ if (options[:with].nil? or comment[:body] =~ options[:with])
169
+ comment_authors |= [comment.user.login]
170
+ end
171
+ end
172
+
173
+ # remove the current user from the list to check
174
+ comment_authors -= [self.class.user]
175
+ end
176
+
177
+ def get_commited_time(commit_sha)
178
+ last_commit = connection.repos.commits.find remote_user, remote_repo_name, commit_sha
179
+ Time.parse last_commit.commit.author[:date]
180
+ end
181
+
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,52 @@
1
+ module GitReflow
2
+ module GitServer
3
+ autoload :Base, 'git_reflow/git_server/base'
4
+ autoload :GitHub, 'git_reflow/git_server/git_hub'
5
+
6
+ extend self
7
+
8
+ class ConnectionError < StandardError; end
9
+
10
+ def connect(options = nil)
11
+ options ||= { provider: 'GitHub' }
12
+ begin
13
+ provider_name = options[:provider]
14
+ provider = provider_class_for(options.delete(:provider)).new(options)
15
+ provider.authenticate(options.keep_if {|key, value| key == :silent })
16
+ provider
17
+ rescue ConnectionError => e
18
+ puts "Error connecting to #{provider_name}: #{e.message}"
19
+ end
20
+ end
21
+
22
+ def connection
23
+ return nil unless current_provider
24
+ current_provider.connection
25
+ end
26
+
27
+ def current_provider
28
+ if (provider = GitReflow::Config.get('reflow.git-server')) and provider.length > 0
29
+ begin
30
+ provider_class_for(provider)
31
+ rescue ConnectionError => e
32
+ puts e.message
33
+ nil
34
+ end
35
+ else
36
+ puts "[notice] Reflow hasn't been setup yet. Run 'git reflow setup' to continue"
37
+ nil
38
+ end
39
+ end
40
+
41
+ def can_connect_to?(provider)
42
+ GitReflow::GitServer.const_defined?(provider)
43
+ end
44
+
45
+ private
46
+
47
+ def provider_class_for(provider)
48
+ raise ConnectionError, "GitServer not setup for \"#{provider}\"" unless self.can_connect_to?(provider)
49
+ GitReflow::GitServer.const_get(provider)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,39 @@
1
+ module GitReflow
2
+ module Sandbox
3
+ extend self
4
+
5
+ def run(command, options = {})
6
+ options = { loud: true }.merge(options)
7
+
8
+ if options[:with_system] == true
9
+ system(command)
10
+ elsif options[:loud] == true
11
+ puts `#{command}`
12
+ else
13
+ `#{command}`
14
+ end
15
+ end
16
+
17
+ def run_command_with_label(command, options = {})
18
+ label_color = options.delete(:color) || :green
19
+ puts command.colorize(label_color)
20
+ run(command, options)
21
+ end
22
+
23
+ # WARNING: this currently only supports OS X and UBUNTU
24
+ def ask_to_open_in_browser(url)
25
+ if RUBY_PLATFORM =~ /darwin|linux/i
26
+ open_in_browser = ask "Would you like to open it in your browser? "
27
+ if open_in_browser =~ /^y/i
28
+ if RUBY_PLATFORM =~ /darwin/i
29
+ # OS X
30
+ run "open #{url}"
31
+ else
32
+ # Ubuntu
33
+ run "xdg-open #{url}"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module GitReflow
2
- VERSION = "0.3.5"
2
+ VERSION = "0.4.0"
3
3
  end