From 443ed333b02e38b7c85d167dbfa9dc7b122014b4 Mon Sep 17 00:00:00 2001 From: tyler wanek Date: Tue, 7 Feb 2017 14:37:54 -0700 Subject: [PATCH 1/9] Explicitly namespace Local to v8 --- .../manual/include/convenient_hunk.h | 4 +-- .../manual/include/convenient_patch.h | 4 +-- .../manual/include/git_buf_converter.h | 2 +- .../manual/include/str_array_converter.h | 4 +-- generate/templates/manual/include/wrapper.h | 4 +-- generate/templates/partials/async_function.cc | 36 +++++++++---------- .../templates/partials/callback_helpers.cc | 6 ++-- generate/templates/partials/convert_to_v8.cc | 4 +-- .../templates/partials/field_accessors.cc | 16 ++++----- generate/templates/partials/fields.cc | 2 +- generate/templates/partials/sync_function.cc | 6 ++-- generate/templates/templates/class_content.cc | 10 +++--- generate/templates/templates/class_header.h | 4 +-- generate/templates/templates/nodegit.cc | 4 +-- .../templates/templates/struct_content.cc | 10 +++--- generate/templates/templates/struct_header.h | 4 +-- 16 files changed, 60 insertions(+), 60 deletions(-) diff --git a/generate/templates/manual/include/convenient_hunk.h b/generate/templates/manual/include/convenient_hunk.h index 63d77d900..37e9ab111 100644 --- a/generate/templates/manual/include/convenient_hunk.h +++ b/generate/templates/manual/include/convenient_hunk.h @@ -27,9 +27,9 @@ using namespace v8; class ConvenientHunk : public Nan::ObjectWrap { public: static Nan::Persistent constructor_template; - static void InitializeComponent (Local target); + static void InitializeComponent (v8::Local target); - static Local New(void *raw); + static v8::Local New(void *raw); HunkData *GetValue(); char *GetHeader(); diff --git a/generate/templates/manual/include/convenient_patch.h b/generate/templates/manual/include/convenient_patch.h index d6f6c69a1..9d6921ef8 100644 --- a/generate/templates/manual/include/convenient_patch.h +++ b/generate/templates/manual/include/convenient_patch.h @@ -38,9 +38,9 @@ using namespace v8; class ConvenientPatch : public Nan::ObjectWrap { public: static Nan::Persistent constructor_template; - static void InitializeComponent (Local target); + static void InitializeComponent (v8::Local target); - static Local New(void *raw); + static v8::Local New(void *raw); ConvenientLineStats GetLineStats(); git_delta_t GetStatus(); diff --git a/generate/templates/manual/include/git_buf_converter.h b/generate/templates/manual/include/git_buf_converter.h index e2ea08bba..fcbd1eaba 100644 --- a/generate/templates/manual/include/git_buf_converter.h +++ b/generate/templates/manual/include/git_buf_converter.h @@ -10,7 +10,7 @@ using namespace v8; class StrArrayConverter { public: - static git_strarray *Convert (Local val); + static git_strarray *Convert (v8::Local val); }; #endif diff --git a/generate/templates/manual/include/str_array_converter.h b/generate/templates/manual/include/str_array_converter.h index c3509f128..37f1bcc1d 100644 --- a/generate/templates/manual/include/str_array_converter.h +++ b/generate/templates/manual/include/str_array_converter.h @@ -11,11 +11,11 @@ using namespace v8; class StrArrayConverter { public: - static git_strarray *Convert (Local val); + static git_strarray *Convert (v8::Local val); private: static git_strarray *ConvertArray(Array *val); - static git_strarray *ConvertString(Local val); + static git_strarray *ConvertString(v8::Local val); static git_strarray *AllocStrArray(const size_t count); static git_strarray *ConstructStrArray(int argc, char** argv); }; diff --git a/generate/templates/manual/include/wrapper.h b/generate/templates/manual/include/wrapper.h index c040ea64d..9dcbe3186 100644 --- a/generate/templates/manual/include/wrapper.h +++ b/generate/templates/manual/include/wrapper.h @@ -17,10 +17,10 @@ class Wrapper : public Nan::ObjectWrap { public: static Nan::Persistent constructor_template; - static void InitializeComponent (Local target); + static void InitializeComponent (v8::Local target); void *GetValue(); - static Local New(const void *raw); + static v8::Local New(const void *raw); private: Wrapper(void *raw); diff --git a/generate/templates/partials/async_function.cc b/generate/templates/partials/async_function.cc index 3d3227d4a..633ebbfae 100644 --- a/generate/templates/partials/async_function.cc +++ b/generate/templates/partials/async_function.cc @@ -61,7 +61,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%endif%} {%endeach%} - Nan::Callback *callback = new Nan::Callback(Local::Cast(info[{{args|jsArgsCount}}])); + Nan::Callback *callback = new Nan::Callback(v8::Local::Cast(info[{{args|jsArgsCount}}])); {{ cppFunctionName }}Worker *worker = new {{ cppFunctionName }}Worker(baton, callback); {%each args|argsInfo as arg %} {%if not arg.isReturn %} @@ -129,14 +129,14 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { if (baton->error_code == GIT_OK) { {%endif%} {%if return.isResultOrError %} - Local result = Nan::New(baton->error_code); + v8::Local result = Nan::New(baton->error_code); {%elsif not .|returnsCount %} - Local result = Nan::Undefined(); + v8::Local result = Nan::Undefined(); {%else%} - Local to; + v8::Local to; {%if .|returnsCount > 1 %} - Local result = Nan::New(); + v8::Local result = Nan::New(); {%endif%} {%each .|returnsInfo 0 1 as _return %} {%partial convertToV8 _return %} @@ -145,17 +145,17 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { {%endif%} {%endeach%} {%if .|returnsCount == 1 %} - Local result = to; + v8::Local result = to; {%endif%} {%endif%} - Local argv[2] = { + v8::Local argv[2] = { Nan::Null(), result }; callback->Call(2, argv); } else { if (baton->error) { - Local argv[1] = { + v8::Local argv[1] = { Nan::Error(baton->error->message) }; callback->Call(1, argv); @@ -163,7 +163,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { free((void *)baton->error->message); free((void *)baton->error); } else if (baton->error_code < 0) { - std::queue< Local > workerArguments; + std::queue< v8::Local > workerArguments; {%each args|argsInfo as arg %} {%if not arg.isReturn %} {%if not arg.isSelf %} @@ -175,7 +175,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { {%endeach%} bool callbackFired = false; while(!workerArguments.empty()) { - Local node = workerArguments.front(); + v8::Local node = workerArguments.front(); workerArguments.pop(); if ( @@ -191,11 +191,11 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { continue; } - Local nodeObj = node->ToObject(); - Local checkValue = GetPrivate(nodeObj, Nan::New("NodeGitPromiseError").ToLocalChecked()); + v8::Local nodeObj = node->ToObject(); + v8::Local checkValue = GetPrivate(nodeObj, Nan::New("NodeGitPromiseError").ToLocalChecked()); if (!checkValue.IsEmpty() && !checkValue->IsNull() && !checkValue->IsUndefined()) { - Local argv[1] = { + v8::Local argv[1] = { checkValue->ToObject() }; callback->Call(1, argv); @@ -203,10 +203,10 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { break; } - Local properties = nodeObj->GetPropertyNames(); + v8::Local properties = nodeObj->GetPropertyNames(); for (unsigned int propIndex = 0; propIndex < properties->Length(); ++propIndex) { - Local propName = properties->Get(propIndex)->ToString(); - Local nodeToQueue = nodeObj->Get(propName); + v8::Local propName = properties->Get(propIndex)->ToString(); + v8::Local nodeToQueue = nodeObj->Get(propName); if (!nodeToQueue->IsUndefined()) { workerArguments.push(nodeToQueue); } @@ -214,9 +214,9 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() { } if (!callbackFired) { - Local err = Nan::Error("Method {{ jsFunctionName }} has thrown an error.")->ToObject(); + v8::Local err = Nan::Error("Method {{ jsFunctionName }} has thrown an error.")->ToObject(); err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code)); - Local argv[1] = { + v8::Local argv[1] = { err }; callback->Call(1, argv); diff --git a/generate/templates/partials/callback_helpers.cc b/generate/templates/partials/callback_helpers.cc index acd44f424..c1d0ab74a 100644 --- a/generate/templates/partials/callback_helpers.cc +++ b/generate/templates/partials/callback_helpers.cc @@ -30,7 +30,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}_{{ cbFunction.name }}_async(void {% endif %} {% endeach %} - Local argv[{{ cbFunction.args|jsArgsCount }}] = { + v8::Local argv[{{ cbFunction.args|jsArgsCount }}] = { {% each cbFunction.args|argsInfo as arg %} {% if arg | isPayload %} {%-- payload is always the last arg --%} @@ -54,7 +54,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}_{{ cbFunction.name }}_async(void }; Nan::TryCatch tryCatch; - Local result = callback->Call({{ cbFunction.args|jsArgsCount }}, argv); + v8::Local result = callback->Call({{ cbFunction.args|jsArgsCount }}, argv); if(PromiseCompletion::ForwardIfPromise(result, baton, {{ cppFunctionName }}_{{ cbFunction.name }}_promiseCompleted)) { return; @@ -124,7 +124,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}_{{ cbFunction.name }}_promiseComp {{ cppClassName }}* instance = static_cast<{{ cppClassName }}*>(baton->{% each cbFunction.args|argsInfo as arg %} {% if arg.payload == true %}{{arg.name}}{% elsif arg.lastArg %}{{arg.name}}{% endif %} {% endeach %}); - Local parent = instance->handle(); + v8::Local parent = instance->handle(); SetPrivate(parent, Nan::New("NodeGitPromiseError").ToLocalChecked(), result); baton->result = {{ cbFunction.return.error }}; diff --git a/generate/templates/partials/convert_to_v8.cc b/generate/templates/partials/convert_to_v8.cc index d9b1d8830..bfe268f3e 100644 --- a/generate/templates/partials/convert_to_v8.cc +++ b/generate/templates/partials/convert_to_v8.cc @@ -33,12 +33,12 @@ {%-- // FIXME this is not general purpose enough. --%} {% if size %} - Local tmpArray = Nan::New({{= parsedName =}}->{{ size }}); + v8::Local tmpArray = Nan::New({{= parsedName =}}->{{ size }}); for (unsigned int i = 0; i < {{= parsedName =}}->{{ size }}; i++) { Nan::Set(tmpArray, Nan::New(i), Nan::New({{= parsedName =}}->{{ key }}[i]).ToLocalChecked()); } {% else %} - Local tmpArray = Nan::New({{= parsedName =}}); + v8::Local tmpArray = Nan::New({{= parsedName =}}); {% endif %} to = tmpArray; diff --git a/generate/templates/partials/field_accessors.cc b/generate/templates/partials/field_accessors.cc index f9f9065a0..f689b1811 100644 --- a/generate/templates/partials/field_accessors.cc +++ b/generate/templates/partials/field_accessors.cc @@ -39,7 +39,7 @@ } {% elsif field.isLibgitType %} - Local {{ field.name }}(value->ToObject()); + v8::Local {{ field.name }}(value->ToObject()); wrapper->{{ field.name }}.Reset({{ field.name }}); @@ -52,16 +52,16 @@ if (value->IsFunction()) { callback = new Nan::Callback(value.As()); } else if (value->IsObject()) { - Local object = value.As(); - Local callbackKey; + v8::Local object = value.As(); + v8::Local callbackKey; Nan::MaybeLocal maybeObjectCallback = Nan::Get(object, Nan::New("callback").ToLocalChecked()); if (!maybeObjectCallback.IsEmpty()) { - Local objectCallback = maybeObjectCallback.ToLocalChecked(); + v8::Local objectCallback = maybeObjectCallback.ToLocalChecked(); if (objectCallback->IsFunction()) { callback = new Nan::Callback(objectCallback.As()); Nan::MaybeLocal maybeObjectThrottle = Nan::Get(object, Nan::New("throttle").ToLocalChecked()); if(!maybeObjectThrottle.IsEmpty()) { - Local objectThrottle = maybeObjectThrottle.ToLocalChecked(); + v8::Local objectThrottle = maybeObjectThrottle.ToLocalChecked(); if (objectThrottle->IsNumber()) { throttle = (int)objectThrottle.As()->Value(); } @@ -153,7 +153,7 @@ {% endif %} {% endeach %} - Local argv[{{ field.args|jsArgsCount }}] = { + v8::Local argv[{{ field.args|jsArgsCount }}] = { {% each field.args|argsInfo as arg %} {% if arg.name == "payload" %} {%-- payload is always the last arg --%} @@ -176,7 +176,7 @@ }; Nan::TryCatch tryCatch; - Local result = instance->{{ field.name }}.GetCallback()->Call({{ field.args|jsArgsCount }}, argv); + v8::Local result = instance->{{ field.name }}.GetCallback()->Call({{ field.args|jsArgsCount }}, argv); if(PromiseCompletion::ForwardIfPromise(result, baton, {{ cppClassName }}::{{ field.name }}_promiseCompleted)) { return; @@ -245,7 +245,7 @@ {{ cppClassName }}* instance = static_cast<{{ cppClassName }}*>(baton->{% each field.args|argsInfo as arg %} {% if arg.payload == true %}{{arg.name}}{% elsif arg.lastArg %}{{arg.name}}{% endif %} {% endeach %}); - Local parent = instance->handle(); + v8::Local parent = instance->handle(); SetPrivate(parent, Nan::New("NodeGitPromiseError").ToLocalChecked(), result); baton->result = {{ field.return.error }}; diff --git a/generate/templates/partials/fields.cc b/generate/templates/partials/fields.cc index ae3aeae44..9d6e6e39d 100644 --- a/generate/templates/partials/fields.cc +++ b/generate/templates/partials/fields.cc @@ -1,7 +1,7 @@ {% each fields|fieldsInfo as field %} {% if not field.ignore %} NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) { - Local to; + v8::Local to; {% if field | isFixedLengthString %} char* {{ field.name }} = (char *)Nan::ObjectWrap::Unwrap<{{ cppClassName }}>(info.This())->GetValue()->{{ field.name }}; diff --git a/generate/templates/partials/sync_function.cc b/generate/templates/partials/sync_function.cc index d53a5c2d0..c07c77b51 100644 --- a/generate/templates/partials/sync_function.cc +++ b/generate/templates/partials/sync_function.cc @@ -17,7 +17,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) { {%if not arg.isReturn %} {%partial convertFromV8 arg %} {%if arg.saveArg %} - Local {{ arg.name }}(info[{{ arg.jsArg }}]->ToObject()); + v8::Local {{ arg.name }}(info[{{ arg.jsArg }}]->ToObject()); {{ cppClassName }} *thisObj = Nan::ObjectWrap::Unwrap<{{ cppClassName }}>(info.This()); thisObj->{{ cppFunctionName }}_{{ arg.name }}.Reset({{ arg.name }}); @@ -108,9 +108,9 @@ if (Nan::ObjectWrap::Unwrap<{{ cppClassName }}>(info.This())->GetValue() != NULL } {%endif%} - Local to; + v8::Local to; {%if .|returnsCount > 1 %} - Local toReturn = Nan::New(); + v8::Local toReturn = Nan::New(); {%endif%} {%each .|returnsInfo as _return %} {%partial convertToV8 _return %} diff --git a/generate/templates/templates/class_content.cc b/generate/templates/templates/class_content.cc index a6f2a180e..48e67b0eb 100644 --- a/generate/templates/templates/class_content.cc +++ b/generate/templates/templates/class_content.cc @@ -43,10 +43,10 @@ using namespace node; {% endeach %} } - void {{ cppClassName }}::InitializeComponent(Local target) { + void {{ cppClassName }}::InitializeComponent(v8::Local target) { Nan::HandleScope scope; - Local tpl = Nan::New(JSNewFunction); + v8::Local tpl = Nan::New(JSNewFunction); tpl->InstanceTemplate()->SetInternalFieldCount(1); tpl->SetClassName(Nan::New("{{ jsClassName }}").ToLocalChecked()); @@ -69,17 +69,17 @@ using namespace node; InitializeTemplate(tpl); - Local _constructor_template = Nan::GetFunction(tpl).ToLocalChecked(); + v8::Local _constructor_template = Nan::GetFunction(tpl).ToLocalChecked(); constructor_template.Reset(_constructor_template); Nan::Set(target, Nan::New("{{ jsClassName }}").ToLocalChecked(), _constructor_template); } {% else %} - void {{ cppClassName }}::InitializeComponent(Local target) { + void {{ cppClassName }}::InitializeComponent(v8::Local target) { Nan::HandleScope scope; - Local object = Nan::New(); + v8::Local object = Nan::New(); {% each functions as function %} {% if not function.ignore %} diff --git a/generate/templates/templates/class_header.h b/generate/templates/templates/class_header.h index 6f19f517f..ea04c120f 100644 --- a/generate/templates/templates/class_header.h +++ b/generate/templates/templates/class_header.h @@ -52,7 +52,7 @@ class {{ cppClassName }} : public friend class NodeGitWrapper<{{ cppClassName }}Traits>; {%endif %} public: - static void InitializeComponent (Local target); + static void InitializeComponent (v8::Local target); {% each functions as function %} {% if not function.ignore %} @@ -95,7 +95,7 @@ class {{ cppClassName }} : public {% endif %} ) {} - {{ cppClassName }}({{ cType }} *raw, bool selfFreeing, Local owner = Local()) + {{ cppClassName }}({{ cType }} *raw, bool selfFreeing, v8::Local owner = v8::Local()) : NodeGitWrapper<{{ cppClassName }}Traits>(raw, selfFreeing, owner) {} ~{{ cppClassName }}(); diff --git a/generate/templates/templates/nodegit.cc b/generate/templates/templates/nodegit.cc index 23adae3b5..9f392cabc 100644 --- a/generate/templates/templates/nodegit.cc +++ b/generate/templates/templates/nodegit.cc @@ -121,7 +121,7 @@ void OpenSSL_ThreadSetup() { ThreadPool libgit2ThreadPool(10, uv_default_loop()); -extern "C" void init(Local target) { +extern "C" void init(v8::Local target) { // Initialize thread safety in openssl and libssh2 OpenSSL_ThreadSetup(); init_ssh2(); @@ -146,7 +146,7 @@ extern "C" void init(Local target) { NODE_SET_METHOD(target, "getThreadSafetyStatus", LockMasterGetStatus); NODE_SET_METHOD(target, "getThreadSafetyDiagnostics", LockMasterGetDiagnostics); - Local threadSafety = Nan::New(); + v8::Local threadSafety = Nan::New(); threadSafety->Set(Nan::New("DISABLED").ToLocalChecked(), Nan::New((int)LockMaster::Disabled)); threadSafety->Set(Nan::New("ENABLED_FOR_ASYNC_ONLY").ToLocalChecked(), Nan::New((int)LockMaster::EnabledForAsyncOnly)); threadSafety->Set(Nan::New("ENABLED").ToLocalChecked(), Nan::New((int)LockMaster::Enabled)); diff --git a/generate/templates/templates/struct_content.cc b/generate/templates/templates/struct_content.cc index 14b3db242..c6f9e5b91 100644 --- a/generate/templates/templates/struct_content.cc +++ b/generate/templates/templates/struct_content.cc @@ -68,7 +68,7 @@ void {{ cppClassName }}::ConstructFields() { {% if not field.ignore %} {% if not field.isEnum %} {% if field.hasConstructor |or field.isLibgitType %} - Local {{ field.name }}Temp = {{ field.cppClassName }}::New( + v8::Local {{ field.name }}Temp = {{ field.cppClassName }}::New( {%if not field.cType|isPointer %}&{%endif%}this->raw->{{ field.name }}, false )->ToObject(); @@ -82,7 +82,7 @@ void {{ cppClassName }}::ConstructFields() { this->raw->{{ fields|payloadFor field.name }} = (void *)this; {% elsif field.payloadFor %} - Local {{ field.name }} = Nan::Undefined(); + v8::Local {{ field.name }} = Nan::Undefined(); this->{{ field.name }}.Reset({{ field.name }}); {% endif %} {% endif %} @@ -90,10 +90,10 @@ void {{ cppClassName }}::ConstructFields() { {% endeach %} } -void {{ cppClassName }}::InitializeComponent(Local target) { +void {{ cppClassName }}::InitializeComponent(v8::Local target) { Nan::HandleScope scope; - Local tpl = Nan::New(JSNewFunction); + v8::Local tpl = Nan::New(JSNewFunction); tpl->InstanceTemplate()->SetInternalFieldCount(1); tpl->SetClassName(Nan::New("{{ jsClassName }}").ToLocalChecked()); @@ -108,7 +108,7 @@ void {{ cppClassName }}::InitializeComponent(Local target) { InitializeTemplate(tpl); - Local _constructor_template = Nan::GetFunction(tpl).ToLocalChecked(); + v8::Local _constructor_template = Nan::GetFunction(tpl).ToLocalChecked(); constructor_template.Reset(_constructor_template); Nan::Set(target, Nan::New("{{ jsClassName }}").ToLocalChecked(), _constructor_template); } diff --git a/generate/templates/templates/struct_header.h b/generate/templates/templates/struct_header.h index dd8f8570e..94fd3bc0f 100644 --- a/generate/templates/templates/struct_header.h +++ b/generate/templates/templates/struct_header.h @@ -29,8 +29,8 @@ class {{ cppClassName }} : public NodeGitWrapper<{{ cppClassName }}Traits> { // grant full access to base class friend class NodeGitWrapper<{{ cppClassName }}Traits>; public: - {{ cppClassName }}({{ cType }}* raw, bool selfFreeing, v8::Local owner = Local()); - static void InitializeComponent (Local target); + {{ cppClassName }}({{ cType }}* raw, bool selfFreeing, v8::Local owner = v8::Local()); + static void InitializeComponent (v8::Local target); {% each fields as field %} {% if not field.ignore %} From 530555f31da7d0c9033f091c01ddb6bc2f17a3ea Mon Sep 17 00:00:00 2001 From: tyler wanek Date: Tue, 7 Feb 2017 14:38:13 -0700 Subject: [PATCH 2/9] implement unsafe git_remote_ls feature --- generate/input/descriptor.json | 6 +- generate/input/libgit2-supplement.json | 73 ++++++++++ .../templates/manual/include/functions/copy.h | 2 + generate/templates/manual/remote/ls.cc | 127 ++++++++++++++++++ .../templates/manual/src/functions/copy.cc | 10 ++ 5 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 generate/templates/manual/remote/ls.cc diff --git a/generate/input/descriptor.json b/generate/input/descriptor.json index a9264214a..2e6327d46 100644 --- a/generate/input/descriptor.json +++ b/generate/input/descriptor.json @@ -1805,6 +1805,9 @@ } }, "remote": { + "dependencies": [ + "../include/remote_head.h" + ], "cType": "git_remote", "selfFreeing": true, "functions": { @@ -1969,9 +1972,6 @@ } } }, - "remote_head": { - "ignore": true - }, "repository": { "dependencies": [ "git2/sys/repository.h" diff --git a/generate/input/libgit2-supplement.json b/generate/input/libgit2-supplement.json index b686795c3..b4e38cc6b 100644 --- a/generate/input/libgit2-supplement.json +++ b/generate/input/libgit2-supplement.json @@ -126,6 +126,40 @@ }, "group": "rebase" }, + "git_remote_reference_list": { + "args": [ + { + "name": "out", + "type": "std::vector *" + }, + { + "name": "callbacks", + "type": "git_remote_callbacks *" + }, + { + "name": "proxy_opts", + "type": "git_proxy_options *" + }, + { + "name": "custom_headers", + "type": "git_strarray *" + }, + { + "name": "remote", + "type": "git_remote *" + } + ], + "type": "function", + "isManual": true, + "cFile": "generate/templates/manual/remote/ls.cc", + "isAsync": true, + "isPrototypeMethod": true, + "group": "remote", + "return": { + "type": "int", + "isErrorCode": true + } + }, "git_reset": { "type": "function", "file": "reset.h", @@ -277,6 +311,12 @@ "git_reflog_entry_message" ] ], + [ + "remote", + [ + "git_remote_reference_list" + ] + ], [ "revwalk", [ @@ -614,6 +654,39 @@ } } ], + [ + "git_remote_head", + { + "types": "struct", + "fields": [ + { + "type": "int", + "name": "local" + }, + { + "type": "git_oid", + "name": "oid" + }, + { + "type": "git_oid", + "name": "loid" + }, + { + "type": "char *", + "name": "name" + }, + { + "type": "char *", + "name": "symref_target" + } + ], + "used": { + "needs": [ + "git_remote_reference_list" + ] + } + } + ], [ "git_time_t", { diff --git a/generate/templates/manual/include/functions/copy.h b/generate/templates/manual/include/functions/copy.h index f7f942475..9983e575a 100644 --- a/generate/templates/manual/include/functions/copy.h +++ b/generate/templates/manual/include/functions/copy.h @@ -14,6 +14,8 @@ const git_index_time *git_index_time_dup(const git_index_time *arg); const git_time *git_time_dup(const git_time *arg); const git_diff_delta *git_diff_delta_dup(const git_diff_delta *arg); const git_diff_file *git_diff_file_dup(const git_diff_file *arg); +git_remote_head *git_remote_head_dup(const git_remote_head *src); + void git_time_dup(git_time **out, const git_time *arg); void git_transfer_progress_dup(git_transfer_progress **out, const git_transfer_progress *arg); diff --git a/generate/templates/manual/remote/ls.cc b/generate/templates/manual/remote/ls.cc new file mode 100644 index 000000000..6f18c08fc --- /dev/null +++ b/generate/templates/manual/remote/ls.cc @@ -0,0 +1,127 @@ +NAN_METHOD(GitRemote::ReferenceList) +{ + if (info.Length() == 0 || !info[0]->IsObject()) { + return Nan::ThrowError("RemoteCallbacks callbacks is required."); + } + if (info.Length() == 1 || !info[1]->IsObject()) { + return Nan::ThrowError("ProxyOptions proxy_opts is required."); + } + + if (info.Length() == 2 || !(Nan::To(info[2]).FromJust())) { + return Nan::ThrowError("Array, String Object, or string custom_headers is required."); + } + if (info.Length() == 3 || !info[3]->IsFunction()) { + return Nan::ThrowError("Callback is required and must be a Function."); + } + + ReferenceListBaton* baton = new ReferenceListBaton; + + baton->error_code = GIT_OK; + baton->error = NULL; + baton->out = new std::vector; + baton->remote = Nan::ObjectWrap::Unwrap(info.This())->GetValue(); + baton->callbacks = Nan::ObjectWrap::Unwrap(info[0]->ToObject())->GetValue(); + baton->proxy_opts = Nan::ObjectWrap::Unwrap(info[1]->ToObject())->GetValue(); + baton->custom_headers = StrArrayConverter::Convert(info[2]); + + Nan::Callback *callback = new Nan::Callback(Local::Cast(info[1])); + ReferenceListWorker *worker = new ReferenceListWorker(baton, callback); + worker->SaveToPersistent("remote", info.This()); + if (!info[1]->IsUndefined() && !info[0]->IsNull()) + worker->SaveToPersistent("callbacks", info[0]->ToObject()); + if (!info[2]->IsUndefined() && !info[1]->IsNull()) + worker->SaveToPersistent("proxy_opts", info[1]->ToObject()); + if (!info[3]->IsUndefined() && !info[2]->IsNull()) + worker->SaveToPersistent("custom_headers", info[2]->ToObject()); + Nan::AsyncQueueWorker(worker); + return; +} + +void GitRemote::ReferenceListWorker::Execute() +{ + giterr_clear(); + baton->error_code = git_remote_connect( + baton->remote, + GIT_DIRECTION_FETCH, + baton->callbacks, + baton->proxy_opts, + baton->custom_headers + ); + + if (baton->error_code != GIT_OK) { + baton->error = git_error_dup(giterr_last()); + delete baton->out; + baton->out = NULL; + return; + } + + const git_remote_head **remote_heads; + size_t num_remote_heads; + baton->error_code = git_remote_ls( + &remote_heads, + &num_remote_heads, + baton->remote + ); + + if (baton->error_code != GIT_OK) { + baton->error = git_error_dup(giterr_last()); + delete baton->out; + baton->out = NULL; + return; + } + + baton->out->reserve(num_remote_heads); + + for (unsigned int head_index = 0; head_index < num_remote_heads; ++head_index) { + git_remote_head *remote_head = git_remote_head_dup(remote_heads[head_index]); + baton->out->push_back(remote_head); + } + + git_remote_disconnect(baton->remote); +} + +void GitRemote::ReferenceListWorker::HandleOKCallback() +{ + if (baton->out != NULL) + { + unsigned int size = baton->out->size(); + Local result = Nan::New(size); + for (unsigned int i = 0; i < size; i++) { + Nan::Set(result, Nan::New(i), GitRemoteHead::New(baton->out->at(i), true)); + } + + delete baton->out; + + Local argv[2] = { + Nan::Null(), + result + }; + callback->Call(2, argv); + } + else if (baton->error) + { + Local argv[1] = { + Nan::Error(baton->error->message) + }; + callback->Call(1, argv); + if (baton->error->message) + { + free((void *)baton->error->message); + } + + free((void *)baton->error); + } + else if (baton->error_code < 0) + { + Local err = Nan::Error("Method next has thrown an error.")->ToObject(); + err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code)); + Local argv[1] = { + err + }; + callback->Call(1, argv); + } + else + { + callback->Call(0, NULL); + } +} diff --git a/generate/templates/manual/src/functions/copy.cc b/generate/templates/manual/src/functions/copy.cc index f09f2cbaa..747dc24a2 100644 --- a/generate/templates/manual/src/functions/copy.cc +++ b/generate/templates/manual/src/functions/copy.cc @@ -20,3 +20,13 @@ void git_transfer_progress_dup(git_transfer_progress **out, const git_transfer_p *out = (git_transfer_progress *)malloc(sizeof(git_transfer_progress)); memcpy(*out, arg, sizeof(git_transfer_progress)); } + +git_remote_head *git_remote_head_dup(const git_remote_head *src) { + git_remote_head *dest = (git_remote_head *)malloc(sizeof(git_remote_head)); + dest->local = src->local; + git_oid_cpy(&dest->oid, &src->oid); + git_oid_cpy(&dest->loid, &src->loid); + dest->name = strdup(src->name); + dest->symref_target = strdup(src->symref_target); + return dest; +} From 3156c14a19227316f06ce40d6dfaa95963dd17dc Mon Sep 17 00:00:00 2001 From: tyler wanek Date: Tue, 7 Feb 2017 15:22:57 -0700 Subject: [PATCH 3/9] get unsafe git_remote_ls building and running --- generate/templates/manual/remote/ls.cc | 8 +++---- .../templates/manual/src/functions/copy.cc | 4 +++- lib/remote.js | 22 +++++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/generate/templates/manual/remote/ls.cc b/generate/templates/manual/remote/ls.cc index 6f18c08fc..07e782055 100644 --- a/generate/templates/manual/remote/ls.cc +++ b/generate/templates/manual/remote/ls.cc @@ -24,7 +24,7 @@ NAN_METHOD(GitRemote::ReferenceList) baton->proxy_opts = Nan::ObjectWrap::Unwrap(info[1]->ToObject())->GetValue(); baton->custom_headers = StrArrayConverter::Convert(info[2]); - Nan::Callback *callback = new Nan::Callback(Local::Cast(info[1])); + Nan::Callback *callback = new Nan::Callback(Local::Cast(info[3])); ReferenceListWorker *worker = new ReferenceListWorker(baton, callback); worker->SaveToPersistent("remote", info.This()); if (!info[1]->IsUndefined() && !info[0]->IsNull()) @@ -63,6 +63,7 @@ void GitRemote::ReferenceListWorker::Execute() baton->remote ); + git_remote_disconnect(baton->remote); if (baton->error_code != GIT_OK) { baton->error = git_error_dup(giterr_last()); delete baton->out; @@ -72,12 +73,10 @@ void GitRemote::ReferenceListWorker::Execute() baton->out->reserve(num_remote_heads); - for (unsigned int head_index = 0; head_index < num_remote_heads; ++head_index) { + for (size_t head_index = 0; head_index < num_remote_heads; ++head_index) { git_remote_head *remote_head = git_remote_head_dup(remote_heads[head_index]); baton->out->push_back(remote_head); } - - git_remote_disconnect(baton->remote); } void GitRemote::ReferenceListWorker::HandleOKCallback() @@ -90,6 +89,7 @@ void GitRemote::ReferenceListWorker::HandleOKCallback() Nan::Set(result, Nan::New(i), GitRemoteHead::New(baton->out->at(i), true)); } + delete baton->out; Local argv[2] = { diff --git a/generate/templates/manual/src/functions/copy.cc b/generate/templates/manual/src/functions/copy.cc index 747dc24a2..9a2e7c3c7 100644 --- a/generate/templates/manual/src/functions/copy.cc +++ b/generate/templates/manual/src/functions/copy.cc @@ -27,6 +27,8 @@ git_remote_head *git_remote_head_dup(const git_remote_head *src) { git_oid_cpy(&dest->oid, &src->oid); git_oid_cpy(&dest->loid, &src->loid); dest->name = strdup(src->name); - dest->symref_target = strdup(src->symref_target); + dest->symref_target = src->symref_target + ? strdup(src->symref_target) + : NULL; return dest; } diff --git a/lib/remote.js b/lib/remote.js index 47fac857e..53ab4fc83 100644 --- a/lib/remote.js +++ b/lib/remote.js @@ -9,6 +9,7 @@ var _connect = Remote.prototype.connect; var _download = Remote.prototype.download; var _fetch = Remote.prototype.fetch; var _push = Remote.prototype.push; +var _referenceList = Remote.prototype.referenceList; var _upload = Remote.prototype.upload; /** @@ -112,6 +113,27 @@ Remote.prototype.push = function(refSpecs, opts) { return _push.call(this, refSpecs, opts); }; +/** + * Lists advertised heads from remote + * + * @async + * @param {RemoteCallbacks} callbacks The callback functions for the connection + * @param {ProxyOptions} proxyOpts Proxy settings + * @param {Array} customHeaders extra HTTP headers to use + * @param {Function} callback + * @return {Number} error code + */ +Remote.prototype.referenceList = function( + callbacks, + proxyOpts, + customHeaders +) { + callbacks = normalizeOptions(callbacks, NodeGit.RemoteCallbacks); + proxyOpts = normalizeOptions(proxyOpts || {}, NodeGit.ProxyOptions); + customHeaders = customHeaders || []; + + return _referenceList.call(this, callbacks, proxyOpts, customHeaders); +}; /** * Connects to a remote * From b46ba8c1499ebebe0127343503e3dfc75482a5af Mon Sep 17 00:00:00 2001 From: tyler wanek Date: Tue, 7 Feb 2017 15:37:54 -0700 Subject: [PATCH 4/9] lock remote during ls execution --- generate/templates/manual/remote/ls.cc | 73 +++++++++++++++----------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/generate/templates/manual/remote/ls.cc b/generate/templates/manual/remote/ls.cc index 07e782055..defff6f20 100644 --- a/generate/templates/manual/remote/ls.cc +++ b/generate/templates/manual/remote/ls.cc @@ -40,42 +40,52 @@ NAN_METHOD(GitRemote::ReferenceList) void GitRemote::ReferenceListWorker::Execute() { giterr_clear(); - baton->error_code = git_remote_connect( - baton->remote, - GIT_DIRECTION_FETCH, - baton->callbacks, - baton->proxy_opts, - baton->custom_headers - ); - if (baton->error_code != GIT_OK) { - baton->error = git_error_dup(giterr_last()); - delete baton->out; - baton->out = NULL; - return; - } + { + LockMaster lockMaster( + /*asyncAction: */true, + baton->remote, + baton->callbacks, + baton->proxy_opts, + baton->custom_headers + ); + baton->error_code = git_remote_connect( + baton->remote, + GIT_DIRECTION_FETCH, + baton->callbacks, + baton->proxy_opts, + baton->custom_headers + ); - const git_remote_head **remote_heads; - size_t num_remote_heads; - baton->error_code = git_remote_ls( - &remote_heads, - &num_remote_heads, - baton->remote - ); + if (baton->error_code != GIT_OK) { + baton->error = git_error_dup(giterr_last()); + delete baton->out; + baton->out = NULL; + return; + } - git_remote_disconnect(baton->remote); - if (baton->error_code != GIT_OK) { - baton->error = git_error_dup(giterr_last()); - delete baton->out; - baton->out = NULL; - return; - } + const git_remote_head **remote_heads; + size_t num_remote_heads; + baton->error_code = git_remote_ls( + &remote_heads, + &num_remote_heads, + baton->remote + ); + + git_remote_disconnect(baton->remote); + if (baton->error_code != GIT_OK) { + baton->error = git_error_dup(giterr_last()); + delete baton->out; + baton->out = NULL; + return; + } - baton->out->reserve(num_remote_heads); + baton->out->reserve(num_remote_heads); - for (size_t head_index = 0; head_index < num_remote_heads; ++head_index) { - git_remote_head *remote_head = git_remote_head_dup(remote_heads[head_index]); - baton->out->push_back(remote_head); + for (size_t head_index = 0; head_index < num_remote_heads; ++head_index) { + git_remote_head *remote_head = git_remote_head_dup(remote_heads[head_index]); + baton->out->push_back(remote_head); + } } } @@ -89,7 +99,6 @@ void GitRemote::ReferenceListWorker::HandleOKCallback() Nan::Set(result, Nan::New(i), GitRemoteHead::New(baton->out->at(i), true)); } - delete baton->out; Local argv[2] = { From a4ead57aaa5208f1ee3a641ef63ab65f3e970526 Mon Sep 17 00:00:00 2001 From: tyler wanek Date: Wed, 8 Feb 2017 08:08:03 -0700 Subject: [PATCH 5/9] Build test for reference list --- lib/remote.js | 6 ++-- test/tests/remote.js | 84 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/lib/remote.js b/lib/remote.js index 53ab4fc83..f89dfd65e 100644 --- a/lib/remote.js +++ b/lib/remote.js @@ -114,21 +114,21 @@ Remote.prototype.push = function(refSpecs, opts) { }; /** - * Lists advertised heads from remote + * Lists advertised references from a remote * * @async * @param {RemoteCallbacks} callbacks The callback functions for the connection * @param {ProxyOptions} proxyOpts Proxy settings * @param {Array} customHeaders extra HTTP headers to use * @param {Function} callback - * @return {Number} error code + * @return {Promise} */ Remote.prototype.referenceList = function( callbacks, proxyOpts, customHeaders ) { - callbacks = normalizeOptions(callbacks, NodeGit.RemoteCallbacks); + callbacks = normalizeOptions(callbacks || {}, NodeGit.RemoteCallbacks); proxyOpts = normalizeOptions(proxyOpts || {}, NodeGit.ProxyOptions); customHeaders = customHeaders || []; diff --git a/test/tests/remote.js b/test/tests/remote.js index dfe3fb318..9f796774e 100644 --- a/test/tests/remote.js +++ b/test/tests/remote.js @@ -2,6 +2,7 @@ var assert = require("assert"); var path = require("path"); var local = path.join.bind(path, __dirname); var _ = require("lodash"); +var fp = require("lodash/fp"); var garbageCollect = require("../utils/garbage_collect.js"); @@ -444,4 +445,87 @@ describe("Remote", function() { Remote.getSelfFreeingInstanceCount()); }); }); + + it("can retrieve the list of references advertised by a remote", function() { + var expectedRemoteHeads = { + HEAD: { + local: 0, + oid: "32789a79e71fbc9e04d3eff7425e1771eb595150", + loid: "0000000000000000000000000000000000000000", + name: "HEAD", + symrefTarget: "refs/heads/master" + }, + "refs/heads/checkout-test": { + local: 0, + oid: "1729c73906bb8467f4095c2f4044083016b4dfde", + loid: "0000000000000000000000000000000000000000", + name: "refs/heads/checkout-test", + symrefTarget: null + }, + "refs/heads/master": { + local: 0, + oid: "32789a79e71fbc9e04d3eff7425e1771eb595150", + loid: "0000000000000000000000000000000000000000", + name: "refs/heads/master", + symrefTarget: null + }, + "refs/heads/rev-walk": { + local: 0, + oid: "32789a79e71fbc9e04d3eff7425e1771eb595150", + loid: "0000000000000000000000000000000000000000", + name: "refs/heads/rev-walk", + symrefTarget: null + }, + "refs/tags/annotated-tag": { + local: 0, + oid: "dc800017566123ff3c746b37284a24a66546667e", + loid: "0000000000000000000000000000000000000000", + name: "refs/tags/annotated-tag", + symrefTarget: null + }, + "refs/tags/annotated-tag^{}": { + local: 0, + oid: "32789a79e71fbc9e04d3eff7425e1771eb595150", + loid: "0000000000000000000000000000000000000000", + name: "refs/tags/annotated-tag^{}", + symrefTarget: null + }, + "refs/tags/light-weight-tag": { + local: 0, + oid: "32789a79e71fbc9e04d3eff7425e1771eb595150", + loid: "0000000000000000000000000000000000000000", + name: "refs/tags/light-weight-tag", + symrefTarget: null + } + }; + + return this.repository.getRemote("origin") + .then(function(remote) { + return remote.referenceList(); + }) + .then(function(remoteHeads) { + var remoteHeadsBySha = fp.flow([ + fp.map(function(remoteHead) { + return { + local: remoteHead.local(), + oid: remoteHead.oid().toString(), + loid: remoteHead.loid().toString(), + name: remoteHead.name(), + symrefTarget: remoteHead.symrefTarget() + }; + }), + fp.keyBy("name") + ])(remoteHeads); + + fp.flow([ + fp.keys, + fp.forEach(function(remoteHeadName) { + assert(fp.isEqual( + expectedRemoteHeads[remoteHeadName], + remoteHeadsBySha[remoteHeadName] + ), "Expectations for head " + remoteHeadName + " were not met."); + }) + ])(expectedRemoteHeads); + }); + }); }); From 7fe20abbf3e2ddd4f00a4e34bc63d0872a6906fc Mon Sep 17 00:00:00 2001 From: tyler wanek Date: Wed, 8 Feb 2017 08:38:15 -0700 Subject: [PATCH 6/9] clean up memory from git_remote_head --- generate/input/descriptor.json | 7 +++++++ generate/templates/manual/include/functions/free.h | 12 ++++++++++++ generate/templates/manual/src/functions/free.cc | 9 +++++++++ generate/templates/templates/binding.gyp | 1 + 4 files changed, 29 insertions(+) create mode 100644 generate/templates/manual/include/functions/free.h create mode 100644 generate/templates/manual/src/functions/free.cc diff --git a/generate/input/descriptor.json b/generate/input/descriptor.json index 2e6327d46..da9c37d52 100644 --- a/generate/input/descriptor.json +++ b/generate/input/descriptor.json @@ -1972,6 +1972,13 @@ } } }, + "remote_head": { + "dependencies": [ + "../include/functions/free.h" + ], + "freeFunctionName": "git_remote_head_free", + "selfFreeing": true + }, "repository": { "dependencies": [ "git2/sys/repository.h" diff --git a/generate/templates/manual/include/functions/free.h b/generate/templates/manual/include/functions/free.h new file mode 100644 index 000000000..873417b98 --- /dev/null +++ b/generate/templates/manual/include/functions/free.h @@ -0,0 +1,12 @@ +#include + +#include + +#include "git2.h" + +#ifndef NODEGIT_FREE_FUNCTIONS +#define NODEGIT_FREE_FUNCTIONS + +void git_remote_head_free(git_remote_head *remote_head); + +#endif diff --git a/generate/templates/manual/src/functions/free.cc b/generate/templates/manual/src/functions/free.cc new file mode 100644 index 000000000..a52a7016f --- /dev/null +++ b/generate/templates/manual/src/functions/free.cc @@ -0,0 +1,9 @@ +#include + +#include "git2.h" + +void git_remote_head_free(git_remote_head *remote_head) { + free(remote_head->name); + free(remote_head->symref_target); + free(remote_head); +} diff --git a/generate/templates/templates/binding.gyp b/generate/templates/templates/binding.gyp index ece88cd15..041c1ea27 100644 --- a/generate/templates/templates/binding.gyp +++ b/generate/templates/templates/binding.gyp @@ -18,6 +18,7 @@ "src/promise_completion.cc", "src/wrapper.cc", "src/functions/copy.cc", + "src/functions/free.cc", "src/convenient_patch.cc", "src/convenient_hunk.cc", "src/str_array_converter.cc", From 37f34b56455e2449b8a7d57c87e6ac56b2b52101 Mon Sep 17 00:00:00 2001 From: tyler wanek Date: Thu, 9 Feb 2017 09:06:38 -0700 Subject: [PATCH 7/9] limit reference_list to only wrap git_remote_ls --- generate/input/libgit2-supplement.json | 12 ------- generate/templates/manual/remote/ls.cc | 43 ++------------------------ lib/remote.js | 21 +++---------- test/tests/remote.js | 25 +++++++++++++-- 4 files changed, 30 insertions(+), 71 deletions(-) diff --git a/generate/input/libgit2-supplement.json b/generate/input/libgit2-supplement.json index b4e38cc6b..52bb45651 100644 --- a/generate/input/libgit2-supplement.json +++ b/generate/input/libgit2-supplement.json @@ -132,18 +132,6 @@ "name": "out", "type": "std::vector *" }, - { - "name": "callbacks", - "type": "git_remote_callbacks *" - }, - { - "name": "proxy_opts", - "type": "git_proxy_options *" - }, - { - "name": "custom_headers", - "type": "git_strarray *" - }, { "name": "remote", "type": "git_remote *" diff --git a/generate/templates/manual/remote/ls.cc b/generate/templates/manual/remote/ls.cc index defff6f20..561e0f1f1 100644 --- a/generate/templates/manual/remote/ls.cc +++ b/generate/templates/manual/remote/ls.cc @@ -1,16 +1,6 @@ NAN_METHOD(GitRemote::ReferenceList) { - if (info.Length() == 0 || !info[0]->IsObject()) { - return Nan::ThrowError("RemoteCallbacks callbacks is required."); - } - if (info.Length() == 1 || !info[1]->IsObject()) { - return Nan::ThrowError("ProxyOptions proxy_opts is required."); - } - - if (info.Length() == 2 || !(Nan::To(info[2]).FromJust())) { - return Nan::ThrowError("Array, String Object, or string custom_headers is required."); - } - if (info.Length() == 3 || !info[3]->IsFunction()) { + if (info.Length() == 0 || !info[0]->IsFunction()) { return Nan::ThrowError("Callback is required and must be a Function."); } @@ -20,19 +10,10 @@ NAN_METHOD(GitRemote::ReferenceList) baton->error = NULL; baton->out = new std::vector; baton->remote = Nan::ObjectWrap::Unwrap(info.This())->GetValue(); - baton->callbacks = Nan::ObjectWrap::Unwrap(info[0]->ToObject())->GetValue(); - baton->proxy_opts = Nan::ObjectWrap::Unwrap(info[1]->ToObject())->GetValue(); - baton->custom_headers = StrArrayConverter::Convert(info[2]); - Nan::Callback *callback = new Nan::Callback(Local::Cast(info[3])); + Nan::Callback *callback = new Nan::Callback(Local::Cast(info[0])); ReferenceListWorker *worker = new ReferenceListWorker(baton, callback); worker->SaveToPersistent("remote", info.This()); - if (!info[1]->IsUndefined() && !info[0]->IsNull()) - worker->SaveToPersistent("callbacks", info[0]->ToObject()); - if (!info[2]->IsUndefined() && !info[1]->IsNull()) - worker->SaveToPersistent("proxy_opts", info[1]->ToObject()); - if (!info[3]->IsUndefined() && !info[2]->IsNull()) - worker->SaveToPersistent("custom_headers", info[2]->ToObject()); Nan::AsyncQueueWorker(worker); return; } @@ -44,26 +25,9 @@ void GitRemote::ReferenceListWorker::Execute() { LockMaster lockMaster( /*asyncAction: */true, - baton->remote, - baton->callbacks, - baton->proxy_opts, - baton->custom_headers - ); - baton->error_code = git_remote_connect( - baton->remote, - GIT_DIRECTION_FETCH, - baton->callbacks, - baton->proxy_opts, - baton->custom_headers + baton->remote ); - if (baton->error_code != GIT_OK) { - baton->error = git_error_dup(giterr_last()); - delete baton->out; - baton->out = NULL; - return; - } - const git_remote_head **remote_heads; size_t num_remote_heads; baton->error_code = git_remote_ls( @@ -72,7 +36,6 @@ void GitRemote::ReferenceListWorker::Execute() baton->remote ); - git_remote_disconnect(baton->remote); if (baton->error_code != GIT_OK) { baton->error = git_error_dup(giterr_last()); delete baton->out; diff --git a/lib/remote.js b/lib/remote.js index f89dfd65e..517eae55d 100644 --- a/lib/remote.js +++ b/lib/remote.js @@ -9,7 +9,6 @@ var _connect = Remote.prototype.connect; var _download = Remote.prototype.download; var _fetch = Remote.prototype.fetch; var _push = Remote.prototype.push; -var _referenceList = Remote.prototype.referenceList; var _upload = Remote.prototype.upload; /** @@ -39,7 +38,7 @@ Remote.prototype.connect = function( proxyOpts, customHeaders ) { - callbacks = normalizeOptions(callbacks, NodeGit.RemoteCallbacks); + callbacks = normalizeOptions(callbacks || {}, NodeGit.RemoteCallbacks); proxyOpts = normalizeOptions(proxyOpts || {}, NodeGit.ProxyOptions); customHeaders = customHeaders || []; @@ -117,23 +116,11 @@ Remote.prototype.push = function(refSpecs, opts) { * Lists advertised references from a remote * * @async - * @param {RemoteCallbacks} callbacks The callback functions for the connection - * @param {ProxyOptions} proxyOpts Proxy settings - * @param {Array} customHeaders extra HTTP headers to use - * @param {Function} callback - * @return {Promise} + * @return {Promise>} a list of the remote heads currently + * available on the remote for download */ -Remote.prototype.referenceList = function( - callbacks, - proxyOpts, - customHeaders -) { - callbacks = normalizeOptions(callbacks || {}, NodeGit.RemoteCallbacks); - proxyOpts = normalizeOptions(proxyOpts || {}, NodeGit.ProxyOptions); - customHeaders = customHeaders || []; +Remote.prototype.referenceList = Remote.prototype.referenceList; - return _referenceList.call(this, callbacks, proxyOpts, customHeaders); -}; /** * Connects to a remote * diff --git a/test/tests/remote.js b/test/tests/remote.js index 9f796774e..4dddda2b7 100644 --- a/test/tests/remote.js +++ b/test/tests/remote.js @@ -501,9 +501,15 @@ describe("Remote", function() { return this.repository.getRemote("origin") .then(function(remote) { - return remote.referenceList(); + return Promise.all([ + remote, + remote.connect(NodeGit.Enums.DIRECTION.FETCH) + ]); + }) + .then(function([remote]) { + return Promise.all([remote, remote.referenceList()]); }) - .then(function(remoteHeads) { + .then(function([remote, remoteHeads]) { var remoteHeadsBySha = fp.flow([ fp.map(function(remoteHead) { return { @@ -526,6 +532,21 @@ describe("Remote", function() { ), "Expectations for head " + remoteHeadName + " were not met."); }) ])(expectedRemoteHeads); + + return remote.disconnect(); + }); + }); + + it("will error when retrieving reference list if not connected", function() { + return this.repository.getRemote("origin") + .then(function(remote) { + return remote.referenceList(); + }) + .then(function() { + assert.fail("Unconnected remote should have no reference list."); + }) + .catch(function(notConnectedError) { + assert(notConnectedError.message === "this remote has never connected"); }); }); }); From 185cebe99f6fdfbf0c2b544a7fa5e80df48ca1e6 Mon Sep 17 00:00:00 2001 From: tyler wanek Date: Wed, 15 Feb 2017 08:24:06 -0700 Subject: [PATCH 8/9] Address PR concerns --- generate/templates/manual/remote/ls.cc | 2 +- generate/templates/manual/src/functions/copy.cc | 5 ++++- lib/remote.js | 9 ++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/generate/templates/manual/remote/ls.cc b/generate/templates/manual/remote/ls.cc index 561e0f1f1..d426d6f79 100644 --- a/generate/templates/manual/remote/ls.cc +++ b/generate/templates/manual/remote/ls.cc @@ -85,7 +85,7 @@ void GitRemote::ReferenceListWorker::HandleOKCallback() } else if (baton->error_code < 0) { - Local err = Nan::Error("Method next has thrown an error.")->ToObject(); + Local err = Nan::Error("Reference List has thrown an error.")->ToObject(); err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code)); Local argv[1] = { err diff --git a/generate/templates/manual/src/functions/copy.cc b/generate/templates/manual/src/functions/copy.cc index 9a2e7c3c7..90327650b 100644 --- a/generate/templates/manual/src/functions/copy.cc +++ b/generate/templates/manual/src/functions/copy.cc @@ -26,7 +26,10 @@ git_remote_head *git_remote_head_dup(const git_remote_head *src) { dest->local = src->local; git_oid_cpy(&dest->oid, &src->oid); git_oid_cpy(&dest->loid, &src->loid); - dest->name = strdup(src->name); + + dest->name = src->name + ? strdup(src->name) + : NULL; dest->symref_target = src->symref_target ? strdup(src->symref_target) : NULL; diff --git a/lib/remote.js b/lib/remote.js index 517eae55d..b7c897957 100644 --- a/lib/remote.js +++ b/lib/remote.js @@ -113,11 +113,14 @@ Remote.prototype.push = function(refSpecs, opts) { }; /** - * Lists advertised references from a remote + * Lists advertised references from a remote. You must connect to the remote + * before using referenceList. * * @async - * @return {Promise>} a list of the remote heads currently - * available on the remote for download + * @return {Promise>} a list of the remote heads the remote + * had available at the last established + * connection. + * */ Remote.prototype.referenceList = Remote.prototype.referenceList; From 91079d7964e733ad9878b8fb3aa79c17c9ce9195 Mon Sep 17 00:00:00 2001 From: tyler wanek Date: Wed, 15 Feb 2017 08:41:25 -0700 Subject: [PATCH 9/9] remove destructuring --- test/tests/remote.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/tests/remote.js b/test/tests/remote.js index 4dddda2b7..57d77517d 100644 --- a/test/tests/remote.js +++ b/test/tests/remote.js @@ -506,10 +506,13 @@ describe("Remote", function() { remote.connect(NodeGit.Enums.DIRECTION.FETCH) ]); }) - .then(function([remote]) { + .then(function(results) { + var remote = results[0]; return Promise.all([remote, remote.referenceList()]); }) - .then(function([remote, remoteHeads]) { + .then(function(results) { + var remote = results[0]; + var remoteHeads = results[1]; var remoteHeadsBySha = fp.flow([ fp.map(function(remoteHead) { return {