removing test slices; renaming slices to builds

This commit is contained in:
ekatek
2014-04-07 15:25:30 -07:00
parent 77358ba28b
commit 8a96a1c25a
7 changed files with 244 additions and 283 deletions

View File

@@ -410,7 +410,7 @@ var Target = function (options) {
// All of the Slices that are to go into this target, in the order
// that they are to be loaded.
self.slices = [];
self.builds = [];
// JavaScript files. List of File. They will be loaded at startup in
// the order given.
@@ -441,7 +441,7 @@ _.extend(Target.prototype, {
// target-type-dependent function such as write() or toJsImage().
//
// options
// - packages: packages to include (Unipackage or 'foo' or 'foo.slice'),
// - packages: packages to include (Unipackage or 'foo' or 'foo.build'),
// per _determineLoadOrder
// - test: packages to test (Unipackage or 'foo'), per _determineLoadOrder
// - minify: true to minify
@@ -451,7 +451,7 @@ _.extend(Target.prototype, {
make: function (options) {
var self = this;
// Populate the list of slices to load
// Populate the list of builds to load
self._determineLoadOrder({
packages: options.packages || [],
test: options.test || []
@@ -486,57 +486,53 @@ _.extend(Target.prototype, {
}
},
// Determine the packages to load, create Slices for
// them, put them in load order, save in slices.
// Determine the packages to load, create Builds for
// them, put them in load order, save in builds.
//
// options include:
// - packages: an array of packages (or, properly speaking, slices)
// - packages: an array of packages (or, properly speaking, builds)
// to include. Each element should either be a Unipackage object or a
// package name as a string (to include that package's default
// slices for this arch, or a string of the form 'package.slice'
// to include a particular named slice from a particular package.
// builds for this arch, or a string of the form 'package.build'
// to include a particular named build from a particular package.
// - test: an array of packages (as Unipackage objects or as name
// strings) whose test slices should be included
// strings) whose test builds should be included
_determineLoadOrder: function (options) {
var self = this;
var packageLoader = self.packageLoader;
// Find the roots
var rootSlices =
var rootBuilds =
_.flatten([
_.map(options.packages || [], function (p) {
if (typeof p === "string")
return packageLoader.getSlices(p, self.arch);
return packageLoader.getBuilds(p, self.arch);
else
return p.getDefaultSlices(self.arch);
}),
_.map(options.test || [], function (p) {
var pkg = (typeof p === "string" ? packageLoader.getPackage(p) : p);
return pkg.getTestSlices(self.arch);
return p.getDefaultBuilds(self.arch);
})
]);
// PHASE 1: Which slices will be used?
// PHASE 1: Which builds will be used?
//
// Figure out which slices are going to be used in the target, regardless of
// Figure out which builds are going to be used in the target, regardless of
// order. We ignore weak dependencies here, because they don't actually
// create a "must-use" constraint, just an ordering constraint.
// What slices will be used in the target? Built in Phase 1, read in
// What builds will be used in the target? Built in Phase 1, read in
// Phase 2.
var getsUsed = {}; // Map from slice.id to Slice.
var addToGetsUsed = function (slice) {
if (_.has(getsUsed, slice.id))
var getsUsed = {}; // Map from build.id to Build.
var addToGetsUsed = function (build) {
if (_.has(getsUsed, build.id))
return;
getsUsed[slice.id] = slice;
compiler.eachUsedSlice(slice.uses, self.arch, packageLoader,
getsUsed[build.id] = build;
compiler.eachUsedBuild(build.uses, self.arch, packageLoader,
{skipWeak: true}, addToGetsUsed);
};
_.each(rootSlices, addToGetsUsed);
_.each(rootBuilds, addToGetsUsed);
// PHASE 2: In what order should we load the slices?
// PHASE 2: In what order should we load the builds?
//
// Set self.slices to be all of the roots, plus all of their non-weak
// Set self.builds to be all of the roots, plus all of their non-weak
// dependencies, in the correct load order. "Load order" means that if X
// depends on (uses) Y, and that relationship is not marked as unordered, Y
// appears before X in the ordering. Raises an exception iff there is no
@@ -544,47 +540,47 @@ _.extend(Target.prototype, {
//
// XXX The topological sort code here is duplicated in catalog.js.
// What slices have not yet been added to self.slices?
var needed = _.clone(getsUsed); // Map from slice.id to Slice.
// Slices that we are in the process of adding; used to detect circular
// What builds have not yet been added to self.builds?
var needed = _.clone(getsUsed); // Map from build.id to Build.
// Builds that we are in the process of adding; used to detect circular
// ordered dependencies.
var onStack = {}; // Map from slice.id to true.
var onStack = {}; // Map from build.id to true.
// This helper recursively adds slice's ordered dependencies to self.slices,
// then adds slice itself.
var add = function (slice) {
// This helper recursively adds build's ordered dependencies to self.builds,
// then adds build itself.
var add = function (build) {
// If this has already been added, there's nothing to do.
if (!_.has(needed, slice.id))
if (!_.has(needed, build.id))
return;
// Process each ordered dependency. (If we have an unordered dependency
// `u`, then there's no reason to add it *now*, and for all we know, `u`
// will depend on `slice` and need to be added after it. So we ignore
// will depend on `build` and need to be added after it. So we ignore
// those edge. Because we did follow those edges in Phase 1, any unordered
// slices were at some point in `needed` and will not be left out).
compiler.eachUsedSlice(
slice.uses, self.arch, packageLoader, {skipUnordered: true},
function (usedSlice, useOptions) {
// builds were at some point in `needed` and will not be left out).
compiler.eachUsedBuild(
build.uses, self.arch, packageLoader, {skipUnordered: true},
function (usedBuild, useOptions) {
// If this is a weak dependency, and nothing else in the target had a
// strong dependency on it, then ignore this edge.
if (useOptions.weak && ! _.has(getsUsed, usedSlice.id))
if (useOptions.weak && ! _.has(getsUsed, usedBuild.id))
return;
if (onStack[usedSlice.id]) {
if (onStack[usedBuild.id]) {
buildmessage.error("circular dependency between packages " +
slice.pkg.name + " and " + usedSlice.pkg.name);
build.pkg.name + " and " + usedBuild.pkg.name);
// recover by not enforcing one of the depedencies
return;
}
onStack[usedSlice.id] = true;
add(usedSlice);
delete onStack[usedSlice.id];
onStack[usedBuild.id] = true;
add(usedBuild);
delete onStack[usedBuild.id];
});
self.slices.push(slice);
delete needed[slice.id];
self.builds.push(build);
delete needed[build.id];
};
while (true) {
// Get an arbitrary slice from those that remain, or break if none remain.
// Get an arbitrary build from those that remain, or break if none remain.
var first = null;
for (first in needed) break;
if (! first)
@@ -594,7 +590,7 @@ _.extend(Target.prototype, {
}
},
// Process all of the sorted slices (which includes running the JavaScript
// Process all of the sorted builds (which includes running the JavaScript
// linker).
_emitResources: function () {
var self = this;
@@ -603,15 +599,15 @@ _.extend(Target.prototype, {
var isOs = archinfo.matches(self.arch, "os");
// Copy their resources into the bundle in order
_.each(self.slices, function (slice) {
var isApp = ! slice.pkg.name;
_.each(self.builds, function (build) {
var isApp = ! build.pkg.name;
// Emit the resources
var resources = slice.getResources(self.arch, self.packageLoader);
var resources = build.getResources(self.arch, self.packageLoader);
// First, find all the assets, so that we can associate them with each js
// resource (for os slices).
var sliceAssets = {};
// resource (for os builds).
var buildAssets = {};
_.each(resources, function (resource) {
if (resource.type !== "asset")
return;
@@ -630,7 +626,7 @@ _.extend(Target.prototype, {
if (isBrowser)
f.setUrlFromRelPath(resource.servePath);
else {
sliceAssets[resource.path] = resource.data;
buildAssets[resource.path] = resource.data;
}
self.asset.push(f);
@@ -663,21 +659,21 @@ _.extend(Target.prototype, {
if (resource.type === "js" && isOs) {
// Hack, but otherwise we'll end up putting app assets on this file.
if (resource.servePath !== "/packages/global-imports.js")
f.setAssets(sliceAssets);
f.setAssets(buildAssets);
if (! isApp && slice.nodeModulesPath) {
var nmd = self.nodeModulesDirectories[slice.nodeModulesPath];
if (! isApp && build.nodeModulesPath) {
var nmd = self.nodeModulesDirectories[build.nodeModulesPath];
if (! nmd) {
nmd = new NodeModulesDirectory({
sourcePath: slice.nodeModulesPath,
sourcePath: build.nodeModulesPath,
// It's important that this path end with
// node_modules. Otherwise, if two modules in this package
// depend on each other, they won't be able to find each
// other!
preferredBundlePath: path.join(
'npm', slice.pkg.name, slice.sliceName, 'node_modules')
'npm', build.pkg.name, build.buildName, 'node_modules')
});
self.nodeModulesDirectories[slice.nodeModulesPath] = nmd;
self.nodeModulesDirectories[build.nodeModulesPath] = nmd;
}
f.nodeModulesDirectory = nmd;
}
@@ -703,12 +699,12 @@ _.extend(Target.prototype, {
});
// Depend on the source files that produced these resources.
self.watchSet.merge(slice.watchSet);
self.watchSet.merge(build.watchSet);
// Remember the versions of all of the build-time dependencies
// that were used in these resources.
// XXX assumes that this merges cleanly
_.extend(self.pluginProviderPackageDirs,
slice.pkg.pluginProviderPackageDirs)
build.pkg.pluginProviderPackageDirs)
});
},
@@ -757,7 +753,7 @@ _.extend(Target.prototype, {
// would be 'os'.
mostCompatibleArch: function () {
var self = this;
return archinfo.leastSpecificDescription(_.pluck(self.slices, 'arch'));
return archinfo.leastSpecificDescription(_.pluck(self.builds, 'arch'));
}
});
@@ -1995,7 +1991,7 @@ exports.buildJsImage = function (options) {
var packageSource = new PackageSource;
packageSource.initFromOptions(options.name, {
sliceName: "plugin",
buildName: "plugin",
use: options.use || [],
sourceRoot: options.sourceRoot,
sources: options.sources || [],

View File

@@ -17,7 +17,7 @@ var compiler = exports;
// Whenever you change anything about the code that generates unipackages, bump
// this version number. The idea is that the "format" field of the unipackage
// JSON file only changes when the actual specified structure of the
// unipackage/slice changes, but this version (which is build-tool-specific) can
// unipackage/build changes, but this version (which is build-tool-specific) can
// change when the the contents (not structure) of the built output changes. So
// eg, if we improve the linker's static analysis, this should be bumped.
//
@@ -31,24 +31,24 @@ compiler.BUILT_BY = 'meteor/11';
// XXX where should this go? I'll make it a random utility function
// for now
//
// 'dependencies' is the 'uses' attribute from a UnipackageSlice. Call
// 'callback' with each slice (of architecture matching `arch`)
// 'dependencies' is the 'uses' attribute from a UnipackageBuild. Call
// 'callback' with each build (of architecture matching `arch`)
// referenced by that dependency list. This includes directly used
// slices, and slices that are transitively "implied" by used
// slices. (But not slices that are used by slices that we use!)
// builds, and builds that are transitively "implied" by used
// builds. (But not builds that are used by builds that we use!)
// Options are skipWeak and skipUnordered, meaning to ignore direct
// "uses" that are weak or unordered.
//
// packageLoader is the PackageLoader that should be used to resolve
// the dependencies.
compiler.eachUsedSlice = function (dependencies, arch, packageLoader, options,
compiler.eachUsedBuild = function (dependencies, arch, packageLoader, options,
callback) {
if (typeof options === "function") {
callback = options;
options = {};
}
var processedSliceId = {};
var processedBuildId = {};
var usesToProcess = [];
_.each(dependencies, function (use) {
if (options.skipUnordered && use.unordered)
@@ -61,19 +61,19 @@ compiler.eachUsedSlice = function (dependencies, arch, packageLoader, options,
while (!_.isEmpty(usesToProcess)) {
var use = usesToProcess.shift();
var slices =
packageLoader.getSlices(_.pick(use, 'package', 'spec'),
var builds =
packageLoader.getBuilds(_.pick(use, 'package', 'spec'),
arch);
_.each(slices, function (slice) {
if (_.has(processedSliceId, slice.id))
_.each(builds, function (build) {
if (_.has(processedBuildId, build.id))
return;
processedSliceId[slice.id] = true;
callback(slice, {
processedBuildId[build.id] = true;
callback(build, {
unordered: !!use.unordered,
weak: !!use.weak
});
_.each(slice.implies, function (implied) {
_.each(build.implies, function (implied) {
usesToProcess.push(implied);
});
});
@@ -117,7 +117,7 @@ var determineBuildTimeDependencies = function (packageSource) {
// -- Direct dependencies --
// XXX it looks like when we load plugins in compileSlice, we honor
// XXX it looks like when we load plugins in compileBuild, we honor
// implied plugins, but here where we're determining dependencies,
// we don't include them. we should probably straighten this out.
var dependencyMetadata =
@@ -166,8 +166,8 @@ var determineBuildTimeDependencies = function (packageSource) {
// no way to specify weak/unordered. Much like an app.
_.each(info.use, function (spec) {
var parsedSpec = utils.parseSpec(spec);
if (parsedSpec.slice)
throw new Error("can't deal with slice specs here yet");
if (parsedSpec.build)
throw new Error("can't deal with build specs here yet");
constraints[parsedSpec.package] = parsedSpec.constraint || null;
});
@@ -180,9 +180,9 @@ var determineBuildTimeDependencies = function (packageSource) {
compiler.determineBuildTimeDependencies = determineBuildTimeDependencies;
// inputSlice is a SourceSlice to compile. Process all source files
// inputBuild is a SourceBuild to compile. Process all source files
// through the appropriate handlers and run the prelink phase on any
// resulting JavaScript. Create a new UnipackageSlice and add it to
// resulting JavaScript. Create a new UnipackageBuild and add it to
// 'unipackage'.
//
// packageLoader is a PackageLoader that can load our build-time
@@ -191,13 +191,13 @@ compiler.determineBuildTimeDependencies = determineBuildTimeDependencies;
// not be able to) load transitive dependencies of those packages.
//
// Returns a list of source files that were used in the compilation.
var compileSlice = function (unipackage, inputSlice, packageLoader,
var compileBuild = function (unipackage, inputBuild, packageLoader,
nodeModulesPath, isPortable) {
var isApp = ! inputSlice.pkg.name;
var isApp = ! inputBuild.pkg.name;
var resources = [];
var js = [];
var sources = [];
var watchSet = inputSlice.watchSet.clone();
var watchSet = inputBuild.watchSet.clone();
// *** Determine and load active plugins
@@ -206,10 +206,10 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
// a special "use" role anymore. it's not totally clear to me what
// the correct behavior should be -- we need to resolve whether we
// think about extensions as being global to a package or particular
// to a slice.
// to a build.
// (there's also some weirdness here with handling implies, because
// the implies field is on the target slice, but we really only care
// the implies field is on the target build, but we really only care
// about packages.)
var activePluginPackages = [unipackage];
@@ -218,7 +218,7 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
// not some unrelated package in the target has a dependency. And we
// skip unordered dependencies, because it's not going to work to
// have circular build-time dependencies.
_.each(inputSlice.uses, function (dependency) {
_.each(inputBuild.uses, function (dependency) {
if (! dependency.weak && ! dependency.unordered &&
dependency.package !== unipackage.name &&
packageLoader.containsPlugins(dependency.package)) {
@@ -250,7 +250,7 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
if (ext in allHandlers && allHandlers[ext] !== handler) {
buildmessage.error(
"conflict: two packages included in " +
(inputSlice.pkg.name || "the app") + ", " +
(inputBuild.pkg.name || "the app") + ", " +
(allHandlers[ext].pkg.name || "the app") + " and " +
(otherPkg.name || "the app") + ", " +
"are both trying to handle ." + ext);
@@ -269,19 +269,19 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
// listings or, in some hypothetical universe, control files) to
// determine its source files.
var sourceExtensions = _.keys(allHandlers);
var sourceItems = inputSlice.getSourcesFunc(sourceExtensions, watchSet);
var sourceItems = inputBuild.getSourcesFunc(sourceExtensions, watchSet);
// *** Process each source file
var addAsset = function (contents, relPath, hash) {
// XXX hack
if (! inputSlice.pkg.name)
if (! inputBuild.pkg.name)
relPath = relPath.replace(/^(private|public)\//, '');
resources.push({
type: "asset",
data: contents,
path: relPath,
servePath: path.join(inputSlice.pkg.serveRoot, relPath),
servePath: path.join(inputBuild.pkg.serveRoot, relPath),
hash: hash
});
@@ -291,7 +291,7 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
_.each(sourceItems, function (source) {
var relPath = source.relPath;
var fileOptions = _.clone(source.fileOptions) || {};
var absPath = path.resolve(inputSlice.pkg.sourceRoot, relPath);
var absPath = path.resolve(inputBuild.pkg.sourceRoot, relPath);
var filename = path.basename(relPath);
var file = watch.readAndWatchFileWithHash(watchSet, absPath);
var contents = file.contents;
@@ -352,8 +352,8 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
// - 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.
// - declaredExports: An array of symbols exported by this slice, or null
// if it may not export any symbols (eg, test slices). This is used by
// - declaredExports: An array of symbols exported by this build, or null
// if it may not export any symbols (eg, test builds). This is used by
// CoffeeScript to ensure that it doesn't close over those symbols, eg.
// - read(n): read from the input file. If n is given it should
// be an integer, and you will receive the next n bytes of the
@@ -404,7 +404,7 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
// (code that isn't dependent on the arch, other than 'browser'
// vs 'os') -- they can look at the arch that is provided
// but they can't rely on the running on that particular arch
// (in the end, an arch-specific slice will be emitted only if
// (in the end, an arch-specific build will be emitted only if
// there are native node modules). Obviously this should
// change. A first step would be a setOutputArch() function
// analogous to what we do with native node modules, but maybe
@@ -438,19 +438,19 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
_fullInputPath: absPath, // avoid, see above..
// XXX duplicates _pathForSourceMap() in linker
pathForSourceMap: (
inputSlice.pkg.name
? inputSlice.pkg.name + "/" + relPath
inputBuild.pkg.name
? inputBuild.pkg.name + "/" + relPath
: path.basename(relPath)),
// null if this is an app. intended to be used for the sources
// dictionary for source maps.
packageName: inputSlice.pkg.name,
rootOutputPath: inputSlice.pkg.serveRoot,
arch: inputSlice.arch, // XXX: what is the story with arch?
packageName: inputBuild.pkg.name,
rootOutputPath: inputBuild.pkg.serveRoot,
arch: inputBuild.arch, // XXX: what is the story with arch?
archMatches: function (pattern) {
return archinfo.matches(inputSlice.arch, pattern);
return archinfo.matches(inputBuild.arch, pattern);
},
fileOptions: fileOptions,
declaredExports: _.pluck(inputSlice.declaredExports, 'name'),
declaredExports: _.pluck(inputBuild.declaredExports, 'name'),
read: function (n) {
if (n === undefined || readOffset + n > contents.length)
n = contents.length - readOffset;
@@ -459,7 +459,7 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
return ret;
},
appendDocument: function (options) {
if (! archinfo.matches(inputSlice.arch, "browser"))
if (! archinfo.matches(inputBuild.arch, "browser"))
throw new Error("Document sections can only be emitted to " +
"browser targets");
if (options.section !== "head" && options.section !== "body")
@@ -472,7 +472,7 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
});
},
addStylesheet: function (options) {
if (! archinfo.matches(inputSlice.arch, "browser"))
if (! archinfo.matches(inputBuild.arch, "browser"))
throw new Error("Stylesheets can only be emitted to " +
"browser targets");
if (typeof options.data !== "string")
@@ -480,7 +480,7 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
resources.push({
type: "css",
data: new Buffer(options.data, 'utf8'),
servePath: path.join(inputSlice.pkg.serveRoot, options.path),
servePath: path.join(inputBuild.pkg.serveRoot, options.path),
sourceMap: options.sourceMap
});
},
@@ -489,12 +489,12 @@ var compileSlice = function (unipackage, inputSlice, 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(inputSlice.arch, "browser"))
if (options.bare && ! archinfo.matches(inputBuild.arch, "browser"))
throw new Error("'bare' option may only be used for browser targets");
js.push({
source: options.data,
sourcePath: options.sourcePath,
servePath: path.join(inputSlice.pkg.serveRoot, options.path),
servePath: path.join(inputBuild.pkg.serveRoot, options.path),
bare: !! options.bare,
sourceMap: options.sourceMap
});
@@ -529,9 +529,9 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
// Load jsAnalyze from the js-analyze package... unless we are the
// js-analyze package, in which case never mind. (The js-analyze package's
// default slice is not allowed to depend on anything!)
// default build is not allowed to depend on anything!)
var jsAnalyze = null;
if (! _.isEmpty(js) && inputSlice.pkg.name !== "js-analyze") {
if (! _.isEmpty(js) && inputBuild.pkg.name !== "js-analyze") {
jsAnalyze = uniload.load({
packages: ["js-analyze"]
})["js-analyze"].JSAnalyze;
@@ -541,17 +541,17 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
inputFiles: js,
useGlobalNamespace: isApp,
combinedServePath: isApp ? null :
"/packages/" + inputSlice.pkg.name +
(inputSlice.sliceName === "main" ? "" : (":" + inputSlice.sliceName)) + ".js",
name: inputSlice.pkg.name || null,
declaredExports: _.pluck(inputSlice.declaredExports, 'name'),
"/packages/" + inputBuild.pkg.name +
(inputBuild.buildName === "main" ? "" : (":" + inputBuild.buildName)) + ".js",
name: inputBuild.pkg.name || null,
declaredExports: _.pluck(inputBuild.declaredExports, 'name'),
jsAnalyze: jsAnalyze
});
// *** Determine captured variables
var packageVariables = [];
var packageVariableNames = {};
_.each(inputSlice.declaredExports, function (symbol) {
_.each(inputBuild.declaredExports, function (symbol) {
if (_.has(packageVariableNames, symbol.name))
return;
packageVariables.push({
@@ -570,7 +570,7 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
});
// *** Consider npm dependencies and portability
var arch = inputSlice.arch;
var arch = inputBuild.arch;
if (arch === "os" && ! isPortable) {
// Contains non-portable npm module builds, so set arch correctly
arch = archinfo.host();
@@ -580,16 +580,16 @@ var compileSlice = function (unipackage, inputSlice, packageLoader,
nodeModulesPath = undefined;
}
// *** Output slice object
unipackage.addSlice({
name: inputSlice.sliceName,
arch: inputSlice.arch, // XXX: arch?
uses: inputSlice.uses,
implies: inputSlice.implies,
// *** Output build object
unipackage.addBuild({
name: inputBuild.buildName,
arch: inputBuild.arch, // XXX: arch?
uses: inputBuild.uses,
implies: inputBuild.implies,
watchSet: watchSet,
nodeModulesPath: nodeModulesPath,
prelinkFiles: results.files,
noExports: inputSlice.noExports,
noExports: inputBuild.noExports,
packageVariables: packageVariables,
resources: resources
});
@@ -671,8 +671,8 @@ compiler.compile = function (packageSource, options) {
// Add this plugin's dependencies to our "plugin dependency"
// WatchSet. buildResult.watchSet will end up being the merged
// watchSets of all of the slices of the plugin -- plugins have
// only one slice and this should end up essentially being just
// watchSets of all of the builds of the plugin -- plugins have
// only one build and this should end up essentially being just
// the source files of the plugin.
pluginWatchSet.merge(buildResult.watchSet);
@@ -714,24 +714,23 @@ compiler.compile = function (packageSource, options) {
metadata: packageSource.metadata,
version: packageSource.version,
earliestCompatibleVersion: packageSource.earliestCompatibleVersion,
defaultSlices: packageSource.defaultSlices,
testSlices: packageSource.testSlices,
defaultBuilds: packageSource.defaultBuilds,
plugins: plugins,
pluginWatchSet: pluginWatchSet,
buildTimeDirectDependencies: buildTimeDeps.directDependencies,
buildTimePluginDependencies: buildTimeDeps.pluginDependencies
});
// Build slices. Might use our plugins, so needs to happen
// Build builds. Might use our plugins, so needs to happen
// second.
var packageLoader = new PackageLoader({
versions: buildTimeDeps.directDependencies
});
_.each(packageSource.slices, function (slice) {
var sliceSources = compileSlice(unipackage, slice, packageLoader,
_.each(packageSource.builds, function (build) {
var buildSources = compileBuild(unipackage, build, packageLoader,
nodeModulesPath, isPortable);
sources.push.apply(sources, sliceSources);
sources.push.apply(sources, buildSources);
});
// XXX what should we do if the PackageSource doesn't have a version?
@@ -921,8 +920,8 @@ compiler.checkUpToDate = function (packageSource, unipackage) {
var watchSet = new watch.WatchSet();
watchSet.merge(unipackage.pluginWatchSet);
_.each(unipackage.slices, function (slice) {
watchSet.merge(slice.watchSet);
_.each(unipackage.builds, function (build) {
watchSet.merge(build.watchSet);
});
if (! watch.isUpToDate(watchSet)) {

View File

@@ -90,21 +90,21 @@ _.extend(PackageLoader.prototype, {
return catalog.catalog.getLoadPathForPackage(name, version);
},
// Given a slice set spec -- either a package name like "ddp", or a particular
// slice within the package like "ddp/client", or a parsed object like
// {package: "ddp", slice: "client"} -- return the list of matching slices (as
// an array of Slice objects) for a given architecture.
getSlices: function (spec, arch) {
// Given a build set spec -- either a package name like "ddp", or a particular
// build within the package like "ddp/client", or a parsed object like
// {package: "ddp", build: "client"} -- return the list of matching builds (as
// an array of Build objects) for a given architecture.
getBuilds: function (spec, arch) {
var self = this;
if (typeof spec === "string")
spec = utils.parseSpec(spec);
var pkg = self.getPackage(spec.package, { throwOnError: true });
if (spec.slice)
return [pkg.getSingleSlice(spec.slice, arch)];
if (spec.build)
return [pkg.getSingleBuild(spec.build, arch)];
else
return pkg.getDefaultSlices(arch);
return pkg.getDefaultBuilds(arch);
}
});

View File

@@ -76,7 +76,7 @@ var loadOrderSort = function (a, b) {
};
///////////////////////////////////////////////////////////////////////////////
// SourceSlice
// SourceBuild
///////////////////////////////////////////////////////////////////////////////
// Options:
@@ -92,17 +92,17 @@ var loadOrderSort = function (a, b) {
//
// Do not include the source files in watchSet. They will be
// added at compile time when the sources are actually read.
var SourceSlice = function (pkg, options) {
var SourceBuild = function (pkg, options) {
var self = this;
options = options || {};
self.pkg = pkg;
// Name for this slice. For example, the "client" in "ddp.client"
// Name for this build. For example, the "client" in "ddp.client"
// (which, NB, we might load on server arches).
self.sliceName = options.name;
self.buildName = options.name;
// The architecture (fully or partially qualified) that can use this
// slice.
// build.
self.arch = options.arch;
// Packages used. The ordering is significant only for determining
@@ -113,7 +113,7 @@ var SourceSlice = function (pkg, options) {
// - package: the package name
// - constraint: the constraint on the version of the package to use,
// as a string (may be null)
// - slice: the slice name (optional)
// - build: the build name (optional)
// - unordered: If true, we don't want the package's imports and we
// don't want to force the package to load before us. We just want
// to ensure that it loads if we load.
@@ -125,18 +125,18 @@ var SourceSlice = function (pkg, options) {
// such a dependency would have no effect.
//
// In most places, instead of using 'uses' directly, you want to use
// something like compiler.eachUsedSlice so you also take into
// something like compiler.eachUsedBuild so you also take into
// account implied packages.
self.uses = options.uses || [];
// Packages which are "implied" by using this package. If a slice X
// uses this slice Y, and Y implies Z, then X will effectively use Z
// Packages which are "implied" by using this package. If a build X
// uses this build Y, and Y implies Z, then X will effectively use Z
// as well (and get its imports and plugins). An array of objects
// of the same type as the elements of self.uses (although for now
// unordered and weak are not allowed).
self.implies = options.implies || [];
// A function that returns the source files for this slice. Array of
// A function that returns the source files for this build. Array of
// objects with keys "relPath" and "fileOptions". Null if loaded
// from unipackage.
//
@@ -151,11 +151,11 @@ var SourceSlice = function (pkg, options) {
// local plugins in this package) to compute this.
self.getSourcesFunc = options.getSourcesFunc || null;
// True if this slice is not permitted to have any exports, and in
// fact should not even define `Package.name` (ie, test slices).
// True if this build is not permitted to have any exports, and in
// fact should not even define `Package.name` (ie, test builds).
self.noExports = options.noExports || false;
// Symbols that this slice should export. List of symbols (as
// Symbols that this build should export. List of symbols (as
// strings). Null on packages where noExports is set.
self.declaredExports = options.declaredExports || null;
@@ -207,27 +207,22 @@ var PackageSource = function () {
// compatible replacement. Set if and only if version is set.
self.earliestCompatibleVersion = null;
// Available editions/subpackages ("slices") of this package. Array
// of SourceSlice.
self.slices = [];
// Available editions/subpackages ("builds") of this package. Array
// of SourceBuild.
self.builds = [];
// Map from an arch to the list of slice names that should be
// Map from an arch to the list of build names that should be
// included by default if this package is used without specifying a
// slice (eg, as "ddp" rather than "ddp.server"). The most specific
// build (eg, as "ddp" rather than "ddp.server"). The most specific
// arch will be used.
self.defaultSlices = {};
// Map from an arch to the list of slice names that should be
// included when this package is tested. The most specific arch will
// be used.
self.testSlices = {};
self.defaultBuilds = {};
// The information necessary to build the plugins in this
// package. Map from plugin name to object with keys 'name', 'use',
// 'sources', and 'npmDependencies'.
self.pluginInfo = {};
// Analogous to watchSet in SourceSlice but for plugins. At this
// Analogous to watchSet in SourceBuild but for plugins. At this
// stage will typically contain just 'package.js'.
self.pluginWatchSet = new watch.WatchSet;
@@ -250,8 +245,7 @@ _.extend(PackageSource.prototype, {
initEmpty: function (name) {
var self = this;
self.name = name;
self.defaultSlices = {'': []};
self.testSlices = {'': []};
self.defaultBuilds = {'': []};
},
// Programmatically initialize a PackageSource from scratch.
@@ -272,7 +266,7 @@ _.extend(PackageSource.prototype, {
// Options:
// - sourceRoot (required if sources present)
// - serveRoot (required if sources present)
// - sliceName
// - buildName
// - use
// - sources (array of paths or relPath/fileOptions objects)
// - npmDependencies
@@ -299,19 +293,19 @@ _.extend(PackageSource.prototype, {
return source;
});
var slice = new SourceSlice(self, {
name: options.sliceName,
var build = new SourceBuild(self, {
name: options.buildName,
arch: "os",
uses: _.map(options.use, utils.parseSpec),
getSourcesFunc: function () { return sources; },
nodeModulesPath: nodeModulesPath
});
self.slices.push(slice);
self.builds.push(build);
if (! self._checkCrossSliceVersionConstraints())
throw new Error("only one slice, so how can consistency check fail?");
if (! self._checkCrossBuildVersionConstraints())
throw new Error("only one build, so how can consistency check fail?");
self.defaultSlices = {'os': [options.sliceName]};
self.defaultBuilds = {'os': [options.buildName]};
},
// Initialize a PackageSource from a package.js-style package
@@ -447,7 +441,7 @@ _.extend(PackageSource.prototype, {
// == 'Npm' object visible in package.js ==
var Npm = {
depends: function (_npmDependencies) {
// XXX make npmDependencies be per slice, so that production
// XXX make npmDependencies be per build, so that production
// doesn't have to ship all of the npm modules used by test
// code
if (npmDependencies) {
@@ -550,9 +544,9 @@ _.extend(PackageSource.prototype, {
// symbols exported
var exports = {client: [], server: []};
// packages used and implied (keys are 'package', 'slice', 'unordered', and
// 'weak'). an "implied" package is a package that will be used by a slice
// which uses us. (since you can't use a test slice, only the use slice can
// packages used and implied (keys are 'package', 'build', 'unordered', and
// 'weak'). an "implied" package is a package that will be used by a build
// which uses us. (since you can't use a test build, only the use build can
// have "implies".)
var uses = {use: {client: [], server: []},
test: {client: [], server: []}};
@@ -786,8 +780,8 @@ _.extend(PackageSource.prototype, {
});
// Make sure that if a dependency was specified in multiple
// slices, the constraint is exactly the same.
if (! self._checkCrossSliceVersionConstraints()) {
// builds, the constraint is exactly the same.
if (! self._checkCrossBuildVersionConstraints()) {
// A build error was written. Recover by ignoring the
// fact that we have differing constraints.
}
@@ -818,7 +812,7 @@ _.extend(PackageSource.prototype, {
files.rm_recursive(path.join(self.sourceRoot, '.npm', f));
});
// Create slices
// Create builds
_.each(["use", "test"], function (role) {
_.each(["browser", "os"], function (arch) {
var where = (arch === "browser") ? "client" : "server";
@@ -836,20 +830,20 @@ _.extend(PackageSource.prototype, {
// in the "meteor" package).
var alreadyDependsOnMeteor =
!! _.find(uses[role][where], function (u) {
return u.package === "meteor" && !u.slice;
return u.package === "meteor" && !u.build;
});
if (! alreadyDependsOnMeteor)
uses[role][where].unshift({ package: "meteor" });
}
// Each slice has its own separate WatchSet. This is so that, eg, a test
// slice's dependencies doesn't end up getting merged into the
// pluginWatchSet of a package that uses it: only the use slice's
// Each build has its own separate WatchSet. This is so that, eg, a test
// build's dependencies doesn't end up getting merged into the
// pluginWatchSet of a package that uses it: only the use build's
// dependencies need to go there!
var watchSet = new watch.WatchSet();
watchSet.addFile(packageJsPath, packageJsHash);
self.slices.push(new SourceSlice(self, {
self.builds.push(new SourceBuild(self, {
name: ({ use: "main", test: "tests" })[role],
arch: arch,
uses: uses[role][where],
@@ -862,9 +856,8 @@ _.extend(PackageSource.prototype, {
});
});
// Default slices
self.defaultSlices = { browser: ['main'], 'os': ['main'] };
self.testSlices = { browser: ['tests'], 'os': ['tests'] };
// Default builds
self.defaultBuilds = { browser: ['main'], 'os': ['main'] };
},
// Initialize a package from an application directory (has .meteor/packages).
@@ -875,28 +868,28 @@ _.extend(PackageSource.prototype, {
self.sourceRoot = appDir;
self.serveRoot = path.sep;
_.each(["client", "server"], function (sliceName) {
_.each(["client", "server"], function (buildName) {
// Determine used packages
var names = project.getPackages(appDir);
var arch = sliceName === "server" ? "os" : "browser";
var arch = buildName === "server" ? "os" : "browser";
// Create slice
var slice = new SourceSlice(self, {
name: sliceName,
// Create build
var build = new SourceBuild(self, {
name: buildName,
arch: arch,
uses: _.map(names, utils.parseSpec)
});
self.slices.push(slice);
self.builds.push(build);
// Watch control files for changes
// XXX this read has a race with the actual reads that are used
_.each([path.join(appDir, '.meteor', 'packages'),
path.join(appDir, '.meteor', 'release')], function (p) {
watch.readAndWatchFile(slice.watchSet, p);
watch.readAndWatchFile(build.watchSet, p);
});
// Determine source files
slice.getSourcesFunc = function (extensions, watchSet) {
build.getSourcesFunc = function (extensions, watchSet) {
var sourceInclude = _.map(
extensions,
function (ext) {
@@ -926,8 +919,8 @@ _.extend(PackageSource.prototype, {
exclude: sourceExclude
});
var otherSliceRegExp =
(sliceName === "server" ? /^client\/$/ : /^server\/$/);
var otherBuildRegExp =
(buildName === "server" ? /^client\/$/ : /^server\/$/);
// The paths that we've called checkForInfiniteRecursion on.
var seenPaths = {};
@@ -957,7 +950,7 @@ _.extend(PackageSource.prototype, {
include: [/\/$/],
exclude: [/^packages\/$/, /^programs\/$/, /^tests\/$/,
/^public\/$/, /^private\/$/,
otherSliceRegExp].concat(sourceExclude)
otherBuildRegExp].concat(sourceExclude)
});
checkForInfiniteRecursion('');
@@ -980,7 +973,7 @@ _.extend(PackageSource.prototype, {
// directory names that are only special at the top level.
Array.prototype.push.apply(sourceDirectories, readAndWatchDirectory(dir, {
include: [/\/$/],
exclude: [/^tests\/$/, otherSliceRegExp].concat(sourceExclude)
exclude: [/^tests\/$/, otherBuildRegExp].concat(sourceExclude)
}));
}
@@ -993,7 +986,7 @@ _.extend(PackageSource.prototype, {
// Special case: on the client, JavaScript files in a
// `client/compatibility` directory don't get wrapped in a closure.
if (sliceName === "client" && relPath.match(/\.js$/)) {
if (buildName === "client" && relPath.match(/\.js$/)) {
var clientCompatSubstr =
path.sep + 'client' + path.sep + 'compatibility' + path.sep;
if ((path.sep + relPath).indexOf(clientCompatSubstr) !== -1)
@@ -1002,8 +995,8 @@ _.extend(PackageSource.prototype, {
return sourceObj;
});
// Now look for assets for this slice.
var assetDir = sliceName === "client" ? "public" : "private";
// Now look for assets for this build.
var assetDir = buildName === "client" ? "public" : "private";
var assetDirs = readAndWatchDirectory('', {
include: [new RegExp('^' + assetDir + '/$')]
});
@@ -1048,14 +1041,14 @@ _.extend(PackageSource.prototype, {
};
});
if (! self._checkCrossSliceVersionConstraints()) {
// should never happen since we created the slices from
if (! self._checkCrossBuildVersionConstraints()) {
// should never happen since we created the builds from
// .meteor/packages, which doesn't have a way to express
// different constraints for different slices
// different constraints for different builds
throw new Error("conflicting constraints in a package?");
}
self.defaultSlices = { browser: ['client'], 'os': ['server'] };
self.defaultBuilds = { browser: ['client'], 'os': ['server'] };
},
// True if the package defines any plugins.
@@ -1064,7 +1057,7 @@ _.extend(PackageSource.prototype, {
return ! _.isEmpty(self.pluginInfo);
},
// Return dependency metadata for all slices, in the format needed
// Return dependency metadata for all builds, in the format needed
// by the package catalog.
//
// Options:
@@ -1079,23 +1072,23 @@ _.extend(PackageSource.prototype, {
if (options.logError)
return null;
else
throw new Error("inconsistent dependency constraint across slices?");
throw new Error("inconsistent dependency constraint across builds?");
}
return ret;
},
// If dependencies aren't consistent across slices, return false and
// If dependencies aren't consistent across builds, return false and
// also log a buildmessage error if inside a buildmessage job. Else
// return true.
// XXX: Check that this is used when refactoring is done.
_checkCrossSliceVersionConstraints: function () {
_checkCrossBuildVersionConstraints: function () {
var self = this;
return !! self._computeDependencyMetadata({ logError: true });
},
// Compute the return value for getDependencyMetadata, or return
// null if there is a dependency that doesn't have the same
// constraint across all slices (and, if logError is true, log a
// constraint across all builds (and, if logError is true, log a
// buildmessage error).
//
// For options, see getDependencyMetadata.
@@ -1107,9 +1100,9 @@ _.extend(PackageSource.prototype, {
var allConstraints = {}; // for error reporting. package name to array
var failed = false;
_.each(self.slices, function (slice) {
_.each(self.builds, function (build) {
// XXX also iterate over "implies"
_.each(slice.uses, function (use) {
_.each(build.uses, function (use) {
if ((use.weak && options.skipWeak) ||
(use.unordered && options.skipUnordered))
return;
@@ -1134,9 +1127,9 @@ _.extend(PackageSource.prototype, {
}
d.references.push({
slice: slice.sliceName,
arch: archinfo.withoutSpecificOs(slice.arch),
targetSlice: use.slice, // usually undefined, for "default slices"
build: build.buildName,
arch: archinfo.withoutSpecificOs(build.arch),
targetBuild: use.build, // usually undefined, for "default builds"
weak: use.weak,
unordered: use.unordered
});

View File

@@ -124,8 +124,8 @@ project.getDirectDependencies = function(appDir) {
var programSubdir = path.join(project.getProgramsDirectory(appDir), item);
var programSource = new PackageSource(programSubdir);
programSource.initFromPackageDir(programName, programSubdir);
_.each(programSource.slices, function (sourceSlice) {
_.each(sourceSlice.uses, function (use) {
_.each(programSource.builds, function (sourceBuild) {
_.each(sourceBuild.uses, function (use) {
programsDeps[programName][use["package"]] = use.constraint || "none";
});
});

View File

@@ -32,14 +32,14 @@ var rejectBadPath = function (p) {
// - packageVariables
// - resources
var nextUniqueSliceId = 1;
var UnipackageSlice = function (unipackage, options) {
var nextUniqueBuildId = 1;
var UnipackageBuild = function (unipackage, options) {
var self = this;
options = options || {};
self.pkg = unipackage;
// These have the same meaning as they do in SourceSlice.
self.sliceName = options.name;
self.buildName = options.name;
self.arch = options.arch;
self.uses = options.uses;
self.implies = options.implies || [];
@@ -57,8 +57,8 @@ var UnipackageSlice = function (unipackage, options) {
// to keep track of UnipackageSlices in a map; it's used by bundler
// and compiler. We put some human readable info in here too to make
// debugging easier.
self.id = unipackage.name + "." + self.sliceName + "@" + self.arch + "#" +
(nextUniqueSliceId ++);
self.id = unipackage.name + "." + self.buildName + "@" + self.arch + "#" +
(nextUniqueBuildId ++);
// Prelink output.
//
@@ -103,7 +103,7 @@ var UnipackageSlice = function (unipackage, options) {
self.nodeModulesPath = options.nodeModulesPath;
};
_.extend(UnipackageSlice.prototype, {
_.extend(UnipackageBuild.prototype, {
// Get the resources that this function contributes to a bundle, in
// the same format as self.resources as documented above. This
// includes static assets and fully linked JavaScript.
@@ -136,14 +136,14 @@ _.extend(UnipackageSlice.prototype, {
// shouldn't be affected by the non-local decision of whether or not an
// unrelated package in the target depends on something).
var imports = {}; // map from symbol to supplying package name
compiler.eachUsedSlice(
compiler.eachUsedBuild(
self.uses,
bundleArch, packageLoader,
{skipWeak: true, skipUnordered: true}, function (otherSlice) {
_.each(otherSlice.packageVariables, function (symbol) {
// Slightly hacky implementation of test-only exports.
if (symbol.export === true ||
(symbol.export === "tests" && self.sliceName === "tests"))
(symbol.export === "tests" && self.buildName === "tests"))
imports[symbol.name] = otherSlice.pkg.name;
});
});
@@ -208,11 +208,10 @@ var Unipackage = function () {
self.metadata = {};
self.version = null;
self.earliestCompatibleVersion = null;
self.defaultSlices = {};
self.testSlices = {};
self.defaultBuilds = {};
// Build slices. Array of UnipackageSlice.
self.slices = [];
self.builds = [];
// Plugins in this package. Map from plugin name to {arch -> JsImage}.
self.plugins = {};
@@ -264,8 +263,7 @@ _.extend(Unipackage.prototype, {
initEmpty: function (name) {
var self = this;
self.name = name;
self.defaultSlices = {'': []};
self.testSlices = {'': []};
self.defaultBuilds = {'': []};
},
// This is primarily intended to be used by the compiler. After
@@ -276,8 +274,7 @@ _.extend(Unipackage.prototype, {
self.metadata = options.metadata;
self.version = options.version;
self.earliestCompatibleVersion = options.earliestCompatibleVersion;
self.defaultSlices = options.defaultSlices;
self.testSlices = options.testSlices;
self.defaultBuilds = options.defaultBuilds;
self.plugins = options.plugins;
self.pluginWatchSet = options.pluginWatchSet;
self.buildTimeDirectDependencies = options.buildTimeDirectDependencies;
@@ -288,25 +285,25 @@ _.extend(Unipackage.prototype, {
// called as part of building up a new Unipackage using
// initFromOptions. 'options' are the options to the UnipackageSlice
// constructor.
addSlice: function (options) {
addBuild: function (options) {
var self = this;
self.slices.push(new UnipackageSlice(self, options));
self.builds.push(new UnipackageBuild(self, options));
},
architectures: function () {
var self = this;
return _.uniq(_.pluck(self.slices, 'arch')).sort();
return _.uniq(_.pluck(self.builds, 'arch')).sort();
},
// Return the slice of the package to use for a given slice name
// (eg, 'main' or 'test') and target architecture (eg,
// 'os.linux.x86_64' or 'browser'), or throw an exception if
// that packages can't be loaded under these circumstances.
getSingleSlice: function (name, arch) {
getSingleBuild: function (name, arch) {
var self = this;
var chosenArch = archinfo.mostSpecificMatch(
arch, _.pluck(_.where(self.slices, { sliceName: name }), 'arch'));
arch, _.pluck(_.where(self.builds, { buildName: name }), 'arch'));
if (! chosenArch) {
// XXX need improvement. The user should get a graceful error
@@ -318,7 +315,7 @@ _.extend(Unipackage.prototype, {
"' that runs on architecture '" + arch + "'");
}
return _.where(self.slices, { sliceName: name, arch: chosenArch })[0];
return _.where(self.builds, { buildName: name, arch: chosenArch })[0];
},
// Return the slices that should be used on a given arch if the
@@ -327,11 +324,11 @@ _.extend(Unipackage.prototype, {
//
// On error, throw an exception, or if inside
// buildmessage.capture(), log a build error and return [].
getDefaultSlices: function (arch) {
getDefaultBuilds: function (arch) {
var self = this;
var chosenArch = archinfo.mostSpecificMatch(arch,
_.keys(self.defaultSlices));
_.keys(self.defaultBuilds));
if (! chosenArch) {
buildmessage.error(
@@ -342,29 +339,8 @@ _.extend(Unipackage.prototype, {
return [];
}
return _.map(self.defaultSlices[chosenArch], function (name) {
return self.getSingleSlice(name, arch);
});
},
// Return the slices that should be used to test the package on a
// given arch.
getTestSlices: function (arch) {
var self = this;
var chosenArch = archinfo.mostSpecificMatch(arch,
_.keys(self.testSlices));
if (! chosenArch) {
buildmessage.error(
(self.name || "this app") +
" does not have tests for architecture " + arch + "'",
{ secondary: true });
// recover by returning by no slices
return [];
}
return _.map(self.testSlices[chosenArch], function (name) {
return self.getSingleSlice(name, arch);
return _.map(self.defaultBuilds[chosenArch], function (name) {
return self.getSingleBuild(name, arch);
});
},
@@ -521,10 +497,8 @@ _.extend(Unipackage.prototype, {
}
// If multiple sub-unipackages specify defaultSlices or testSlices for the
// same arch, just take the answer from the first sub-unipackage.
self.defaultSlices = _.extend(mainJson.defaultSlices,
self.defaultSlices || {});
self.testSlices = _.extend(mainJson.testSlices,
self.testSlices || {});
self.defaultBuilds = _.extend(mainJson.defaultSlices,
self.defaultBuilds || {});
_.each(mainJson.plugins, function (pluginMeta) {
rejectBadPath(pluginMeta.path);
@@ -548,7 +522,7 @@ _.extend(Unipackage.prototype, {
// Skip slices we already have.
var alreadyHaveSlice = _.find(self.slices, function (slice) {
return slice.sliceName === sliceMeta.name &&
return slice.buildName === sliceMeta.name &&
slice.arch === sliceMeta.arch;
});
if (alreadyHaveSlice)
@@ -615,7 +589,7 @@ _.extend(Unipackage.prototype, {
JSON.stringify(resource.type));
});
self.slices.push(new UnipackageSlice(self, {
self.builds.push(new UnipackageBuild(self, {
name: sliceMeta.name,
arch: sliceMeta.arch,
uses: sliceJson.uses,
@@ -661,8 +635,7 @@ _.extend(Unipackage.prototype, {
version: self.version,
earliestCompatibleVersion: self.earliestCompatibleVersion,
slices: [],
defaultSlices: self.defaultSlices,
testSlices: self.testSlices,
defaultSlices: self.defaultBuilds,
plugins: []
};
@@ -717,10 +690,10 @@ _.extend(Unipackage.prototype, {
});
// Slices
_.each(self.slices, function (slice) {
_.each(self.builds, function (slice) {
// Make up a filename for this slice
var baseSliceName =
(slice.sliceName === "main" ? "" : (slice.sliceName + ".")) +
(slice.buildName === "main" ? "" : (slice.buildName + ".")) +
slice.arch;
var sliceDir =
builder.generateFilename(baseSliceName, { directory: true });
@@ -728,7 +701,7 @@ _.extend(Unipackage.prototype, {
builder.generateFilename(baseSliceName + ".json");
mainJson.slices.push({
name: slice.sliceName,
name: slice.buildName,
arch: slice.arch,
path: sliceJsonFile
});
@@ -952,7 +925,7 @@ _.extend(Unipackage.prototype, {
var watchFiles = [];
var watchSet = new watch.WatchSet();
watchSet.merge(self.pluginWatchSet);
_.each(self.slices, function (slice) {
_.each(self.builds, function (slice) {
watchSet.merge(slice.watchSet);
});
_.each(watchSet.files, function (hash, fileAbsPath) {

View File

@@ -219,7 +219,7 @@ exports.parseSpec = function (spec) {
throw new Error("Bad package spec: " + spec);
var ret = { package: m[1] };
if (m[3])
ret.slice = m[3];
ret.build = m[3];
if (m[5])
ret.constraint = m[5];
return ret;