Skip to content

Commit

Permalink
CheckoutOptions: Support progress callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
modocache committed Jan 28, 2015
1 parent 857c95c commit dbaeace
Show file tree
Hide file tree
Showing 17 changed files with 229 additions and 97 deletions.
176 changes: 110 additions & 66 deletions Gift.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Gift/Gift.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ FOUNDATION_EXPORT double GiftVersionNumber;

//! Project version string for Gift.
FOUNDATION_EXPORT const unsigned char GiftVersionString[];

#import <Gift/GIFTCheckoutOptions.h>
9 changes: 9 additions & 0 deletions Gift/Repository/Options/Checkout/CheckoutOptions+C.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
internal extension CheckoutOptions {
/**
Returns a C struct initialized with this options instance's values.
Used by libgit2 functions.
*/
internal var cOptions: git_checkout_options {
return gift_checkoutOptions(UInt32(strategy.rawValue), progressCallback)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@
*/
public struct CheckoutOptions {
internal let strategy: CheckoutStrategy
internal let progressCallback: GIFTCheckoutProgressCallback!

public init(strategy: CheckoutStrategy) {
public init(
strategy: CheckoutStrategy,
progressCallback: GIFTCheckoutProgressCallback! = nil
) {
self.strategy = strategy
self.progressCallback = progressCallback
}
}
38 changes: 38 additions & 0 deletions Gift/Repository/Options/Checkout/GIFTCheckoutOptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#import <Foundation/Foundation.h>

typedef struct git_checkout_options git_checkout_options;

/**
A callback function that is executed during a checkout.
@param checkedOutFilePath A path to the file that is being checked out.
@param fileIndex The index of the file whose checkout triggered this
callback. For example, when the first file has been
checked out, this is '0'. The second file is '1', the
third is '2', and so on.
@param fileCount The total number of files to be checked out. When the
file index is equal to this file count, it can be
inferred that this callback will no longer be called
for the current checkout.
*/
typedef void (^GIFTCheckoutProgressCallback)(NSString *checkedOutFilePath,
NSUInteger fileIndex,
NSUInteger fileCount);

/**
Returns a set of checkout options with the given paramters.
@warning This function is necessary in order to allow a Swift closure
to be used as a progress callback. It is impossible to
obtain a reference to a C function from Swift that we may
then use to configure a git_checkout_options struct.
@param strategyValue The raw value of a CheckoutStrategy options set
used to control how a checkout should be performed.
@param progressCallback An optional progress callback block to be invoked
as remote files are checked out. Note that this
callback will not be invoked for local checkouts.
@return A set of checkout options initialized with the given values.
*/
extern git_checkout_options gift_checkoutOptions(unsigned int strategyValue,
GIFTCheckoutProgressCallback progressCallback);
34 changes: 34 additions & 0 deletions Gift/Repository/Options/Checkout/GIFTCheckoutOptions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#import "GIFTCheckoutOptions.h"
#import <git2/checkout.h>

#pragma mark - Internal Functions

static void gift_checkoutProgressCallback(const char *cPath,
size_t completedSteps,
size_t totalSteps,
void *payload) {
if (payload == NULL) {
return;
}

NSString *path = nil;
if (cPath != NULL) {
path = @(cPath);
}

GIFTCheckoutProgressCallback block = (__bridge GIFTCheckoutProgressCallback)payload;
block(path, completedSteps, totalSteps);
}

#pragma mark - Public Interface

extern git_checkout_options gift_checkoutOptions(unsigned int strategyValue,
GIFTCheckoutProgressCallback progressCallback) {
git_checkout_options options = GIT_CHECKOUT_OPTIONS_INIT;
options.checkout_strategy = strategyValue;
if (progressCallback != nil) {
options.progress_cb = gift_checkoutProgressCallback;
options.progress_payload = (__bridge void *)[progressCallback copy];
}
return options;
}
27 changes: 0 additions & 27 deletions Gift/Repository/Options/CheckoutOptions+C.swift

This file was deleted.

File renamed without changes.
33 changes: 30 additions & 3 deletions GiftTests/Repository/RepositorySpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ class RepositorySpec: QuickSpec {
}

describe("cloneRepository") {
var remoteURL: NSURL!
var destinationURL: NSURL!

context("on the local filesystem") {
var remoteURL: NSURL!
var destinationURL: NSURL!
beforeEach {
remoteURL = temporaryDirectoryURL().URLByAppendingPathComponent("park-slope")
destinationURL = temporaryDirectoryURL().URLByAppendingPathComponent("sunset-park")
}

context("but the remote does not exist") {
it("fails") {
let repository = cloneRepository(remoteURL, destinationURL)
let repository = cloneRepository(remoteURL,destinationURL)
let path = remoteURL.path!.stringByResolvingSymlinksInPath
let faiureMessage = "Failed to resolve path '\(path)': No such file or directory"
expect(repository).to(haveFailed(localizedDescription: faiureMessage))
Expand All @@ -44,6 +45,32 @@ class RepositorySpec: QuickSpec {
}
}
}

xcontext("from a remote URL") {
beforeEach {
remoteURL = NSURL(string: "git://git.libssh2.org/libssh2.git")
destinationURL = temporaryDirectoryURL().URLByAppendingPathComponent("libssh2")
}

context("and the remote exists") {
it("is succesful") {
let options = CloneOptions(
checkoutOptions: CheckoutOptions(
strategy: CheckoutStrategy.SafeCreate,
progressCallback: { (path: String!, completedSteps: UInt, totalSteps: UInt) in
println("path '\(path != nil ? path : nil)', "
+ "completedSteps '\(completedSteps)', "
+ "totalSteps '\(totalSteps)'")
}
),
remoteCallbacks: RemoteCallbacks()
)

expect(cloneRepository(remoteURL, destinationURL, options: options))
.to(haveSucceeded())
}
}
}
}
}
}

0 comments on commit dbaeace

Please sign in to comment.