git-process 0.9.1.pre3 → 0.9.2

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 (57) hide show
  1. data/CHANGELOG.md +0 -0
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +2 -0
  4. data/README.md +27 -9
  5. data/bin/git-new-fb +42 -13
  6. data/bin/git-pull-request +79 -13
  7. data/bin/git-sync +47 -13
  8. data/bin/git-to-master +56 -13
  9. data/git-process.gemspec +1 -1
  10. data/lib/git-process/{abstract-error-builder.rb → abstract_error_builder.rb} +13 -3
  11. data/lib/git-process/{git-abstract-merge-error-builder.rb → git_abstract_merge_error_builder.rb} +15 -5
  12. data/lib/git-process/{git-branch.rb → git_branch.rb} +13 -1
  13. data/lib/git-process/git_branches.rb +72 -0
  14. data/lib/git-process/{git-lib.rb → git_lib.rb} +82 -70
  15. data/lib/git-process/git_merge_error.rb +38 -0
  16. data/lib/git-process/git_process.rb +124 -0
  17. data/lib/git-process/git_process_error.rb +18 -0
  18. data/lib/git-process/git_process_options.rb +101 -0
  19. data/lib/git-process/git_rebase_error.rb +38 -0
  20. data/lib/git-process/{git-status.rb → git_status.rb} +13 -1
  21. data/lib/git-process/{github-client.rb → github_client.rb} +13 -1
  22. data/lib/git-process/github_pull_request.rb +107 -0
  23. data/lib/git-process/{github-service.rb → github_service.rb} +39 -21
  24. data/lib/git-process/new_fb.rb +40 -0
  25. data/lib/git-process/parked_changes_error.rb +40 -0
  26. data/lib/git-process/pull_request.rb +61 -0
  27. data/lib/git-process/rebase_to_master.rb +110 -0
  28. data/lib/git-process/sync.rb +63 -0
  29. data/lib/git-process/uncommitted_changes_error.rb +23 -0
  30. data/lib/git-process/version.rb +19 -9
  31. data/spec/GitRepoHelper.rb +35 -21
  32. data/spec/{git-abstract-merge-error-builder_spec.rb → git_abstract_merge_error_builder_spec.rb} +3 -3
  33. data/spec/{git-lib_spec.rb → git_lib_spec.rb} +79 -16
  34. data/spec/git_process_spec.rb +36 -0
  35. data/spec/{git-status_spec.rb → git_status_spec.rb} +28 -29
  36. data/spec/github_pull_request_spec.rb +91 -0
  37. data/spec/{github-service_spec.rb → github_service_spec.rb} +1 -1
  38. data/spec/new_fb_spec.rb +80 -0
  39. data/spec/rebase_to_master_spec.rb +314 -0
  40. data/spec/spec_helper.rb +1 -1
  41. data/spec/sync_spec.rb +149 -0
  42. metadata +46 -43
  43. data/lib/git-process/git-branches.rb +0 -53
  44. data/lib/git-process/git-merge-error.rb +0 -31
  45. data/lib/git-process/git-new-fb-options.rb +0 -34
  46. data/lib/git-process/git-process-error.rb +0 -10
  47. data/lib/git-process/git-process-options.rb +0 -82
  48. data/lib/git-process/git-process.rb +0 -194
  49. data/lib/git-process/git-pull-request-options.rb +0 -42
  50. data/lib/git-process/git-rebase-error.rb +0 -31
  51. data/lib/git-process/git-sync-options.rb +0 -34
  52. data/lib/git-process/git-to-master-options.rb +0 -18
  53. data/lib/git-process/parked-changes-error.rb +0 -32
  54. data/lib/git-process/pull-request.rb +0 -38
  55. data/lib/git-process/uncommitted-changes-error.rb +0 -15
  56. data/spec/git-process_spec.rb +0 -328
  57. data/spec/pull-request_spec.rb +0 -57
@@ -1,10 +1,20 @@
1
- require "rubygems"
2
- require "bundler/setup"
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
3
12
 
4
13
  require 'logger'
