Skip to content

Commit 74a7e07

Browse files
authored
Merge pull request nodegit#1091 from smith-kyle/improve-generate
Generate script: Don't write .cc or .h files if unchanged
2 parents 248afda + 02060bf commit 74a7e07

File tree

5 files changed

+136
-45
lines changed

5 files changed

+136
-45
lines changed

generate/scripts/generateJson.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,7 @@ module.exports = function generateJson() {
231231
}
232232

233233

234-
utils.writeFile("output/idefs.json", output);
235-
234+
utils.writeLocalFile("output/idefs.json", output);
236235
};
237236

238237
if (require.main === module) {

generate/scripts/generateMissingTests.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module.exports = function generateMissingTests() {
1212
var testFilePath = path.join(testFilesPath, idef.filename + ".js");
1313
var result = {};
1414

15-
var file = utils.readFile(testFilePath);
15+
var file = utils.readLocalFile(testFilePath);
1616
if (file) {
1717
var fieldsResult = [];
1818
var functionsResult = [];
@@ -58,7 +58,7 @@ module.exports = function generateMissingTests() {
5858

5959
Promise.all(promises).then(
6060
function() {
61-
utils.writeFile("output/missing-tests.json", output);
61+
utils.writeLocalFile("/output/missing-tests.json", output);
6262
},
6363
function(fail) {
6464
console.error(fail);

generate/scripts/generateNativeCode.js

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const path = require("path");
22
const promisify = require("promisify-node");
33
const fse = promisify(require("fs-extra"));
4+
const os = require('os');
45
const exec = require('../../utils/execPromise');
56
const utils = require("./utils");
67

@@ -24,27 +25,27 @@ module.exports = function generateNativeCode() {
2425
};
2526

2627
var partials = {
27-
asyncFunction: utils.readFile("templates/partials/async_function.cc"),
28-
callbackHelpers: utils.readFile("templates/partials/callback_helpers.cc"),
29-
convertFromV8: utils.readFile("templates/partials/convert_from_v8.cc"),
30-
convertToV8: utils.readFile("templates/partials/convert_to_v8.cc"),
31-
doc: utils.readFile("templates/partials/doc.cc"),
32-
fields: utils.readFile("templates/partials/fields.cc"),
33-
guardArguments: utils.readFile("templates/partials/guard_arguments.cc"),
34-
syncFunction: utils.readFile("templates/partials/sync_function.cc"),
35-
fieldAccessors: utils.readFile("templates/partials/field_accessors.cc"),
36-
traits: utils.readFile("templates/partials/traits.h")
28+
asyncFunction: utils.readLocalFile("templates/partials/async_function.cc"),
29+
callbackHelpers: utils.readLocalFile("templates/partials/callback_helpers.cc"),
30+
convertFromV8: utils.readLocalFile("templates/partials/convert_from_v8.cc"),
31+
convertToV8: utils.readLocalFile("templates/partials/convert_to_v8.cc"),
32+
doc: utils.readLocalFile("templates/partials/doc.cc"),
33+
fields: utils.readLocalFile("templates/partials/fields.cc"),
34+
guardArguments: utils.readLocalFile("templates/partials/guard_arguments.cc"),
35+
syncFunction: utils.readLocalFile("templates/partials/sync_function.cc"),
36+
fieldAccessors: utils.readLocalFile("templates/partials/field_accessors.cc"),
37+
traits: utils.readLocalFile("templates/partials/traits.h")
3738
};
3839

3940
var templates = {
40-
class_content: utils.readFile("templates/templates/class_content.cc"),
41-
struct_content: utils.readFile("templates/templates/struct_content.cc"),
42-
class_header: utils.readFile("templates/templates/class_header.h"),
43-
struct_header: utils.readFile("templates/templates/struct_header.h"),
44-
binding: utils.readFile("templates/templates/binding.gyp"),
45-
nodegitCC: utils.readFile("templates/templates/nodegit.cc"),
46-
nodegitJS: utils.readFile("templates/templates/nodegit.js"),
47-
enums: utils.readFile("templates/templates/enums.js")
41+
class_content: utils.readLocalFile("templates/templates/class_content.cc"),
42+
struct_content: utils.readLocalFile("templates/templates/struct_content.cc"),
43+
class_header: utils.readLocalFile("templates/templates/class_header.h"),
44+
struct_header: utils.readLocalFile("templates/templates/struct_header.h"),
45+
binding: utils.readLocalFile("templates/templates/binding.gyp"),
46+
nodegitCC: utils.readLocalFile("templates/templates/nodegit.cc"),
47+
nodegitJS: utils.readLocalFile("templates/templates/nodegit.js"),
48+
enums: utils.readLocalFile("templates/templates/enums.js")
4849
};
4950

5051
var filters = {
@@ -99,51 +100,63 @@ module.exports = function generateNativeCode() {
99100
return !idef.ignore;
100101
});
101102

103+
const tempDirPath = path.join(os.tmpdir(), 'nodegit_build');
104+
const tempSrcDirPath = path.join(tempDirPath, "src");
105+
const tempIncludeDirPath = path.join(tempDirPath, "include");
102106

103-
fse.remove(path.resolve(__dirname, "../../src")).then(function() {
104-
return fse.remove(path.resolve(__dirname, "../../include"));
105-
}).then(function() {
106-
return fse.copy(path.resolve(__dirname, "../templates/manual/include"), path.resolve(__dirname, "../../include"));
107+
const finalSrcDirPath = path.join(__dirname, '../../src');
108+
const finalIncludeDirPath = path.join(__dirname, '../../include');
109+
110+
fse.remove(tempDirPath).then(function() {
111+
return fse.copy(path.resolve(__dirname, "../templates/manual/include"), tempIncludeDirPath);
107112
}).then(function() {
108-
return fse.copy(path.resolve(__dirname, "../templates/manual/src"), path.resolve(__dirname, "../../src"));
113+
return fse.copy(path.resolve(__dirname, "../templates/manual/src"), tempSrcDirPath);
109114
}).then(function() {
110115
// Write out single purpose templates.
111-
utils.writeFile("../binding.gyp", beautify(templates.binding.render(enabled)), "binding.gyp");
112-
utils.writeFile("../src/nodegit.cc", templates.nodegitCC.render(enabled), "nodegit.cc");
113-
utils.writeFile("../lib/nodegit.js", beautify(templates.nodegitJS.render(enabled)), "nodegit.js");
116+
utils.writeLocalFile("../binding.gyp", beautify(templates.binding.render(enabled)), "binding.gyp");
117+
utils.writeFile(path.join(tempSrcDirPath, "nodegit.cc"), templates.nodegitCC.render(enabled), "nodegit.cc");
118+
utils.writeLocalFile("../lib/nodegit.js", beautify(templates.nodegitJS.render(enabled)), "nodegit.js");
114119
// Write out all the classes.
115120
enabled.forEach(function(idef) {
116121
if (idef.type && idef.type != "enum") {
117122
utils.writeFile(
118-
"../src/" + idef.filename + ".cc",
123+
path.join(tempSrcDirPath, idef.filename + ".cc"),
119124
templates[idef.type + "_content"].render(idef),
120125
idef.type + "_content.cc"
121126
);
127+
122128
utils.writeFile(
123-
"../include/" + idef.filename + ".h",
129+
path.join(tempIncludeDirPath, idef.filename + ".h"),
124130
templates[idef.type + "_header"].render(idef),
125131
idef.type + "_header.h"
126132
);
127133
}
128134
});
129135

130-
utils.writeFile("../lib/enums.js", beautify(templates.enums.render(enabled)), "enums.js");
136+
utils.writeLocalFile("../lib/enums.js", beautify(templates.enums.render(enabled)), "enums.js");
131137
}).then(function() {
132138
return exec("command -v astyle").then(function(astyle) {
133139
if (astyle) {
134140
return exec(
135141
"astyle --options=\".astylerc\" "
136-
+ path.resolve(__dirname, "../../src") + "/*.cc "
137-
+ path.resolve(__dirname, "../../include") + "/*.h"
142+
+ tempSrcDirPath + "/*.cc "
143+
+ tempIncludeDirPath + "/*.h"
138144
).then(function() {
139145
return exec(
140146
"rm "
141-
+ path.resolve(__dirname, "../../src") + "/*.cc.orig "
142-
+ path.resolve(__dirname, "../../include") + "/*.h.orig "
147+
+ tempSrcDirPath + "/*.cc.orig "
148+
+ tempIncludeDirPath + "/*.h.orig "
143149
);
144150
});
145151
}
146152
}, function() {})
153+
}).then(function() {
154+
return Promise.all([
155+
utils.syncDirs(tempSrcDirPath, finalSrcDirPath),
156+
utils.syncDirs(tempIncludeDirPath, finalIncludeDirPath),
157+
]);
158+
}).then(function() {
159+
return fse.remove(tempDirPath);
147160
}).catch(console.log);
148161

149162
};

generate/scripts/utils.js

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const fse = require("fs-extra");
2+
const walk = require("walk");
23

34
const fs = require("fs");
45
const path = require("path");
@@ -10,18 +11,25 @@ var util = {
1011
pointerRegex: /\s*\*\s*/,
1112
doublePointerRegex: /\s*\*\*\s*/,
1213

13-
readFile: function(file) {
14+
readLocalFile: function(filePath) {
15+
return util.readFile(local(filePath));
16+
},
17+
18+
readFile: function(filePath) {
1419
try {
15-
return fs.readFileSync(local(file)).toString();
20+
return fs.readFileSync(filePath).toString();
1621
}
1722
catch (unhandledException) {
1823
return "";
1924
}
2025
},
2126

22-
writeFile: function(file, content, header) {
27+
writeLocalFile: function(filePath, content, header) {
28+
return util.writeFile(local(filePath), content, header);
29+
},
30+
31+
writeFile: function(filePath, content, header) {
2332
try {
24-
var file = local(file);
2533
if (typeof content == "object") {
2634
content = JSON.stringify(content, null, 2)
2735
}
@@ -35,8 +43,8 @@ var util = {
3543
content;
3644
}
3745

38-
fse.ensureFileSync(file);
39-
fse.writeFileSync(file, content);
46+
fse.ensureFileSync(filePath);
47+
fse.writeFileSync(filePath, content);
4048
return true;
4149
}
4250
catch (exception) {
@@ -62,14 +70,84 @@ var util = {
6270
}).join("");
6371
},
6472

73+
getFilePathsRelativeToDir: function(dir) {
74+
const files = [];
75+
const walker = walk.walk(dir, { followLinks: false });
76+
if (!util.isDirectory(dir)) {
77+
return Promise.resolve([]);
78+
}
79+
80+
return new Promise(function(resolve, reject) {
81+
walker.on('file', function(root, stat, next) {
82+
files.push(path.relative(dir, path.join(root, stat.name)));
83+
next();
84+
});
85+
86+
walker.on('end', function() {
87+
resolve(files);
88+
});
89+
90+
walker.on('errors', function() {
91+
reject();
92+
});
93+
});
94+
},
95+
96+
isFile: function(path) {
97+
var isFile;
98+
try {
99+
isFile = fse.statSync(path).isFile();
100+
} catch(e) {
101+
isFile = false;
102+
}
103+
104+
return isFile;
105+
},
106+
107+
isDirectory: function(path) {
108+
var isDirectory;
109+
try {
110+
isDirectory = fse.statSync(path).isDirectory();
111+
} catch(e) {
112+
isDirectory = false;
113+
}
114+
115+
return isDirectory;
116+
},
117+
65118
isPointer: function(type) {
66119
return util.pointerRegex.test(type) || util.doublePointerRegex.test(type);
67120
},
68121

69122
isDoublePointer: function(type) {
70123
return util.doublePointerRegex.test(type);
71-
}
124+
},
72125

126+
syncDirs: function(fromDir, toDir) {
127+
return Promise.all([
128+
util.getFilePathsRelativeToDir(toDir),
129+
util.getFilePathsRelativeToDir(fromDir)
130+
]).then(function(filePaths) {
131+
const toFilePaths = filePaths[0];
132+
const fromFilePaths = filePaths[1];
133+
134+
// Delete files that aren't in fromDir
135+
toFilePaths.forEach(function(filePath) {
136+
if (!util.isFile(path.join(fromDir, filePath))) {
137+
fse.remove(path.join(toDir, filePath));
138+
}
139+
});
140+
141+
// Copy files that don't exist in toDir or have different contents
142+
fromFilePaths.forEach(function(filePath) {
143+
const toFilePath = path.join(toDir, filePath);
144+
const fromFilePath = path.join(fromDir, filePath);
145+
if (!util.isFile(toFilePath) || util.readFile(toFilePath) !== util.readFile(fromFilePath)) {
146+
fse.copy(fromFilePath, toFilePath);
147+
}
148+
});
149+
});
150+
}
73151
};
74152

75153
module.exports = util;

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@
5252
"js-beautify": "~1.5.10",
5353
"jshint": "~2.8.0",
5454
"lcov-result-merger": "~1.0.2",
55-
"mocha": "~2.3.4"
55+
"mocha": "~2.3.4",
56+
"walk": "^2.3.9"
5657
},
5758
"vendorDependencies": {
5859
"libssh2": "1.7.0",

0 commit comments

Comments
 (0)