Skip to content

Commit 458e080

Browse files
committed
Using code-generation to implement libgit2 c++ bindings. The oid class is fully code-gen'd and all tests pass.
1 parent 4b6885e commit 458e080

23 files changed

+14995
-337
lines changed

gen.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var fs = require('fs'),
2+
ejs = require('ejs'),
3+
path = require('path');
4+
5+
var idefs = JSON.parse(fs.readFileSync('v0.18.0.json')),
6+
classTemplate = ejs.compile(fs.readFileSync(path.resolve("./templates/class.cc.ejs")).toString()),
7+
headerTemplate = ejs.compile(fs.readFileSync(path.resolve("./templates/header.h.ejs")).toString());
8+
9+
for (var i in idefs) {
10+
var idef = idefs[i];
11+
if (idef.jsClassName != "Oid") continue;
12+
13+
fs.writeFileSync(path.resolve("./include/" + idef.filename), headerTemplate(idef));
14+
fs.writeFileSync(path.resolve("./src/" + path.basename(idef.filename, '.h') + '.cc'), classTemplate(idef));
15+
}

include/oid.h

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
/*
2-
* Copyright 2013, Tim Branyen @tbranyen <tim@tabdeveloper.com>
3-
* @author Michael Robinson @codeofinterest <mike@pagesofinterest.net>
4-
*
5-
* Dual licensed under the MIT and GPL licenses.
6-
*/
1+
/**
2+
* This code is auto-generated; unless you know what you're doing, do not modify!
3+
**/
74

8-
#ifndef OID_H
9-
#define OID_H
5+
#ifndef GITOID_H
6+
#define GITOID_H
107

118
#include <v8.h>
129
#include <node.h>
@@ -21,36 +18,19 @@ class GitOid : public ObjectWrap {
2118
public:
2219

2320
static Persistent<Function> constructor_template;
24-
2521
static void Initialize (Handle<v8::Object> target);
22+
2623
git_oid GetValue();
27-
void SetValue(git_oid oid);
2824

29-
protected:
30-
GitOid() {}
31-
~GitOid() {}
25+
private:
26+
GitOid(git_oid *raw);
27+
~GitOid();
3228

3329
static Handle<Value> New(const Arguments& args);
3430

35-
static Handle<Value> Sha(const Arguments& args);
36-
3731
static Handle<Value> FromString(const Arguments& args);
38-
static void FromStringWork(uv_work_t* req);
39-
static void FromStringAfterWork(uv_work_t* req);
40-
41-
private:
42-
git_oid oid;
43-
44-
struct FromStringBaton {
45-
uv_work_t request;
46-
const git_error* error;
47-
48-
std::string fromString;
49-
GitOid* oid;
50-
git_oid rawOid;
51-
52-
Persistent<Function> callback;
53-
};
32+
static Handle<Value> Sha(const Arguments& args);
33+
git_oid *raw;
5434
};
5535

5636
#endif

