regrit 0.0.5
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.
- data/.gitignore +4 -0
- data/Gemfile +3 -0
- data/README.md +3 -0
- data/Rakefile +10 -0
- data/lib/regrit.rb +20 -0
- data/lib/regrit/errors.rb +58 -0
- data/lib/regrit/provider.rb +14 -0
- data/lib/regrit/provider/mock.rb +78 -0
- data/lib/regrit/provider/system.rb +70 -0
- data/lib/regrit/ref.rb +15 -0
- data/lib/regrit/remote_repo.rb +76 -0
- data/lib/regrit/version.rb +3 -0
- data/regrit.gemspec +27 -0
- data/spec/id_rsa +27 -0
- data/spec/id_rsa.pub +1 -0
- data/spec/mocks_enabled_spec.rb +100 -0
- data/spec/remote_repo_spec.rb +109 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/wrong_key +27 -0
- metadata +195 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
data/lib/regrit.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Regrit
|
2
|
+
def self.enable_mock!
|
3
|
+
Provider::Mock.default!
|
4
|
+
@mocking = true
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.disable_mock!
|
8
|
+
@mocking = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.mocking?
|
12
|
+
@mocking
|
13
|
+
end
|
14
|
+
|
15
|
+
disable_mock!
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'regrit/errors'
|
19
|
+
require 'regrit/remote_repo'
|
20
|
+
require 'regrit/provider'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Regrit
|
2
|
+
# Error base class
|
3
|
+
class Error < RuntimeError
|
4
|
+
end
|
5
|
+
|
6
|
+
# Raised when the URI received is not a valid or able to be parsed.
|
7
|
+
class InvalidURIError < Error
|
8
|
+
def initialize
|
9
|
+
super "Invalid repository URI"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Raised when a repository is not accessible in some form.
|
14
|
+
class Inaccessible < Error
|
15
|
+
def initialize(message)
|
16
|
+
super "Repository Inaccessible: #{message}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Raised when a secure repository is accessed without a key
|
21
|
+
class PrivateKeyRequired < Inaccessible
|
22
|
+
def initialize(uri)
|
23
|
+
super "SSH private key required for secure git repository: #{uri}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Raised when accessing a repository times out
|
28
|
+
class TimeoutError < Inaccessible
|
29
|
+
def initialize(command, uri)
|
30
|
+
super "Timeout when attempting to access git repository: #{uri} with command: #{command.inspect}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Raised when there is an error calling git ls-remote (i.e. inaccessible repo)
|
35
|
+
class CommandError < Inaccessible
|
36
|
+
def initialize(command, status, stdout, stderr)
|
37
|
+
super <<-ERROR
|
38
|
+
Command `#{command}` exited with a non-zero exit status [#{status}]:
|
39
|
+
stdout:
|
40
|
+
#{stdout}
|
41
|
+
|
42
|
+
stderr:
|
43
|
+
#{stderr}
|
44
|
+
ERROR
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Raised when the Refs format is unrecognized
|
49
|
+
class InvalidRefsFormat < Inaccessible
|
50
|
+
def initialize(raw_refs)
|
51
|
+
super <<-ERROR
|
52
|
+
Invalid git refs format:
|
53
|
+
#{raw_refs}
|
54
|
+
ERROR
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Regrit
|
2
|
+
module Provider
|
3
|
+
class Mock
|
4
|
+
class NotImplemented < Regrit::Error
|
5
|
+
def initialize
|
6
|
+
super "Command not implemented."
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :accessible
|
12
|
+
attr_accessor :refs
|
13
|
+
attr_accessor :timeout
|
14
|
+
|
15
|
+
def default!
|
16
|
+
self.accessible = true
|
17
|
+
self.timeout = false
|
18
|
+
self.refs = <<-REFS
|
19
|
+
123456789abcdef0123456789abcdef012345678\tHEAD
|
20
|
+
123456789abcdef0123456789abcdef012345678\trefs/heads/master
|
21
|
+
REFS
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
default!
|
26
|
+
|
27
|
+
def initialize(uri, options)
|
28
|
+
@uri = uri
|
29
|
+
end
|
30
|
+
|
31
|
+
def ls_remote(named=nil)
|
32
|
+
raise_errors
|
33
|
+
if named
|
34
|
+
one_ref(named) || ''
|
35
|
+
else
|
36
|
+
self.class.refs
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def clone(*argv)
|
41
|
+
raise NotImplemented
|
42
|
+
end
|
43
|
+
|
44
|
+
def fetch(*argv)
|
45
|
+
raise NotImplemented
|
46
|
+
end
|
47
|
+
|
48
|
+
def push(*argv)
|
49
|
+
raise NotImplemented
|
50
|
+
end
|
51
|
+
|
52
|
+
def pull(*argv)
|
53
|
+
raise NotImplemented
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
|
58
|
+
|
59
|
+
def one_ref(named)
|
60
|
+
self.class.refs.split(/\n/).detect do |ref|
|
61
|
+
ref_name = ref.split(/\t/).last
|
62
|
+
ref_name.split('/').last == named || ref_name.split('/',2).last == named || ref_name == named # git style matching
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def raise_errors
|
67
|
+
unless self.class.accessible
|
68
|
+
raise CommandError.new('mock command', 1, '', 'stderr')
|
69
|
+
end
|
70
|
+
|
71
|
+
if self.class.timeout
|
72
|
+
raise TimeoutError.new('mock command', @uri)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'open4'
|
2
|
+
require 'escape'
|
3
|
+
require 'git-ssh-wrapper'
|
4
|
+
require 'system_timer'
|
5
|
+
|
6
|
+
module Regrit
|
7
|
+
module Provider
|
8
|
+
class System
|
9
|
+
DEFAULT_TIMEOUT = 5
|
10
|
+
|
11
|
+
def initialize(uri, options)
|
12
|
+
@uri = uri
|
13
|
+
@timeout = options[:timeout] || DEFAULT_TIMEOUT
|
14
|
+
load_git_ssh_wrapper(options) if @uri.ssh?
|
15
|
+
end
|
16
|
+
|
17
|
+
def ls_remote(named=nil)
|
18
|
+
git "ls-remote", @uri.to_s, named
|
19
|
+
end
|
20
|
+
|
21
|
+
def clone(*argv)
|
22
|
+
git "clone", *argv
|
23
|
+
end
|
24
|
+
|
25
|
+
def fetch(*argv)
|
26
|
+
git "fetch", *argv
|
27
|
+
end
|
28
|
+
|
29
|
+
def push(*argv)
|
30
|
+
git "push", *argv
|
31
|
+
end
|
32
|
+
|
33
|
+
def pull(*argv)
|
34
|
+
git "pull", *argv
|
35
|
+
end
|
36
|
+
|
37
|
+
def git(*argv)
|
38
|
+
spawn "#{git_command} #{Escape.shell_command(argv.flatten.compact)}"
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
# Only require open4 here so as not to set a hard dependency.
|
44
|
+
#
|
45
|
+
# Might raise CommandError or TimeoutError
|
46
|
+
def spawn(command)
|
47
|
+
stdout, stderr = '', ''
|
48
|
+
SystemTimer.timeout(@timeout) do
|
49
|
+
Open4.spawn(command, :stdout => stdout, :stderr => stderr, :timeout => @timeout)
|
50
|
+
end
|
51
|
+
stdout
|
52
|
+
rescue Open4::SpawnError => e
|
53
|
+
raise CommandError.new(e.cmd, e.exitstatus, stdout, stderr)
|
54
|
+
rescue Timeout::Error
|
55
|
+
raise TimeoutError.new(command, @uri)
|
56
|
+
end
|
57
|
+
|
58
|
+
def git_command
|
59
|
+
# GIT_ASKPASS='echo' keeps password prompts from stalling the proccess (they still fail)
|
60
|
+
"env GIT_ASKPASS='echo' #{@uri.ssh? ? @git_ssh_wrapper.git_ssh : ''} git"
|
61
|
+
end
|
62
|
+
|
63
|
+
def load_git_ssh_wrapper(options)
|
64
|
+
@git_ssh_wrapper = GitSSHWrapper.new(options)
|
65
|
+
rescue GitSSHWrapper::PrivateKeyRequired
|
66
|
+
raise Regrit::PrivateKeyRequired.new(@uri)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/regrit/ref.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Regrit
|
2
|
+
class Ref
|
3
|
+
def initialize(repo, ref)
|
4
|
+
@repo = repo
|
5
|
+
@commit, @name = ref.split(/\t/)
|
6
|
+
raise InvalidRefsFormat.new(ref) if @name.nil?
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :commit, :name
|
10
|
+
|
11
|
+
def abbrev_commit
|
12
|
+
commit[0...7]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'gitable'
|
2
|
+
require 'regrit/ref'
|
3
|
+
|
4
|
+
module Regrit
|
5
|
+
class RemoteRepo
|
6
|
+
|
7
|
+
REFS_REGEXP = /^[0-9a-f]{40}\t\w/i
|
8
|
+
|
9
|
+
attr_reader :uri
|
10
|
+
|
11
|
+
def initialize(uri, options={})
|
12
|
+
if uri.nil? || uri.empty?
|
13
|
+
raise InvalidURIError
|
14
|
+
end
|
15
|
+
|
16
|
+
begin
|
17
|
+
@uri = Gitable::URI.parse(uri)
|
18
|
+
rescue TypeError, Gitable::URI::InvalidURIError
|
19
|
+
raise InvalidURIError
|
20
|
+
end
|
21
|
+
|
22
|
+
# no user without ssh and no ssh without user - ^ is the XOR operator
|
23
|
+
if @uri.ssh? ^ @uri.user
|
24
|
+
raise InvalidURIError
|
25
|
+
end
|
26
|
+
|
27
|
+
@provider = Provider.new(@uri, options)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Decide if the URI is likely to require authentication
|
31
|
+
# @return [Boolean] Does the repo require auth?
|
32
|
+
def private_key_required?
|
33
|
+
@uri.ssh?
|
34
|
+
end
|
35
|
+
|
36
|
+
# Attempt to grab refs. If the repository is auth required and a private key
|
37
|
+
# is passed, use ssh to attempt access to the repository.
|
38
|
+
#
|
39
|
+
# @return [Boolean] can the repository be accessed?
|
40
|
+
def accessible?
|
41
|
+
!!refs
|
42
|
+
rescue Inaccessible
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
# Use a git ls-remote to load all repository refs
|
47
|
+
#
|
48
|
+
# @return [Array] An Array of Ref objects
|
49
|
+
def refs
|
50
|
+
@refs ||= load_refs
|
51
|
+
end
|
52
|
+
|
53
|
+
# Use a git ls-remote to find a single ref
|
54
|
+
#
|
55
|
+
# @return [Ref, nil] A Ref object or nil
|
56
|
+
def ref(named)
|
57
|
+
load_refs(named).first
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
attr_reader :provider
|
63
|
+
|
64
|
+
def load_refs(named=nil)
|
65
|
+
raw_refs = provider.ls_remote(named)
|
66
|
+
|
67
|
+
return [] if raw_refs.empty?
|
68
|
+
|
69
|
+
unless raw_refs =~ REFS_REGEXP
|
70
|
+
raise InvalidRefsFormat.new(raw_refs)
|
71
|
+
end
|
72
|
+
|
73
|
+
raw_refs.split(/\n/).map { |ref| Ref.new(self, ref) }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/regrit.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "regrit/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "regrit"
|
7
|
+
s.version = Regrit::VERSION
|
8
|
+
s.authors = ["Martin Emde"]
|
9
|
+
s.email = ["martin.emde@gmail.com"]
|
10
|
+
s.homepage = "http://github.org/martinemde/regrit"
|
11
|
+
s.summary = %q{Never regrit how you talk with remote git repositories}
|
12
|
+
s.description = %q{Deal with remote git repositories, yo.}
|
13
|
+
|
14
|
+
s.add_dependency "gitable", "~> 0.1.2"
|
15
|
+
s.add_dependency "open4"
|
16
|
+
s.add_dependency "escape"
|
17
|
+
s.add_dependency "git-ssh-wrapper", "~> 0.0.1"
|
18
|
+
s.add_dependency "SystemTimer"
|
19
|
+
|
20
|
+
s.add_development_dependency "rspec", "~> 1.3"
|
21
|
+
s.add_development_dependency "rake"
|
22
|
+
|
23
|
+
s.files = `git ls-files`.split("\n")
|
24
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
25
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
end
|
data/spec/id_rsa
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEowIBAAKCAQEAw/yPM/JVRBMB31fNQE5rI38EhGsUGY5yYRlNkojqCTddBdPs
|
3
|
+
DKjq56q4iPn2YCl01h2wYdOYRwgHkWRSCiYuveFKojqlY7/IcXbWqNShAuV6bAMy
|
4
|
+
eCC1c5pNzGJYylv7WuP1MWT+0/mnJp3pykN5u7FDZ3MfYwMbl1SKqKnw6oKa5RCS
|
5
|
+
m7zPuj62o+KdEHTvce4ozoWkGzSAReh1hDTivJFYOMFgrn1y4GMWBskjcYK9iMQB
|
6
|
+
ZI3gzM+QRKk7bMyEh+kwZxhJ4sYJlpJjMzEsMgpER2lzuQDRDktGieaUYBLdo/3R
|
7
|
+
9op3B1Zkb/xJgtS1aOfZQAC720hMjEkNsrZIwwIBIwKCAQEAgMqJ/ZCebpAlzUhT
|
8
|
+
repjqZyckYgxx6bAMS3ihN2hG//PajrOUXZROScLjTaL9gydPD9lR5mtNf32WDqc
|
9
|
+
T8/y1Iy8BDUq2yZB5CmFv2cn+pbMyqMD6IqF3kDUCfd8LTUhhN7xlXzh+QMksvoO
|
10
|
+
qXzMVsTxx6NsZaL038nXdiaIX5aBDyow9XuAGjli6gDjN4+MLtw4VaOdo6GZJmDe
|
11
|
+
pDAf8WIM+y1RtnFcQrZOO6lU+aOAPdi8cboj8mNrgAt0hyOndDqWrWFzBtWviXtV
|
12
|
+
Ok2IcUNvGnO20ax0EaC3oTRTtwEvbywTx9aCSJ6eyGyL64MX749Mr4Tk4mmwXlyx
|
13
|
+
Wf268wKBgQDnrNrSkT856yOCUu2tC95MiC0NyKQF64o+YILIkdzsDJnB7Y7I80wt
|
14
|
+
WkaTLx09RgW6pEbC341fSUIYCaTb/jGynEje74qgjC8bWDtQmXUKbgcznS4qYVgl
|
15
|
+
rcGoAt9ZSXdeDVk2qRqSagahDSEvz8tbXn0NPGXeo8db3XUIIf2hPQKBgQDYkG/7
|
16
|
+
Gn7eAD5P4bvvS92V8Fu6KoR2pfchMI97iTAfH0D8+X5TCbxrNtqRW32yxd0/vgbo
|
17
|
+
Gri6HdTJg0v8BSHH9/k/p12K/kagVt4su3KrLepcdtkc4PAnRbZw1H/zWSpj7XfL
|
18
|
+
HVX89ya7f8ad0ja7LpC7fhNqp09p3HN9P24x/wKBgHclsl2pyL6zcVj3cutH7qsE
|
19
|
+
NG19ISedtM+fWTPzPmrEptjDUL8eCetwQY2F8ce9nIvfdNk/xQxu0Yi0gKunTMJB
|
20
|
+
vxORIrj3ozKiZ6XLQ4G07cLF3Tpd8tGMj3r6Kbjj9D7/jPeKKuw2hxD/cCc3qmmB
|
21
|
+
DRy/+eA2+NAov9hL/sfzAoGBAJSATMlxQQ1B/tewu2JCppKzchlBuer1dkKk9Kx7
|
22
|
+
VDKZFp7W94llwwewleAEOO+dnwcjN++dS3hO+E+qfT8Zdj/6fwcTrdunC9upR+Qo
|
23
|
+
w6iUg3Kao4GETOe6xj69mZDsr1p28w7vi2uiKTAdGnrZShn0C3lAglfDLyQE4Xp0
|
24
|
+
o1V7AoGBAJW1veLTbtmKMQ0WdaN594R75D+ORhSrbj7Dr+ITb9Iz81HBT1lN2hjx
|
25
|
+
T4qWNo4yhny8MH1+NCK8SfQBpgdFo+SYL0fPBEr1DEH2PsnbDAyxvdn4QvfqCEAH
|
26
|
+
duj2CyGRhITAc98l3r6a1j0gDeyLaeXRPGu+CKg3pngW+/IuNTUA
|
27
|
+
-----END RSA PRIVATE KEY-----
|
data/spec/id_rsa.pub
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAw/yPM/JVRBMB31fNQE5rI38EhGsUGY5yYRlNkojqCTddBdPsDKjq56q4iPn2YCl01h2wYdOYRwgHkWRSCiYuveFKojqlY7/IcXbWqNShAuV6bAMyeCC1c5pNzGJYylv7WuP1MWT+0/mnJp3pykN5u7FDZ3MfYwMbl1SKqKnw6oKa5RCSm7zPuj62o+KdEHTvce4ozoWkGzSAReh1hDTivJFYOMFgrn1y4GMWBskjcYK9iMQBZI3gzM+QRKk7bMyEh+kwZxhJ4sYJlpJjMzEsMgpER2lzuQDRDktGieaUYBLdo/3R9op3B1Zkb/xJgtS1aOfZQAC720hMjEkNsrZIww== memde@kaffir.local
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Regrit::RemoteRepo do
|
4
|
+
before { Regrit.enable_mock! }
|
5
|
+
after { Regrit.disable_mock! }
|
6
|
+
|
7
|
+
before { @uri = 'git://example.com/does/not/work.git' }
|
8
|
+
|
9
|
+
context "(public)" do
|
10
|
+
# This uri would not work if we weren't mocked
|
11
|
+
subject { described_class.new(@uri) }
|
12
|
+
|
13
|
+
it { should_not be_private_key_required }
|
14
|
+
|
15
|
+
context "(mocked accessible)" do
|
16
|
+
before { Regrit::Provider::Mock.accessible = true }
|
17
|
+
it { should be_accessible }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "(mocked inaccessible)" do
|
21
|
+
before { Regrit::Provider::Mock.accessible = false }
|
22
|
+
it { should_not be_accessible }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "(mocked timeout)" do
|
26
|
+
before { Regrit::Provider::Mock.timeout = true }
|
27
|
+
it { should_not be_accessible }
|
28
|
+
|
29
|
+
it "should raise TimeoutError" do
|
30
|
+
subject { described_class.new(@uri) }
|
31
|
+
|
32
|
+
lambda { subject.refs }.should raise_error(Regrit::TimeoutError)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
context "(private)" do
|
39
|
+
# This uri would not work if we weren't mocked
|
40
|
+
|
41
|
+
context "(mocked accessible)" do
|
42
|
+
before { Regrit::Provider::Mock.accessible = true }
|
43
|
+
|
44
|
+
it "still raises on bad key" do
|
45
|
+
pending("should we care if the key is blank in mock mode?") do
|
46
|
+
lambda { described_class.new(@uri, :private_key => '') }.should raise_error
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with a key" do
|
51
|
+
subject { described_class.new(@uri, :private_key => 'any key') }
|
52
|
+
it { subject.should be_accessible }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "(mocked inaccessible)" do
|
57
|
+
before { Regrit::Provider::Mock.accessible = false }
|
58
|
+
|
59
|
+
it "still raises on bad key" do
|
60
|
+
pending("should we care if the key is blank in mock mode?") do
|
61
|
+
lambda { described_class.new(@uri, :private_key => '') }.should raise_error
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with a key" do
|
66
|
+
subject { described_class.new(@uri, :private_key => private_key) }
|
67
|
+
it { subject.should_not be_accessible }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "(refs)" do
|
73
|
+
subject { described_class.new(@uri) }
|
74
|
+
|
75
|
+
it "returns default refs" do
|
76
|
+
subject.should have(2).refs
|
77
|
+
subject.ref('master').abbrev_commit.should == "1234567"
|
78
|
+
subject.refs.first.name.should == "HEAD"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns nil if no ref matches" do
|
82
|
+
subject.ref('thisdoesntexist').should be_nil
|
83
|
+
end
|
84
|
+
|
85
|
+
context "(setting the response)" do
|
86
|
+
before do
|
87
|
+
Regrit::Provider::Mock.refs = <<-REFS
|
88
|
+
1234567890123456789012345678901234567890\tHEAD
|
89
|
+
1234567890123456789012345678901234567890\trefs/heads/master
|
90
|
+
REFS
|
91
|
+
end
|
92
|
+
|
93
|
+
it "returns the refs as set" do
|
94
|
+
subject.should have(2).refs
|
95
|
+
subject.ref('master').abbrev_commit.should == "1234567"
|
96
|
+
subject.refs.first.name.should == "HEAD"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Regrit::RemoteRepo do
|
4
|
+
|
5
|
+
context "(invalid uri)" do
|
6
|
+
[
|
7
|
+
'http://',
|
8
|
+
'git://user@host.com/repo/here.git', # not valid according to docs
|
9
|
+
nil, ""
|
10
|
+
].each do |uri|
|
11
|
+
it "raises on initialization with #{uri.inspect}" do
|
12
|
+
lambda { described_class.new(uri) }.should raise_error(Regrit::InvalidURIError)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "(valid uri)" do
|
18
|
+
[
|
19
|
+
# valid host names as described by git documentation
|
20
|
+
'rsync://host.xz/path/to/repo.git/',
|
21
|
+
'ftps://host.xz/path/to/repo.git/',
|
22
|
+
'ftp://host.xz/path/to/repo.git/',
|
23
|
+
'http://host.xz/path/to/repo.git/',
|
24
|
+
'https://host.xz/path/to/repo.git/',
|
25
|
+
'git://host.xz/path/to/repo.git',
|
26
|
+
'git://host.xz:8888/path/to/repo.git/',
|
27
|
+
'git://host.xz/~user/path/to/repo.git',
|
28
|
+
'git://host.xz:8888/~user/path/to/repo.git/',
|
29
|
+
'git://11.22.33.44/~user/path/to/repo.git',
|
30
|
+
'git://12.34.56.78:8888/~user/path/to/repo.git/',
|
31
|
+
'ssh://user@11.22.33.44/path/to/repo.git/',
|
32
|
+
'ssh://user@111.222.333.444:8888/path/to/repo.git',
|
33
|
+
'ssh://user@host.xz:8888/path/to/repo.git',
|
34
|
+
'ssh://user@host.xz/path/to/repo.git/',
|
35
|
+
'ssh://user@host.xz/~user/path/to/repo.git/',
|
36
|
+
'ssh://user@host.xz/~/path/to/repo.git',
|
37
|
+
'user@host.xz:/path/to/repo.git',
|
38
|
+
'user@123.123.123.123:/path/to/repo.git',
|
39
|
+
'user@host.xz:~user/path/to/repo.git/',
|
40
|
+
'user@1.0.0.0:~user/path/to/repo.git/',
|
41
|
+
'user@host.xz:path/to/repo.git',
|
42
|
+
].each do |uri|
|
43
|
+
it "creates a Regrit::RemoteRepo with #{uri.inspect}" do
|
44
|
+
described_class.new(uri, :private_key => private_key).should be_a_kind_of(described_class)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# These specs could be a bit more brittle because they access public repositories
|
50
|
+
describe "accessing" do
|
51
|
+
context "(non-resolving)" do
|
52
|
+
subject { described_class.new("git://example.com/non-resolve.git") }
|
53
|
+
|
54
|
+
it "doesn't hang when trying to access a bad server name" do
|
55
|
+
should_not be_accessible
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "(non-existant)" do
|
60
|
+
subject { described_class.new("git://github.com/engineyard/this_project_will_never_exist_and_if_it_does_then_this_will_break.git") }
|
61
|
+
|
62
|
+
it { should_not be_private_key_required }
|
63
|
+
it { should_not be_accessible }
|
64
|
+
end
|
65
|
+
|
66
|
+
context "(public)" do
|
67
|
+
subject { described_class.new("git://github.com/rails/rails.git") }
|
68
|
+
|
69
|
+
it { should_not be_private_key_required }
|
70
|
+
it { should be_accessible }
|
71
|
+
end
|
72
|
+
|
73
|
+
context "(private)" do
|
74
|
+
before { @uri = "git@github.com:martinemde/regrit.git" }
|
75
|
+
subject { described_class.new(@uri, :private_key => private_key) }
|
76
|
+
|
77
|
+
it { should be_private_key_required }
|
78
|
+
it { should be_accessible }
|
79
|
+
|
80
|
+
describe "loading refs" do
|
81
|
+
it { should have_at_least(2).refs }
|
82
|
+
|
83
|
+
it "has a master ref" do
|
84
|
+
subject.ref('master').name.should == 'refs/heads/master'
|
85
|
+
end
|
86
|
+
|
87
|
+
it "has a refs/heads/master ref" do
|
88
|
+
subject.ref('refs/heads/master').name.should == 'refs/heads/master'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it "raises on initialization without a key" do
|
93
|
+
lambda { described_class.new(@uri) }.should raise_error(Regrit::PrivateKeyRequired)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "raises on initialization with an empty key" do
|
97
|
+
lambda { described_class.new(@uri, :private_key => '') }.should raise_error(Regrit::PrivateKeyRequired)
|
98
|
+
end
|
99
|
+
|
100
|
+
context "with wrong key" do
|
101
|
+
subject { described_class.new(@uri, :private_key => wrong_private_key) }
|
102
|
+
it { should_not be_accessible }
|
103
|
+
it "raises a CommandError on trying to access refs" do
|
104
|
+
lambda { subject.refs }.should raise_error(Regrit::CommandError)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
unless defined? Bundler
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.setup
|
5
|
+
end
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
|
+
require 'regrit'
|
10
|
+
require 'spec'
|
11
|
+
|
12
|
+
module TestPrivateKey
|
13
|
+
def private_key
|
14
|
+
Pathname.new('spec/id_rsa').read
|
15
|
+
end
|
16
|
+
|
17
|
+
def wrong_private_key
|
18
|
+
Pathname.new('spec/wrong_key').read
|
19
|
+
end
|
20
|
+
|
21
|
+
def private_key_path
|
22
|
+
Pathname.new('spec/id_rsa').to_s
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Spec::Runner.configure do |config|
|
27
|
+
config.include TestPrivateKey
|
28
|
+
end
|
data/spec/wrong_key
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEogIBAAKCAQEAwxjNTMWto8Q0l6TLQoWb5cT81f02+lapbhmGEqrEcF/cM1Un
|
3
|
+
QaQmJfvz+ZC32pyYqmav5x4RT4RRaxm4xjlRo22hMroXlnzKLgm+a6hA0R5a2gk+
|
4
|
+
quxs25XtvRxIig/H4OoLcfxmbUIqpT3ma7rgWE1+cxWsryCLKjv4Pp1bLeIAjyWk
|
5
|
+
eANUXbr7xn+uDSuL69b08A5AlvS1AfE1Mtwj2X1djoeivByJ4MAj5oOwIuoijHvW
|
6
|
+
bL+VDeXm1FPUMtRDN7t8NLOjbKU/UXZXSQJDqhJ9agb6DTSCrsZcarSbP3fr5I19
|
7
|
+
W6IeH1vDjCydHOdno4pQdZbpuI9c5c+x+WHv5wIBIwKCAQAQuPunfqh7wFxHgydd
|
8
|
+
eSqeqnwSV4hembbAS1Sig6pwCDdyHT3hDhHl/6cypgEhXeEzLV+I1rEG0NPHWfnl
|
9
|
+
Gtscov8wO9Yi138LQqnr+HqVlOM3Qp74tS3m75gI5SrKAVpGenYCdLhSggOnw3om
|
10
|
+
fbt1SHiNhYPUfyHfDHRdI243IdmxX2UIwhmUkHSUwWFTJqvwXZx6MnlPGV/s/hew
|
11
|
+
1lwIJKkdbNavphv0Sw6ycYs0KpRx5FHJStT25r6R59JRsmnTbDEZWEso5B4doHzp
|
12
|
+
JQbYbKxIPOx7bRyKo/vAZ6tozqjLRabs7QQaK7zjS+5KZBlbz1NfCMueZF+iS/AS
|
13
|
+
b2FLAoGBAOpoVIK43ry44ETA2vJAKh47VYQ61k7fnyfES+Mg9k4b+va68ddOPL2G
|
14
|
+
SZ6bxwFx5YG+KCCkVcIaO39/BaHhimD1UnZAmBV/lMmxBeoneWT6N3tqdSHQbXha
|
15
|
+
zLeko0QgzwIcAXSC1l1Q/XEs9k+apoVMYmbs1rJj27RvKUSYHCGhAoGBANUReDGu
|
16
|
+
TBffmrw+KfcC6O0RkqR46xUcgtjGEOhYIPlegVx8Sq1sozDjCtnTkAFQaTJIQVDx
|
17
|
+
Vh5d0Q1ZvZyYKGT1JXPMasu6qxZGyrvW2OQoPH1fdbvyI2gCgIEBV9ytPeMvtMK3
|
18
|
+
U+ZHtWFYwHFzsQ/StRzeru/HdfdmhdHfh7SHAoGBAKC8kbi5SEblLBHjVE5X4l3f
|
19
|
+
ixjX42lI4inlsGE7LI1VA9xi7voJw0AhkZFU4DuBTOtAkItpX2CHBDorNw/rHQ9J
|
20
|
+
Ipo66/F8DkEo7hzn3jac8thI/9ysLc7fLUq6CY3NWr+eLOIt1NJGKiG4bmJ4rLMt
|
21
|
+
EEaTxmuyMEE2SC8JN9yLAoGATyO+7eGnPBE5eR5nW79AkpF/nCzpmiCIXyT+9zat
|
22
|
+
KWw+rVK8ptCUYp15DxQQ6ouUyYiNSfM9PnqeGubRZgyhShHpVuWGwLMMWLs1W7Yz
|
23
|
+
TW4H1suvYxDLUoSWIUmkSqa/NyBZFR+FkAwBio6t4P8V4U5DRTzEojQkgHaJedau
|
24
|
+
v2UCgYEA2nCMG3AQLEy1QRz1ZaNiZ+kzdWByWj235YozBBtWgygt14/LBlM9+Tc4
|
25
|
+
lwdu/+eJFa4b+PV22MJNyfHUAq7PuYAxyc3PpAfrv9XC7PuIVue5u+GyIjqVrUYU
|
26
|
+
fDZo8xXylLsAceKIu8gftDx3yRFRqc7VQuqHu2OKnz606CviYU4=
|
27
|
+
-----END RSA PRIVATE KEY-----
|
metadata
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: regrit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 21
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Martin Emde
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-14 00:00:00 -08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 31
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 1
|
31
|
+
- 2
|
32
|
+
version: 0.1.2
|
33
|
+
requirement: *id001
|
34
|
+
name: gitable
|
35
|
+
prerelease: false
|
36
|
+
type: :runtime
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
requirement: *id002
|
48
|
+
name: open4
|
49
|
+
prerelease: false
|
50
|
+
type: :runtime
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
requirement: *id003
|
62
|
+
name: escape
|
63
|
+
prerelease: false
|
64
|
+
type: :runtime
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ~>
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 29
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
- 0
|
75
|
+
- 1
|
76
|
+
version: 0.0.1
|
77
|
+
requirement: *id004
|
78
|
+
name: git-ssh-wrapper
|
79
|
+
prerelease: false
|
80
|
+
type: :runtime
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
requirement: *id005
|
92
|
+
name: SystemTimer
|
93
|
+
prerelease: false
|
94
|
+
type: :runtime
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 9
|
102
|
+
segments:
|
103
|
+
- 1
|
104
|
+
- 3
|
105
|
+
version: "1.3"
|
106
|
+
requirement: *id006
|
107
|
+
name: rspec
|
108
|
+
prerelease: false
|
109
|
+
type: :development
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
hash: 3
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
version: "0"
|
120
|
+
requirement: *id007
|
121
|
+
name: rake
|
122
|
+
prerelease: false
|
123
|
+
type: :development
|
124
|
+
description: Deal with remote git repositories, yo.
|
125
|
+
email:
|
126
|
+
- martin.emde@gmail.com
|
127
|
+
executables: []
|
128
|
+
|
129
|
+
extensions: []
|
130
|
+
|
131
|
+
extra_rdoc_files: []
|
132
|
+
|
133
|
+
files:
|
134
|
+
- .gitignore
|
135
|
+
- Gemfile
|
136
|
+
- README.md
|
137
|
+
- Rakefile
|
138
|
+
- lib/regrit.rb
|
139
|
+
- lib/regrit/errors.rb
|
140
|
+
- lib/regrit/provider.rb
|
141
|
+
- lib/regrit/provider/mock.rb
|
142
|
+
- lib/regrit/provider/system.rb
|
143
|
+
- lib/regrit/ref.rb
|
144
|
+
- lib/regrit/remote_repo.rb
|
145
|
+
- lib/regrit/version.rb
|
146
|
+
- regrit.gemspec
|
147
|
+
- spec/id_rsa
|
148
|
+
- spec/id_rsa.pub
|
149
|
+
- spec/mocks_enabled_spec.rb
|
150
|
+
- spec/remote_repo_spec.rb
|
151
|
+
- spec/spec.opts
|
152
|
+
- spec/spec_helper.rb
|
153
|
+
- spec/wrong_key
|
154
|
+
has_rdoc: true
|
155
|
+
homepage: http://github.org/martinemde/regrit
|
156
|
+
licenses: []
|
157
|
+
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
|
161
|
+
require_paths:
|
162
|
+
- lib
|
163
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
hash: 3
|
169
|
+
segments:
|
170
|
+
- 0
|
171
|
+
version: "0"
|
172
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
|
+
none: false
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
hash: 3
|
178
|
+
segments:
|
179
|
+
- 0
|
180
|
+
version: "0"
|
181
|
+
requirements: []
|
182
|
+
|
183
|
+
rubyforge_project:
|
184
|
+
rubygems_version: 1.3.7
|
185
|
+
signing_key:
|
186
|
+
specification_version: 3
|
187
|
+
summary: Never regrit how you talk with remote git repositories
|
188
|
+
test_files:
|
189
|
+
- spec/id_rsa
|
190
|
+
- spec/id_rsa.pub
|
191
|
+
- spec/mocks_enabled_spec.rb
|
192
|
+
- spec/remote_repo_spec.rb
|
193
|
+
- spec/spec.opts
|
194
|
+
- spec/spec_helper.rb
|
195
|
+
- spec/wrong_key
|