mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
(still outstanding: changes to package publication workflow) A package marked debugOnly in the package source is not to be bundled in production. Moreover, if a package/app depends on a debugOnly package, that entire tree should not be bundled. (But we should take it into account when figuring out versions!) Does the following: - In the catalog, we have a function that takes in a set of versions and a set of original constraints and traverses it, recursively, to build a subset of versions that we *should* bundle, and the corresponding subset of versions that we shouldn't (because they are either debugOnly themselves or pulled in by debugOnly packages). (We do this in the catalog because it is an addon onto the results of the constraint solver, tied deeply into our representation of data) - In the packageLoader, we keep track packages & versions that we should bundle, and also, packages that we should exclude. We do this in the package-loader because, essentially, that's the object that we use to keep the results of the constraint-solver, and we already propagate it to all functions that care about it. (Possibly we should subsequently rename it later). - In the compiler, when we figure out buildTimeDependencies, we ask if we need to bundle debug builds. If not, we filter them out (see above). Also, when we actually build together unibuilds, we don't touch the ones that the packageloader tells us to exclude (which ensures that they don't make it into the final product). - In the project, we keep track of whether this project is building in debug mode. That's because the project is where we keep the state of our curent project that we are building, and if we are ever in the state of building multiple things, then that's the code that we would need to touch (see also that we make a similar assumption when solving constraints). - Adds the option to keepthe project debug-build-free and calls it in commands when approporiate.
130 lines
4.6 KiB
JavaScript
130 lines
4.6 KiB
JavaScript
var fs = require('fs');
|
|
var path = require('path');
|
|
var _ = require('underscore');
|
|
var catalog = require('./catalog.js');
|
|
var utils = require('./utils.js');
|
|
var buildmessage = require('./buildmessage.js');
|
|
var isopack = require('./isopack.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.
|
|
exports.PackageLoader = function (options) {
|
|
var self = this;
|
|
if (!options.catalog)
|
|
throw Error("Must specify a catalog");
|
|
|
|
self.versions = null;
|
|
// Ignore specified versions if we're doing this as part of uniload.
|
|
// The PackageLoader created in uniload.js will not specify a versions option,
|
|
// but other PackageLoaders (eg, created to build plugins in compiler.compile)
|
|
// might, but we should ignore that since uniload never loads versioned
|
|
// packages; it only loads precompiled packages (for built releases) or local
|
|
//packages (from checkout).
|
|
if (options.versions && options.catalog !== catalog.uniload)
|
|
self.versions = options.versions;
|
|
|
|
self.uniloadDir = options.uniloadDir;
|
|
self.constraintSolverOpts = options.constraintSolverOpts;
|
|
self.catalog = options.catalog;
|
|
self.excluded = options.excluded;
|
|
};
|
|
|
|
_.extend(exports.PackageLoader.prototype, {
|
|
// Given the name of a package, return a Isopack 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 isopack.Isopack;
|
|
pkg.initEmpty(name);
|
|
return pkg;
|
|
}
|
|
|
|
return self.catalog.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.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 self.catalog.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;
|
|
// We shouldn't ever download packages for uniload.
|
|
if (self.catalog === catalog.uniload)
|
|
return;
|
|
tropohouse.default.downloadMissingPackages(self.versions, {
|
|
serverArch: options.serverArch
|
|
});
|
|
},
|
|
|
|
// Sometimes, we have figured out the versions for packages, but we have no
|
|
// intention of loading them. In this case, they are considered 'excluded
|
|
// packages'. This function lets us know if we have hit one of those.
|
|
excludedPackage: function (packageName) {
|
|
var self = this;
|
|
return self.excluded && self.excluded[packageName];
|
|
}
|
|
});
|