From 424cd4f655739bba2c993e9c4805c7467f029697 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 24 Mar 2013 23:21:15 +1300 Subject: [PATCH 01/11] Updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 764267fb5..7fcf4f50d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nodegit", "description": "Node.js libgit2 asynchronous native bindings", - "version": "0.0.75", + "version": "0.0.76", "homepage": "https://github.com/tbranyen/nodegit", "keywords": [ "libgit2", From cabadca17d6ba20a4f6c07f3645517d188eb98e5 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:03:14 +1300 Subject: [PATCH 02/11] Added commit.file tests --- test/convenience-commit.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/convenience-commit.js b/test/convenience-commit.js index 34154ac62..9f0b2bbcb 100644 --- a/test/convenience-commit.js +++ b/test/convenience-commit.js @@ -170,3 +170,19 @@ exports.parentsDiffTrees = function(test) { }); }); }; + +exports.file = function(test) { + test.expect(5); + git.repo('../.git', function(error, repository) { + repository.commit(historyCountKnownSHA, function(error, commit) { + commit.file('README.md', function(error, file) { + test.equal(error, null, 'Should not error'); + test.notEqual(file, null, 'File should not be null'); + test.equal(file.name, 'README.md', 'File name should match expected'); + test.equal(file.sha, 'b252f396b17661462372f78b7bcfc403b8731aaa', 'SHA shoud match expected'); + test.equal(file.attributes, 33188, 'Attributes should match expected'); + test.done(); + }); + }); + }); +}; From b25974d254664c2c66d56fa3a5197a7a2997a61b Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:03:39 +1300 Subject: [PATCH 03/11] Updated tree_entry constructor --- include/tree_entry.h | 2 +- src/tree_entry.cc | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/tree_entry.h b/include/tree_entry.h index 2d3634695..c028444bd 100755 --- a/include/tree_entry.h +++ b/include/tree_entry.h @@ -26,7 +26,7 @@ class GitTreeEntry : ObjectWrap { /** * v8::FunctionTemplate used to create Node.js constructor */ - static Persistent constructor_template; + static Persistent constructor_template; /** * Used to intialize the EventEmitter from Node.js diff --git a/src/tree_entry.cc b/src/tree_entry.cc index f8541fd18..134932f7e 100755 --- a/src/tree_entry.cc +++ b/src/tree_entry.cc @@ -18,18 +18,18 @@ using namespace v8; using namespace node; void GitTreeEntry::Initialize(Handle target) { - Local t = FunctionTemplate::New(New); + Local tpl = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("TreeEntry")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(String::NewSymbol("TreeEntry")); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "name", Name); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "attributes", Attributes); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "id", Id); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "toObject", ToObject); + NODE_SET_PROTOTYPE_METHOD(tpl, "name", Name); + NODE_SET_PROTOTYPE_METHOD(tpl, "attributes", Attributes); + NODE_SET_PROTOTYPE_METHOD(tpl, "id", Id); + NODE_SET_PROTOTYPE_METHOD(tpl, "toObject", ToObject); - target->Set(String::NewSymbol("TreeEntry"), constructor_template->GetFunction()); + constructor_template = Persistent::New(tpl->GetFunction()); + target->Set(String::NewSymbol("TreeEntry"), constructor_template); } git_tree_entry* GitTreeEntry::GetValue() { @@ -63,7 +63,7 @@ Handle GitTreeEntry::New(const Arguments& args) { entry->Wrap(args.This()); - return scope.Close( args.This() ); + return scope.Close(args.This()); } Handle GitTreeEntry::Name(const Arguments& args) { @@ -121,5 +121,5 @@ Handle GitTreeEntry::ToObject(const Arguments& args) { return scope.Close( Undefined() ); } -Persistent GitTreeEntry::constructor_template; +Persistent GitTreeEntry::constructor_template; From 48bd48bc1f5589a51f308cc1aeeabb358dda17bc Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:04:13 +1300 Subject: [PATCH 04/11] Added missing semicolons --- lib/diff_list.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/diff_list.js b/lib/diff_list.js index d9a615ce3..caf1a055b 100644 --- a/lib/diff_list.js +++ b/lib/diff_list.js @@ -19,7 +19,7 @@ var GitDiffList = function(rawRepo, rawDiffList) { fileDeltas.forEach(function(fileDelta) { event.emit('file', null, fileDelta); allFileDeltas.push(fileDelta); - }) + }); }, function hunkCallback(error, diffHunk) { // @todo implement? }, function lineCallback(error, diffLine) { @@ -27,7 +27,7 @@ var GitDiffList = function(rawRepo, rawDiffList) { }, function endCallback(error) { event.emit('end', error, allFileDeltas); }); - }) + }); return event; }; From b4d97832fcbf2fe5c3cc6a8f994de6c60828e040 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:04:36 +1300 Subject: [PATCH 05/11] Converted tree entry by name to entry by path --- include/tree.h | 26 +++++------ src/tree.cc | 115 ++++++++++++++++++++++++++----------------------- 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/include/tree.h b/include/tree.h index 2b8839032..3309c88d6 100755 --- a/include/tree.h +++ b/include/tree.h @@ -25,7 +25,7 @@ class GitTree : public ObjectWrap { /** * v8::FunctionTemplate used to create Node.js constructor */ - static Persistent constructor_template; + static Persistent constructor_template; /** * Used to intialize the EventEmitter from Node.js @@ -69,8 +69,6 @@ class GitTree : public ObjectWrap { */ git_tree_entry* EntryByIndex(int idx); - git_tree_entry* EntryByName(const char* name); - int SortEntries(); void ClearEntries(); @@ -99,9 +97,9 @@ class GitTree : public ObjectWrap { static Handle EntryByIndex(const Arguments& args); static void EIO_EntryByIndex(uv_work_t *req); static void EIO_AfterEntryByIndex(uv_work_t *req); - static Handle EntryByName(const Arguments& args); - static void EIO_EntryByName(uv_work_t *req); - static void EIO_AfterEntryByName(uv_work_t *req); + static Handle EntryByPath(const Arguments& args); + static void EntryByPathWork(uv_work_t *req); + static void EntryByPathAfterWork(uv_work_t *req); static Handle SortEntries(const Arguments& args); static Handle ClearEntries(const Arguments& args); @@ -129,13 +127,15 @@ class GitTree : public ObjectWrap { int idx; Persistent callback; }; - /** - * Structure to handle async entryByName - */ - struct entryname_request { - GitTree* tree; - GitTreeEntry* entry; - std::string name; + + struct EntryByPathBaton { + uv_work_t request; + const git_error* error; + + git_tree* rawTree; + std::string path; + git_tree_entry* rawEntry; + Persistent callback; }; }; diff --git a/src/tree.cc b/src/tree.cc index 14fa22efa..46ed0f8b2 100755 --- a/src/tree.cc +++ b/src/tree.cc @@ -11,6 +11,9 @@ Copyright (c) 2011, Tim Branyen @tbranyen #include "../include/oid.h" #include "../include/tree.h" #include "../include/tree_entry.h" +#include "../include/error.h" + +#include "../include/functions/string.h" using namespace v8; using namespace node; @@ -18,19 +21,19 @@ using namespace node; void GitTree::Initialize (Handle target) { HandleScope scope; - Local t = FunctionTemplate::New(New); + Local tpl = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("Tree")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(String::NewSymbol("Tree")); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "lookup", Lookup); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "entryCount", EntryCount); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "entryByIndex", EntryByIndex); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "entryByName", EntryByName); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "sortEntries", EntryCount); + NODE_SET_PROTOTYPE_METHOD(tpl, "lookup", Lookup); + NODE_SET_PROTOTYPE_METHOD(tpl, "entryCount", EntryCount); + NODE_SET_PROTOTYPE_METHOD(tpl, "entryByIndex", EntryByIndex); + NODE_SET_PROTOTYPE_METHOD(tpl, "entryByPath", EntryByPath); + NODE_SET_PROTOTYPE_METHOD(tpl, "sortEntries", EntryCount); - target->Set(String::NewSymbol("Tree"), constructor_template->GetFunction()); + constructor_template = Persistent::New(tpl->GetFunction()); + target->Set(String::NewSymbol("Tree"), constructor_template); } git_tree* GitTree::GetValue() { @@ -53,10 +56,6 @@ git_tree_entry* GitTree::EntryByIndex(int idx) { return const_cast(git_tree_entry_byindex(this->tree, idx)); } -git_tree_entry* GitTree::EntryByName(const char* name) { - return const_cast(git_tree_entry_byname(this->tree, name)); -} - int GitTree::SortEntries() { //return git_tree_sort_entries(this->tree); return 0; @@ -216,69 +215,77 @@ void GitTree::EIO_AfterEntryByIndex(uv_work_t *req) { delete er; } -Handle GitTree::EntryByName(const Arguments& args) { +Handle GitTree::EntryByPath(const Arguments& args) { HandleScope scope; - GitTree *tree = ObjectWrap::Unwrap(args.This()); - - Local callback; - - if(args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("TreeEntry is required and must be a Object."))); - } - - if(args.Length() == 1 || !args[1]->IsString()) { + if(args.Length() == 0 || !args[0]->IsString()) { return ThrowException(Exception::Error(String::New("Name is required and must be a String."))); } - if(args.Length() == 2 || !args[2]->IsFunction()) { + if(args.Length() == 1 || !args[1]->IsFunction()) { return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); } - callback = Local::Cast(args[2]); - String::Utf8Value name(args[1]->ToString()); - - entryname_request *er = new entryname_request(); - er->tree = tree; - er->entry = ObjectWrap::Unwrap(args[0]->ToObject()); - er->name = *name; - er->callback = Persistent::New(callback); + EntryByPathBaton *baton = new EntryByPathBaton; + baton->request.data = baton; + baton->error = NULL; + baton->rawEntry = NULL; + GitTree *tree = ObjectWrap::Unwrap(args.This()); tree->Ref(); - uv_work_t *req = new uv_work_t; - req->data = er; - uv_queue_work(uv_default_loop(), req, EIO_EntryByName, (uv_after_work_cb)EIO_AfterEntryByName); + baton->rawTree = tree->GetValue(); + baton->path = stringArgToString(args[0]->ToString()); + baton->callback = Persistent::New(Local::Cast(args[1])); - return scope.Close( Undefined() ); -} + uv_queue_work(uv_default_loop(), &baton->request, EntryByPathWork, (uv_after_work_cb)EntryByPathAfterWork); -void GitTree::EIO_EntryByName(uv_work_t *req) { - entryname_request *er = static_cast(req->data); + return Undefined(); +} - er->entry->SetValue(er->tree->EntryByName(er->name.c_str())); +void GitTree::EntryByPathWork(uv_work_t *req) { + EntryByPathBaton *baton = static_cast(req->data); + int returnCode = git_tree_entry_bypath(&baton->rawEntry, baton->rawTree, baton->path.c_str()); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); + } } -void GitTree::EIO_AfterEntryByName(uv_work_t *req) { - entryname_request *er = static_cast(req->data); +void GitTree::EntryByPathAfterWork(uv_work_t *req) { + HandleScope scope; + EntryByPathBaton *baton = static_cast(req->data); - delete req; - er->tree->Unref(); + if (baton->error) { + Local argv[1] = { + GitError::WrapError(baton->error) + }; - Handle argv[1]; - argv[0] = Boolean::New(er->entry->GetValue() != NULL); + TryCatch try_catch; - TryCatch try_catch; + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); - er->callback->Call(Context::GetCurrent()->Global(), 1, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } else { - if(try_catch.HasCaught()) - FatalException(try_catch); + Local entry = GitTreeEntry::constructor_template->NewInstance(); + GitTreeEntry *entryInstance = ObjectWrap::Unwrap(entry); + entryInstance->SetValue(baton->rawEntry); - er->callback.Dispose(); + Handle argv[2] = { + Local::New(Null()), + entry + }; - delete er; + TryCatch try_catch; + baton->callback->Call(Context::GetCurrent()->Global(), 2, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } + delete req; } Handle GitTree::SortEntries(const Arguments& args) { @@ -300,4 +307,4 @@ Handle GitTree::ClearEntries(const Arguments& args) { return scope.Close( Undefined() ); } -Persistent GitTree::constructor_template; +Persistent GitTree::constructor_template; From 5c7cc61f9d4387be71402194620e5da64bbf0d19 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:05:32 +1300 Subject: [PATCH 06/11] Added tree entry fetch details placeholder --- lib/tree_entry.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/tree_entry.js b/lib/tree_entry.js index 5b954047c..22dfdeeb8 100644 --- a/lib/tree_entry.js +++ b/lib/tree_entry.js @@ -75,6 +75,11 @@ var _TreeEntry = function(rawObject) { return self.attributes === 16384; }; + self.fetchDetails = function(callback) { + console.log('tree fetch details'); + callback(null, self); + }; + self.tree = function() { var tree = new git.raw.Tree( self.repo ); if( tree.error ) { From c403efc73e84783d746b94cebd09cff524173a4a Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:05:50 +1300 Subject: [PATCH 07/11] Simplified tree entry function --- lib/tree.js | 45 +++++++++++---------------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/lib/tree.js b/lib/tree.js index 2b7f5b96d..35198dab4 100644 --- a/lib/tree.js +++ b/lib/tree.js @@ -1,7 +1,7 @@ var git = require('../'), events = require('events'); -var _Tree = function(rawObject, tree) { +var Tree = function(rawObject, tree) { var self = {}; if (rawObject instanceof git.raw.Repo && @@ -90,44 +90,21 @@ var _Tree = function(rawObject, tree) { return event; }; - self.entry = function(name, callback) { + self.entry = function(path, callback) { if(!callback) { - return; + throw new Error('Tree entry function requires a callback'); } - var entry = git.entry(self.repo); - - var path = name.split('/'); - if(path.length === 1) { - self.tree.entryByName(entry.entry, path[0], function(valid) { - callback(valid ? entry : undefined); - }); - } - else { - var recurse = function(tree) { - var name = path.shift(); - tree = tree || self.tree; - - tree.entryByName(entry.entry, name, function(valid) { - if(!path.length) { - callback( valid ? entry : undefined ); - } - else { - if (valid) { - recurse( entry.tree().tree ); - } - else { - callback(undefined); - } - } - }); - }; - - recurse(); - } + self.tree.entryByPath(path, function(error, entry) { + if (error) { + callback(git.error(error), null); + } else { + git.entry(entry).fetchDetails(callback); + } + }); }; return self; }; -exports.tree = _Tree; +exports.tree = Tree; From 9a1cec3684fc5a4741f29f5f46f2fdf024fdaa4c Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:06:31 +1300 Subject: [PATCH 08/11] Fixed issue with commit parentDiffTrees returning an empty {} instead of [] when commit has no parents --- lib/commit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commit.js b/lib/commit.js index c952f4d36..3abc34cf6 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -171,7 +171,7 @@ var _Commit = function(rawCommit) { */ self.parentsDiffTrees = function(callback) { if (!self.parentCount) { - callback(null, {}); + callback(null, []); return; } var parentDiffLists = []; From cc05e512f776c30269f406599d2f5ee9a1ecd90f Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:06:41 +1300 Subject: [PATCH 09/11] Updated commit file function --- lib/commit.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/commit.js b/lib/commit.js index 3abc34cf6..3c726faae 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -27,7 +27,7 @@ function applyDetails(details, context) { * @param {RawCommit|Null} rawCommit * @return {Commit} */ -var _Commit = function(rawCommit) { +var Commit = function(rawCommit) { var self = {}; if(rawCommit && rawCommit instanceof git.raw.Commit) { @@ -99,8 +99,8 @@ var _Commit = function(rawCommit) { return git.tree(self.repo, tree); }; - self.file = function(path) { - return self.tree().entry(path); + self.file = function(path, callback) { + self.tree().entry(path, callback); }; /** @@ -144,7 +144,7 @@ var _Commit = function(rawCommit) { error = git.error(errorCode); return callback(error, null); } - var parentCommit = new _Commit(parent); + var parentCommit = new Commit(parent); parentCommit.fetchDetails(function returnParent(error) { callback(error, parentCommit); }); @@ -158,7 +158,7 @@ var _Commit = function(rawCommit) { * @return {Commit} */ self.parentSync = function(position) { - var parent = new _Commit(self.commit.parentSync(position)); + var parent = new Commit(self.commit.parentSync(position)); return parent.fetchDetailsSync(); }; @@ -192,4 +192,4 @@ var _Commit = function(rawCommit) { return self; }; -exports.commit = _Commit; +exports.commit = Commit; From d63b6e9a0a89154ae379976600381cb2cbc3933e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:06:57 +1300 Subject: [PATCH 10/11] Minor style update --- src/commit.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commit.cc b/src/commit.cc index 7573a2e8f..2c88d001b 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -268,7 +268,7 @@ Handle GitCommit::Lookup(const Arguments& args) { return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); } - LookupBaton *baton = new LookupBaton(); + LookupBaton *baton = new LookupBaton; baton->request.data = baton; baton->error = NULL; baton->repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); From 0a191d551f0e39f84aa3eef6ea60415fd3c91e7d Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 Mar 2013 01:07:23 +1300 Subject: [PATCH 11/11] Version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7fcf4f50d..025bec00e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nodegit", "description": "Node.js libgit2 asynchronous native bindings", - "version": "0.0.76", + "version": "0.0.77", "homepage": "https://github.com/tbranyen/nodegit", "keywords": [ "libgit2",