mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'devel' into release-0.9.4
Conflicts: docs/client/data.js
This commit is contained in:
@@ -3587,6 +3587,9 @@ package is exported to.
|
||||
{{> autoApiBox "PackageAPI#export" }}
|
||||
{{> autoApiBox "PackageAPI#addFiles" }}
|
||||
|
||||
{{> autoApiBox "Package.registerBuildPlugin"}}
|
||||
{{> autoApiBox "Plugin.registerSourceHandler"}}
|
||||
|
||||
<h3 id="packagetests"><span>Unit Tests</span></h3>
|
||||
|
||||
{{#markdown}}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -392,7 +392,10 @@ var toc = [
|
||||
{name: "Package.onTest", id: "packagetests"},
|
||||
{name: "Npm.depends", id: "Npm-depends"},
|
||||
{name: "Npm.require", id: "Npm-require"},
|
||||
{name: "Cordova.depends", id: "Cordova-depends"}
|
||||
{name: "Cordova.depends", id: "Cordova-depends"},
|
||||
{name: "Package.registerBuildPlugin", id: "Package-registerBuildPlugin"}, [
|
||||
{name: "Plugin.registerSourceHandler", id: "Plugin-registerSourceHandler"}
|
||||
]
|
||||
]
|
||||
],
|
||||
|
||||
|
||||
@@ -48,6 +48,22 @@
|
||||
"Blaze.renderWithData",
|
||||
"Blaze.toHTML",
|
||||
"Blaze.toHTMLWithData",
|
||||
"CompileStep",
|
||||
"CompileStep#addAsset",
|
||||
"CompileStep#addHtml",
|
||||
"CompileStep#addJavaScript",
|
||||
"CompileStep#addStylesheet",
|
||||
"CompileStep#arch",
|
||||
"CompileStep#declaredExports",
|
||||
"CompileStep#error",
|
||||
"CompileStep#fileOptions",
|
||||
"CompileStep#fullInputPath",
|
||||
"CompileStep#inputPath",
|
||||
"CompileStep#inputSize",
|
||||
"CompileStep#packageName",
|
||||
"CompileStep#pathForSourceMap",
|
||||
"CompileStep#read",
|
||||
"CompileStep#rootOutputPath",
|
||||
"Cordova",
|
||||
"Cordova.depends",
|
||||
"DDP.connect",
|
||||
@@ -135,12 +151,15 @@
|
||||
"Package.describe",
|
||||
"Package.onTest",
|
||||
"Package.onUse",
|
||||
"Package.registerBuildPlugin",
|
||||
"PackageAPI",
|
||||
"PackageAPI#addFiles",
|
||||
"PackageAPI#export",
|
||||
"PackageAPI#imply",
|
||||
"PackageAPI#use",
|
||||
"PackageAPI#versionsFrom",
|
||||
"Plugin",
|
||||
"Plugin.registerSourceHandler",
|
||||
"ReactiveVar",
|
||||
"ReactiveVar#get",
|
||||
"ReactiveVar#set",
|
||||
|
||||
2
meteor
2
meteor
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
BUNDLE_VERSION=0.3.55
|
||||
BUNDLE_VERSION=0.3.55 # XXX: 0.3.56 is used on the cordova-0.9.4 branch
|
||||
|
||||
# OS Check. Put here because here is where we download the precompiled
|
||||
# bundles that are arch specific.
|
||||
|
||||
@@ -64,7 +64,7 @@ Blaze.View.prototype.lookup = function (name, _options) {
|
||||
} else if (lookupTemplate && (name in Blaze.Template) &&
|
||||
(Blaze.Template[name] instanceof Blaze.Template)) {
|
||||
return Blaze.Template[name];
|
||||
} else if (Blaze._globalHelpers[name]) {
|
||||
} else if (Blaze._globalHelpers[name] != null) {
|
||||
return wrapHelper(bindDataContext(Blaze._globalHelpers[name]));
|
||||
} else {
|
||||
return function () {
|
||||
|
||||
@@ -147,7 +147,7 @@ _.extend(Meteor, {
|
||||
var warnedAboutWrapAsync = false;
|
||||
|
||||
/**
|
||||
* @deprecated in 1.0.0
|
||||
* @deprecated in 0.9.3
|
||||
*/
|
||||
Meteor._wrapAsync = function(fn, context) {
|
||||
if (! warnedAboutWrapAsync) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
UglifyJSMinify = Npm.require('uglify-js').minify;
|
||||
|
||||
var cssParse = Npm.require('css-parse');
|
||||
var cssStringify = Npm.require('css-stringify');
|
||||
var path = Npm.require('path');
|
||||
var url = Npm.require('url');
|
||||
UglifyJS = Npm.require('uglify-js');
|
||||
UglifyJSMinify = UglifyJS.minify;
|
||||
|
||||
CssTools = {
|
||||
parseCss: cssParse,
|
||||
|
||||
@@ -11,7 +11,7 @@ Npm.depends({
|
||||
|
||||
Package.on_use(function (api) {
|
||||
api.use('underscore', 'server');
|
||||
api.export(['CssTools', 'UglifyJSMinify']);
|
||||
api.export(['CssTools', 'UglifyJSMinify', 'UglifyJS']);
|
||||
api.add_files(['minification.js', 'minifiers.js'], 'server');
|
||||
});
|
||||
|
||||
|
||||
@@ -1610,28 +1610,28 @@ var runOneTwoTest = function (test, subTemplateName, optionsData) {
|
||||
};
|
||||
|
||||
Tinytest.add('spacebars-tests - old - template_tests - with stops without re-running helper', function (test) {
|
||||
runOneTwoTest(test, 'spacebars_test_helpers_stop_with');
|
||||
runOneTwoTest(test, 'old_spacebars_test_helpers_stop_with');
|
||||
});
|
||||
|
||||
Tinytest.add('spacebars-tests - old - template_tests - each stops without re-running helper', function (test) {
|
||||
runOneTwoTest(test, 'spacebars_test_helpers_stop_each');
|
||||
runOneTwoTest(test, 'old_spacebars_test_helpers_stop_each');
|
||||
});
|
||||
|
||||
Tinytest.add('spacebars-tests - old - template_tests - each inside with stops without re-running helper', function (test) {
|
||||
runOneTwoTest(test, 'spacebars_test_helpers_stop_with_each');
|
||||
runOneTwoTest(test, 'old_spacebars_test_helpers_stop_with_each');
|
||||
});
|
||||
|
||||
Tinytest.add('spacebars-tests - old - template_tests - if stops without re-running helper', function (test) {
|
||||
runOneTwoTest(test, 'spacebars_test_helpers_stop_if', ['a', 'b', 'a']);
|
||||
runOneTwoTest(test, 'old_spacebars_test_helpers_stop_if', ['a', 'b', 'a']);
|
||||
});
|
||||
|
||||
Tinytest.add('spacebars-tests - old - template_tests - unless stops without re-running helper', function (test) {
|
||||
runOneTwoTest(test, 'spacebars_test_helpers_stop_unless', ['a', 'b', 'a']);
|
||||
runOneTwoTest(test, 'old_spacebars_test_helpers_stop_unless', ['a', 'b', 'a']);
|
||||
});
|
||||
|
||||
Tinytest.add('spacebars-tests - old - template_tests - inclusion stops without re-running function', function (test) {
|
||||
var t = Template.old_spacebars_test_helpers_stop_inclusion3;
|
||||
runOneTwoTest(test, 'spacebars_test_helpers_stop_inclusion', [t, t, t]);
|
||||
runOneTwoTest(test, 'old_spacebars_test_helpers_stop_inclusion', [t, t, t]);
|
||||
});
|
||||
|
||||
Tinytest.add('spacebars-tests - old - template_tests - template with callbacks inside with stops without recalculating data', function (test) {
|
||||
@@ -1639,7 +1639,7 @@ Tinytest.add('spacebars-tests - old - template_tests - template with callbacks i
|
||||
tmpl.created = function () {};
|
||||
tmpl.rendered = function () {};
|
||||
tmpl.destroyed = function () {};
|
||||
runOneTwoTest(test, 'spacebars_test_helpers_stop_with_callbacks');
|
||||
runOneTwoTest(test, 'old_spacebars_test_helpers_stop_with_callbacks');
|
||||
});
|
||||
|
||||
Tinytest.add('spacebars-tests - old - template_tests - no data context is seen as an empty object', function (test) {
|
||||
|
||||
@@ -992,3 +992,7 @@ Hi there!
|
||||
{{/with}}
|
||||
{{/with}}
|
||||
</template>
|
||||
|
||||
<template name="spacebars_template_test_falsy_helper">
|
||||
foo:{{foo}} GLOBAL_ZERO:{{GLOBAL_ZERO}}
|
||||
</template>
|
||||
|
||||
@@ -669,7 +669,6 @@ Tinytest.add("spacebars-tests - template_tests - select tags", function (test) {
|
||||
options.update({}, {$set: {selected: false}}, {multi: true});
|
||||
Tracker.flush();
|
||||
options.update({}, {$set: {selected: true}}, {multi: true});
|
||||
window.avital = true;
|
||||
Tracker.flush();
|
||||
test.equal($(selectEl).find('option')[0].selected, true);
|
||||
test.equal($(selectEl).find('option')[1].selected, true);
|
||||
@@ -2903,3 +2902,12 @@ Tinytest.add("spacebars-tests - template_tests - content context back-compat", f
|
||||
Tracker.flush();
|
||||
test.equal(canonicalizeHtml(div.innerHTML), 'FA');
|
||||
});
|
||||
|
||||
Tinytest.add("spacebars-tests - template_tests - falsy helper", function (test) {
|
||||
var tmpl = Template.spacebars_template_test_falsy_helper;
|
||||
tmpl.foo = 0;
|
||||
Template.registerHelper('GLOBAL_ZERO', 0);
|
||||
|
||||
var div = renderToDiv(tmpl);
|
||||
test.equal(canonicalizeHtml(div.innerHTML), 'foo:0 GLOBAL_ZERO:0');
|
||||
});
|
||||
|
||||
@@ -191,6 +191,9 @@ var getCurrentProgressTracker = function () {
|
||||
return progress ? progress : rootProgress;
|
||||
};
|
||||
|
||||
var nudge = function () {
|
||||
getCurrentProgressTracker().nudge();
|
||||
};
|
||||
|
||||
var addChildTracker = function (title) {
|
||||
var options = {};
|
||||
@@ -299,10 +302,20 @@ var enterJob = function (options, f) {
|
||||
|
||||
return currentProgress.withValue(progress, function () {
|
||||
if (!currentMessageSet.get()) {
|
||||
var nestingLevel = currentNestingLevel.get();
|
||||
var start;
|
||||
if (debugBuild) {
|
||||
start = Date.now();
|
||||
console.log("START", nestingLevel, options.title);
|
||||
}
|
||||
try {
|
||||
return f();
|
||||
} finally {
|
||||
progress.reportProgressDone();
|
||||
if (debugBuild) {
|
||||
var end = Date.now();
|
||||
console.log("DONE", nestingLevel, options.title, "took " + (end - start));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,5 +562,6 @@ _.extend(exports, {
|
||||
reportProgress: reportProgress,
|
||||
reportProgressDone: reportProgressDone,
|
||||
getCurrentProgressTracker: getCurrentProgressTracker,
|
||||
addChildTracker: addChildTracker
|
||||
addChildTracker: addChildTracker,
|
||||
nudge: nudge
|
||||
});
|
||||
|
||||
174
tools/bundler.js
174
tools/bundler.js
@@ -236,6 +236,8 @@ var File = function (options) {
|
||||
// disk).
|
||||
self.sourcePath = options.sourcePath;
|
||||
|
||||
self.info = options.info || '?';
|
||||
|
||||
// If this file was generated, a sourceMap (as a string) with debugging
|
||||
// information, as well as the "root" that paths in it should be resolved
|
||||
// against. Set with setSourceMap.
|
||||
@@ -270,6 +272,11 @@ var File = function (options) {
|
||||
};
|
||||
|
||||
_.extend(File.prototype, {
|
||||
toString: function() {
|
||||
var self = this;
|
||||
return "File: [info=" + self.info + "]";
|
||||
},
|
||||
|
||||
hash: function () {
|
||||
var self = this;
|
||||
if (! self._hash)
|
||||
@@ -430,6 +437,15 @@ var Target = function (options) {
|
||||
|
||||
// A mapping from Cordova plugin name to Cordova plugin version number.
|
||||
self.cordovaDependencies = {};
|
||||
|
||||
// For the todos sample app:
|
||||
// false: 99.6 KB / 316 KB
|
||||
// vs
|
||||
// true: 99 KB / 315 KB
|
||||
|
||||
// METEOR_MINIFY_LEGACY is an undocumented safety-valve environment variable,
|
||||
// in case people hit trouble
|
||||
self._minifyTogether = !!process.env.METEOR_MINIFY_LEGACY;
|
||||
};
|
||||
|
||||
_.extend(Target.prototype, {
|
||||
@@ -625,6 +641,7 @@ _.extend(Target.prototype, {
|
||||
return;
|
||||
|
||||
var f = new File({
|
||||
info: 'unbuild ' + resource,
|
||||
data: resource.data,
|
||||
cacheable: false,
|
||||
hash: resource.hash
|
||||
@@ -659,7 +676,7 @@ _.extend(Target.prototype, {
|
||||
// meteor.js?
|
||||
return;
|
||||
|
||||
var f = new File({data: resource.data, cacheable: false});
|
||||
var f = new File({ info: 'resource ' + resource.servePath, data: resource.data, cacheable: false});
|
||||
|
||||
var relPath = stripLeadingSlash(resource.servePath);
|
||||
f.setTargetPathFromRelPath(relPath);
|
||||
@@ -726,16 +743,32 @@ _.extend(Target.prototype, {
|
||||
minifyJs: function (minifiers) {
|
||||
var self = this;
|
||||
|
||||
var allJs = _.map(self.js, function (file) {
|
||||
return file.contents('utf8');
|
||||
}).join('\n;\n');
|
||||
var allJs;
|
||||
|
||||
allJs = minifiers.UglifyJSMinify(allJs, {
|
||||
var minifyOptions = {
|
||||
fromString: true,
|
||||
compress: {drop_debugger: false}
|
||||
}).code;
|
||||
compress: {drop_debugger: false }
|
||||
};
|
||||
|
||||
self.js = [new File({ data: new Buffer(allJs, 'utf8') })];
|
||||
if (self._minifyTogether) {
|
||||
var sources = _.map(self.js, function (file) {
|
||||
return file.contents('utf8');
|
||||
});
|
||||
|
||||
buildmessage.enterJob({title: "Minifying"}, function () {
|
||||
allJs = _minify(minifiers.UglifyJS, '', sources, minifyOptions).code;
|
||||
});
|
||||
} else {
|
||||
minifyOptions.compress.unused = false;
|
||||
minifyOptions.compress.dead_code = false;
|
||||
|
||||
allJs = buildmessage.forkJoin({title: "Minifying" }, self.js, function (file) {
|
||||
var source = file.contents('utf8');
|
||||
return _minify(minifiers.UglifyJS, file.info, source, minifyOptions).code;
|
||||
}).join("\n\n");
|
||||
}
|
||||
|
||||
self.js = [new File({ info: 'minified js', data: new Buffer(allJs, 'utf8') })];
|
||||
self.js[0].setUrlToHash(".js");
|
||||
},
|
||||
|
||||
@@ -771,6 +804,127 @@ _.extend(Target.prototype, {
|
||||
}
|
||||
});
|
||||
|
||||
// This code should mirror the minify function in UglifyJs2,
|
||||
_minify = function(UglifyJS, key, files, options) {
|
||||
options = UglifyJS.defaults(options, {
|
||||
spidermonkey : false,
|
||||
outSourceMap : null,
|
||||
sourceRoot : null,
|
||||
inSourceMap : null,
|
||||
fromString : false,
|
||||
warnings : false,
|
||||
mangle : {},
|
||||
output : null,
|
||||
compress : {}
|
||||
});
|
||||
UglifyJS.base54.reset();
|
||||
|
||||
var totalFileSize = 0;
|
||||
_.forEach(files, function (file) {
|
||||
totalFileSize += file.length;
|
||||
});
|
||||
|
||||
var phases = 2;
|
||||
if (options.compress) phases++;
|
||||
if (options.mangle) phases++;
|
||||
if (options.output) phases++;
|
||||
|
||||
var progress = {current: 0, end: totalFileSize * phases, done: false};
|
||||
var progressTracker = buildmessage.getCurrentProgressTracker();
|
||||
|
||||
// 1. parse
|
||||
var toplevel = null,
|
||||
sourcesContent = {};
|
||||
|
||||
if (options.spidermonkey) {
|
||||
toplevel = UglifyJS.AST_Node.from_mozilla_ast(files);
|
||||
} else {
|
||||
if (typeof files == "string")
|
||||
files = [ files ];
|
||||
buildmessage.forkJoin({title: 'Minifying: parsing ' + key}, files, function (file) {
|
||||
var code = options.fromString
|
||||
? file
|
||||
: fs.readFileSync(file, "utf8");
|
||||
sourcesContent[file] = code;
|
||||
toplevel = UglifyJS.parse(code, {
|
||||
filename: options.fromString ? "?" : file,
|
||||
toplevel: toplevel
|
||||
});
|
||||
|
||||
progress.current += code.length;
|
||||
progressTracker.reportProgress(progress);
|
||||
});
|
||||
}
|
||||
|
||||
// 2. compress
|
||||
var compress;
|
||||
if (options.compress) buildmessage.enterJob({title: "Minify: compress 1 " + key}, function () {
|
||||
compress = { warnings: options.warnings };
|
||||
UglifyJS.merge(compress, options.compress);
|
||||
toplevel.figure_out_scope();
|
||||
});
|
||||
if (options.compress) buildmessage.enterJob({title: "Minify: compress 2 " + key}, function () {
|
||||
var sq = UglifyJS.Compressor(compress);
|
||||
toplevel = toplevel.transform(sq);
|
||||
|
||||
progress.current += totalFileSize;
|
||||
progressTracker.reportProgress(progress);
|
||||
});
|
||||
|
||||
// 3. mangle
|
||||
if (options.mangle) buildmessage.enterJob({title: "Minify: mangling " + key}, function () {
|
||||
toplevel.figure_out_scope();
|
||||
toplevel.compute_char_frequency();
|
||||
toplevel.mangle_names(options.mangle);
|
||||
|
||||
progress.current += totalFileSize;
|
||||
progressTracker.reportProgress(progress);
|
||||
});
|
||||
|
||||
// 4. output
|
||||
var inMap = options.inSourceMap;
|
||||
var output = {};
|
||||
if (typeof options.inSourceMap == "string") {
|
||||
inMap = fs.readFileSync(options.inSourceMap, "utf8");
|
||||
}
|
||||
if (options.outSourceMap) {
|
||||
output.source_map = UglifyJS.SourceMap({
|
||||
file: options.outSourceMap,
|
||||
orig: inMap,
|
||||
root: options.sourceRoot
|
||||
});
|
||||
if (options.sourceMapIncludeSources) {
|
||||
for (var file in sourcesContent) {
|
||||
if (sourcesContent.hasOwnProperty(file)) {
|
||||
options.source_map.get().setSourceContent(file, sourcesContent[file]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.output) buildmessage.enterJob({title: "Minify: merging " + key}, function () {
|
||||
UglifyJS.merge(output, options.output);
|
||||
|
||||
progress.current += totalFileSize;
|
||||
progressTracker.reportProgress(progress);
|
||||
});
|
||||
|
||||
|
||||
var stream;
|
||||
buildmessage.enterJob({title: "Minify: printing " + key}, function () {
|
||||
stream = UglifyJS.OutputStream(output);
|
||||
toplevel.print(stream);
|
||||
|
||||
progress.current += totalFileSize;
|
||||
progressTracker.reportProgress(progress);
|
||||
});
|
||||
|
||||
return {
|
||||
code : stream + "",
|
||||
map : output.source_map + ""
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////// ClientTarget ////////////////////
|
||||
|
||||
@@ -842,7 +996,7 @@ _.extend(ClientTarget.prototype, {
|
||||
if (! stringifiedCss.code)
|
||||
return;
|
||||
|
||||
self.css = [new File({ data: new Buffer(stringifiedCss.code, 'utf8') })];
|
||||
self.css = [new File({ info: 'combined css', data: new Buffer(stringifiedCss.code, 'utf8') })];
|
||||
|
||||
// Add the contents of the input files to the source map of the new file
|
||||
stringifiedCss.map.sourcesContent =
|
||||
@@ -890,7 +1044,7 @@ _.extend(ClientTarget.prototype, {
|
||||
minifiedCss = minifiers.CssTools.minifyCss(allCss);
|
||||
}
|
||||
if (!! minifiedCss) {
|
||||
self.css = [new File({ data: new Buffer(minifiedCss, 'utf8') })];
|
||||
self.css = [new File({ info: 'minified css', data: new Buffer(minifiedCss, 'utf8') })];
|
||||
self.css[0].setUrlToHash(".css", "?meteor_css_resource=true");
|
||||
}
|
||||
},
|
||||
|
||||
@@ -528,19 +528,13 @@ _.extend(CompleteCatalog.prototype, {
|
||||
constr.push(utils.parseConstraint(name + "@=" + packageSource.version));
|
||||
});
|
||||
|
||||
var patience = new utils.Patience({
|
||||
messageAfterMs: 1000,
|
||||
message: "Figuring out the best package versions to use. This may take a moment."
|
||||
});
|
||||
|
||||
var ret;
|
||||
try {
|
||||
var ret = buildmessage.enterJob({ title: "Figuring out the best package versions to use." }, function () {
|
||||
// Then, call the constraint solver, to get the valid transitive subset of
|
||||
// those versions to record for our solution. (We don't just return the
|
||||
// original version lock because we want to record the correct transitive
|
||||
// dependencies)
|
||||
try {
|
||||
ret = self.resolver.resolve(deps, constr, resolverOpts);
|
||||
return self.resolver.resolve(deps, constr, resolverOpts);
|
||||
} catch (e) {
|
||||
// Maybe we only failed because we need to refresh. Try to refresh
|
||||
// (unless we already are) and retry.
|
||||
@@ -550,11 +544,10 @@ _.extend(CompleteCatalog.prototype, {
|
||||
}
|
||||
catalog.official.refresh();
|
||||
self.resolver || self._initializeResolver();
|
||||
ret = self.resolver.resolve(deps, constr, resolverOpts);
|
||||
return self.resolver.resolve(deps, constr, resolverOpts);
|
||||
}
|
||||
} finally {
|
||||
patience.stop();
|
||||
}
|
||||
});
|
||||
|
||||
if (ret["usedRCs"]) {
|
||||
var expPackages = [];
|
||||
_.each(ret.answer, function(version, package) {
|
||||
@@ -692,6 +685,7 @@ _.extend(CompleteCatalog.prototype, {
|
||||
// This may be a singleton, but the resolver is in a package so it
|
||||
// doesn't have access to it.
|
||||
utils.Patience.nudge();
|
||||
buildmessage.nudge();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -152,6 +152,7 @@ main.registerCommand({
|
||||
|
||||
main.registerCommand({
|
||||
name: 'run',
|
||||
pretty: true,
|
||||
requiresApp: true,
|
||||
maxArgs: Infinity,
|
||||
options: {
|
||||
|
||||
@@ -578,25 +578,121 @@ var compileUnibuild = function (unipkg, inputSourceArch, packageLoader,
|
||||
// way to return errors (that could go in an overall list of
|
||||
// errors experienced across all files)
|
||||
var readOffset = 0;
|
||||
|
||||
/**
|
||||
* The comments for this class aren't used to generate docs right now.
|
||||
* The docs live in the GitHub Wiki at: https://github.com/meteor/meteor/wiki/CompileStep-API-for-Build-Plugin-Source-Handlers
|
||||
* @class CompileStep
|
||||
* @summary The object passed into Plugin.registerSourceHandler
|
||||
* @global
|
||||
*/
|
||||
var compileStep = {
|
||||
|
||||
/**
|
||||
* @summary The total number of bytes in the input file.
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
* @type {Integer}
|
||||
*/
|
||||
inputSize: contents.length,
|
||||
|
||||
/**
|
||||
* @summary The filename and relative path of the input file.
|
||||
* Please don't use this filename to read the file from disk, instead
|
||||
* use [compileStep.read](CompileStep-read).
|
||||
* @type {String}
|
||||
* @instance
|
||||
* @memberOf CompileStep
|
||||
*/
|
||||
inputPath: relPath,
|
||||
|
||||
/**
|
||||
* @summary The filename and absolute path of the input file.
|
||||
* Please don't use this filename to read the file from disk, instead
|
||||
* use [compileStep.read](CompileStep-read).
|
||||
* @type {String}
|
||||
* @instance
|
||||
* @memberOf CompileStep
|
||||
*/
|
||||
fullInputPath: absPath,
|
||||
|
||||
// The below is used in the less and stylus packages... so it should be
|
||||
// public API.
|
||||
_fullInputPath: absPath, // avoid, see above..
|
||||
|
||||
// XXX duplicates _pathForSourceMap() in linker
|
||||
pathForSourceMap: (
|
||||
inputSourceArch.pkg.name
|
||||
? inputSourceArch.pkg.name + "/" + relPath
|
||||
: path.basename(relPath)),
|
||||
/**
|
||||
* @summary If you are generating a sourcemap for the compiled file, use
|
||||
* this path for the original file in the sourcemap.
|
||||
* @type {String}
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
pathForSourceMap: (inputSourceArch.pkg.name ?
|
||||
inputSourceArch.pkg.name + "/" + relPath : path.basename(relPath)),
|
||||
|
||||
// null if this is an app. intended to be used for the sources
|
||||
// dictionary for source maps.
|
||||
/**
|
||||
* @summary The name of the package in which the file being built exists.
|
||||
* @type {String}
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
packageName: inputSourceArch.pkg.name,
|
||||
|
||||
/**
|
||||
* @summary On web targets, this will be the root URL prepended
|
||||
* to the paths you pick for your output files. For example,
|
||||
* it could be "/packages/my-package".
|
||||
* @type {String}
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
rootOutputPath: inputSourceArch.pkg.serveRoot,
|
||||
arch: inputSourceArch.arch, // XXX: what is the story with arch?
|
||||
|
||||
/**
|
||||
* @summary The architecture for which we are building. Can be "os",
|
||||
* "web.browser", or "web.cordova".
|
||||
* @type {String}
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
arch: inputSourceArch.arch,
|
||||
|
||||
/**
|
||||
* @deprecated in 0.9.4
|
||||
* This is a duplicate API of the above, we don't need it.
|
||||
*/
|
||||
archMatches: function (pattern) {
|
||||
return archinfo.matches(inputSourceArch.arch, pattern);
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary Any options passed to "api.addFiles".
|
||||
* @type {Object}
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
fileOptions: fileOptions,
|
||||
|
||||
/**
|
||||
* @summary The list of exports that the current package has defined.
|
||||
* Can be used to treat those symbols differently during compilation.
|
||||
* @type {Object}
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
declaredExports: _.pluck(inputSourceArch.declaredExports, 'name'),
|
||||
|
||||
/**
|
||||
* @summary Read from the input file. If `n` is specified, returns the
|
||||
* next `n` bytes of the file as a Buffer. XXX not sure if this actually
|
||||
* returns a String sometimes...
|
||||
* @param {Integer} [n] The number of bytes to return.
|
||||
* @instance
|
||||
* @memberOf CompileStep
|
||||
*/
|
||||
read: function (n) {
|
||||
if (n === undefined || readOffset + n > contents.length)
|
||||
n = contents.length - readOffset;
|
||||
@@ -604,7 +700,18 @@ var compileUnibuild = function (unipkg, inputSourceArch, packageLoader,
|
||||
readOffset += n;
|
||||
return ret;
|
||||
},
|
||||
appendDocument: function (options) {
|
||||
|
||||
/**
|
||||
* @summary Works in web targets only. Add markup to the `head` or `body`
|
||||
* section of the document.
|
||||
* @param {Object} options
|
||||
* @param {String} options.section Which section of the document should
|
||||
* be appended to. Can only be "head" or "body".
|
||||
* @param {String} options.data The content to append.
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
addHtml: function (options) {
|
||||
if (! archinfo.matches(inputSourceArch.arch, "web"))
|
||||
throw new Error("Document sections can only be emitted to " +
|
||||
"web targets");
|
||||
@@ -617,6 +724,26 @@ var compileUnibuild = function (unipkg, inputSourceArch, packageLoader,
|
||||
data: new Buffer(options.data, 'utf8')
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated in 0.9.4
|
||||
*/
|
||||
appendDocument: function (options) {
|
||||
this.addHtml(options);
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary Web targets only. Add a stylesheet to the document.
|
||||
* @param {Object} options
|
||||
* @param {String} path The requested path for the added CSS, may not be
|
||||
* satisfied if there are path conflicts.
|
||||
* @param {String} data The content of the stylesheet that should be
|
||||
* added.
|
||||
* @param {String} sourceMap A stringified JSON sourcemap, in case the
|
||||
* stylesheet was generated from a different file.
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
addStylesheet: function (options) {
|
||||
if (! archinfo.matches(inputSourceArch.arch, "web"))
|
||||
throw new Error("Stylesheets can only be emitted to " +
|
||||
@@ -631,6 +758,22 @@ var compileUnibuild = function (unipkg, inputSourceArch, packageLoader,
|
||||
sourceMap: options.sourceMap
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary Add JavaScript code. The code added will only see the
|
||||
* namespaces imported by this package as runtime dependencies using
|
||||
* ['api.use'](#PackageAPI-use). If the file being compiled was added
|
||||
* with the bare flag, the resulting JavaScript won't be wrapped in a
|
||||
* closure.
|
||||
* @param {Object} options
|
||||
* @param {String} options.path The path at which the JavaScript file
|
||||
* should be inserted, may not be honored in case of path conflicts.
|
||||
* @param {String} options.data The code to be added.
|
||||
* @param {String} options.sourcePath The path that will be used in
|
||||
* any error messages generated by this file, e.g. `foo.js:4:1: error`.
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
addJavaScript: function (options) {
|
||||
if (typeof options.data !== "string")
|
||||
throw new Error("'data' option to addJavaScript must be a string");
|
||||
@@ -642,15 +785,45 @@ var compileUnibuild = function (unipkg, inputSourceArch, packageLoader,
|
||||
source: options.data,
|
||||
sourcePath: options.sourcePath,
|
||||
servePath: path.join(inputSourceArch.pkg.serveRoot, options.path),
|
||||
bare: !! options.bare,
|
||||
bare: !! fileOptions.bare,
|
||||
sourceMap: options.sourceMap
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary Add a file to serve as-is to the browser or to include on
|
||||
* the browser, depending on the target. On the web, it will be served
|
||||
* at the exact path requested. For server targets, it can be retrieved
|
||||
* using `Assets.getText` or `Assets.getBinary`.
|
||||
* @param {Object} options
|
||||
* @param {String} path The path at which to serve the asset.
|
||||
* @param {Buffer|String} data The data that should be placed in
|
||||
* the file.
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
addAsset: function (options) {
|
||||
if (! (options.data instanceof Buffer))
|
||||
throw new Error("'data' option to addAsset must be a Buffer");
|
||||
if (! (options.data instanceof Buffer)) {
|
||||
if (_.isString(options.data)) {
|
||||
options.data = new Buffer(options.data);
|
||||
} else {
|
||||
throw new Error("'data' option to addAsset must be a Buffer or String.");
|
||||
}
|
||||
}
|
||||
|
||||
addAsset(options.data, options.path);
|
||||
},
|
||||
|
||||
/**
|
||||
* @summary Display a build error.
|
||||
* @param {Object} options
|
||||
* @param {String} message The error message to display.
|
||||
* @param {String} [sourcePath] The path to display in the error message.
|
||||
* @param {Integer} line The line number to display in the error message.
|
||||
* @param {String} func The function name to display in the error message.
|
||||
* @memberOf CompileStep
|
||||
* @instance
|
||||
*/
|
||||
error: function (options) {
|
||||
buildmessage.error(options.message || ("error building " + relPath), {
|
||||
file: options.sourcePath,
|
||||
|
||||
@@ -45,7 +45,7 @@ var emptyCachedServerDataJson = function () {
|
||||
};
|
||||
|
||||
// Given a connection, makes a call to the package server. (Checks to see if
|
||||
// the connection is connected, and reconnectes if needed -- a workaround for
|
||||
// the connection is connected, and reconnects if needed -- a workaround for
|
||||
// the fact that connections in the tool do not reconnect)
|
||||
exports.callPackageServer = function (conn) {
|
||||
if (!conn.connected) {
|
||||
|
||||
@@ -587,7 +587,27 @@ _.extend(PackageSource.prototype, {
|
||||
// - sources: sources for the plugin (array of string)
|
||||
// - npmDependencies: map from npm package name to required
|
||||
// version (string)
|
||||
_transitional_registerBuildPlugin: function (options) {
|
||||
|
||||
/**
|
||||
* @summary Define a build plugin. A build plugin extends the build
|
||||
* process for apps and packages that use this package. For example,
|
||||
* the `coffeescript` package uses a build plugin to compile CoffeeScript
|
||||
* source files into JavaScript.
|
||||
* @param {Object} [options]
|
||||
* @param {String} options.name A cosmetic name, must be unique in the
|
||||
* package.
|
||||
* @param {String|String[]} options.use Meteor packages that this
|
||||
* plugin uses, independent of the packages specified in
|
||||
* [api.onUse](#PackageAPI-onUse).
|
||||
* @param {String[]} options.sources The source files that make up the
|
||||
* build plugin, independent from [api.addFiles](#PackageAPI-addFiles).
|
||||
* @param {Object} options.npmDependencies An object where the keys
|
||||
* are NPM package names, and the keys are the version numbers of
|
||||
* required NPM packages, just like in [Npm.depends](#Npm-depends).
|
||||
* @memberOf Package
|
||||
* @locus package.js
|
||||
*/
|
||||
registerBuildPlugin: function (options) {
|
||||
// Tests don't have plugins; plugins initialized in the control file
|
||||
// belong to the package and not to the test. (This will be less
|
||||
// confusing in the new control file format).
|
||||
@@ -620,6 +640,13 @@ _.extend(PackageSource.prototype, {
|
||||
self.pluginInfo[options.name] = options;
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated in 0.9.4
|
||||
*/
|
||||
_transitional_registerBuildPlugin: function (options) {
|
||||
this.registerBuildPlugin(options);
|
||||
},
|
||||
|
||||
includeTool: function () {
|
||||
if (!files.inCheckout()) {
|
||||
buildmessage.error("Package.includeTool() can only be used with a " +
|
||||
|
||||
@@ -42,6 +42,10 @@ var Progress = function (options) {
|
||||
self._isDone = false;
|
||||
|
||||
self._selfActive = false;
|
||||
|
||||
// If we're faking progress using the exponential trick, the counter
|
||||
// stores the number of actual ticks
|
||||
self._exponentialCounter = undefined;
|
||||
};
|
||||
|
||||
_.extend(Progress.prototype, {
|
||||
@@ -64,6 +68,30 @@ _.extend(Progress.prototype, {
|
||||
self.reportProgress(state);
|
||||
},
|
||||
|
||||
// For when we don't have a clear idea how long something will take,
|
||||
// (i.e. no end estimate), just call nudge occasionally. We'll build
|
||||
// an exponential progress bar for the task.
|
||||
nudge: function () {
|
||||
var self = this;
|
||||
|
||||
var halfLife = 25;
|
||||
|
||||
var state = _.clone(self._selfState);
|
||||
|
||||
if (!self._exponentialCounter) {
|
||||
self._exponentialCounter = 1;
|
||||
// Arbitrary endpoint
|
||||
state.end = 100;
|
||||
} else {
|
||||
self._exponentialCounter++;
|
||||
}
|
||||
|
||||
var fractionLeft = Math.pow(0.5, self._exponentialCounter / halfLife);
|
||||
state.current = state.end * (1 - fractionLeft);
|
||||
|
||||
self.reportProgress(state);
|
||||
},
|
||||
|
||||
// Tries to determine which is the 'current' job in the tree
|
||||
// This is very heuristical... we use some hints, like:
|
||||
// don't descend into fork-join jobs; we know these execute concurrently,
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
var _ = require('underscore');
|
||||
var Future = require('fibers/future');
|
||||
|
||||
var files = require('./files.js');
|
||||
var release = require('./release.js');
|
||||
|
||||
var buildmessage = require('./buildmessage.js');
|
||||
var fiberHelpers = require('./fiber-helpers.js');
|
||||
var runLog = require('./run-log.js');
|
||||
|
||||
var Console = require('./console.js').Console;
|
||||
|
||||
var Proxy = require('./run-proxy.js').Proxy;
|
||||
var Selenium = require('./run-selenium.js').Selenium;
|
||||
var HttpProxy = require('./run-httpproxy.js').HttpProxy;
|
||||
@@ -106,6 +111,7 @@ _.extend(Runner.prototype, {
|
||||
// XXX leave a pidfile and check if we are already running
|
||||
start: function () {
|
||||
var self = this;
|
||||
|
||||
self.proxy.start();
|
||||
|
||||
// print the banner only once we've successfully bound the port
|
||||
@@ -145,16 +151,19 @@ _.extend(Runner.prototype, {
|
||||
// but all of the ones I tried look terrible in the terminal.
|
||||
if (! self.quiet) {
|
||||
var animationFrame = 0;
|
||||
var printUpdate = function () {
|
||||
runLog.logTemporary("=> Starting MongoDB... " +
|
||||
spinner[animationFrame]);
|
||||
var printUpdate = fiberHelpers.bindEnvironment(function () {
|
||||
//runLog.logTemporary("=> Starting MongoDB... " +
|
||||
// spinner[animationFrame]);
|
||||
buildmessage.nudge();
|
||||
animationFrame = (animationFrame + 1) % spinner.length;
|
||||
};
|
||||
});
|
||||
printUpdate();
|
||||
var mongoProgressTimer = setInterval(printUpdate, 200);
|
||||
}
|
||||
|
||||
self.mongoRunner.start();
|
||||
buildmessage.enterJob({ title: 'Starting MongoDB' }, function () {
|
||||
self.mongoRunner.start();
|
||||
});
|
||||
|
||||
if (! self.quiet) {
|
||||
clearInterval(mongoProgressTimer);
|
||||
@@ -324,6 +333,7 @@ exports.run = function (appDir, options) {
|
||||
|
||||
var runner = new Runner(appDir, runOptions);
|
||||
runner.start();
|
||||
Console.enableProgressBar(false);
|
||||
var result = fut.wait();
|
||||
runner.stop();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
var _ = require('underscore');
|
||||
var uniload = require('./uniload.js');
|
||||
var release = require('./release.js');
|
||||
var Console = require('./console.js').Console;
|
||||
|
||||
// runLog is primarily used by the parts of the tool which run apps locally. It
|
||||
// writes to standard output (and standard error, if rawLogs is set), and allows
|
||||
@@ -64,12 +65,12 @@ _.extend(RunLog.prototype, {
|
||||
|
||||
if (self.consecutiveRestartMessages) {
|
||||
self.consecutiveRestartMessages = null;
|
||||
process.stdout.write("\n");
|
||||
Console.stdout.write("\n");
|
||||
}
|
||||
|
||||
if (self.consecutiveClientRestartMessages) {
|
||||
self.consecutiveClientRestartMessages = null;
|
||||
process.stdout.write("\n");
|
||||
Console.stdout.write("\n");
|
||||
}
|
||||
|
||||
if (self.temporaryMessageLength) {
|
||||
@@ -95,9 +96,9 @@ _.extend(RunLog.prototype, {
|
||||
|
||||
self._clearSpecial();
|
||||
if (self.rawLogs)
|
||||
process[isStderr ? "stderr" : "stdout"].write(line + "\n");
|
||||
Console[isStderr ? "stderr" : "stdout"].write(line + "\n");
|
||||
else
|
||||
process.stdout.write(Log.format(obj, { color: true }) + "\n");
|
||||
Console.stdout.write(Log.format(obj, { color: true }) + "\n");
|
||||
|
||||
// XXX deal with test server logging differently?!
|
||||
},
|
||||
@@ -115,7 +116,7 @@ _.extend(RunLog.prototype, {
|
||||
self._record(obj);
|
||||
|
||||
self._clearSpecial();
|
||||
process.stdout.write(msg + "\n");
|
||||
Console.stdout.write(msg + "\n");
|
||||
},
|
||||
|
||||
// Write a message to the terminal that will get overwritten by the
|
||||
|
||||
@@ -391,6 +391,11 @@ _.extend(Unipackage.prototype, {
|
||||
if (self._pluginsInitialized)
|
||||
return;
|
||||
|
||||
/**
|
||||
* @global
|
||||
* @namespace Plugin
|
||||
* @summary The namespace that is exposed inside build plugin files.
|
||||
*/
|
||||
var Plugin = {
|
||||
// 'extension' is a file extension without the separation dot
|
||||
// (eg 'js', 'coffee', 'coffee.md')
|
||||
@@ -401,6 +406,21 @@ _.extend(Unipackage.prototype, {
|
||||
//
|
||||
// 'handler' is a function that takes a single argument, a
|
||||
// CompileStep (#CompileStep)
|
||||
|
||||
/**
|
||||
* @summary Inside a build plugin source file specified in
|
||||
* [Package.registerBuildPlugin](#Package-registerBuildPlugin),
|
||||
* add a handler to compile files with a certain file extension.
|
||||
* @param {String} fileExtension The file extension that this plugin
|
||||
* should handle, without the first dot.
|
||||
* Examples: `"coffee"`, `"coffee.md"`.
|
||||
* @param {Function} handler A function that takes one argument,
|
||||
* a CompileStep object.
|
||||
*
|
||||
* Documentation for CompileStep is available [on the GitHub Wiki](https://github.com/meteor/meteor/wiki/CompileStep-API-for-Build-Plugin-Source-Handlers).
|
||||
* @memberOf Plugin
|
||||
* @locus Build Plugin
|
||||
*/
|
||||
registerSourceHandler: function (extension, options, handler) {
|
||||
if (!handler) {
|
||||
handler = options;
|
||||
|
||||
Reference in New Issue
Block a user