Skip to content
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
3 changes: 3 additions & 0 deletions generate/input/descriptor.json
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,9 @@
}
},
"patch": {
"dependencies": [
"../include/convenient_patch.h"
],
"functions": {
"git_patch_free": {
"ignore": true
Expand Down
28 changes: 28 additions & 0 deletions generate/input/libgit2-supplement.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,28 @@
},
"new" : {
"functions": {
"git_patch_convenient_from_diff": {
"args": [
{
"name": "diff",
"type": "git_diff *"
},
{
"name": "out",
"type": "std::vector<PatchData*> *"
}
],
"type": "function",
"isManual": true,
"cFile": "generate/templates/manual/patches/convenient_patches.cc",
"isAsync": true,
"isPrototypeMethod": false,
"group": "patch",
"return": {
"type": "int",
"isErrorCode": true
}
},
"git_rebase_next": {
"type": "function",
"file": "rebase.h",
Expand Down Expand Up @@ -232,6 +254,12 @@
"git_odb_object_type"
]
],
[
"patch",
[
"git_patch_convenient_from_diff"
]
],
[
"revwalk",
[
Expand Down
75 changes: 75 additions & 0 deletions generate/templates/manual/include/convenient_hunk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#ifndef CONVENIENTHUNK_H
#define CONVENIENTHUNK_H
// generated from class_header.h
#include <nan.h>
#include <string>

#include "async_baton.h"
#include "promise_completion.h"

extern "C" {
#include <git2.h>
}

#include "../include/typedefs.h"

struct HunkData {
git_diff_hunk hunk;
std::vector<git_diff_line *> *lines;
size_t numLines;
};

void HunkDataFree(HunkData *hunk);

using namespace node;
using namespace v8;

class ConvenientHunk : public Nan::ObjectWrap {
public:
static Nan::Persistent<Function> constructor_template;
static void InitializeComponent (Local<v8::Object> target);

static Local<v8::Value> New(void *raw);

HunkData *GetValue();
char *GetHeader();
size_t GetSize();

private:
ConvenientHunk(HunkData *hunk);
~ConvenientHunk();

HunkData *hunk;

static NAN_METHOD(JSNewFunction);
static NAN_METHOD(Size);

static NAN_METHOD(OldStart);
static NAN_METHOD(OldLines);
static NAN_METHOD(NewStart);
static NAN_METHOD(NewLines);
static NAN_METHOD(HeaderLen);
static NAN_METHOD(Header);

struct LinesBaton {
HunkData *hunk;
std::vector<git_diff_line *> *lines;
};
class LinesWorker : public Nan::AsyncWorker {
public:
LinesWorker(
LinesBaton *_baton,
Nan::Callback *callback
) : Nan::AsyncWorker(callback)
, baton(_baton) {};
~LinesWorker() {};
void Execute();
void HandleOKCallback();

private:
LinesBaton *baton;
};
static NAN_METHOD(Lines);
};

#endif
108 changes: 108 additions & 0 deletions generate/templates/manual/include/convenient_patch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#ifndef CONVENIENTPATCH_H
#define CONVENIENTPATCH_H
// generated from class_header.h
#include <nan.h>
#include <string>

#include "async_baton.h"
#include "promise_completion.h"

extern "C" {
#include <git2.h>
}

#include "../include/typedefs.h"
#include "../include/convenient_hunk.h"

struct ConvenientLineStats {
size_t context;
size_t additions;
size_t deletions;
};

struct PatchData {
ConvenientLineStats lineStats;
git_delta_t status;
git_diff_file new_file;
git_diff_file old_file;
std::vector<HunkData *> *hunks;
size_t numHunks;
};

PatchData *createFromRaw(git_patch *raw);
void PatchDataFree(PatchData *patch);

using namespace node;
using namespace v8;

class ConvenientPatch : public Nan::ObjectWrap {
public:
static Nan::Persistent<Function> constructor_template;
static void InitializeComponent (Local<v8::Object> target);

static Local<v8::Value> New(void *raw);

ConvenientLineStats GetLineStats();
git_delta_t GetStatus();
git_diff_file GetOldFile();
git_diff_file GetNewFile();
size_t GetNumHunks();
PatchData *GetValue();

private:
ConvenientPatch(PatchData *raw);
~ConvenientPatch();

PatchData *patch;

static NAN_METHOD(JSNewFunction);

// patch methods
static NAN_METHOD(LineStats);

// hunk methods
static NAN_METHOD(Size);

struct HunksBaton {
PatchData *patch;
std::vector<HunkData *> *hunks;
};
class HunksWorker : public Nan::AsyncWorker {
public:
HunksWorker(
HunksBaton *_baton,
Nan::Callback *callback
) : Nan::AsyncWorker(callback)
, baton(_baton) {};
~HunksWorker() {};
void Execute();
void HandleOKCallback();

private:
HunksBaton *baton;
};

static NAN_METHOD(Hunks);

// delta methods
static NAN_METHOD(OldFile);
static NAN_METHOD(NewFile);

// convenient status methods
static NAN_METHOD(Status);
static NAN_METHOD(IsUnmodified);
static NAN_METHOD(IsAdded);
static NAN_METHOD(IsDeleted);
static NAN_METHOD(IsModified);
static NAN_METHOD(IsRenamed);
static NAN_METHOD(IsCopied);
static NAN_METHOD(IsIgnored);
static NAN_METHOD(IsUntracked);
static NAN_METHOD(IsTypeChange);
static NAN_METHOD(IsUnreadable);
static NAN_METHOD(IsConflicted);

// Hunk methods
};

#endif
123 changes: 123 additions & 0 deletions generate/templates/manual/patches/convenient_patches.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
NAN_METHOD(GitPatch::ConvenientFromDiff) {
if (info.Length() == 0 || !info[0]->IsObject()) {
return Nan::ThrowError("Diff diff is required.");
}

if (info.Length() == 1 || !info[1]->IsFunction()) {
return Nan::ThrowError("Callback is required and must be a Function.");
}

ConvenientFromDiffBaton *baton = new ConvenientFromDiffBaton;

baton->error_code = GIT_OK;
baton->error = NULL;

baton->diff = Nan::ObjectWrap::Unwrap<GitDiff>(info[0]->ToObject())->GetValue();
baton->out = new std::vector<PatchData *>;
baton->out->reserve(git_diff_num_deltas(baton->diff));

Nan::Callback *callback = new Nan::Callback(Local<Function>::Cast(info[1]));
ConvenientFromDiffWorker *worker = new ConvenientFromDiffWorker(baton, callback);

worker->SaveToPersistent("diff", info[0]);

Nan::AsyncQueueWorker(worker);
return;
}

void GitPatch::ConvenientFromDiffWorker::Execute() {
giterr_clear();

{
LockMaster lockMaster(true, baton->diff);
std::vector<git_patch *> patchesToBeFreed;

for (int i = 0; i < git_diff_num_deltas(baton->diff); ++i) {
git_patch *nextPatch;
int result = git_patch_from_diff(&nextPatch, baton->diff, i);

if (result) {
while (!patchesToBeFreed.empty())
{
git_patch_free(patchesToBeFreed.back());
patchesToBeFreed.pop_back();
}

while (!baton->out->empty()) {
PatchDataFree(baton->out->back());
baton->out->pop_back();
}

baton->error_code = result;

if (giterr_last() != NULL) {
baton->error = git_error_dup(giterr_last());
}

delete baton->out;
baton->out = NULL;

return;
}

if (nextPatch != NULL) {
baton->out->push_back(createFromRaw(nextPatch));
}
}

while (!patchesToBeFreed.empty())
{
git_patch_free(patchesToBeFreed.back());
patchesToBeFreed.pop_back();
}
}
}

void GitPatch::ConvenientFromDiffWorker::HandleOKCallback() {
if (baton->out != NULL) {
unsigned int size = baton->out->size();
Local<Array> result = Nan::New<Array>(size);

for (unsigned int i = 0; i < size; ++i) {
Nan::Set(result, Nan::New<Number>(i), ConvenientPatch::New((void *)baton->out->at(i)));
}

delete baton->out;

Local<v8::Value> argv[2] = {
Nan::Null(),
result
};
callback->Call(2, argv);

return;
}

if (baton->error) {
Local<v8::Value> argv[1] = {
Nan::Error(baton->error->message)
};
callback->Call(1, argv);
if (baton->error->message)
{
free((void *)baton->error->message);
}

free((void *)baton->error);

return;
}

if (baton->error_code < 0) {
Local<v8::Object> err = Nan::Error("method convenientFromDiff has thrown an error.")->ToObject();
err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
Local<v8::Value> argv[1] = {
err
};
callback->Call(1, argv);

return;
}

callback->Call(0, NULL);
}
Loading