Skip to content

Commit

Permalink
Passing pointer through block doesn't work as expected
Browse files Browse the repository at this point in the history
turns back to normal procedural calls, iterator tested.
  • Loading branch information
Arnon Keereena committed Apr 28, 2017
1 parent de2984c commit aa9f066
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 29 deletions.
48 changes: 26 additions & 22 deletions SwiftGit2/CommitIterator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class CommitIterator: IteratorProtocol {
var branch: Branch
var revisionWalker: OpaquePointer? = nil
var oid: git_oid
private var unsafeCommit: OpaquePointer? = nil

public init(repo: Repository, branch: Branch) {
self.repo = repo
Expand All @@ -31,33 +32,36 @@ public class CommitIterator: IteratorProtocol {
git_revwalk_push(revisionWalker, &oid)
}

private func error(from gitCommands: [(key: String, value: () -> Int32)]) -> NSError? {
// TODO: Make a flatMap command that stops on first nil
let errors: [NSError] = gitCommands.flatMap {
let result = $0.value()
return result == GIT_OK.rawValue ? nil : NSError(gitError: result, pointOfFailure: $0.key)
}
if errors.count > 0 {
return errors.first!
} else {
return nil
private func result(withName name: String, from result: Int32) -> (stop: Bool, error: NSError?) {
guard result == GIT_OK.rawValue else {
if result == GIT_ITEROVER.rawValue {
return (stop: true, error: nil)
} else {
return (stop: false, error: NSError(gitError: result, pointOfFailure: name))
}
}
return (stop: false, error: nil)
}

public func next() -> Element? {
var unsafeCommit: OpaquePointer? = nil
let gitCommands = [
(key: "git_revwalk_next", value: { return git_revwalk_next(&self.oid, self.revisionWalker) }),
(key: "git_commit_lookup", value: { return git_commit_lookup(&unsafeCommit, self.repo.pointer, &self.oid) })
]
if let error = error(from: gitCommands) {
let revwalkGitResult = git_revwalk_next(&self.oid, self.revisionWalker)
let revwalkResult = result(withName: "git_revwalk_next", from: revwalkGitResult)
if revwalkResult.stop {
return nil
} else if let error = revwalkResult.error {
return Result.failure(error)
} else {
guard let commit = unsafeCommit else {
return nil
}
git_commit_free(unsafeCommit)
return Result.success(Commit(commit))
}
let lookupGitResult = git_commit_lookup(&self.unsafeCommit, self.repo.pointer, &self.oid)
let lookupResult = result(withName: "git_commit_lookup", from: lookupGitResult)
if lookupResult.stop {
return nil
} else if let error = lookupResult.error {
return Result.failure(error)
}
guard let commit = unsafeCommit else {
return nil
}
git_commit_free(unsafeCommit)
return Result.success(Commit(commit))
}
}
13 changes: 12 additions & 1 deletion SwiftGit2/Repository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,22 @@ final public class Repository {
return setHEAD(reference).flatMap { self.checkout(strategy: strategy, progress: progress) }
}

/// Cache for commits(in: branch)
///
/// Specifically for allowing syntax "while let commit = repo.commits(in: branch).next() {}"
public var branchCommitIteratorMap: [Branch: CommitIterator] = [:]

/// Load all commits in the specified branch in topological & time order descending
///
/// :param: branch The branch to get all commits from
/// :returns: Returns a result with array of branches or the error that occurred
public func commits(in branch: Branch) -> CommitIterator {
return CommitIterator(repo: self, branch: branch)
if let iterator = branchCommitIteratorMap[branch] {
return iterator
} else {
let iterator = CommitIterator(repo: self, branch: branch)
branchCommitIteratorMap[branch] = iterator
return iterator
}
}
}
16 changes: 10 additions & 6 deletions SwiftGit2Tests/RepositorySpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -603,12 +603,16 @@ class RepositorySpec: QuickSpec {

fdescribe("Repository.allCommits(in:)") {
it("should return all (9) commits") {
// let repo = Fixtures.simpleRepository
// let branches = repo.localBranches().value!
// let commits = branches.map { repo.allCommits(in: $0).value!.map { $0 } }
// let count = commits.reduce(0) { $0 + $1.count }
// let expected = 9
// expect(count).to(equal(expected))
let repo = Fixtures.simpleRepository
let branches = repo.localBranches().value!
var count = 0
let expected = 9
for branch in branches {
while let commit = repo.commits(in: branch).next() {
count += 1
}
}
expect(count).to(equal(expected))
}
}
}
Expand Down

0 comments on commit aa9f066

Please sign in to comment.