mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
wip
This commit is contained in:
@@ -37,9 +37,9 @@ ConstraintSolver.PackagesResolver = function (catalog, options) {
|
||||
forEveryVersion(function (packageName, version, versionDef) {
|
||||
var unibuilds = {};
|
||||
// XXX in theory there might be different archs but in practice they are
|
||||
// always "os" and "browser". Fix this once we actually have different
|
||||
// always "os" and "client". Fix this once we actually have different
|
||||
// archs used.
|
||||
_.each(["os", "browser"], function (arch) {
|
||||
_.each(["os", "client", "client.browser", "client.test"], function (arch) {
|
||||
var unitName = packageName + "#" + arch;
|
||||
unibuilds[unitName] = new ConstraintSolver.UnitVersion(
|
||||
unitName, version, versionDef.earliestCompatibleVersion);
|
||||
@@ -128,10 +128,10 @@ ConstraintSolver.PackagesResolver.prototype.resolve =
|
||||
}
|
||||
|
||||
// split every package name to one or more archs belonging to that package
|
||||
// (["foobar"] => ["foobar#os", "foobar#browser"])
|
||||
// XXX for now just put #os and #browser
|
||||
// (["foobar"] => ["foobar#os", "foobar#client"])
|
||||
// XXX for now just put #os and #client
|
||||
options.upgrade = _.filter(_.flatten(_.map(options.upgrade, function (packageName) {
|
||||
return [packageName + "#os", packageName + "#browser"];
|
||||
return [packageName + "#os", packageName + "#client"];
|
||||
})), _.identity);
|
||||
|
||||
var dc = self._splitDepsToConstraints(dependencies, constraints);
|
||||
@@ -162,7 +162,7 @@ ConstraintSolver.PackagesResolver.prototype.resolve =
|
||||
var resultChoices = {};
|
||||
_.each(res, function (uv) {
|
||||
// Since we don't yet define the interface for a an app to depend only on
|
||||
// certain unibuilds of the packages (like only browser unibuilds) and we know
|
||||
// certain unibuilds of the packages (like only client unibuilds) and we know
|
||||
// that each unibuild weakly depends on other sibling unibuilds of the same
|
||||
// version, we can safely output the whole package for each unibuild in the
|
||||
// result.
|
||||
@@ -198,7 +198,7 @@ ConstraintSolver.PackagesResolver.prototype.propagateExactDeps =
|
||||
};
|
||||
|
||||
// takes dependencies and constraints and rewrites the names from "foo" to
|
||||
// "foo#os" and "foo#browser"
|
||||
// "foo#os" and "foo#client"
|
||||
// XXX right now creates a dependency for every unibuild it can find
|
||||
ConstraintSolver.PackagesResolver.prototype._splitDepsToConstraints =
|
||||
function (inputDeps, inputConstraints) {
|
||||
@@ -233,8 +233,8 @@ ConstraintSolver.PackagesResolver.prototype._unibuildsForPackage =
|
||||
var self = this;
|
||||
var unibuildPrefix = packageName + "#";
|
||||
var unibuilds = [];
|
||||
// XXX hardcode os and browser
|
||||
_.each(["os", "browser"], function (arch) {
|
||||
// XXX hardcode os and client
|
||||
_.each(["os", "client", "client.browser", "client.test"], function (arch) {
|
||||
if (self.resolver.unitsVersions[unibuildPrefix + arch])
|
||||
unibuilds.push(unibuildPrefix + arch);
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Plugin.registerSourceHandler("css", function (compileStep) {
|
||||
// XXX annoying that this is replicated in .css, .less, and .styl
|
||||
if (! compileStep.archMatches('browser')) {
|
||||
if (! compileStep.archMatches('client')) {
|
||||
// XXX in the future, might be better to emit some kind of a
|
||||
// warning if a stylesheet is included on the server, rather than
|
||||
// silently ignoring it. but that would mean you can't stick .css
|
||||
|
||||
@@ -2,8 +2,7 @@ var path = Npm.require('path');
|
||||
|
||||
var doHTMLScanning = function (compileStep, htmlScanner) {
|
||||
|
||||
// XXX use archinfo rather than rolling our own
|
||||
if (! compileStep.arch.match(/^browser(\.|$)/))
|
||||
if (! compileStep.archMatches("client"))
|
||||
// XXX might be nice to throw an error here, but then we'd have to
|
||||
// make it so that packages.js ignores html files that appear in
|
||||
// the server directories in an app tree.. or, it might be nice to
|
||||
|
||||
@@ -492,7 +492,8 @@ main.registerCommand({
|
||||
directory: { type: Boolean },
|
||||
architecture: { type: String },
|
||||
// Undocumented
|
||||
'for-deploy': { type: Boolean }
|
||||
'for-deploy': { type: Boolean },
|
||||
'client-arch': { type: String }
|
||||
}
|
||||
}, function (options) {
|
||||
// XXX if they pass a file that doesn't end in .tar.gz or .tgz, add
|
||||
@@ -537,7 +538,9 @@ main.registerCommand({
|
||||
// default? i guess the problem with using DEPLOY_ARCH as default
|
||||
// is then 'meteor bundle' with no args fails if you have any local
|
||||
// packages with binary npm dependencies
|
||||
arch: bundleArch
|
||||
arch: bundleArch,
|
||||
clientArchs: options['client-arch'] ? [options['client-arch']]
|
||||
: ['client.browser']
|
||||
}
|
||||
});
|
||||
if (bundleResult.errors) {
|
||||
|
||||
@@ -67,6 +67,7 @@ compiler.eachUsedUnibuild = function (
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
var acceptableWeakPackages = options.acceptableWeakPackages || {};
|
||||
|
||||
var processedBuildId = {};
|
||||
@@ -81,6 +82,7 @@ compiler.eachUsedUnibuild = function (
|
||||
|
||||
while (!_.isEmpty(usesToProcess)) {
|
||||
var use = usesToProcess.shift();
|
||||
console.log(use);
|
||||
|
||||
var unibuild = packageLoader.getUnibuild(use.package, arch);
|
||||
if (!unibuild) {
|
||||
@@ -448,11 +450,11 @@ var compileUnibuild = function (unipackage, inputSourceArch, packageLoader,
|
||||
// information.
|
||||
// - pathForSourceMap: If this file is to be included in a source map,
|
||||
// this is the name you should use for it in the map.
|
||||
// - rootOutputPath: on browser targets, for resources such as
|
||||
// - rootOutputPath: on client targets, for resources such as
|
||||
// stylesheet and static assets, this is the root URL that
|
||||
// will get prepended to the paths you pick for your output
|
||||
// files so that you get your own namespace, for example
|
||||
// '/packages/foo'. null on non-browser targets
|
||||
// '/packages/foo'. null on non-client targets
|
||||
// - fileOptions: any options passed to "api.add_files"; for
|
||||
// use by the plugin. The built-in "js" plugin uses the "bare"
|
||||
// option for files that shouldn't be wrapped in a closure.
|
||||
@@ -464,11 +466,11 @@ var compileUnibuild = function (unipackage, inputSourceArch, packageLoader,
|
||||
// file as a Buffer. If n is omitted you get the rest of the
|
||||
// file.
|
||||
// - appendDocument({ section: "head", data: "my markup" })
|
||||
// Browser targets only. Add markup to the "head" or "body"
|
||||
// Client targets only. Add markup to the "head" or "body"
|
||||
// section of the document.
|
||||
// - addStylesheet({ path: "my/stylesheet.css", data: "my css",
|
||||
// sourceMap: "stringified json sourcemap"})
|
||||
// Browser targets only. Add a stylesheet to the
|
||||
// Client targets only. Add a stylesheet to the
|
||||
// document. 'path' is a requested URL for the stylesheet that
|
||||
// may or may not ultimately be honored. (Meteor will add
|
||||
// appropriate tags to cause the stylesheet to be loaded. It
|
||||
@@ -563,9 +565,9 @@ var compileUnibuild = function (unipackage, inputSourceArch, packageLoader,
|
||||
return ret;
|
||||
},
|
||||
appendDocument: function (options) {
|
||||
if (! archinfo.matches(inputSourceArch.arch, "browser"))
|
||||
if (! archinfo.matches(inputSourceArch.arch, "client"))
|
||||
throw new Error("Document sections can only be emitted to " +
|
||||
"browser targets");
|
||||
"client targets");
|
||||
if (options.section !== "head" && options.section !== "body")
|
||||
throw new Error("'section' must be 'head' or 'body'");
|
||||
if (typeof options.data !== "string")
|
||||
@@ -577,9 +579,9 @@ var compileUnibuild = function (unipackage, inputSourceArch, packageLoader,
|
||||
});
|
||||
},
|
||||
addStylesheet: function (options) {
|
||||
if (! archinfo.matches(inputSourceArch.arch, "browser"))
|
||||
if (! archinfo.matches(inputSourceArch.arch, "client"))
|
||||
throw new Error("Stylesheets can only be emitted to " +
|
||||
"browser targets");
|
||||
"client targets");
|
||||
if (typeof options.data !== "string")
|
||||
throw new Error("'data' option to addStylesheet must be a string");
|
||||
sourceIsWatched = true;
|
||||
@@ -596,8 +598,8 @@ var compileUnibuild = function (unipackage, inputSourceArch, packageLoader,
|
||||
throw new Error("'data' option to addJavaScript must be a string");
|
||||
if (typeof options.sourcePath !== "string")
|
||||
throw new Error("'sourcePath' option must be supplied to addJavaScript. Consider passing inputPath.");
|
||||
if (options.bare && ! archinfo.matches(inputSourceArch.arch, "browser"))
|
||||
throw new Error("'bare' option may only be used for browser targets");
|
||||
if (options.bare && ! archinfo.matches(inputSourceArch.arch, "client"))
|
||||
throw new Error("'bare' option may only be used for client targets");
|
||||
sourceIsWatched = true;
|
||||
js.push({
|
||||
source: options.data,
|
||||
|
||||
@@ -40,6 +40,7 @@ _.extend(exports.PackageLoader.prototype, {
|
||||
if (options.throwOnError === undefined) {
|
||||
options.throwOnError = true;
|
||||
}
|
||||
|
||||
var loadPath = self.getLoadPathForPackage(name);
|
||||
if (! loadPath) {
|
||||
if (options.throwOnError === false)
|
||||
|
||||
@@ -667,22 +667,29 @@ _.extend(PackageSource.prototype, {
|
||||
buildmessage.error("Package name invalid: " + self.name);
|
||||
}
|
||||
|
||||
var allWheres = ['server', 'client'];
|
||||
var allWhereObj = {};
|
||||
_.each(allWheres, function (where) {
|
||||
allWhereObj[where] = [];
|
||||
});
|
||||
|
||||
// source files used
|
||||
var sources = {client: [], server: []};
|
||||
var sources = _.clone(allWhereObj);
|
||||
|
||||
// symbols exported
|
||||
var exports = {client: [], server: []};
|
||||
var exports = _.clone(allWhereObj);
|
||||
|
||||
// packages used and implied (keys are 'package', 'unordered', and
|
||||
// 'weak'). an "implied" package is a package that will be used by a unibuild
|
||||
// which uses us.
|
||||
var uses = {client: [], server: []};
|
||||
var implies = {client: [], server: []};
|
||||
var uses = _.clone(allWhereObj);
|
||||
var implies = _.clone(allWhereObj);
|
||||
|
||||
// For this old-style, on_use/on_test/where-based package, figure
|
||||
// out its dependencies by calling its on_xxx functions and seeing
|
||||
// what it does.
|
||||
//
|
||||
// XXX fix this comment
|
||||
// We have a simple strategy. Call its on_xxx handler with no
|
||||
// 'where', which is what happens when the package is added
|
||||
// directly to an app, and see what files it adds to the client
|
||||
@@ -702,25 +709,23 @@ _.extend(PackageSource.prototype, {
|
||||
return x ? [x] : [];
|
||||
};
|
||||
|
||||
var allWheres = ['client', 'server'];
|
||||
var toWhereArray = function (where) {
|
||||
if (!(where instanceof Array)) {
|
||||
where = where ? [where] : allWheres;
|
||||
}
|
||||
where = _.uniq(where);
|
||||
var realWhere = _.intersection(where, allWheres);
|
||||
if (realWhere.length !== where.length) {
|
||||
var badWheres = _.difference(where, allWheres);
|
||||
// avoid using _.each so as to not add more frames to skip
|
||||
for (var i = 0; i < badWheres.length; ++i) {
|
||||
_.each(where, function (inputWhere) {
|
||||
var isMatch = _.any(_.map(allWheres, function (actualWhere) {
|
||||
return archinfo.matches(inputWhere, actualWhere);
|
||||
}));
|
||||
if (! isMatch) {
|
||||
buildmessage.error(
|
||||
"Invalid 'where' argument: '" + badWheres[i] + "'",
|
||||
"Invalid 'where' argument: '" + indivWhere + "'",
|
||||
// skip toWhereArray in addition to the actual API function
|
||||
{useMyCaller: 1});
|
||||
};
|
||||
// recover by using the real ones only
|
||||
}
|
||||
return realWhere;
|
||||
}
|
||||
});
|
||||
return where;
|
||||
};
|
||||
|
||||
var api = {
|
||||
@@ -728,7 +733,8 @@ _.extend(PackageSource.prototype, {
|
||||
// used. Can also take literal package objects, if you have
|
||||
// anonymous packages you want to use (eg, app packages)
|
||||
//
|
||||
// @param where 'client', 'server', or an array of those.
|
||||
// @param where 'client', 'client.browser', 'client.test', 'server',
|
||||
// or an array of those.
|
||||
// The default is ['client', 'server'].
|
||||
//
|
||||
// options can include:
|
||||
@@ -843,7 +849,7 @@ _.extend(PackageSource.prototype, {
|
||||
//
|
||||
// @param symbols String (eg "Foo") or array of String
|
||||
// @param where 'client', 'server', or an array of those.
|
||||
// The default is ['client', 'server'].
|
||||
// The default is ['client', 'client.test', 'client.browser', 'server'].
|
||||
// @param options 'testOnly', boolean.
|
||||
export: function (symbols, where, options) {
|
||||
// Support `api.export("FooTest", {testOnly: true})` without
|
||||
@@ -883,7 +889,7 @@ _.extend(PackageSource.prototype, {
|
||||
// packages and any remaining handlers. It violates the
|
||||
// principle of least surprise to half-run a handler
|
||||
// and then continue.
|
||||
sources = {client: [], server: []};
|
||||
sources = _.clone(allWhereObj);
|
||||
fileAndDepLoader = null;
|
||||
self.pluginInfo = {};
|
||||
npmDependencies = null;
|
||||
@@ -909,9 +915,9 @@ _.extend(PackageSource.prototype, {
|
||||
|
||||
// For all implies and uses, fill in the unspecified dependencies from the
|
||||
// release.
|
||||
_.each(['server', 'client'], function (label) {
|
||||
uses[label] = _.map(uses[label], setFromRel);
|
||||
implies[label] = _.map(implies[label], setFromRel);
|
||||
_.each(allWheres, function (label) {
|
||||
uses[label] = _.map(uses[label], setFromRel);
|
||||
implies[label] = _.map(implies[label], setFromRel);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -949,45 +955,47 @@ _.extend(PackageSource.prototype, {
|
||||
});
|
||||
|
||||
// Create source architectures, one for the server and one for the client.
|
||||
_.each(["browser", "os"], function (arch) {
|
||||
var where = (arch === "browser") ? "client" : "server";
|
||||
_.each(["client", "os"], function (arch) {
|
||||
var sourceWhere = (arch === "client") ? "client" : "server";
|
||||
_.each(allWheres, function (where) {
|
||||
if (archinfo.matches(where, sourceWhere)) {
|
||||
// Everything depends on the package 'meteor', which sets up
|
||||
// the basic environment) (except 'meteor' itself, and js-analyze
|
||||
// which needs to be loaded by the linker).
|
||||
// XXX add a better API for js-analyze to declare itself here
|
||||
if (name !== "meteor" && name !== "js-analyze" &&
|
||||
!process.env.NO_METEOR_PACKAGE) {
|
||||
// Don't add the dependency if one already exists. This allows the
|
||||
// package to create an unordered dependency and override the one that
|
||||
// we'd add here. This is necessary to resolve the circular dependency
|
||||
// between meteor and underscore (underscore has an unordered
|
||||
// dependency on meteor dating from when the .js extension handler was
|
||||
// in the "meteor" package).
|
||||
var alreadyDependsOnMeteor =
|
||||
!! _.find(uses[where], function (u) {
|
||||
return u.package === "meteor";
|
||||
});
|
||||
if (! alreadyDependsOnMeteor)
|
||||
uses[where].unshift({ package: "meteor" });
|
||||
}
|
||||
|
||||
// Everything depends on the package 'meteor', which sets up
|
||||
// the basic environment) (except 'meteor' itself, and js-analyze
|
||||
// which needs to be loaded by the linker).
|
||||
// XXX add a better API for js-analyze to declare itself here
|
||||
if (name !== "meteor" && name !== "js-analyze" &&
|
||||
!process.env.NO_METEOR_PACKAGE) {
|
||||
// Don't add the dependency if one already exists. This allows the
|
||||
// package to create an unordered dependency and override the one that
|
||||
// we'd add here. This is necessary to resolve the circular dependency
|
||||
// between meteor and underscore (underscore has an unordered
|
||||
// dependency on meteor dating from when the .js extension handler was
|
||||
// in the "meteor" package).
|
||||
var alreadyDependsOnMeteor =
|
||||
!! _.find(uses[where], function (u) {
|
||||
return u.package === "meteor";
|
||||
});
|
||||
if (! alreadyDependsOnMeteor)
|
||||
uses[where].unshift({ package: "meteor" });
|
||||
}
|
||||
|
||||
// Each unibuild has its own separate WatchSet. This is so that, eg, a test
|
||||
// unibuild's dependencies doesn't end up getting merged into the
|
||||
// pluginWatchSet of a package that uses it: only the use unibuild's
|
||||
// dependencies need to go there!
|
||||
var watchSet = new watch.WatchSet();
|
||||
watchSet.addFile(packageJsPath, packageJsHash);
|
||||
|
||||
self.architectures.push(new SourceArch(self, {
|
||||
name: "main",
|
||||
arch: arch,
|
||||
uses: uses[where],
|
||||
implies: implies[where],
|
||||
getSourcesFunc: function () { return sources[where]; },
|
||||
declaredExports: exports[where],
|
||||
watchSet: watchSet
|
||||
}));
|
||||
// Each unibuild has its own separate WatchSet. This is so that, eg, a test
|
||||
// unibuild's dependencies doesn't end up getting merged into the
|
||||
// pluginWatchSet of a package that uses it: only the use unibuild's
|
||||
// dependencies need to go there!
|
||||
var watchSet = new watch.WatchSet();
|
||||
watchSet.addFile(packageJsPath, packageJsHash);
|
||||
self.architectures.push(new SourceArch(self, {
|
||||
name: "main",
|
||||
arch: arch,
|
||||
uses: uses[where],
|
||||
implies: implies[where],
|
||||
getSourcesFunc: function () { return sources[where]; },
|
||||
declaredExports: exports[where],
|
||||
watchSet: watchSet
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// If we have built this before, read the versions that we ended up using.
|
||||
@@ -1034,7 +1042,7 @@ _.extend(PackageSource.prototype, {
|
||||
// Determine used packages
|
||||
var project = require('./project.js').project;
|
||||
var names = project.getConstraints();
|
||||
var arch = archName === "server" ? "os" : "browser";
|
||||
var arch = archName === "server" ? "os" : "client";
|
||||
|
||||
// Create unibuild
|
||||
var sourceArch = new SourceArch(self, {
|
||||
@@ -1185,6 +1193,7 @@ _.extend(PackageSource.prototype, {
|
||||
include: [/.?/],
|
||||
// we DO look under dot directories here
|
||||
exclude: ignoreFiles
|
||||
|
||||
});
|
||||
|
||||
_.each(assetsAndSubdirs, function (item) {
|
||||
|
||||
@@ -156,7 +156,7 @@ _.extend(Unibuild.prototype, {
|
||||
importStubServePath: isApp && '/packages/global-imports.js',
|
||||
prelinkFiles: self.prelinkFiles,
|
||||
packageVariables: self.packageVariables,
|
||||
includeSourceMapInstructions: archinfo.matches(self.arch, "browser"),
|
||||
includeSourceMapInstructions: archinfo.matches(self.arch, "client"),
|
||||
name: self.pkg.name || null
|
||||
});
|
||||
|
||||
@@ -305,7 +305,7 @@ _.extend(Unipackage.prototype, {
|
||||
_.pluck(self.unibuilds, 'arch').concat(self._toolArchitectures())
|
||||
).sort();
|
||||
// Ensure that our buildArchitectures string does not look like
|
||||
// browser+os+os.osx.x86_64
|
||||
// client+os+os.osx.x86_64
|
||||
// This would happen if there is an 'os' unibuild but a platform-specific
|
||||
// tool (eg, in meteor-tool). This would confuse catalog.getBuildsForArches
|
||||
// into thinking that it would work for Linux, since the 'os' means
|
||||
@@ -336,7 +336,7 @@ _.extend(Unipackage.prototype, {
|
||||
},
|
||||
|
||||
// Return the unibuild of the package to use for a given target architecture
|
||||
// (eg, 'os.linux.x86_64' or 'browser'), or throw an exception if that
|
||||
// (eg, 'os.linux.x86_64' or 'client'), or throw an exception if that
|
||||
// packages can't be loaded under these circumstances.
|
||||
getUnibuildAtArch: function (arch) {
|
||||
var self = this;
|
||||
@@ -623,6 +623,9 @@ _.extend(Unipackage.prototype, {
|
||||
JSON.stringify(resource.type));
|
||||
});
|
||||
|
||||
if (unibuildMeta.arch === 'browser')
|
||||
unibuildMeta.arch = 'client'; // XXX hack, figure out how to get this work
|
||||
|
||||
self.unibuilds.push(new Unibuild(self, {
|
||||
name: unibuildMeta.name,
|
||||
arch: unibuildMeta.arch,
|
||||
|
||||
Reference in New Issue
Block a user