5
- require 'git-branch'
6
- require 'git-branches'
7
- require 'git-status'
14
+ require 'git-process/git_branch'
15
+ require 'git-process/git_branches'
16
+ require 'git-process/git_status'
17
+ require 'git-process/git_process_error'
8
18
 
9
19
 
10
20
  class String
@@ -18,67 +28,51 @@ class String
18
28
  end
19
29
 
20
30
 
21
- module Git
31
+ module GitProc
22
32
 
23
33
  class GitExecuteError < StandardError
24
34
  end
25
35
 
26
36
 
27
- # @!attribute [r] logger
28
- # @return [Logger] a logger
29
- # @!attribute [r] git
30
- # @return [Git] an instance of the Git library
31
- class GitLib
32
- attr_reader :logger
37
+ #
38
+ # Provides Git commands
39
+ #
40
+ # = Assumes =
41
+ # log_level
42
+ # workdir
43
+ #
44
+ module GitLib
33
45
 
34
- def initialize(dir, options = {})
35
- initialize_logger(options[:logger], options[:log_level])
36
- initialize_git(dir)
37
- end
38
-
39
-
40
- def initialize_logger(logger, log_level)
41
- if logger
42
- @logger = logger
43
- else
46
+ def logger
47
+ unless @logger
44
48
  @logger = Logger.new(STDOUT)
45
49
  @logger.level = log_level || Logger::WARN
46
50
  @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
47
51
  f = Logger::Formatter.new
48
52
  @logger.formatter = proc do |severity, datetime, progname, msg|
49
53
  "#{msg}\n"
50
- # "#{severity[0..0]}: #{datetime.strftime(@logger.datetime_format)}: #{msg}\n"
51
54
  end
52
55
  end
56
+ @logger
53
57
  end
54
58
 
55
59
 
56
- def initialize_git(dir, git = nil)
57
- if dir
58
- @workdir = File.expand_path(dir)
59
- unless File.directory?(File.join(workdir, '.git'))
60
- logger.info { "Initializing new repository at #{workdir}" }
61
- command(:init)
62
- else
63
- logger.debug { "Opening existing repository at #{workdir}" }
64
- end
65
- end
60
+ def server_name
61
+ @server_name ||= remote_name
66
62
  end
67
63
 
68
64
 
69
- private :initialize_logger, :initialize_git
70
-
71
-
72
- def workdir
73
- @workdir
65
+ def master_branch
66
+ @master_branch ||= config('gitProcess.integrationBranch') || 'master'
74
67
  end
75
68
 
76
69
 
70
+ # @return [Boolean] does this have a remote defined?
77
71
  def has_a_remote?
78
- if @remote == nil
79
- @remote = (command('remote') != '')
72
+ if @has_remote == nil
73
+ @has_remote = (command(:remote) != '')
80
74
  end
81
- @remote
75
+ @has_remote
82
76
  end
83
77
 
84
78
 
@@ -102,13 +96,13 @@ module Git
102
96
  end
103
97
 
104
98
 
105
- def fetch
106
- command(:fetch, ['-p', Process.server_name])
99
+ def fetch(name = remote_name)
100
+ command(:fetch, ['-p', name])
107
101
  end
108
102
 
109
103
 
110
104
  def branches
111
- GitBranches.new(self)
105
+ GitProc::GitBranches.new(self)
112
106
  end
113
107
 
114
108
 
@@ -129,7 +123,7 @@ module Git
129
123
  def branch(branch_name, opts = {})
130
124
  args = []
131
125
  if opts[:delete]
132
- logger.info { "Deleting local branch '#{branch_name}'."}
126
+ logger.info { "Deleting local branch '#{branch_name}'."} unless branch_name == '_parking_'
133
127
 
134
128
  args << (opts[:force] ? '-D' : '-d')
135
129
  args << branch_name
@@ -177,14 +171,22 @@ module Git
177
171
 
178
172
  if opts[:delete]
179
173
  if remote_branch
180
- opts[:delete] = remote_branch
174
+ rb = remote_branch
181
175
  elsif local_branch
