Skip to content

Commit 22402dd

Browse files
committed
Refactored repo open async
1 parent 999dd71 commit 22402dd

3 files changed

Lines changed: 80 additions & 60 deletions

File tree

include/repo.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ class GitRepo : public ObjectWrap {
3636
static Handle<Value> New(const Arguments& args);
3737

3838
static Handle<Value> Open(const Arguments& args);
39-
static void EIO_Open(uv_work_t* req);
40-
static void EIO_AfterOpen(uv_work_t* req);
39+
static void OpenWork(uv_work_t* req);
40+
static void OpenAfterWork(uv_work_t* req);
4141

4242
static Handle<Value> Lookup(const Arguments& args);
4343
static void EIO_Lookup(uv_work_t* req);
@@ -52,10 +52,13 @@ class GitRepo : public ObjectWrap {
5252
private:
5353
git_repository* repo;
5454

55-
struct open_request {
56-
GitRepo* repo;
57-
int err;
55+
struct OpenBaton {
56+
uv_work_t request;
57+
const git_error* error;
58+
59+
git_repository* repo;
5860
std::string path;
61+
5962
Persistent<Function> callback;
6063
};
6164

lib/repo.js

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,45 @@ var git = require("../");
33
/* Module: Repo
44
* Work with a repository.
55
*/
6-
exports.repo = function(dir, async) {
6+
exports.repo = function(directory, callback) {
77
var self = {
88
// Assign a new repo object
99
repo: new git.raw.Repo()
1010
};
1111

12-
if (dir && async) {
13-
self.repo.open(dir, function() {
14-
git.util().asyncComplete.call(self, arguments, async);
12+
if (directory) {
13+
if (!callback || typeof callback !== 'function') {
14+
throw new Error('If directory is provided, callback function is required');
15+
}
16+
self.repo.open(directory, function(error, repository) {
17+
if (error) {
18+
callback(git.error(error), null);
19+
return;
20+
}
21+
self.repo = repository;
22+
callback(null, self);
1523
});
1624
}
17-
else if (dir) {
18-
// TODO: Make this eventually
19-
// this.repo.openSync(path.resolve(dir)
20-
//this.repo.open(path.resolve(dir)
21-
self.repo.open(dir);
22-
}
23-
24-
// Look up a branch and find its tree
25-
self.branch = function(name, async) {
26-
if (!async) {
27-
// TODO: Implement Sync API
28-
return;
29-
}
3025

31-
git.ref(self.repo).lookup("refs/heads/" + name, function(err, ref) {
32-
if (err) {
33-
return git.util().asyncComplete.call(this, arguments, async);
26+
/**
27+
* Look up a branch and find its tree.
28+
*
29+
* @param {String} name Branch name, e.g. 'master'
30+
* @param {Function}
31+
*/
32+
self.branch = function(name, callback) {
33+
git.ref(self.repo).lookup('refs/heads/' + name, function(error, ref) {
34+
if (error) {
35+
callback(git.error(error), null);
36+
return;
3437
}
3538

36-
git.commit(self.repo).lookup(self.repo, ref.oid().oid, function() {
37-
git.util().asyncComplete.call(this, arguments, async);
39+
git.commit(self.repo).lookup(self.repo, ref.oid().oid, function(error, commit) {
40+
if (error) {
41+
callback(git.error(error), null);
42+
return;
43+
}
44+
callback(null, commit);
3845
});
3946
});
4047
};

src/repo.cc

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Copyright (c) 2011, Tim Branyen @tbranyen <tim@tabdeveloper.com>
1111
#include "../include/object.h"
1212
#include "../include/repo.h"
1313
#include "../include/commit.h"
14+
#include "../include/error.h"
1415

1516
using namespace v8;
1617
using namespace node;
@@ -61,15 +62,12 @@ Handle<Value> GitRepo::New(const Arguments& args) {
6162
GitRepo *repo = new GitRepo();
6263
repo->Wrap(args.This());
6364

64-
return scope.Close( args.This() );
65+
return scope.Close(args.This());
6566
}
6667

6768
Handle<Value> GitRepo::Open(const Arguments& args) {
6869
HandleScope scope;
6970

70-
GitRepo *repo = ObjectWrap::Unwrap<GitRepo>(args.This());
71-
Local<Function> callback;
72-
7371
if(args.Length() == 0 || !args[0]->IsString()) {
7472
return ThrowException(Exception::Error(String::New("Path is required and must be a String.")));
7573
}
@@ -78,52 +76,64 @@ Handle<Value> GitRepo::Open(const Arguments& args) {
7876
return ThrowException(Exception::Error(String::New("Callback is required and must be a Function.")));
7977
}
8078

81-
callback = Local<Function>::Cast(args[1]);
82-
83-
open_request *ar = new open_request();
84-
ar->repo = repo;
85-
79+
OpenBaton *baton = new OpenBaton();
80+
baton->request.data = baton;
81+
baton->error = NULL;
8682
String::Utf8Value path(args[0]);
87-
ar->path = *path;
83+
baton->path = *path;
84+
baton->callback = Persistent<Function>::New(Local<Function>::Cast(args[1]));
8885

89-
ar->callback = Persistent<Function>::New(callback);
90-
91-
repo->Ref();
86+
uv_queue_work(uv_default_loop(), &baton->request, OpenWork, OpenAfterWork);
9287

93-
uv_work_t *req = new uv_work_t;
94-
req->data = ar;
95-
uv_queue_work(uv_default_loop(), req, EIO_Open, EIO_AfterOpen);
96-
97-
return scope.Close( Undefined() );
88+
return Undefined();
9889
}
9990

100-
void GitRepo::EIO_Open(uv_work_t *req) {
101-
open_request *ar = static_cast<open_request *>(req->data);
102-
103-
ar->err = ar->repo->Open(ar->path.c_str());
91+
void GitRepo::OpenWork(uv_work_t *req) {
92+
OpenBaton *baton = static_cast<OpenBaton *>(req->data);
10493

94+
int returnCode = git_repository_open(&baton->repo, baton->path.c_str());
95+
if (returnCode != GIT_OK) {
96+
baton->error = giterr_last();
97+
}
10598
}
10699

107-
void GitRepo::EIO_AfterOpen(uv_work_t *req) {
100+
void GitRepo::OpenAfterWork(uv_work_t *req) {
108101
HandleScope scope;
109102

110-
open_request *ar = static_cast<open_request *>(req->data);
103+
OpenBaton *baton = static_cast<OpenBaton *>(req->data);
111104
delete req;
112-
ar->repo->Unref();
113105

114-
Local<Value> argv[1];
115-
argv[0] = Integer::New(ar->err);
106+
if (baton->error) {
107+
Local<Value> argv[1] = {
108+
GitError::WrapError(baton->error)
109+
};
116110

117-
TryCatch try_catch;
111+
TryCatch try_catch;
118112

119-
ar->callback->Call(Context::GetCurrent()->Global(), 1, argv);
113+
baton->callback->Call(Context::GetCurrent()->Global(), 1, argv);
120114

121-
if(try_catch.HasCaught())
122-
FatalException(try_catch);
115+
if (try_catch.HasCaught()) {
116+
node::FatalException(try_catch);
117+
}
118+
} else {
123119

124-
ar->callback.Dispose();
120+
Local<Object> repository = GitRepo::constructor_template->NewInstance();
121+
GitRepo *repositoryInstance = ObjectWrap::Unwrap<GitRepo>(repository);
122+
repositoryInstance->SetValue(baton->repo);
125123

126-
delete ar;
124+
Handle<Value> argv[2] = {
125+
Local<Value>::New(Null()),
126+
repository
127+
};
128+
129+
TryCatch try_catch;
130+
131+
baton->callback->Call(Context::GetCurrent()->Global(), 2, argv);
132+
133+
if (try_catch.HasCaught()) {
134+
node::FatalException(try_catch);
135+
}
136+
}
127137
}
128138

129139
Handle<Value> GitRepo::Lookup(const Arguments& args) {

0 commit comments

Comments
 (0)