Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Give GTTree some love #208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jul 10, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Classes/GTTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
@class GTTreeEntry;
@class GTIndex;

typedef enum GTTreeEnumerationOptions {
GTTreeEnumerationOptionPre = GIT_TREEWALK_PRE, // Walk the tree in pre-order (subdirectories come first)
GTTreeEnumerationOptionPost = GIT_TREEWALK_POST, // Walk the tree in post-order (subdirectories come last)
} GTTreeEnumerationOptions;

@interface GTTree : GTObject

// The number of entries in the tree.
Expand All @@ -55,6 +60,22 @@
// returns a GTTreeEntry or nil if there is nothing with the specified name
- (GTTreeEntry *)entryWithName:(NSString *)name;

// Enumerates the contents of the tree
//
// options - One of `GTTreeEnumerationOptionPre` (for pre-order walks) or
// `GTTreeEnumerationOptionPost` (for post-order walks).
// error - The error if one occurred.
// block - A block that will be called back with a path to the root of the tree
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. I clarified the docs.

// and the current entry. Cannot be nil.
// Return a negative value to stop the walk, a positive one to skip the
// descendents of the entry, or 0 to continue the enumeration.
//
// returns YES if the enumeration completed successfully, NO otherwise
- (BOOL)enumerateContentsWithOptions:(GTTreeEnumerationOptions)options error:(NSError **)error block:(int(^)(NSString *root, GTTreeEntry *entry))block;

// Returns the contents of the tree, as an array of GTTreeEntries
- (NSArray *)contents;

// Merges the given tree into the receiver in memory and produces the result as
// an index.
//
Expand Down
58 changes: 58 additions & 0 deletions Classes/GTTree.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@
#import "GTRepository.h"
#import "GTIndex.h"
#import "NSError+Git.h"
#import "GTTreeEntry+Private.h"

typedef int(^GTTreeEnumerationBlock)(NSString *root, GTTreeEntry *entry);

typedef struct GTTreeEnumerationStruct {
__unsafe_unretained GTTree *myself;
__unsafe_unretained GTTreeEnumerationBlock block;
__unsafe_unretained NSMutableDictionary *directoryStructure;
} GTTreeEnumerationStruct;

@implementation GTTree

Expand Down Expand Up @@ -61,6 +70,55 @@ - (git_tree *)git_tree {
return (git_tree *)self.git_object;
}

#pragma mark Contents

static int treewalk_cb(const char *root, const git_tree_entry *git_entry, void *payload) {
GTTreeEnumerationStruct *enumStruct = (GTTreeEnumerationStruct *)payload;
NSString *rootString = @(root);
GTTreeEntry *parentEntry = enumStruct->directoryStructure[rootString];
GTTree *parentTree = parentEntry ? parentEntry.tree : enumStruct->myself;

GTTreeEntry *entry = [[GTTreeEntry alloc] initWithEntry:git_entry parentTree:parentTree];
if ([entry type] == GTObjectTypeTree) {
NSString *path = [rootString stringByAppendingPathComponent:entry.name];
enumStruct->directoryStructure[path] = entry;
}
return enumStruct->block(rootString, entry);
}


- (BOOL)enumerateContentsWithOptions:(GTTreeEnumerationOptions)option error:(NSError **)error block:(GTTreeEnumerationBlock)block {
NSParameterAssert(block != nil);

NSMutableDictionary *structure = [[NSMutableDictionary alloc] initWithCapacity:[self entryCount]];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: dot syntax for entryCount


GTTreeEnumerationStruct enumStruct = {
.myself = self,
.block = block,
.directoryStructure = structure,
};

int gitError = git_tree_walk(self.git_tree, (git_treewalk_mode)option, treewalk_cb, &enumStruct);
if (gitError != GIT_OK) {
if (error != NULL) *error = [NSError git_errorFor:gitError withAdditionalDescription:@"Failed to enumerate tree"];
}
return gitError != GIT_OK;
}

- (NSArray *)contents {
NSError *error = nil;
__block NSMutableArray *_contents = [NSMutableArray array];
int gitError = [self enumerateContentsWithOptions:GTTreeEnumerationOptionPre error:&error block:^int(NSString *root, GTTreeEntry *entry) {
[_contents addObject:entry];
return [entry type] == GTObjectTypeTree ? 1 : 0;
}];
if (gitError < GIT_OK) {
NSLog(@"%@", error);
return nil;
}
return _contents;
}

#pragma mark Merging