182
- opts[:delete] = local_branch
176
+ rb = local_branch
177
+ elsif !(opts[:delete].is_a? TrueClass)
178
+ rb = opts[:delete]
183
179
  else
184
- raise ArgumentError.new("Need a branch name to delete.") if opts[:delete].is_a? TrueClass
180
+ raise ArgumentError.new("Need a branch name to delete.")
185
181
  end
186
- logger.info { "Deleting remote branch '#{opts[:delete]}' on '#{remote_name}'."}
187
- args << '--delete' << opts[:delete]
182
+
183
+ int_branch = master_branch
184
+ if rb == int_branch
185
+ raise GitProc::GitProcessError.new("Can not delete the integration branch '#{int_branch}'")
186
+ end
187
+
188
+ logger.info { "Deleting remote branch '#{rb}' on '#{remote_name}'."}
189
+ args << '--delete' << rb
188
190
  else
189
191
  local_branch ||= branches.current
190
192
  remote_branch ||= local_branch
@@ -239,7 +241,7 @@ module Git
239
241
  args = []
240
242
  args << '-f' if opts[:force]
241
243
  args << file
242
- command('rm', args)
244
+ command(:rm, args)
243
245
  end
244
246
 
245
247
 
@@ -248,21 +250,24 @@ module Git
248
250
  end
249
251
 
250
252
 
251
- def config(key = nil, value = nil)
253
+ def config(key = nil, value = nil, global = false)
252
254
  if key and value
253
- command('config', [key, value])
254
- config_hash[key] = value
255
+ args = global ? ['--global'] : []
256
+ args << key << value
257
+ command(:config, args)
258
+ config_hash[key] = value unless config_hash.empty?
255
259
  value
256
260
  elsif key
257
261
  value = config_hash[key]
258
262
  unless value
259
- value = command('config', ['--get', key])
260
- config_hash[key] = value
263
+ value = command(:config, ['--get', key])
264
+ value = nil if value.empty?
265
+ config_hash[key] = value unless config_hash.empty?
261
266
  end
262
267
  value
263
268
  else
264
269
  if config_hash.empty?
265
- str = command('config', '--list')
270
+ str = command(:config, '--list')
266
271
  lines = str.split("\n")
267
272
  lines.each do |line|
268
273
  (key, *values) = line.split('=')
@@ -276,14 +281,27 @@ module Git
276
281
 
277
282
  def repo_name
278
283
  unless @repo_name
279
- origin_url = config['remote.origin.url']
280
- raise Git::Process::GitProcessError.new("There is not origin url set up.") if origin_url.empty?
284
+ origin_url = config("remote.#{remote_name}.url")
285
+ raise GitProc::Process::GitProcessError.new("There is no #{remote_name} url set up.") if origin_url.empty?
281
286
  @repo_name = origin_url.sub(/^.*:(.*?)(.git)?$/, '\1')
282
287
  end
283
288
  @repo_name
284
289
  end
285
290
 
286
291
 
292
+ def remote_name
293
+ unless @remote_name
294
+ remote_str = command(:remote)
295
+ unless remote_str == nil or remote_str.empty?
296
+ @remote_name = remote_str.split(/\n/)[0]
297
+ raise "!@remote_name.is_a? String" unless @remote_name.is_a? String
298
+ end
299
+ logger.debug {"Using remote name of '#{@remote_name}'"}
300
+ end
301
+ @remote_name
302
+ end
303
+
304
+
287
305
  #
288
306
  # Returns the status of the git repository.
289
307
  #
@@ -311,30 +329,24 @@ module Git
311
329
 
312
330
 
313
331
  def rerere_enabled?
314
- re = command('config', ['--get', 'rerere.enabled'])
332
+ re = config('rerere.enabled')
315
333
  re && re.to_boolean
316
334
  end
317
335
 
318
336
 
319
337
  def rerere_enabled(re, global = true)
320
- args = []
321
- args << '--global' if global
322
- args << 'rerere.enabled' << re
323
- command(:config, args)
338
+ config('rerere.enabled', re, global)
324
339
  end
325
340
 
326
341
 
327
342
  def rerere_autoupdate?
