Add Remotes

This commit is contained in:
Matt Diephouse 2015-01-03 09:43:42 -05:00
parent e40e19a3fc
commit 4a0b5cd838
8 changed files with 167 additions and 1 deletions

View File

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
BE0991F71A578FB1007D4E6A /* Mantle.zip in Resources */ = {isa = PBXBuildFile; fileRef = BE0991F61A578FB1007D4E6A /* Mantle.zip */; };
BE14AA321A15AA510015B439 /* LlamaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE14AA311A15AA510015B439 /* LlamaKit.framework */; };
BE14AA501A1974010015B439 /* SwiftGit2.m in Sources */ = {isa = PBXBuildFile; fileRef = BE14AA4F1A1974010015B439 /* SwiftGit2.m */; };
BE14AA551A1984550015B439 /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE14AA541A1984550015B439 /* Fixtures.swift */; };
@ -66,6 +67,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
BE0991F61A578FB1007D4E6A /* Mantle.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Mantle.zip; sourceTree = "<group>"; };
BE14AA311A15AA510015B439 /* LlamaKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LlamaKit.framework; path = External/LlamaKit/build/Debug/LlamaKit.framework; sourceTree = "<group>"; };
BE14AA4F1A1974010015B439 /* SwiftGit2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SwiftGit2.m; sourceTree = "<group>"; };
BE14AA541A1984550015B439 /* Fixtures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fixtures.swift; sourceTree = "<group>"; };
@ -143,6 +145,7 @@
isa = PBXGroup;
children = (
BE14AA541A1984550015B439 /* Fixtures.swift */,
BE0991F61A578FB1007D4E6A /* Mantle.zip */,
BE14AA561A198C6E0015B439 /* simple-repository.zip */,
);
path = Fixtures;
@ -426,6 +429,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BE0991F71A578FB1007D4E6A /* Mantle.zip in Resources */,
BE14AA571A198C6E0015B439 /* simple-repository.zip in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -6,3 +6,29 @@
// Copyright (c) 2015 GitHub, Inc. All rights reserved.
//
/// A remote in a git repository.
public struct Remote {
/// The name of the remote.
public let name: String
/// The URL of the remote.
///
/// This may be an SSH URL, which isn't representable using `NSURL`.
public let URL: String
/// Create an instance with a libgit2 `git_remote`.
public init(_ pointer: COpaquePointer) {
name = String.fromCString(git_remote_name(pointer))!
URL = String.fromCString(git_remote_url(pointer))!
}
}
extension Remote: Hashable {
public var hashValue: Int {
return name.hashValue ^ URL.hashValue
}
}
public func == (lhs: Remote, rhs: Remote) -> Bool {
return lhs.name == rhs.name && lhs.URL == rhs.URL
}

View File

@ -146,4 +146,55 @@ final public class Repository {
return treeWithOID(oid).map { $0 as ObjectType }
}
}
// MARK: - Remote Lookups
/// Loads all the remotes in the repository.
///
/// Returns an array of remotes, or an error.
public func allRemotes() -> Result<[Remote]> {
let pointer = UnsafeMutablePointer<git_strarray>.alloc(1)
let repository = self.pointer
let result = git_remote_list(pointer, repository)
if result != GIT_OK.value {
pointer.dealloc(1)
return failure()
}
let strarray = pointer.memory
let remotes: [Result<Remote>] = map(0..<strarray.count) {
let idx = Int($0)
let name = String.fromCString(strarray.strings[idx])!
return self.remoteWithName(name)
}
pointer.dealloc(1)
let error = remotes.reduce(nil) { $0 == nil ? $0 : $1.error() }
if let error = error {
return failure(error)
}
return success(remotes.map { $0.value()! })
}
/// Load a remote from the repository.
///
/// name - The name of the remote.
///
/// Returns the remote if it exists, or an error.
public func remoteWithName(name: String) -> Result<Remote> {
let pointer = UnsafeMutablePointer<COpaquePointer>.alloc(1)
let repository = self.pointer
let result = git_remote_lookup(pointer, repository, name.cStringUsingEncoding(NSUTF8StringEncoding)!)
if result != GIT_OK.value {
pointer.dealloc(1)
return failure()
}
let value = Remote(pointer.memory)
git_remote_free(pointer.memory)
pointer.dealloc(1)
return success(value)
}
}

View File

@ -67,4 +67,8 @@ final class Fixtures {
class var simpleRepository: Repository {
return Fixtures.sharedInstance.repositoryWithName("simple-repository")
}
class var mantleRepository: Repository {
return Fixtures.sharedInstance.repositoryWithName("Mantle")
}
}

Binary file not shown.

View File

@ -11,7 +11,7 @@ import SwiftGit2
import Nimble
import Quick
func from_git_object<T>(repository: Repository, oid: OID, f: COpaquePointer -> T) -> T{
func from_git_object<T>(repository: Repository, oid: OID, f: COpaquePointer -> T) -> T {
let repository = repository.pointer
var oid = oid.oid

View File

@ -10,3 +10,54 @@ import LlamaKit
import SwiftGit2
import Nimble
import Quick
func with_git_remote<T>(repository: Repository, name: String, f: COpaquePointer -> T) -> T {
let repository = repository.pointer
let pointer = UnsafeMutablePointer<COpaquePointer>.alloc(1)
git_remote_lookup(pointer, repository, name.cStringUsingEncoding(NSUTF8StringEncoding)!)
let result = f(pointer.memory)
git_object_free(pointer.memory)
pointer.dealloc(1)
return result
}
class RemoteSpec: QuickSpec {
override func spec() {
describe("init(pointer:)") {
it("should initialize its properties") {
let repo = Fixtures.mantleRepository
let remote = with_git_remote(repo, "upstream") { Remote($0) }
expect(remote.name).to(equal("upstream"))
expect(remote.URL).to(equal("git@github.com:Mantle/Mantle.git"))
}
}
describe("==") {
it("should be true with equal objects") {
let repo = Fixtures.mantleRepository
let remote1 = with_git_remote(repo, "upstream") { Remote($0) }
let remote2 = remote1
expect(remote1).to(equal(remote2))
}
it("should be false with unequal objcets") {
let repo = Fixtures.mantleRepository
let origin = with_git_remote(repo, "origin") { Remote($0) }
let upstream = with_git_remote(repo, "upstream") { Remote($0) }
expect(origin).notTo(equal(upstream))
}
}
describe("hashValue") {
it("should be equal with equal objcets") {
let repo = Fixtures.mantleRepository
let remote1 = with_git_remote(repo, "upstream") { Remote($0) }
let remote2 = remote1
expect(remote1.hashValue).to(equal(remote2.hashValue))
}
}
}
}

View File

@ -222,5 +222,35 @@ class RepositorySpec: QuickSpec {
expect(result).to(equal(tag))
}
}
describe("-allRemotes()") {
it("should return an empty list if there are no remotes") {
let repo = Fixtures.simpleRepository
let result = repo.allRemotes()
expect(result.value()).to(equal([]))
}
it("should return all the remotes") {
let repo = Fixtures.mantleRepository
let remotes = repo.allRemotes().value()
let names = remotes?.map { $0.name }
expect(remotes?.count).to(equal(2))
expect(names).to(contain("origin", "upstream"))
}
}
describe("-remoteWithName()") {
it("should return the remote if it exists") {
let repo = Fixtures.mantleRepository
let result = repo.remoteWithName("upstream")
expect(result.value()?.name).to(equal("upstream"))
}
it("should error if the remote doesn't exist") {
let repo = Fixtures.simpleRepository
let result = repo.remoteWithName("nonexistent")
expect(result.error()).notTo(beNil())
}
}
}
}