Skip to content
Open
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
18 changes: 13 additions & 5 deletions generate/scripts/generateNativeCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,20 @@ module.exports = function generateNativeCode() {
});
});

// Convert partials to Combyne templates and register filters.
Object.keys(partials).forEach(function(partial) {
partials[partial] = combyne(partials[partial]);
Object.keys(filters).forEach(function(filter) {
partials[partial].registerFilter(filter, filters[filter]);
});
});

// Attach all partials to select templates.
Object.keys(partials).forEach(function(partial) {
templates.class_header.registerPartial(partial, combyne(partials[partial]));
templates.class_content.registerPartial(partial, combyne(partials[partial]));
templates.struct_header.registerPartial(partial, combyne(partials[partial]));
templates.struct_content.registerPartial(partial, combyne(partials[partial]));
templates.class_header.registerPartial(partial, partials[partial]);
templates.class_content.registerPartial(partial, partials[partial]);
templates.struct_header.registerPartial(partial, partials[partial]);
templates.struct_content.registerPartial(partial, partials[partial]);
});


Expand All @@ -118,7 +126,7 @@ module.exports = function generateNativeCode() {
const finalSrcDirPath = path.join(__dirname, '../../src');
const finalIncludeDirPath = path.join(__dirname, '../../include');

fse.remove(tempDirPath).then(function() {
return fse.remove(tempDirPath).then(function() {
return fse.copy(path.resolve(__dirname, "../templates/manual/include"), tempIncludeDirPath);
}).then(function() {
return fse.copy(path.resolve(__dirname, "../templates/manual/src"), tempSrcDirPath);
Expand Down
97 changes: 50 additions & 47 deletions generate/templates/manual/clone/clone.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,35 @@
* @param CloneOptions options
* @param Repository callback
*/
NAN_METHOD(GitClone::Clone) {
Napi::Value GitClone::Clone(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();

if (info.Length() == 0 || !info[0]->IsString()) {
return Nan::ThrowError("String url is required.");
if (info.Length() == 0 || !info[0].IsString()) {
Napi::Error::New(env, "String url is required.").ThrowAsJavaScriptException();
return env.Undefined();
}

if (info.Length() == 1 || !info[1]->IsString()) {
return Nan::ThrowError("String local_path is required.");
if (info.Length() == 1 || !info[1].IsString()) {
Napi::Error::New(env, "String local_path is required.").ThrowAsJavaScriptException();
return env.Undefined();
}

if (!info[info.Length() - 1]->IsFunction()) {
return Nan::ThrowError("Callback is required and must be a Function.");
if (!info[info.Length() - 1].IsFunction()) {
Napi::Error::New(env, "Callback is required and must be a Function.").ThrowAsJavaScriptException();
return env.Undefined();
}

CloneBaton *baton = new CloneBaton();
nodegit::Context *nodegitContext = reinterpret_cast<nodegit::Context *>(info.Data().As<External>()->Value());
nodegit::Context *nodegitContext = nodegit::Context::GetCurrentContext();
std::map<std::string, std::shared_ptr<nodegit::CleanupHandle>> cleanupHandles;

if (info[2]->IsNull() || info[2]->IsUndefined()) {
if (info[2].IsNull() || info[2].IsUndefined()) {
baton->options = nullptr;
} else {
auto conversionResult = ConfigurableGitCloneOptions::fromJavascript(nodegitContext, info[2]);
if (!conversionResult.result) {
return Nan::ThrowError(Nan::New(conversionResult.error).ToLocalChecked());
Napi::Error::New(env, conversionResult.error).ThrowAsJavaScriptException();
return env.Undefined();
}

auto convertedObject = conversionResult.result;
Expand All @@ -48,47 +53,47 @@ NAN_METHOD(GitClone::Clone) {
// start convert_from_v8 block
const char *from_url = NULL;

Nan::Utf8String url(Nan::To<v8::String>(info[0]).ToLocalChecked());
std::string urlStr = info[0].As<Napi::String>().Utf8Value();
// malloc with one extra byte so we can add the terminating null character
// C-strings expect:
from_url = (const char *)malloc(url.length() + 1);
from_url = (const char *)malloc(urlStr.length() + 1);
// copy the characters from the nodejs string into our C-string (used instead
// of strdup or strcpy because nulls in the middle of strings are valid coming
// from nodejs):
memcpy((void *)from_url, *url, url.length());
memcpy((void *)from_url, urlStr.c_str(), urlStr.length());
// ensure the final byte of our new string is null, extra casts added to
// ensure compatibility with various C types used in the nodejs binding
// generation:
memset((void *)(((char *)from_url) + url.length()), 0, 1);
memset((void *)(((char *)from_url) + urlStr.length()), 0, 1);
// end convert_from_v8 block
baton->url = from_url;
// start convert_from_v8 block
const char *from_local_path = NULL;

Nan::Utf8String local_path(Nan::To<v8::String>(info[1]).ToLocalChecked());
std::string localPathStr = info[1].As<Napi::String>().Utf8Value();
// malloc with one extra byte so we can add the terminating null character
// C-strings expect:
from_local_path = (const char *)malloc(local_path.length() + 1);
from_local_path = (const char *)malloc(localPathStr.length() + 1);
// copy the characters from the nodejs string into our C-string (used instead
// of strdup or strcpy because nulls in the middle of strings are valid coming
// from nodejs):
memcpy((void *)from_local_path, *local_path, local_path.length());
memcpy((void *)from_local_path, localPathStr.c_str(), localPathStr.length());
// ensure the final byte of our new string is null, extra casts added to
// ensure compatibility with various C types used in the nodejs binding
// generation:
memset((void *)(((char *)from_local_path) + local_path.length()), 0, 1);
memset((void *)(((char *)from_local_path) + localPathStr.length()), 0, 1);
// end convert_from_v8 block
baton->local_path = from_local_path;

Nan::Callback *callback =
new Nan::Callback(v8::Local<Function>::Cast(info[info.Length() - 1]));
Napi::FunctionReference *callback =
new Napi::FunctionReference(Napi::Persistent(info[info.Length() - 1].As<Napi::Function>()));
CloneWorker *worker = new CloneWorker(baton, callback, cleanupHandles);

worker->Reference("url", info[0]);
worker->Reference("local_path", info[1]);

nodegitContext->QueueWorker(worker);
return;
return env.Undefined();
}

nodegit::LockMaster GitClone::CloneWorker::AcquireLocks() {
Expand Down Expand Up @@ -143,63 +148,61 @@ void GitClone::CloneWorker::HandleErrorCallback() {
}

void GitClone::CloneWorker::HandleOKCallback() {
Napi::Env env = GetAsyncResource()->Env();
if (baton->error_code == GIT_OK) {
v8::Local<v8::Value> to;
Napi::Value to;
// start convert_to_v8 block

if (baton->out != NULL) {
// GitRepository baton->out
to = GitRepository::New(baton->out, true);
} else {
to = Nan::Null();
to = env.Null();
}

// end convert_to_v8 block
v8::Local<v8::Value> result = to;
Napi::Value result = to;

v8::Local<v8::Value> argv[2] = {Nan::Null(), result};
callback->Call(2, argv, async_resource);
Napi::Value argv[2] = {env.Null(), result};
CallCallback(argv, 2);
} else {
if (baton->error) {
v8::Local<v8::Object> err;
Napi::Object err;
if (baton->error->message) {
err = Nan::To<v8::Object>(Nan::Error(baton->error->message)).ToLocalChecked();
err = Napi::Error::New(env, baton->error->message).Value();
} else {
err = Nan::To<v8::Object>(Nan::Error("Method clone has thrown an error.")).ToLocalChecked();
err = Napi::Error::New(env, "Method clone has thrown an error.").Value();
}
Nan::Set(err, Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
Nan::Set(err, Nan::New("errorFunction").ToLocalChecked(),
Nan::New("Clone.clone").ToLocalChecked());
v8::Local<v8::Value> argv[1] = {err};
callback->Call(1, argv, async_resource);
err.Set("errno", Napi::Number::New(env, baton->error_code));
err.Set("errorFunction", Napi::String::New(env, "Clone.clone"));
Napi::Value argv[1] = {err};
CallCallback(argv, 1);
if (baton->error->message)
free((void *)baton->error->message);
free((void *)baton->error);
} else if (baton->error_code < 0) {
bool callbackFired = false;
if (!callbackErrorHandle.IsEmpty()) {
v8::Local<v8::Value> maybeError = Nan::New(callbackErrorHandle);
if (!maybeError->IsNull() && !maybeError->IsUndefined()) {
v8::Local<v8::Value> argv[1] = {
Napi::Value maybeError = callbackErrorHandle.Value();
if (!maybeError.IsNull() && !maybeError.IsUndefined()) {
Napi::Value argv[1] = {
maybeError
};
callback->Call(1, argv, async_resource);
CallCallback(argv, 1);
callbackFired = true;
}
}

if (!callbackFired) {
v8::Local<v8::Object> err =
Nan::To<v8::Object>(Nan::Error("Method clone has thrown an error.")).ToLocalChecked();
Nan::Set(err, Nan::New("errno").ToLocalChecked(),
Nan::New(baton->error_code));
Nan::Set(err, Nan::New("errorFunction").ToLocalChecked(),
Nan::New("Clone.clone").ToLocalChecked());
v8::Local<v8::Value> argv[1] = {err};
callback->Call(1, argv, async_resource);
Napi::Object err =
Napi::Error::New(env, "Method clone has thrown an error.").Value();
err.Set("errno", Napi::Number::New(env, baton->error_code));
err.Set("errorFunction", Napi::String::New(env, "Clone.clone"));
Napi::Value argv[1] = {err};
CallCallback(argv, 1);
}
} else {
callback->Call(0, NULL, async_resource);
CallCallback(nullptr, 0);
}
}

Expand Down
95 changes: 50 additions & 45 deletions generate/templates/manual/commit/extract_signature.cc
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
NAN_METHOD(GitCommit::ExtractSignature)
Napi::Value GitCommit::ExtractSignature(const Napi::CallbackInfo& info)
{
if (info.Length() == 0 || !info[0]->IsObject()) {
return Nan::ThrowError("Repository repo is required.");
if (info.Length() == 0 || !info[0].IsObject()) {
Napi::Error::New(info.Env(), "Repository repo is required.").ThrowAsJavaScriptException();
return info.Env().Undefined();
}

if (info.Length() == 1 || (!info[1]->IsObject() && !info[1]->IsString())) {
return Nan::ThrowError("Oid commit_id is required.");
if (info.Length() == 1 || (!info[1].IsObject() && !info[1].IsString())) {
Napi::Error::New(info.Env(), "Oid commit_id is required.").ThrowAsJavaScriptException();
return info.Env().Undefined();
}

if (info.Length() >= 4 && !info[2]->IsString() && !info[2]->IsUndefined() && !info[2]->IsNull()) {
return Nan::ThrowError("String signature_field must be a string or undefined/null.");
if (info.Length() >= 4 && !info[2].IsString() && !info[2].IsUndefined() && !info[2].IsNull()) {
Napi::Error::New(info.Env(), "String signature_field must be a string or undefined/null.").ThrowAsJavaScriptException();
return info.Env().Undefined();
}

if (!info[info.Length() - 1]->IsFunction()) {
return Nan::ThrowError("Callback is required and must be a Function.");
if (!info[info.Length() - 1].IsFunction()) {
Napi::Error::New(info.Env(), "Callback is required and must be a Function.").ThrowAsJavaScriptException();
return info.Env().Undefined();
}

ExtractSignatureBaton* baton = new ExtractSignatureBaton();
Expand All @@ -22,44 +26,46 @@ NAN_METHOD(GitCommit::ExtractSignature)
baton->error = NULL;
baton->signature = GIT_BUF_INIT_CONST(NULL, 0);
baton->signed_data = GIT_BUF_INIT_CONST(NULL, 0);
baton->repo = Nan::ObjectWrap::Unwrap<GitRepository>(Nan::To<v8::Object>(info[0]).ToLocalChecked())->GetValue();
baton->repo = NodeGitWrapper<GitRepositoryTraits>::Unwrap<GitRepository>(info[0].As<Napi::Object>())->GetValue();

// baton->commit_id
if (info[1]->IsString()) {
Nan::Utf8String oidString(Nan::To<v8::String>(info[1]).ToLocalChecked());
if (info[1].IsString()) {
std::string oidStr = info[1].As<Napi::String>().Utf8Value();
baton->commit_id = (git_oid *)malloc(sizeof(git_oid));
if (git_oid_fromstr(baton->commit_id, (const char *)strdup(*oidString)) != GIT_OK) {
if (git_oid_fromstr(baton->commit_id, (const char *)strdup(oidStr.c_str())) != GIT_OK) {
free(baton->commit_id);

if (git_error_last()->klass != GIT_ERROR_NONE) {
return Nan::ThrowError(git_error_last()->message);
Napi::Error::New(info.Env(), git_error_last()->message).ThrowAsJavaScriptException();
return info.Env().Undefined();
} else {
return Nan::ThrowError("Unknown Error");
Napi::Error::New(info.Env(), "Unknown Error").ThrowAsJavaScriptException();
return info.Env().Undefined();
}
}
} else {
baton->commit_id = Nan::ObjectWrap::Unwrap<GitOid>(Nan::To<v8::Object>(info[1]).ToLocalChecked())->GetValue();
baton->commit_id = NodeGitWrapper<GitOidTraits>::Unwrap<GitOid>(info[1].As<Napi::Object>())->GetValue();
}

// baton->field
if (info[2]->IsString()) {
Nan::Utf8String field(Nan::To<v8::String>(info[2]).ToLocalChecked());
baton->field = (char *)malloc(field.length() + 1);
memcpy((void *)baton->field, *field, field.length());
baton->field[field.length()] = 0;
if (info[2].IsString()) {
std::string fieldStr = info[2].As<Napi::String>().Utf8Value();
baton->field = (char *)malloc(fieldStr.length() + 1);
memcpy((void *)baton->field, fieldStr.c_str(), fieldStr.length());
baton->field[fieldStr.length()] = 0;
} else {
baton->field = NULL;
}

Nan::Callback *callback = new Nan::Callback(Local<Function>::Cast(info[info.Length() - 1]));
Napi::FunctionReference *callback = new Napi::FunctionReference(Napi::Persistent(info[info.Length() - 1].As<Napi::Function>()));

std::map<std::string, std::shared_ptr<nodegit::CleanupHandle>> cleanupHandles;
ExtractSignatureWorker *worker = new ExtractSignatureWorker(baton, callback, cleanupHandles);
worker->Reference<GitRepository>("repo", info[0]);
worker->Reference<GitOid>("commit_id", info[1]);
nodegit::Context *nodegitContext = reinterpret_cast<nodegit::Context *>(info.Data().As<External>()->Value());
nodegit::Context *nodegitContext = nodegit::Context::GetCurrentContext();
nodegitContext->QueueWorker(worker);
return;
return info.Env().Undefined();
}

nodegit::LockMaster GitCommit::ExtractSignatureWorker::AcquireLocks() {
Expand Down Expand Up @@ -103,32 +109,31 @@ void GitCommit::ExtractSignatureWorker::HandleErrorCallback() {

void GitCommit::ExtractSignatureWorker::HandleOKCallback()
{
Napi::Env env = GetAsyncResource()->Env();
if (baton->error_code == GIT_OK)
{
Local<v8::Object> result = Nan::New<Object>();
Nan::Set(
result,
Nan::New("signature").ToLocalChecked(),
Nan::New<String>(baton->signature.ptr, baton->signature.size).ToLocalChecked()
Napi::Object result = Napi::Object::New(env);
result.Set(
"signature",
Napi::String::New(env, baton->signature.ptr, baton->signature.size)
);
Nan::Set(
result,
Nan::New("signedData").ToLocalChecked(),
Nan::New<String>(baton->signed_data.ptr, baton->signed_data.size).ToLocalChecked()
result.Set(
"signedData",
Napi::String::New(env, baton->signed_data.ptr, baton->signed_data.size)
);

Local<v8::Value> argv[2] = {
Nan::Null(),
Napi::Value argv[2] = {
env.Null(),
result
};
callback->Call(2, argv, async_resource);
CallCallback(argv, 2);
}
else if (baton->error)
{
Local<v8::Value> argv[1] = {
Nan::Error(baton->error->message)
Napi::Value argv[1] = {
Napi::Error::New(env, baton->error->message).Value()
};
callback->Call(1, argv, async_resource);
CallCallback(argv, 1);
if (baton->error->message)
{
free((void *)baton->error->message);
Expand All @@ -138,17 +143,17 @@ void GitCommit::ExtractSignatureWorker::HandleOKCallback()
}
else if (baton->error_code < 0)
{
Local<v8::Object> err = Nan::To<v8::Object>(Nan::Error("Extract Signature has thrown an error.")).ToLocalChecked();
Nan::Set(err, Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
Nan::Set(err, Nan::New("errorFunction").ToLocalChecked(), Nan::New("Commit.extractSignature").ToLocalChecked());
Local<v8::Value> argv[1] = {
Napi::Object err = Napi::Error::New(env, "Extract Signature has thrown an error.").Value();
err.Set("errno", Napi::Number::New(env, baton->error_code));
err.Set("errorFunction", Napi::String::New(env, "Commit.extractSignature"));
Napi::Value argv[1] = {
err
};
callback->Call(1, argv, async_resource);
CallCallback(argv, 1);
}
else
{
callback->Call(0, NULL, async_resource);
CallCallback(nullptr, 0);
}

git_buf_dispose(&baton->signature);
Expand Down
Loading