From c4b7ce37168edf66ccf0a53131278d17600e1bd4 Mon Sep 17 00:00:00 2001 From: Arnon Keereena Date: Thu, 4 May 2017 09:33:14 +0200 Subject: [PATCH] Remove branch iterator caching Add support for sequencing to allow syntax for commit in repo.commits(in: branch) --- SwiftGit2/CommitIterator.swift | 75 ++++++++++++++++++++++++++++- SwiftGit2/Repository.swift | 14 +----- SwiftGit2Tests/RepositorySpec.swift | 4 +- 3 files changed, 78 insertions(+), 15 deletions(-) diff --git a/SwiftGit2/CommitIterator.swift b/SwiftGit2/CommitIterator.swift index 3d84f0be..6ad5cd55 100644 --- a/SwiftGit2/CommitIterator.swift +++ b/SwiftGit2/CommitIterator.swift @@ -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 let repo: Repository private var revisionWalker: OpaquePointer? = nil @@ -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(_ transform: (Result) throws -> T) rethrows -> [T] { + var new: [T] = [] + for item in self { + new = new + [try transform(item)] + } + return new + } + + public func filter(_ isIncluded: (Result) throws -> Bool) rethrows -> [Result] { + var new: [Result] = [] + for item in self { + if try isIncluded(item) { + new = new + [item] + } + } + return new + } + + public func forEach(_ body: (Result) 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 { + notImplemented(functionName: self.dropFirst) + return AnySequence { return CommitIterator(repo: self.repo) } + } + + public func dropLast(_ n: Int) -> AnySequence { + notImplemented(functionName: self.dropLast) + return AnySequence { return CommitIterator(repo: self.repo) } + } + + public func drop(while predicate: (Result) throws -> Bool) rethrows -> AnySequence { + notImplemented(functionName: self.drop) + return AnySequence { return CommitIterator(repo: self.repo) } + } + + public func prefix(_ maxLength: Int) -> AnySequence { + notImplemented(functionName: "prefix(_ maxLength:") + return AnySequence { return CommitIterator(repo: self.repo) } + } + + public func prefix(while predicate: (Result) throws -> Bool) rethrows -> AnySequence { + notImplemented(functionName: "prefix(with predicate:") + return AnySequence { return CommitIterator(repo: self.repo) } + } + + public func suffix(_ maxLength: Int) -> AnySequence { + notImplemented(functionName: self.suffix) + return AnySequence { return CommitIterator(repo: self.repo) } + } + + public func split(maxSplits: Int, omittingEmptySubsequences: Bool, whereSeparator isSeparator: (Result) throws -> Bool) rethrows -> [AnySequence] { + notImplemented(functionName: self.split) + return [AnySequence { return CommitIterator(repo: self.repo) }] + } + } diff --git a/SwiftGit2/Repository.swift b/SwiftGit2/Repository.swift index a41d795c..0b0f65ab 100644 --- a/SwiftGit2/Repository.swift +++ b/SwiftGit2/Repository.swift @@ -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 } } diff --git a/SwiftGit2Tests/RepositorySpec.swift b/SwiftGit2Tests/RepositorySpec.swift index 9019e7d8..0688dae7 100644 --- a/SwiftGit2Tests/RepositorySpec.swift +++ b/SwiftGit2Tests/RepositorySpec.swift @@ -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)) }