lib/commit.js

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -54,37 +54,20 @@ Commit.prototype.lookup = function(oid, callback) {
5454
*
5555
* @param {Commit~oidCallback} callback
5656
*/
57-
Commit.prototype.oid = function(callback) {
57+
Commit.prototype.oid = function() {
5858
/**
5959
* @callback Commit~oidCallback Callback executed on OID retrieval.
6060
* @param {GitError|null} error An Error or null if successful.
6161
* @param {Oid|null} commit Retrieved OID object or null.
6262
*/
63-
callback(null, new git.oid(this.rawCommit.oid()));
63+
return new git.oid(this.rawCommit.oid());
6464
};
6565

6666
/**
6767
* Retrieve the SHA.
68-
*
69-
* @param {Commit~shaCallback} callback
7068
*/
71-
Commit.prototype.sha = function(callback) {
72-
/**
73-
* @callback Commit~shaCallback Callback executed on SHA retrieval.
74-
* @param {GitError|null} error An Error or null if successful.
75-
* @param {String|null} sha Retrieved SHA.
76-
*/
77-
this.oid(function(error, oid) {
78-
if (!success(error, callback)) {
79-
return;
80-
}
81-
oid.sha(function(error, sha) {
82-
if (!success(error, callback)) {
83-
return;
84-
}
85-
callback(null, sha);
86-
});
87-
});
69+
Commit.prototype.sha = function() {
70+
return this.oid().sha();
8871
};
8972

9073
/**
@@ -254,41 +237,39 @@ Commit.prototype.history = function() {
254237
var event = new events.EventEmitter(),
255238
self = this;
256239

257-
self.oid(function commitOid(error, oid) {
258-
(new git.revwalk(self.rawRepo)).allocate(function createRevwalk(error, revwalk) {
259-
var commits = [];
260-
revwalk.walk(oid, function commitRevWalk(error, index, commit, noMoreCommits) {
261-
if(error) {
262-
event.emit('end', error, commits);
263-
return false;
264-
}
240+
var oid = self.oid();
241+
(new git.revwalk(self.rawRepo)).allocate(function createRevwalk(error, revwalk) {
242+
var commits = [];
243+
revwalk.walk(oid, function commitRevWalk(error, index, commit, noMoreCommits) {
244+
if(error) {
245+
event.emit('end', error, commits);
246+
return false;
247+
}
265248

266-
if (noMoreCommits) {
267-
/**
268-
* End event.
269-
*
270-
* @event Commit#end
271-
*
272-
* @param {GitError|null} error An error object if there was an issue, null otherwise.
273-
* @param {Commit[]} commits The commits.
274-
*/
275-
event.emit('end', null, commits);
276-
return;
277-
}
249+
if (noMoreCommits) {
278250
/**
279-
* Commit event.
251+
* End event.
280252
*
281-
* @event Commit#commit
253+
* @event Commit#end
282254
*
283255
* @param {GitError|null} error An error object if there was an issue, null otherwise.
284-
* @param {Commit} commit The commit.
256+
* @param {Commit[]} commits The commits.
285257
*/
286-
event.emit('commit', null, commit);
287-
commits.push(commit);
288-
});
258+
event.emit('end', null, commits);
259+
return;
260+
}
261+
/**
262+
* Commit event.
263+
*
264+
* @event Commit#commit
265+
*
266+
* @param {GitError|null} error An error object if there was an issue, null otherwise.
267+
* @param {Commit} commit The commit.
268+
*/
269+
event.emit('commit', null, commit);
270+
commits.push(commit);
289271
});
290272
});
291-
292273
return event;
293274
};
294275

