mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Many of these (mostly in top level commands in commands-packages.js) are not super well thought out: they use a new "doOrDie" helper to run some function in a capture and exit if there are any messages. We really need to get a little more thoughtful about the big picture of error handling (combining "build" errors, network errors, catalog errors, etc). But this at least allows the addition of more buildmessage assertions. At the very least, this ensures that if you edit a package.js in a local package while "meteor run" is running, that instead of crashing the tool it properly shows the buildmessage and lets you fix the issue.
118 lines
4.0 KiB
JavaScript
118 lines
4.0 KiB
JavaScript
var fs = require('fs');
|
|
var path = require('path');
|
|
var _ = require('underscore');
|
|
var packageCache = require('./package-cache.js');
|
|
var catalog = require('./catalog.js');
|
|
var utils = require('./utils.js');
|
|
var buildmessage = require('./buildmessage.js');
|
|
var unipackage = require('./unipackage.js');
|
|
var tropohouse = require('./tropohouse.js');
|
|
|
|
// options:
|
|
// - versions: a map from package name to the version to use. or null to only
|
|
// use local packages and ignore the package versions.
|
|
// - uniloadDir: if specified, versions should be null, and this loader will
|
|
// *only* load packages that are already unipackages and are in this
|
|
// directory
|
|
exports.PackageLoader = function (options) {
|
|
var self = this;
|
|
self.versions = options.versions || null;
|
|
self.uniloadDir = options.uniloadDir;
|
|
self.constraintSolverOpts = options.constraintSolverOpts;
|
|
};
|
|
|
|
_.extend(exports.PackageLoader.prototype, {
|
|
// Given the name of a package, return a Unipackage object, or throw an
|
|
// error if the package wasn't included in the 'versions' passed on
|
|
// initalization or isn't available (for example, hasn't been
|
|
// downloaded yet).
|
|
//
|
|
// Options are:
|
|
// - throwOnError: if true (the default), throw an error if the
|
|
// package can't be found. (If false is passed for throwOnError,
|
|
// then return null if the package can't be found.) When called
|
|
// inside buildmessage.enterJob, however, instead of throwing an
|
|
// error it will record a build error and return a dummy (empty)
|
|
// package.
|
|
// XXX rename to throwOnNotFound
|
|
getPackage: function (name, options) {
|
|
var self = this;
|
|
buildmessage.assertInCapture();
|
|
|
|
options = options || {};
|
|
if (options.throwOnError === undefined) {
|
|
options.throwOnError = true;
|
|
}
|
|
var loadPath = self.getLoadPathForPackage(name);
|
|
if (! loadPath) {
|
|
if (options.throwOnError === false)
|
|
return null;
|
|
buildmessage.error("package not available: " + name);
|
|
// recover by returning a dummy (empty) package
|
|
var pkg = new unipackage.Unipackage;
|
|
pkg.initEmpty(name);
|
|
return pkg;
|
|
}
|
|
|
|
return packageCache.packageCache.loadPackageAtPath(
|
|
name, loadPath, self.constraintSolverOpts);
|
|
},
|
|
|
|
// As getPackage, but returns the path of the package that would be
|
|
// loaded rather than loading the package, and does not take any
|
|
// options. Returns null if the package is not available.
|
|
//
|
|
// XXX it's a little unfortunate that we have two functions called
|
|
// getLoadPathForPackage, one on this object (which does not take a
|
|
// version) and one on Catalog (which does). Maybe rename them to
|
|
// getPackageLoadPath / getPackageVersionLoadPath?
|
|
getLoadPathForPackage: function (name) {
|
|
var self = this;
|
|
buildmessage.assertInCapture();
|
|
|
|
if (self.uniloadDir) {
|
|
var packagePath = path.join(self.uniloadDir, name);
|
|
if (!fs.existsSync(path.join(packagePath, 'unipackage.json'))) {
|
|
return null;
|
|
}
|
|
return packagePath;
|
|
}
|
|
|
|
if (self.versions && ! _.has(self.versions, name)) {
|
|
throw new Error("no version chosen for package " + name + "?");
|
|
}
|
|
|
|
var version;
|
|
if (self.versions) {
|
|
version = self.versions[name];
|
|
} else {
|
|
version = null;
|
|
}
|
|
|
|
return catalog.complete.getLoadPathForPackage(name,
|
|
version,
|
|
self.constraintSolverOpts);
|
|
},
|
|
|
|
// Given a package name like "ddp" and an architecture, get the unibuild of
|
|
// that package at the right architecture.
|
|
getUnibuild: function (packageName, arch) {
|
|
var self = this;
|
|
buildmessage.assertInCapture();
|
|
|
|
var pkg = self.getPackage(packageName, { throwOnError: true });
|
|
return pkg.getUnibuildAtArch(arch);
|
|
},
|
|
|
|
downloadMissingPackages: function (options) {
|
|
var self = this;
|
|
options = options || {};
|
|
// We can only download packages if we know what versions they are.
|
|
if (!self.versions)
|
|
return;
|
|
tropohouse.default.downloadMissingPackages(self.versions, {
|
|
serverArch: options.serverArch
|
|
});
|
|
}
|
|
});
|