Skip to content

Commit 2fea2d3

Browse files
committed
completely rewrite installer
1 parent 9412ebc commit 2fea2d3

File tree

5 files changed

+137
-205
lines changed

5 files changed

+137
-205
lines changed

example/clone.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
var nodegit = require('../');
2-
var rimraf = require('rimraf');
2+
var promisify = require("promisify-node");
3+
var fse = promisify(require("fs-extra"));
34
var path = "/tmp/nodegit-clone-demo";
45

5-
rimraf(path, function() {
6+
fse.remove(path).then(function() {
67
var entry;
78

89
nodegit.Clone.clone(

install.js

Lines changed: 115 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
var os = require("os");
2-
var fs = require("fs");
32
var path = require("path");
43
var zlib = require("zlib");
5-
var exec = require("child_process").exec;
6-
var Q = require("q");
7-
var request = require("request");
84
var tar = require("tar");
9-
var which = require("which");
10-
var rimraf = require("rimraf");
5+
6+
var Promise = require("nodegit-promise");
7+
var promisify = require("promisify-node");
8+
var request = require("request");
9+
var fse = promisify(require("fs-extra"));
10+
fse.ensureDir = promisify(fse.ensureDir);
11+
12+
var exec = promisify(function(command, opts, callback) {
13+
return require("child_process").exec(command, opts, callback);
14+
});
15+
1116
var NODE_VERSION = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
1217

1318
// If the build only flag is set.
@@ -41,7 +46,7 @@ function systemPath(parts) {
4146
}
4247

4348
// Will be used near the end to configure `node-gyp`.
44-
var python;
49+
var pythonPath = '/usr/bin/python';
4550

4651
var local = path.join.bind(path, __dirname);
4752

@@ -66,197 +71,129 @@ if (NODE_VERSION === 0.1) {
6671
pkg.http_parser = pkg.http_parser["0.10"];
6772
}
6873

69-
// Attempt to fallback on a prebuilt binary.
70-
function fetchPrebuilt() {
74+
fse.ensureDir(path.resolve(__dirname, paths.release))
75+
.then(fetch)
76+
.then(finish, compile)
77+
.done()
78+
79+
function fetch() {
7180
if (!buildOnly) {
7281
console.info("[nodegit] Fetching binary from S3.");
7382

7483
// Using the node-pre-gyp module, attempt to fetch a compatible build.
75-
return Q.nfcall(exec, "node-pre-gyp install");
84+
return exec("node-pre-gyp install");
7685
}
7786

78-
throw new Error("Build only");
87+
throw new Error("BUILD_ONLY is set to true, no fetching allowed.");
7988
}
8089

81-
// Attempt to fetch prebuilt binary.
82-
Q.ninvoke(fs, "mkdir", paths.release).then(fetchPrebuilt, fetchPrebuilt)
83-
84-
.fail(function() {
90+
function compile() {
8591
if (!buildOnly) {
8692
console.info("[nodegit] Failed to install prebuilt, attempting compile.");
8793
}
8894

89-
// Ensure all dependencies are available.
90-
return Q.allSettled([
91-
// This will prioritize `python2` over `python`, because we always want to
92-
// work with Python 2.* if it"s available.
93-
Q.nfcall(which, "python2"),
94-
Q.nfcall(which, "python")
95-
])
96-
})
97-
98-
// Determine if all the dependency requirements are met.
99-
.then(function(results) {
10095
console.info("[nodegit] Determining dependencies.");
10196

102-
// Assign to reusable variables.
103-
python = results[0].value || results[1].value;
104-
105-
// Missing Python.
106-
if (!python) {
107-
throw new Error("Python is required to build libgit2.");
108-
}
109-
110-
// Now lets check the Python version to ensure it"s < 3.
111-
return Q.nfcall(exec, python + " --version").then(function(version) {
112-
if (version[1].indexOf("Python 3") === 0) {
113-
throw new Error("Incorrect version of Python, gyp requires < 3.");
114-
}
115-
});
116-
})
117-
118-
// Successfully found all dependencies. First step is to detect the vendor
119-
// directory.
120-
.then(function() {
121-
console.info("[nodegit] Detecting vendor/libgit2.");
122-
123-
return Q.ninvoke(fs, "stat", paths.libgit2).then(function() {
124-
return Q.ninvoke(fs, "stat", paths.libgit2 + pkg.libgit2.sha);
125-
}).fail(function() {
126-
console.info("[nodegit] Removing outdated vendor/libgit2.");
127-
128-
// This directory is outdated, remove.
129-
throw Q.ninvoke(rimraf, null, paths.libgit2);
130-
});
131-
})
132-
133-
// If the directory already exists, no need to refetch.
134-
.fail(function() {
135-
// Otherwise fetch the libgit2 source from GitHub.
136-
console.info("[nodegit] Fetching vendor/libgit2.");
137-
138-
var url = "https://github.com/libgit2/libgit2/tarball/" + pkg.libgit2.sha;
139-
140-
var extract = tar.Extract({
141-
path: paths.libgit2,
142-
strip: true
143-
});
144-
145-
// First extract from Zlib and then extract from Tar.
146-
var expand = request.get(url).pipe(zlib.createUnzip()).pipe(extract);
147-
148-
return Q.ninvoke(expand, "on", "end").then(function() {
149-
// Write out a sha file for testing in the future.
150-
return Q.ninvoke(fs, "writeFile", paths.libgit2 + pkg.libgit2.sha, "");
151-
});
152-
})
153-
154-
// Grab libssh2 if needed.
155-
.then(function() {
156-
console.info("[nodegit] Detecting vendor/libssh2.");
157-
158-
return Q.ninvoke(fs, "stat", paths.libssh2).then(function() {
159-
return Q.ninvoke(fs, "stat", paths.libssh2 + pkg.libssh2.version);
160-
}).fail(function() {
161-
console.info("[nodegit] Removing outdated vendor/libssh2.");
162-
163-
// This directory is outdated, remove.
164-
throw Q.ninvoke(rimraf, null, paths.libssh2);
165-
});
166-
})
167-
168-
// If the directory already exists, no need to refetch.
169-
.fail(function() {
170-
// Otherwise fetch the libssh2 source.
171-
console.info("[nodegit] Fetching vendor/libssh2.");
97+
return python()
98+
.then(getVendorLib("libgit2", "https://github.com/libgit2/libgit2/tarball/" + pkg.libgit2.sha))
99+
.then(getVendorLib("libssh2", pkg.libssh2.url))
100+
.then(getVendorLib("http_parser", pkg.http_parser.url))
101+
.then(buildNative)
102+
.then(finish, fail);
172103

173-
var url = pkg.libssh2.url;
174-
175-
var extract = tar.Extract({
176-
path: paths.libssh2,
177-
strip: true
178-
});
104+
}
179105

180-
// First extract from Zlib and then extract from Tar.
181-
var expand = request.get(url).pipe(zlib.createUnzip()).pipe(extract);
106+
function python() {
107+
return exec("which python2")
108+
.then(function(which){
109+
return which;
110+
}, function(err) {
111+
return null;
112+
})
113+
.then(function(path) {
114+
return path || exec("which python");
115+
})
116+
.then(function(which) {
117+
return which;
118+
}, function(err) {
119+
return null;
120+
})
121+
.then(function(path) {
122+
pythonPath = path.trim();
123+
if (!pythonPath) {
124+
throw new Error("Python is required to build libgit2.");
125+
}
126+
})
127+
.then(function() {
128+
return exec(pythonPath + " -V 2>&1");
129+
})
130+
.then(function(version) {
131+
if (version[1].indexOf("Python 3") === 0) {
132+
throw new Error("Incorrect version of Python, gyp requires < 3.");
133+
}
134+
});
135+
}
182136

183-
return Q.ninvoke(expand, "on", "end").then(function() {
184-
// Write out a sha file for testing in the future.
185-
return Q.ninvoke(fs, "writeFile", paths.libssh2 + pkg.libssh2.version, "");
186-
}).then(function() {
187-
// Only run the configuration script in a BSD-like environment.
188-
if (process.platform !== "win32") {
189-
return Q.nfcall(exec, "cd " + paths.libssh2 + " ; " + paths.libssh2 +
190-
"configure");
137+
function getVendorLib(name, url) {
138+
return function() {
139+
var version = pkg[name].sha || pkg[name].version;
140+
console.info("[nodegit] Detecting vendor/" + name + ".");
141+
if (fse.existsSync(paths[name] + version)) {
142+
console.info("[nodegit] vendor/" + name + " already exists.");
143+
return new Promise(function(resolve, reject) {resolve() });
191144
}
192-
});
193-
})
194-
195-
// Grab http-parser if needed.
196-
.then(function() {
197-
console.info("[nodegit] Detecting vendor/http_parser.");
198-
199-
return Q.ninvoke(fs, "stat", paths.http_parser).then(function() {
200-
return Q.ninvoke(fs, "stat", paths.http_parser + pkg.http_parser.version);
201-
}).fail(function() {
202-
console.info("[nodegit] Removing outdated vendor/http_parser.");
203-
204-
// This directory is outdated, remove.
205-
throw Q.ninvoke(rimraf, null, paths.http_parser);
206-
});
207-
})
208-
209-
// If the directory already exists, no need to refetch.
210-
.fail(function() {
211-
// Otherwise fetch the http_parser source.
212-
console.info("[nodegit] Fetching vendor/http_parser.");
213-
214-
var url = pkg.http_parser.url;
215-
216-
var extract = tar.Extract({
217-
path: paths.http_parser,
218-
strip: true
219-
});
220-
221-
// First extract from Zlib and then extract from Tar.
222-
var expand = request.get(url).pipe(zlib.createUnzip()).pipe(extract);
223-
224-
return Q.ninvoke(expand, "on", "end").then(function() {
225-
// Write out a sha file for testing in the future.
226-
return Q.ninvoke(fs, "writeFile", paths.http_parser +
227-
pkg.http_parser.version, "");
228-
});
229-
})
230-
231-
232-
// Build the native module using node-gyp.
233-
.then(function() {
234-
console.info("[nodegit] Building native node module.");
235-
var pythonFlag = " --python \"" + python + "\"";
236-
237-
return Q.nfcall(exec, systemPath([
238-
".", "node_modules", ".bin", "node-gyp clean configure build" + pythonFlag
239-
]), {
240-
cwd: ".",
241-
maxBuffer: Number.MAX_VALUE
242-
});
243-
})
145+
else {
146+
console.info("[nodegit] Removing outdated vendor/" + name + ".");
147+
return fse.remove(paths[name])
148+
.then(function() {
149+
return new Promise(function (resolve, reject) {
150+
151+
console.info("[nodegit] Fetching vendor/" + name + ".");
152+
153+
var extract = tar.Extract({
154+
path: paths[name],
155+
strip: true
156+
});
157+
158+
request.get(url).pipe(zlib.createUnzip()).pipe(extract)
159+
.on("error", reject)
160+
.on("end", resolve);
161+
});
162+
}).then(function() {
163+
return fse.writeFile(paths[name] + version, "");
164+
}).then(function() {
165+
if ((name == "libssh2") && (process.platform !== "win32")) {
166+
167+
return exec(paths[name] + "configure", {cwd: paths[name]});
168+
}
169+
});
170+
}
171+
}
172+
}
244173

245-
// Display a warning message about failing to build native node module.
246-
.fail(function(message) {
247-
console.info("[nodegit] Failed to build and install nodegit.");
248-
console.info(message.message);
249-
console.info(message.stack);
250-
})
174+
function buildNative() {
175+
return exec("cd " + __dirname).then(function() {
176+
console.info("[nodegit] Building native node module.");
177+
var pythonFlag = " --python \"" + pythonPath + "\"";
178+
var cmd = path.resolve(systemPath([
179+
".", "node_modules", ".bin", "node-gyp clean configure build" + pythonFlag
180+
]));
181+
var opts = {
182+
cwd: __dirname,
183+
maxBuffer: Number.MAX_VALUE
184+
};
185+
return exec(cmd, opts);
186+
})
187+
}
251188

252-
// Display a success message.
253-
.then(function() {
189+
function finish() {
254190
console.info("[nodegit] Completed installation successfully.");
255-
})
191+
return Promise.resolve().done();
192+
}
256193

257-
// Display a warning message about failing to build native node module.
258-
.fail(function(message) {
259-
console.info("[nodegit] Failed to build nodegit.");
194+
function fail(message) {
195+
console.info("[nodegit] Failed to build and install nodegit.");
260196
console.info(message.message);
261-
console.info(message.stack);
262-
});
197+
//console.info(message.stack);
198+
return Promise.resolve().done();
199+
}

lib/commit.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
var events = require("events");
2-
var Promise = require("promise");
2+
var Promise = require("nodegit-promise");
33
var NodeGit = require("../");
44

55
var Commit = NodeGit.Commit;

0 commit comments

Comments
 (0)