@@ -328,27 +309,22 @@ Commit.prototype.parentsDiffTrees = function(callback) {
328309
* @param {DiffList[]|null} diffLists Array of DiffTrees showing changes between this commit and its parent(s)
329310
*/
330311
var self = this;
331-
self.sha(function(error, commitSha) {
312+
var commitSha = self.sha();
313+
self.parents(function commitParents(error, parents) {
332314
if (!success(error, callback)) {
333315
return;
334316
}
335-
self.parents(function commitParents(error, parents) {
336-
if (!success(error, callback)) {
337-
return;
338-
}
339-
var parentDiffLists = [];
340-
parents.forEach(function commitEachParent(parent) {
341-
parent.sha(function commitParentSha(error, parentSha) {
342-
(new git.diffList(self.rawRepo)).treeToTree(parentSha, commitSha, function walkDiffList(error, diffList) {
343-
if (!success(error, callback)) {
344-
return;
345-
}
346-
parentDiffLists.push(diffList);
347-
if (parentDiffLists.length === parents.length) {
348-
callback(null, parentDiffLists);
349-
}
350-
});
351-
});
317+
var parentDiffLists = [];
318+
parents.forEach(function commitEachParent(parent) {
319+
var parentSha = parent.sha();
320+
(new git.diffList(self.rawRepo)).treeToTree(parentSha, commitSha, function walkDiffList(error, diffList) {
321+
if (!success(error, callback)) {
322+
return;
323+
}
324+
parentDiffLists.push(diffList);
325+
if (parentDiffLists.length === parents.length) {
326+
callback(null, parentDiffLists);
327+
}
352328
});
353329
});
354330
});

lib/oid.js

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,27 @@ var Oid = function(rawOid) {
1616
};
1717

1818
/**
19-
* @return {git.raw.Oid} The wrapped raw Oid object.
19+
* Create Oid object from string.
20+
*
21+
* @param {String} sha
2022
*/
21-
Oid.prototype.getRawOid = function() {
22-
return this.rawOid;
23+
Oid.fromString = function(sha) {
24+
var rawOid = git.raw.Oid.fromString(sha);
25+
return new Oid(rawOid);
2326
};
2427

2528
/**
26-
* Create Oid object from string.
27-
*
28-
* @param {String} sha
29-
* @param {Oid~fromStringCallback} callback
29+
* @return {git.raw.Oid} The wrapped raw Oid object.
3030
*/
31-
Oid.prototype.fromString = function(sha, callback) {
32-
/**
33-
* @callback Oid~fromStringCallback Callback executed after raw Oid is created.
34-
* @param {GitError|null} error An Error or null if successful.
35-
* @param {Oid|null} oid The new Oid object.
36-
*/
37-
var self = this;
38-
self.rawOid.fromString(sha, function(error, rawOid) {
39-
if (success(error, callback)) {
40-
self.rawOid = rawOid;
41-
callback(null, self);
42-
}
43-
});
31+
Oid.prototype.getRawOid = function() {
32+
return this.rawOid;
4433
};
4534

4635
/**
4736
* Convert the raw Oid to a SHA
48-
*
49-
* @param {Oid~shaCallback} callback
5037
*/
51-
Oid.prototype.sha = function(callback) {
52-
/**
53-
* @callback Oid~shaCallback Callback executed after SHA is retrieved.
54-
* @param {GitError|null} error An Error or null if successful.
55-
* @param {String|null} sha The SHA.
56-
*/
57-
callback(null, this.rawOid.sha());
38+
Oid.prototype.sha = function() {
39+
return this.rawOid.sha();
5840
};
5941

6042
exports.oid = Oid;

lib/tree_entry.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,8 @@ TreeEntry.prototype.sha = function(callback) {
8080
if (!success(error, callback)) {
8181
return;
8282
}
83-
(new git.oid(oid)).sha(function(error, sha) {
84-
if (success(error, callback)) {
85-
callback(null, sha);
86-
}
87-
});
83+
var sha = new git.oid(oid).sha();
84+
callback(null, sha);
8885
});
8986
};
9087

munge.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
var fs = require('fs'),
2+
_ = require('underscore'),
3+
path = require('path');
4+
5+
var DOUBLE_POINTER_RE = /\*\*$/;
6+
var OUT_VAR_RE = /_out$/;
7+
function isConstructorMethod(cType, functionInfo) {
8+
if (!functionInfo.args.length) return false;
9+
var firstArg = functionInfo.args[0];
10+
return RegExp(cType + " \\*\\*$").test(firstArg.cType) && !isPrototypeMethod(cType, functionInfo) && !/_free$/.test(functionInfo.cFunctionName);
11+
}
12+
13+
function isPrototypeMethod(cType, functionInfo) {
14+
if (!functionInfo.args.length) return false;
15+
16+
var firstArg = functionInfo.args[0];
17+
return RegExp(cType + " \\*$").test(firstArg.cType) && !/_free$/.test(functionInfo.cFunctionName);
18+
}
19+
20+
var idefs = JSON.parse(fs.readFileSync('v0.18.0.json'));
21+
22+
for (var i in idefs) {
23+
var idef = idefs[i];
24+
25+
for (var j in idef.functions) {
26+
var fn = idef.functions[j];
27+
var old1 = fn.isPrototypeMethod;
28+
var old2 = fn.isConstructorMethod;
29+
fn.isPrototypeMethod = isPrototypeMethod(idef.cType, fn);
30+
fn.isConstructorMethod = isConstructorMethod(idef.cType, fn);
31+
fn.isFree = /_free$/.test(fn.cFunctionName);
32+
33+
}
34+
}
35+
console.log(JSON.stringify(idefs, null, 2));

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@
3838
},
3939
"devDependencies": {
4040
"nodeunit": "",
41-
"rimraf": "1.0.x"
41+
"rimraf": "1.0.x",
42+
"ejs": "0.8.x"
4243
},
4344
"scripts": {
4445
"install": "node install.js",
45-
"test": "cd test && nodeunit *.js"
46+
"test": "cd test && nodeunit *.js",
47+
"gen": "node gen.js"
4648
}
4749
}

src/base.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
#include "../include/threads.h"
2525

2626
extern "C" void init(Handle<v8::Object> target) {
27-
HandleScope scope;
28-
2927
GitError::Initialize(target);
3028

3129
GitReference::Initialize(target);

src/commit.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,10 @@ void GitCommit::LookupAfterWork(uv_work_t *req) {
155155
Handle<Value> GitCommit::Oid(const Arguments& args) {
156156
HandleScope scope;
157157

158-
Local<Object> oid = GitOid::constructor_template->NewInstance();
159-
GitOid *oidInstance = ObjectWrap::Unwrap<GitOid>(oid);
160-
oidInstance->SetValue(*const_cast<git_oid *>(ObjectWrap::Unwrap<GitCommit>(args.This())->oid));
161-
162-
return scope.Close(oid);
158+
git_oid *rawOid = (git_oid *)malloc(sizeof(git_oid));
159+
git_oid_cpy(rawOid, ObjectWrap::Unwrap<GitCommit>(args.This())->oid);
160+
Handle<Value> argv[1] = { External::New(rawOid) };
161+
return scope.Close(GitOid::constructor_template->NewInstance(1, argv));
163162
}
164163

165164
Handle<Value> GitCommit::Message(const Arguments& args) {

0 commit comments

Comments
 (0)