Skip to content

Commit 6302655

Browse files
committed
CLI: Check actual module directories to determine if cli dependencies are present and bootstrap semver, see #648
1 parent 49053ff commit 6302655

File tree

1 file changed

+40
-25
lines changed

1 file changed

+40
-25
lines changed

cli/util.js

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
var fs = require("fs"),
33
path = require("path"),
44
child_process = require("child_process"),
5-
Module = require("module");
5+
semver;
66

77
var protobuf = require("..");
88

@@ -71,38 +71,53 @@ exports.inspect = function inspect(object, indent) {
7171
return sb.join("\n");
7272
};
7373

74-
exports.setup = function() {
75-
// this one is important. without it, this folder won't be searched anymore.
76-
try { fs.mkdirSync(path.join(__dirname, "node_modules")); } catch (e) {}
74+
var paths = [
75+
path.resolve(__dirname, "..", "node_modules"),
76+
path.resolve(__dirname, "node_modules")
77+
];
7778

78-
// find out which modules are missing
79-
var pkg = require(path.join(__dirname, "..", "package.json"));
80-
var install = [];
81-
var semver;
82-
pkg.cliDependencies.forEach(function(name) {
83-
var version = pkg.dependencies[name] || pkg.devDependencies[name];
79+
function modExists(name, version) {
80+
for (var i = 0; i < paths.length; ++i) {
8481
try {
85-
var mPath = require.resolve(name + "/package.json"); // jsdoc has no main file
86-
var mPkg = JSON.parse(fs.readFileSync(mPath));
87-
if (semver && !semver.satisfies(mPkg.version, version))
88-
throw Error(mPkg.version + " is outdated");
89-
} catch (e) {
90-
process.stderr.write("installing " + name + "@" + version + " (" + e.message + ")\n");
91-
install.push(version ? name + "@" + version : name);
92-
}
93-
if (name === "semver")
94-
semver = require("semver");
95-
});
96-
if (!install.length) {
97-
try { fs.rmdirSync(path.join(__dirname, "node_modules")); } catch (e) {}
98-
return;
82+
var pkg = JSON.parse(fs.readFileSync(path.join(paths[i], name, "package.json")));
83+
return semver
84+
? semver.satisfies(pkg.version, version)
85+
: parseInt(pkg.version, 10) === parseInt(version.replace(/^[\^~]/, ""), 10); // used for semver only
86+
} catch (e) {}
9987
}
88+
return false;
89+
}
10090

101-
// if any are missing, install them. this relies on an empty package.json in cli/.
91+
function modInstall(install) {
92+
if (typeof install === "string")
93+
install = [ install ];
10294
child_process.execSync("npm --silent install " + install.join(" "), {
10395
cwd: __dirname,
10496
stdio: "ignore"
10597
});
98+
}
99+
100+
exports.setup = function() {
101+
var pkg = require(path.join(__dirname, "..", "package.json"));
102+
var version = pkg.dependencies["semver"] || pkg.devDependencies["semver"];
103+
if (!modExists("semver", version)) {
104+
process.stderr.write("installing semver@" + version + "\n");
105+
modInstall("semver@" + version);
106+
}
107+
semver = require("semver"); // used from now on for version comparison
108+
var install = [];
109+
pkg.cliDependencies.forEach(function(name) {
110+
if (name === "semver")
111+
return;
112+
version = pkg.dependencies[name] || pkg.devDependencies[name];
113+
if (!modExists(name, version)) {
114+
process.stderr.write("installing " + name + "@" + version + "\n");
115+
install.push(name + "@" + version);
116+
}
117+
});
118+
if (!install.length)
119+
return;
120+
modInstall(install);
106121
};
107122

108123
exports.wrap = function(OUTPUT, options) {

0 commit comments

Comments
 (0)