- (GTIndex *)merge:(GTTree *)otherTree ancestor:(GTTree *)ancestorTree error:(NSError **)error {
Expand Down
13 changes: 13 additions & 0 deletions Classes/GTTreeEntry+Private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// GTTreeEntry+Private.h
// ObjectiveGitFramework
//
// Created by Etienne on 10/07/13.
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
//

#import <ObjectiveGit/ObjectiveGit.h>

@interface GTTreeEntry ()
- (GTObjectType)type;
@end
27 changes: 26 additions & 1 deletion Classes/GTTreeEntry.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,25 @@ @interface GTTreeEntry ()

@implementation GTTreeEntry

#pragma mark NSObject

- (NSString *)description {
return [NSString stringWithFormat:@"<%@: %p> name: %@, sha: %@ attributes: %lu", NSStringFromClass([self class]), self, [self name], [self sha], (unsigned long)[self attributes]];
return [NSString stringWithFormat:@"<%@: %p> name: %@, type: %@, sha: %@, attributes: %lu", NSStringFromClass(self.class), self, self.name, self.typeString, self.sha, (unsigned long)self.attributes];
}

- (NSUInteger)hash {
return [self.sha hash];
}

- (BOOL)isEqual:(id)object {
if ([object isKindOfClass:[self class]]) {
return [self isEqualToEntry:object];
}
return [super isEqual:object];
}

- (BOOL)isEqualToEntry:(GTTreeEntry *)treeEntry {
return git_tree_entry_cmp(self.git_tree_entry, treeEntry.git_tree_entry) == 0 ? YES : NO;
}

#pragma mark API
Expand Down Expand Up @@ -70,6 +87,14 @@ - (NSString *)sha {
return [NSString git_stringWithOid:git_tree_entry_id(self.git_tree_entry)];
}

- (GTObjectType)type {
return (GTObjectType)git_tree_entry_type(self.git_tree_entry);
}

- (NSString *)typeString {
return @(git_object_type2string(git_tree_entry_type(self.git_tree_entry)));
}

- (GTRepository *)repository {
return self.tree.repository;
}
Expand Down
5 changes: 5 additions & 0 deletions ObjectiveGitFramework.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
30FDC08116835A8100654BF0 /* GTDiffLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 30FDC07E16835A8100654BF0 /* GTDiffLine.m */; };
30FDC08216835A8100654BF0 /* GTDiffLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 30FDC07E16835A8100654BF0 /* GTDiffLine.m */; };
3E0A23E5159E0FDB00A6068F /* GTObjectDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 55C8054C13861F34004DCB0F /* GTObjectDatabase.h */; settings = {ATTRIBUTES = (Public, ); }; };
4D26799F178DAF31002A2795 /* GTTreeEntry+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D26799D178DAF31002A2795 /* GTTreeEntry+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
55C8054F13861FE7004DCB0F /* GTObjectDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C8054D13861F34004DCB0F /* GTObjectDatabase.m */; };
55C8055013861FE7004DCB0F /* GTObjectDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C8054D13861F34004DCB0F /* GTObjectDatabase.m */; };
55C8057A13875578004DCB0F /* NSString+Git.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C8057313874CDF004DCB0F /* NSString+Git.m */; };
Expand Down Expand Up @@ -332,6 +333,7 @@
30FDC07D16835A8100654BF0 /* GTDiffLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTDiffLine.h; sourceTree = "<group>"; };
30FDC07E16835A8100654BF0 /* GTDiffLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTDiffLine.m; sourceTree = "<group>"; };
32DBCF5E0370ADEE00C91783 /* ObjectiveGitFramework_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectiveGitFramework_Prefix.pch; sourceTree = "<group>"; };
4D26799D178DAF31002A2795 /* GTTreeEntry+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTTreeEntry+Private.h"; sourceTree = "<group>"; };
55C8054C13861F34004DCB0F /* GTObjectDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTObjectDatabase.h; sourceTree = "<group>"; };
55C8054D13861F34004DCB0F /* GTObjectDatabase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = GTObjectDatabase.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
55C8057213874CDF004DCB0F /* NSString+Git.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Git.h"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -675,6 +677,7 @@
BD6B040F131496B8001909D0 /* GTTree.h */,
BD6B0410131496B8001909D0 /* GTTree.m */,
BD6B0415131496CC001909D0 /* GTTreeEntry.h */,
4D26799D178DAF31002A2795 /* GTTreeEntry+Private.h */,
BD6B0416131496CC001909D0 /* GTTreeEntry.m */,
5BE612861745EE3300266D8C /* GTTreeBuilder.h */,
5BE612871745EE3300266D8C /* GTTreeBuilder.m */,
Expand Down Expand Up @@ -839,6 +842,7 @@
6A74CA3616A942C000E1A3C5 /* GTConfiguration+Private.h in Headers */,
30B1E7EF1703522100D0814D /* NSDate+GTTimeAdditions.h in Headers */,
D09C2E371755F16200065E36 /* GTSubmodule.h in Headers */,
4D2679A0178DAF31002A2795 /* GTTreeEntry+Private.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -879,6 +883,7 @@
8821547617147A5200D76B76 /* GTReflogEntry.h in Headers */,
30B1E7EE1703522100D0814D /* NSDate+GTTimeAdditions.h in Headers */,
D09C2E361755F16200065E36 /* GTSubmodule.h in Headers */,
4D26799F178DAF31002A2795 /* GTTreeEntry+Private.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
15 changes: 15 additions & 0 deletions ObjectiveGitTests/GTTreeSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,19 @@
expect(entry.sha).to.equal(@"1385f264afb75a56a5bec74243be9b367ba4ca08");
});

it(@"should give quick access to its contents", ^{
NSArray *treeContents = tree.contents;
expect(treeContents).notTo.beNil();
expect(treeContents.count).to.equal(3);
GTTreeEntry *readme = [tree entryWithName:@"README"];
GTTreeEntry *newTxt = [tree entryWithName:@"new.txt"];
GTTreeEntry *subdir = [tree entryWithName:@"subdir"];
expect(readme).notTo.beNil();
expect(newTxt).notTo.beNil();
expect(subdir).notTo.beNil();
expect(treeContents).to.contain(readme);
expect(treeContents).to.contain(newTxt);
expect(treeContents).to.contain(subdir);
});

SpecEnd