328
- re = command('config', ['--get', 'rerere.autoupdate'])
343
+ re = config('rerere.autoupdate')
329
344
  re && re.to_boolean
330
345
  end
331
346
 
332
347
 
333
348
  def rerere_autoupdate(re, global = true)
334
- args = []
335
- args << '--global' if global
336
- args << 'rerere.autoupdate' << re
337
- command(:config, args)
349
+ config('rerere.autoupdate', re, global)
338
350
  end
339
351
 
340
352
 
@@ -388,7 +400,7 @@ module Git
388
400
  if $?.exitstatus == 1 && out == ''
389
401
  return ''
390
402
  end
391
- raise Git::GitExecuteError.new(git_cmd + ':' + out.to_s)
403
+ raise GitProc::GitExecuteError.new(git_cmd + ':' + out.to_s)
392
404
  end
393
405
  out
394
406
  end
@@ -0,0 +1,38 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ require 'git-process/git_abstract_merge_error_builder'
14
+
15
+ module GitProc
16
+
17
+ class MergeError < GitProcessError
18
+ include AbstractMergeErrorBuilder
19
+
20
+ attr_reader :error_message, :lib
21
+
22
+ def initialize(merge_error_message, lib)
23
+ @lib = lib
24
+ @error_message = merge_error_message
25
+
26
+ msg = build_message
27
+
28
+ super(msg)
29
+ end
30
+
31
+
32
+ def continue_command
33
+ 'git commit'
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,124 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ require 'git-process/git_lib'
14
+ require 'git-process/git_rebase_error'
15
+ require 'git-process/git_merge_error'
16
+
17
+
18
+ module GitProc
19
+
20
+ class Process
21
+ include GitLib
22
+
23
+ def initialize(dir, opts = {})
24
+ @log_level = Process.log_level(opts)
25
+
26
+ if dir
27
+ @workdir = find_workdir(dir)
28
+ if @workdir.nil?
29
+ @workdir = dir
30
+ logger.info { "Initializing new repository at #{workdir}" }
31
+ command(:init)
32
+ else
33
+ logger.debug { "Opening existing repository at #{workdir}" }
34
+ end
35
+ end
36
+ end
37
+
38
+
39
+ def run
40
+ begin
41
+ runner
42
+ rescue GitProc::GitProcessError => exp
43
+ puts exp.message
44
+ exit(-1)
45
+ end
46
+ end
47
+
48
+
49
+ def runner
50
+ # extension point - does nothing by default
51
+ end
52
+
53
+
54
+ def workdir
55
+ @workdir
56
+ end
57
+
58
+
59
+ def log_level
60
+ @log_level
61
+ end
62
+
63
+
64
+ def log_level=(ll)
65
+ @log_level = ll
66
+ end
67
+
68
+
69
+ def remote_master_branch
70
+ "#{server_name}/#{master_branch}"
71
+ end
72
+
73
+
74
+ def Process.log_level(opts)
75
+ if opts[:quiet]
76
+ Logger::ERROR
77
+ elsif opts[:verbose]
78
+ Logger::DEBUG
79
+ else
80
+ Logger::INFO
81
+ end
82
+ end
83
+
84
+
85
+ def is_parked?
86
+ mybranches = branches
87
+ mybranches.parking == mybranches.current
88
+ end
89
+
90
+
91
+ private
92
+
93
+
94
+ def find_workdir(dir)
95
+ if dir == File::SEPARATOR
96
+ nil
97
+ elsif File.directory?(File.join(dir, '.git'))
98
+ dir
99
+ else
100
+ find_workdir(File.expand_path("#{dir}/.."))
101
+ end
102
+ end
103
+
104
+
105
+ def proc_rebase(base)
106
+ begin
107
+ rebase(base)
108
+ rescue GitExecuteError => rebase_error
109
+ raise RebaseError.new(rebase_error.message, self)
110
+ end
111
+ end
112
+
113
+
114
+ def proc_merge(base)
115
+ begin
116
+ merge(base)
117
+ rescue GitExecuteError => merge_error
118
+ raise MergeError.new(merge_error.message, self)
119
+ end
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,18 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ module GitProc
14
+
15
+ class GitProcessError < RuntimeError
16
+ end
17
+
18
+ end
@@ -0,0 +1,101 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ require 'optparse'
14
+ require 'trollop'
15
+ require 'git-process/version'
16
+
17
+ module GitProc
18
+
19
+ module GitProcessOptions
20
+
21
+ DEBUG = false
22
+
23
+ def parse_cli(filename, argv)
24
+ parser = Trollop::Parser.new
25
+ parser.version "#{filename} #{GitProc::Version::STRING}"
26
+
27
+ parser.banner "#{summary}\n\n"
28
+ parser.banner "\nUsage:\n #{usage(filename)}\n\nWhere [options] are:"
29
+
30
+ extend_opts(parser)
31
+ standard_opts(parser)
32
+
33
+ parser.banner "\n#{description}"
34
+
35
+ opts = Trollop::with_standard_exception_handling parser do
36
+ raise Trollop::HelpNeeded if ARGV.empty? and !empty_argv_ok?
37
+ parser.parse argv
38
+ end
39
+
40
+ opts[:info] = false if opts[:verbose] || opts[:quiet]
41
+ opts[:info] = true if opts[:info_given]
42
+
43
+ post_parse(opts, argv)
44
+
45
+ if (DEBUG)
46
+ puts "\n\n#{opts.map{|k,v| "#{k}:#{v}"}.join(', ')}"
47
+ puts "\nargs: #{argv.join(', ')}"
48
+ end
49
+
50
+ opts
51
+ end
52
+
53
+
54
+ def standard_opts(parser)
55
+ parser.opt :info, "Informational messages; show the major things this is doing", :short => :i, :default => true
56
+ parser.opt :quiet, "Quiet messages; only show errors", :short => :q
57
+ parser.opt :verbose, "Verbose messages; show lots of details on what this is doing", :short => :v
58
+ parser.opt :version, "Print version (#{GitProc::Version::STRING}) and exit", :short => :none
59
+ parser.opt :help, "Show this message", :short => :h
60
+
61
+ parser.conflicts :verbose, :info, :quiet
62
+ end
63
+
64
+
65
+ def summary
66
+ "Default summary"
67
+ end
68
+
69
+
70
+ def usage(filename)
71
+ "#{filename} [options]"
72
+ end
73
+
74
+
75
+ def description
76
+ "Default description"
77
+ end
78
+
79
+
80
+ def empty_argv_ok?
81
+ true
82
+ end
83
+
84
+
85
+ def extend_opts(parser)
86
+ # extension point - does nothing by default
87
+ end
88
+
89
+
90
+ # def extend_args(argv)
91
+ # # extension point - does nothing by default
92
+ # end
93
+
94
+
95
+ def post_parse(opts, argv)
96
+ # extension point - does nothing by default
97
+ end
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,38 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ require 'git-process/git_abstract_merge_error_builder'
14
+
15
+ module GitProc
16
+
17
+ class RebaseError < GitProcessError
18
+ include GitProc::AbstractMergeErrorBuilder
19
+
20
+ attr_reader :error_message, :lib
21
+
22
+ def initialize(rebase_error_message, lib)
23
+ @lib = lib
24
+ @error_message = rebase_error_message
25
+
26
+ msg = build_message
27
+
28
+ super(msg)
29
+ end
30
+
31
+
32
+ def continue_command
33
+ 'git rebase --continue'
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -1,4 +1,16 @@
1
- module Git
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ module GitProc
2
14
 
3
15
  #
4
16
  # The status of the Git repository.
@@ -1,3 +1,15 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
1
13
  require 'octokit'
2
14
 
3
15
  module Octokit
@@ -65,7 +77,7 @@ class GitHubClient < Octokit::Client
65
77
 
66
78
  def request(method, path, options, version, authenticate, raw, force_urlencoded)
67
79
  if /api.github.com/ !~ site
68
- path = "/api/v3#{path}"
80
+ path = "/api/v3/#{path}"
69
81
  end
70
82
  old_request(method, path, options, version, authenticate, raw, force_urlencoded)
71
83
  end