Skip to content

Commit

Permalink
Remove branch iterator caching
Browse files Browse the repository at this point in the history
Add support for sequencing to allow syntax
for commit in repo.commits(in: branch)
  • Loading branch information
Arnon Keereena committed May 4, 2017
1 parent 8088f8b commit c4b7ce3
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 15 deletions.
75 changes: 74 additions & 1 deletion SwiftGit2/CommitIterator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import Result
import libgit2

public class CommitIterator: IteratorProtocol {
public class CommitIterator: IteratorProtocol, Sequence {
public typealias Iterator = CommitIterator
public typealias Element = Result<Commit, NSError>
let repo: Repository
private var revisionWalker: OpaquePointer? = nil
Expand Down Expand Up @@ -64,4 +65,76 @@ public class CommitIterator: IteratorProtocol {
git_commit_free(unsafeCommit)
return result
}

public func makeIterator() -> CommitIterator {
return self
}

public private(set) var underestimatedCount: Int = 0
public func map<T>(_ transform: (Result<Commit, NSError>) throws -> T) rethrows -> [T] {
var new: [T] = []
for item in self {
new = new + [try transform(item)]
}
return new
}

public func filter(_ isIncluded: (Result<Commit, NSError>) throws -> Bool) rethrows -> [Result<Commit, NSError>] {
var new: [Result<Commit, NSError>] = []
for item in self {
if try isIncluded(item) {
new = new + [item]
}
}
return new
}

public func forEach(_ body: (Result<Commit, NSError>) throws -> Void) rethrows {
for item in self {
try body(item)
}
}

private func notImplemented(functionName: Any) {
assert(false, "CommitIterator does not implement \(functionName)")
}
private init(repo: Repository) {
self.repo = repo
}

public func dropFirst(_ n: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.dropFirst)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}

public func dropLast(_ n: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.dropLast)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}

public func drop(while predicate: (Result<Commit, NSError>) throws -> Bool) rethrows -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.drop)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}

public func prefix(_ maxLength: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: "prefix(_ maxLength:")
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}

public func prefix(while predicate: (Result<Commit, NSError>) throws -> Bool) rethrows -> AnySequence<Iterator.Element> {
notImplemented(functionName: "prefix(with predicate:")
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}

public func suffix(_ maxLength: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.suffix)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}

public func split(maxSplits: Int, omittingEmptySubsequences: Bool, whereSeparator isSeparator: (Result<Commit, NSError>) throws -> Bool) rethrows -> [AnySequence<Iterator.Element>] {
notImplemented(functionName: self.split)
return [AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }]
}

}
14 changes: 2 additions & 12 deletions SwiftGit2/Repository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -510,22 +510,12 @@ 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 {
if let iterator = branchCommitIteratorMap[branch] {
return iterator
} else {
let iterator = CommitIterator(repo: self, root: branch.oid.oid)
branchCommitIteratorMap[branch] = iterator
return iterator
}
let iterator = CommitIterator(repo: self, root: branch.oid.oid)
return iterator
}
}
4 changes: 2 additions & 2 deletions SwiftGit2Tests/RepositorySpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -619,10 +619,10 @@ class RepositorySpec: QuickSpec {
]
var commitMessages: [String] = []
for branch in branches {
while let commit = repo.commits(in: branch).next() {
for commit in repo.commits(in: branch) {
commitMessages.append(commit.value!.message)
}
}
}
expect(commitMessages.count).to(equal(expectedCount))
expect(commitMessages).to(equal(expectedMessages))
}
Expand Down

0 comments on commit c4b7ce3

Please sign in to comment.