diff --git a/LICENSE.txt b/LICENSE.txt index b271ca44a4..4c09e63af0 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -795,7 +795,15 @@ Copyright 2012 Irakli Gozalishvili. All rights reserved. ---------- -strip-json-comments: https://github.com/sindresorhus/strip-json-comments +ansi-regex: https://github.com/sindresorhus/ansi-regex +ansi-styles: https://github.com/sindresorhus/ansi-styles +escape-string-regexp: https://github.com/sindresorhus/escape-string-regexp +chalk: https://github.com/sindresorhus/chalk +get-stdin: https://github.com/sindresorhus/get-stdin +has-ansi: https://github.com/sindresorhus/has-ansi +strip-ansi: https://github.com/sindresorhus/strip-ansi +strip-json-comments: https://github.com/sindresorhus/strip-json-comments +supports-color: https://github.com/sindresorhus/supports-color ---------- Copyright (c) Sindre Sorhus (sindresorhus.com) diff --git a/meteor b/meteor index ce4f0a969a..c4edf115f4 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/bin/bash -BUNDLE_VERSION=0.3.53 +BUNDLE_VERSION=0.3.55 # OS Check. Put here because here is where we download the precompiled # bundles that are arch specific. diff --git a/packages/constraint-solver/constraint-solver-tests.js b/packages/constraint-solver/constraint-solver-tests.js index 9b796b4773..7b1f667bb9 100644 --- a/packages/constraint-solver/constraint-solver-tests.js +++ b/packages/constraint-solver/constraint-solver-tests.js @@ -86,8 +86,9 @@ var splitArgs = function (deps) { } else { dependencies.push(dep); } - if (constr) - constraints.push({ packageName: dep, type: (constr.indexOf("=") !== -1 ? "exactly" : "compatible-with"), version: constr.replace("=", "")}); + if (constr) { + constraints.push(PackageVersion.parseConstraint(dep + "@" + constr)); + } }); return {dependencies: dependencies, constraints: constraints}; }; @@ -314,7 +315,7 @@ Tinytest.add("constraint solver - no constraint dependency - anything", function Tinytest.add("constraint solver - no constraint dependency - transitive dep still picked right", function (test) { var versions = defaultResolver.resolve( ["sparkle", "sparky-forms"], - [{ packageName: "sparky-forms", version: "1.1.2", type: "compatible-with" }], + [PackageVersion.parseConstraint("sparky-forms@1.1.2")], { _testing: true }).answer; test.equal(versions.sparkle, "2.1.1"); }); diff --git a/scripts/generate-dev-bundle.sh b/scripts/generate-dev-bundle.sh index 334cfb8d62..e4f96af739 100755 --- a/scripts/generate-dev-bundle.sh +++ b/scripts/generate-dev-bundle.sh @@ -161,6 +161,8 @@ npm install kexec@0.2.0 npm install source-map@0.1.32 npm install browserstack-webdriver@2.41.1 npm install node-inspector@0.7.4 +npm install progress@1.1.8 +npm install chalk@0.5.1 # Clean up a big zip file it leaves behind. npm install phantomjs@1.8.1-1 diff --git a/tools/buildmessage.js b/tools/buildmessage.js index 2795fda314..a3312126eb 100644 --- a/tools/buildmessage.js +++ b/tools/buildmessage.js @@ -297,7 +297,7 @@ var enterJob = function (options, f) { progress = parentProgress.addChildTask(progressOptions); } - currentProgress.withValue(progress, function () { + return currentProgress.withValue(progress, function () { if (!currentMessageSet.get()) { try { return f(); diff --git a/tools/catalog.js b/tools/catalog.js index 24a9540953..eb558a11cd 100644 --- a/tools/catalog.js +++ b/tools/catalog.js @@ -18,7 +18,7 @@ var fiberHelpers = require('./fiber-helpers.js'); var project = require('./project.js'); var Future = require('fibers/future'); var Fiber = require('fibers'); - +var Console = require('./console.js').Console; var catalog = exports; catalog.DEFAULT_TRACK = 'METEOR'; @@ -558,27 +558,36 @@ _.extend(CompleteCatalog.prototype, { if (ret["usedRCs"]) { var expPackages = []; _.each(ret.answer, function(version, package) { - if (version.split('-').length > 1 && - !_.findWhere(constr, - { packageName: package, version: version })) { - expPackages.push({ + if (version.split('-').length > 1) { + if (!(resolverOpts.previousSolution && + resolverOpts.previousSolution[package] === version)) { + var oldConstraints = _.where(constr, { name: package } ); + var printMe = true; + _.each(oldConstraints, function (oC) { + _.each(oC.constraints, function (specOC) { + if (specOC.version === version) { + printMe = false; + } + }); + }); + if (printMe) { + expPackages.push({ name: " " + package + "@" + version, description: self.getVersion(package, version).description }); - } + }; + }} }); if (!_.isEmpty(expPackages)) { // XXX: Couldn't figure out how to word this better for better tenses. - process.stderr.write( - "------------------------------------------------------------ \n"); - process.stderr.write( - "In order to resolve constraints, we had to use the following\n"+ - "experimental package versions:\n"); - process.stderr.write(utils.formatList(expPackages)); - process.stderr.write( - "------------------------------------------------------------ \n"); - - process.stderr.write("\n"); + // + // XXX: this shouldn't be here. This is library code... it + // shouldn't be printing. + // https://github.com/meteor/meteor/wiki/Meteor-Style-Guide#only-user-interface-code-should-engage-with-the-user + Console.info( + "\nIn order to resolve constraints, we had to use the following\n"+ + "experimental package versions:"); + Console.info(utils.formatList(expPackages)); } } return ret.answer; diff --git a/tools/commands-packages.js b/tools/commands-packages.js index 3f8317f398..bbd1b1593b 100644 --- a/tools/commands-packages.js +++ b/tools/commands-packages.js @@ -142,6 +142,7 @@ main.registerCommand({ main.registerCommand({ name: 'publish', + pretty: true, minArgs: 0, maxArgs: 0, options: { @@ -278,7 +279,7 @@ main.registerCommand({ if (_.any(allArchs, function (arch) { return arch.match(/^os\./); })) { - Console.warning( + Console.warn( "\nWARNING: Your package contains binary code and is only compatible with " + archinfo.host() + " architecture.\n" + "Please use publish-for-arch to publish new builds of the package.\n"); @@ -744,7 +745,7 @@ main.registerCommand({ name: item }); if (buildmessage.jobHasMessages()) { - Console.warning("\n ...Error reading package:" + item); + Console.warn("\n ...Error reading package:" + item); canBuild = false; return; }; @@ -770,7 +771,7 @@ main.registerCommand({ var compileResult = compiler.compile(packageSource, { officialBuild: true }); if (buildmessage.jobHasMessages()) { - Console.warning("\n ... Error compiling unipackage: " + item ); + Console.warn("\n ... Error compiling unipackage: " + item ); canBuild = false; return; }; @@ -801,7 +802,7 @@ main.registerCommand({ "at the end (ex: 1.0.0-dev). If this is an " + "official release, please set official to true " + "in the release configuration file."); - Console.warning("NOT OK unofficial"); + Console.warn("NOT OK unofficial"); return; } toPublish[item] = {source: packageSource, @@ -1357,9 +1358,10 @@ main.registerCommand({ if (newVersionsAvailable) { Console.info( - "\n * New versions of these packages are available! " + - "Run 'meteor update' to try to update\n" + - " those packages to their latest versions."); +"\n * New versions of these packages are available! Run 'meteor update' to try\n" + +" to update those packages to their latest versions. If your packages cannot be\n" + +" updated further, try typing meteor add @ to see more\n" + +" information."); } return 0; }); @@ -1750,7 +1752,7 @@ main.registerCommand({ // specified, then only upgrade those. var upgradePackages; if (options.args.length === 0) { - upgradePackages = _.pluck(allPackages, 'packageName'); + upgradePackages = _.pluck(allPackages, 'name'); } else { upgradePackages = options.args; } @@ -1774,7 +1776,7 @@ main.registerCommand({ // Just for the sake of good messages, check to see if anything changed. if (_.isEqual(newVersions, versions)) { - Console.info("All your package dependencies are already up to date."); + Console.info("Your packages are at their latest compatible versions."); return 0; } @@ -2222,7 +2224,13 @@ main.registerCommand({ record = fullRecord.record; } - Console.info("\n The maintainers for " + name + " are:"); + if (!record) { + Console.info( +"Could not get list of maintainers: package " + name + " does not exist."); + return 1; + } + + Console.info("\nThe maintainers for " + name + " are:"); _.each(record.maintainers, function (user) { if (! user || !user.username) Console.info(""); diff --git a/tools/config.js b/tools/config.js index 7afb812b79..2ce4418977 100644 --- a/tools/config.js +++ b/tools/config.js @@ -217,10 +217,15 @@ _.extend(exports, { self.getLocalPackageCacheFilename()); }, + // XXX this does not appear to be called. getPackageStorageVersion: function() { return "1.0"; }, + // NOTE: Uses the v1 directory, not v1.1 like package-metadata. This + // is so that we don't double-print banners and the like. Someday we + // should unifiy these so that the tool doesn't have to write to + // multiple different versions of these directories. getBannersShownFilename: function() { return path.join(tropohouse.default.root, "package-metadata", "v1.1", "banners-shown.json"); diff --git a/tools/console.js b/tools/console.js index 648de8fe86..85eb497571 100644 --- a/tools/console.js +++ b/tools/console.js @@ -9,6 +9,7 @@ var ProgressBar = require('progress'); var buildmessage = require('./buildmessage.js'); // XXX: Are we happy with chalk (and its sub-dependencies)? var chalk = require('chalk'); +var cleanup = require('./cleanup.js'); PROGRESS_DEBUG = !!process.env.METEOR_PROGRESS_DEBUG; FORCE_PRETTY=undefined; @@ -40,6 +41,10 @@ var Console = function (options) { self._stream = process.stdout; self._pretty = (FORCE_PRETTY !== undefined ? FORCE_PRETTY : false); + + cleanup.onExit(function (sig) { + self.hideProgressBar(); + }); }; @@ -194,16 +199,24 @@ _.extend(Console.prototype, { } var dest = process.stdout; - var style = null; - - if (level && self._pretty) { + if (level) { switch (level.code) { case LEVEL_CODE_ERROR: dest = process.stderr; - style = chalk.bold.red; break; case LEVEL_CODE_WARN: dest = process.stderr; + break; + } + } + + var style = null; + if (level && self._pretty) { + switch (level.code) { + case LEVEL_CODE_ERROR: + style = chalk.bold.red; + break; + case LEVEL_CODE_WARN: style = chalk.red; break; //case LEVEL_CODE_INFO: @@ -311,6 +324,6 @@ _.extend(Console.prototype, { }); -Console.warning = Console.warn; +Console.prototype.warning = Console.prototype.warn; exports.Console = new Console; \ No newline at end of file diff --git a/tools/package-client.js b/tools/package-client.js index 10a5afdcf1..59cf1911cf 100644 --- a/tools/package-client.js +++ b/tools/package-client.js @@ -12,6 +12,7 @@ var utils = require('./utils.js'); var buildmessage = require('./buildmessage.js'); var compiler = require('./compiler.js'); var uniload = require('./uniload.js'); +var Console = require('./console.js').Console; // Use uniload to load the packages that we need to open a connection to the // current package server and use minimongo in memory. We need the following @@ -82,7 +83,7 @@ exports.loadCachedServerData = function (packageStorageFile) { } // XXX we should probably return an error to the caller here to // figure out how to handle it - process.stderr.write("ERROR " + e.message + "\n"); + Console.stderr.write("ERROR " + e.message + "\n"); process.exit(1); } var ret = noDataToken; @@ -90,7 +91,7 @@ exports.loadCachedServerData = function (packageStorageFile) { ret = JSON.parse(data); } catch (err) { // XXX error handling - process.stderr.write( + Console.stderr.write( "ERROR: Could not parse JSON for local package-metadata cache. \n"); // This should only happen if you decided to manually edit this or // whatever. Regardless, go on and treat this as an empty file. @@ -323,7 +324,7 @@ exports.loggedInPackagesConnection = function () { if (! auth.isLoggedIn()) { // XXX we should have a better account signup page. - process.stderr.write( + Console.stderr.write( "Please log in with your Meteor developer account. If you don't have one,\n" + "you can quickly create one at www.meteor.com.\n"); auth.doUsernamePasswordLogin({ retry: true }); @@ -345,7 +346,7 @@ exports.loggedInPackagesConnection = function () { if (err.message === "access-denied") { // Maybe we thought we were logged in, but our token had been // revoked. - process.stderr.write( + Console.stderr.write( "It looks like you have been logged out! Please log in with your Meteor\n" + "developer account. If you don't have one, you can quickly create one\n" + "at www.meteor.com.\n"); @@ -385,7 +386,7 @@ var bundleSource = function (unipackage, includeSources, packageDir) { name ); if (! files.mkdir_p(sourcePackageDir)) { - process.stderr.write('Failed to create temporary source directory: ' + + Console.stderr.write('Failed to create temporary source directory: ' + sourcePackageDir); return null; } @@ -496,12 +497,12 @@ var createAndPublishBuiltPackage = function (conn, unipackage) { // Note: we really want to do this before createPackageBuild, because the URL // we get from createPackageBuild will expire! - process.stdout.write('Bundling build...\n'); + Console.stdout.write('Bundling build...\n'); var bundleResult = bundleBuild(unipackage); if (buildmessage.jobHasMessages()) return; - process.stdout.write('Creating package build...\n'); + Console.stdout.write('Creating package build...\n'); var uploadInfo = exports.callPackageServer(conn, 'createPackageBuild', { packageName: unipackage.name, @@ -509,21 +510,21 @@ var createAndPublishBuiltPackage = function (conn, unipackage) { buildArchitectures: unipackage.buildArchitectures() }); - process.stdout.write('Uploading build...\n'); + Console.stdout.write('Uploading build...\n'); uploadTarball(uploadInfo.uploadUrl, bundleResult.buildTarball); - process.stdout.write('Publishing package build...\n'); + Console.stdout.write('Publishing package build...\n'); exports.callPackageServer(conn, 'publishPackageBuild', uploadInfo.uploadToken, bundleResult.tarballHash, bundleResult.treeHash); - process.stdout.write('Published ' + unipackage.name + + Console.stdout.write('Published ' + unipackage.name + ', version ' + unipackage.version); - process.stdout.write('\nDone!\n'); + Console.stdout.write('\nDone!\n'); }; exports.createAndPublishBuiltPackage = createAndPublishBuiltPackage; @@ -532,13 +533,13 @@ exports.handlePackageServerConnectionError = function (error) { if (error instanceof AlreadyPrintedMessageError) { // do nothing } else if (error.errorType === 'Meteor.Error') { - process.stderr.write("Error from package server"); + Console.stderr.write("Error from package server"); if (error.message) { - process.stderr.write(": " + error.message); + Console.stderr.write(": " + error.message); } - process.stderr.write("\n"); + Console.stderr.write("\n"); } else if (error.errorType === "DDP.ConnectionError") { - process.stderr.write("Error connecting to package server: " + Console.stderr.write("Error connecting to package server: " + error.message + "\n"); } else { throw error; @@ -577,13 +578,13 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) } catch (e) { if (!e.versionParserError) throw e; - process.stderr.write(e.error + "\n"); + Console.stderr.write(e.error + "\n"); return 1; } // Check that we have a version. if (! version) { - process.stderr.write( + Console.stderr.write( "That package cannot be published because it doesn't have a version.\n"); return 1; } @@ -592,15 +593,15 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) // all string limits on the server, but this is the one that is mostly likely // to be wrong) if (!packageSource.metadata.summary) { - process.stderr.write("Please describe what your package does. \n"); - process.stderr.write("Set a summary in Package.describe in package.js. \n"); + Console.stderr.write("Please describe what your package does. \n"); + Console.stderr.write("Set a summary in Package.describe in package.js. \n"); return 1; } if (packageSource.metadata.summary && packageSource.metadata.summary.length > 100) { - process.stderr.write("Description must be under 100 chars. \n"); - process.stderr.write("Publish failed. \n"); + Console.stderr.write("Description must be under 100 chars. \n"); + Console.stderr.write("Publish failed. \n"); return 1; } @@ -610,15 +611,15 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) if (!options['new']) { var packRecord = catalog.official.getPackage(name); if (!packRecord) { - process.stderr.write('There is no package named ' + name + + Console.stderr.write('There is no package named ' + name + '. If you are creating a new package, use the --create flag. \n'); - process.stderr.write("Publish failed. \n"); + Console.stderr.write("Publish failed. \n"); return 1; } if (!exports.amIAuthorized(name, conn, false)) { - process.stderr.write('You are not an authorized maintainer of ' + name + ".\n"); - process.stderr.write('Only authorized maintainers may publish new versions. \n'); + Console.stderr.write('You are not an authorized maintainer of ' + name + ".\n"); + Console.stderr.write('Only authorized maintainers may publish new versions. \n'); return 1; } } @@ -641,12 +642,11 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) // then we should force the user to specify them. This is because we are not // sure about pre-0.90 package versions yet. if (!packageSource.isCore && !_.isEqual(badConstraints, [])) { - process.stderr.write( + Console.stderr.write( "You must specify a version constraint for the following packages:"); _.each(badConstraints, function(bad) { - process.stderr.write(" " + bad); + Console.stderr.write(" " + bad); }); - process.stderr.write(". \n" ); process.exit(1); } @@ -676,11 +676,11 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) }); if (messages.hasMessages()) { - process.stderr.write(messages.formatMessages()); + Console.stderr.write(messages.formatMessages()); return 1; } - process.stdout.write('Bundling source...\n'); + Console.stdout.write('Bundling source...\n'); var sources = _.union(compileResult.sources, testFiles); @@ -697,14 +697,14 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) // Create the package. Check that the metadata exists. if (options.new) { - process.stdout.write('Creating package...\n'); + Console.stdout.write('Creating package...\n'); try { var packageId = exports.callPackageServer(conn, 'createPackage', { name: packageSource.name }); } catch (err) { - process.stderr.write(err.message + "\n"); + Console.stderr.write(err.message + "\n"); return 3; } @@ -713,18 +713,18 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) if (options.existingVersion) { var existingRecord = catalog.official.getVersion(name, version); if (!existingRecord) { - process.stderr.write("Version does not exist.\n"); + Console.stderr.write("Version does not exist.\n"); return 1; } if (existingRecord.source.treeHash !== sourceBundleResult.treeHash) { - process.stderr.write( + Console.stderr.write( "Package source differs from the existing version.\n"); return 1; } // XXX check that we're actually providing something new? } else { - process.stdout.write('Creating package version...\n'); + Console.stdout.write('Creating package version...\n'); var uploadRec = { packageName: packageSource.name, @@ -740,7 +740,7 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) var uploadInfo = exports.callPackageServer(conn, 'createPackageVersion', uploadRec); } catch (err) { - process.stderr.write("ERROR " + err.message + "\n"); + Console.stderr.write("ERROR " + err.message + "\n"); return 3; } @@ -748,10 +748,10 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) // telling them to try 'meteor publish-for-arch' if they want to // publish a new build. - process.stdout.write('Uploading source...\n'); + Console.stdout.write('Uploading source...\n'); uploadTarball(uploadInfo.uploadUrl, sourceBundleResult.sourceTarball); - process.stdout.write('Publishing package version...\n'); + Console.stdout.write('Publishing package version...\n'); try { exports.callPackageServer(conn, 'publishPackageVersion', @@ -759,7 +759,7 @@ exports.publishPackage = function (packageSource, compileResult, conn, options) { tarballHash: sourceBundleResult.tarballHash, treeHash: sourceBundleResult.treeHash }); } catch (err) { - process.stderr.write("ERROR " + err.message + "\n"); + Console.stderr.write("ERROR " + err.message + "\n"); return 3; } diff --git a/tools/package-source.js b/tools/package-source.js index fdc0210528..52e9cdab2d 100644 --- a/tools/package-source.js +++ b/tools/package-source.js @@ -1297,6 +1297,7 @@ _.extend(PackageSource.prototype, { newConstraint.push(dep.package); } }); + if (_.isEmpty(newConstraint)) return dep; dep.constraint = _.reduce(newConstraint, function(x, y) { return x + " || " + y; diff --git a/tools/selftest.js b/tools/selftest.js index fe8652dc61..2e2276d12f 100644 --- a/tools/selftest.js +++ b/tools/selftest.js @@ -637,6 +637,7 @@ _.extend(Sandbox.prototype, { var packagesDirectoryName = config.getPackagesDirectoryName(serverUrl); files.mkdir_p(path.join(self.warehouse, packagesDirectoryName), 0755); files.mkdir_p(path.join(self.warehouse, 'package-metadata', 'v1'), 0755); + files.mkdir_p(path.join(self.warehouse, 'package-metadata', 'v1.1'), 0755); var stubCatalog = { syncToken: {}, @@ -782,7 +783,7 @@ _.extend(Sandbox.prototype, { var dataFile = config.getLocalPackageCacheFilename(serverUrl); fs.writeFileSync( - path.join(self.warehouse, 'package-metadata', 'v1', dataFile), + path.join(self.warehouse, 'package-metadata', 'v1.1', dataFile), JSON.stringify(stubCatalog, null, 2)); // And a cherry on top diff --git a/tools/tests/autoupdate.js b/tools/tests/autoupdate.js index 130fed5b9b..29cae921f2 100644 --- a/tools/tests/autoupdate.js +++ b/tools/tests/autoupdate.js @@ -7,7 +7,7 @@ var Sandbox = selftest.Sandbox; var editPackageMetadata = function (sandbox, f) { var dataFile = path.join(sandbox.warehouse, - 'package-metadata', 'v1', + 'package-metadata', 'v1.1', config.getLocalPackageCacheFilename()); var data = JSON.parse(fs.readFileSync(dataFile, 'utf8')); f(data); @@ -143,7 +143,7 @@ selftest.define("autoupdate", ['checkout'], function () { run = s.run("update"); run.read("myapp: updated to Meteor v3."); - run.match("All your package dependencies are already up to date.\n"); + run.match("Your packages are at their latest compatible versions.\n"); run.expectEnd(); run.expectExit(0); diff --git a/tools/tests/cordova-platforms.js b/tools/tests/cordova-platforms.js index 6073f350ae..f45f1608b4 100644 --- a/tools/tests/cordova-platforms.js +++ b/tools/tests/cordova-platforms.js @@ -58,6 +58,9 @@ selftest.define("add cordova platforms", function () { run.expectExit(1); run = s.run("add-platform", "android"); + run.match("Do you agree"); + run.write("Y\n"); + run.extraTime = 90; // Huge download run.match("added"); run = s.run("remove-platform", "foo"); diff --git a/tools/tests/cordova-plugins.js b/tools/tests/cordova-plugins.js index 9317219fb8..f0a1654102 100644 --- a/tools/tests/cordova-plugins.js +++ b/tools/tests/cordova-plugins.js @@ -150,7 +150,9 @@ selftest.define("add cordova plugins", ["slow"], function () { run.matchErr("meteor add-platform "); run = s.run("add-platform", "android"); - run.waitSecs(5); + run.match("Do you agree"); + run.write("Y\n"); + run.extraTime = 90; // Huge download run.match("added platform"); run = s.run("add", "cordova:org.apache.cordova.camera@0.3.0"); diff --git a/tools/tests/hot-code-push.js b/tools/tests/hot-code-push.js index 09f65dd46a..57c595c1fb 100644 --- a/tools/tests/hot-code-push.js +++ b/tools/tests/hot-code-push.js @@ -6,6 +6,11 @@ var net = require('net'); var _ = require('underscore'); var files = require('../files.js'); +// XXX: Remove me. This shouldn't be neeeded, but sometimes +// if we run too quickly on fast (or Linux?) machines, we get +// 'stuck' +HACK_DELAY = 3; + selftest.define("css hot code push", function (options) { var s = new Sandbox({ clients: options.clients @@ -74,6 +79,7 @@ selftest.define("css hot code push", function (options) { run.match("numCssChanges: 1"); run.match(/background-color: (red|rgb\(255, 0, 0\))/); + run.waitSecs(HACK_DELAY); s.write(".meteor/packages", "standard-app-packages"); run.match("removed my-package"); run.match("numCssChanges: 0"); @@ -132,25 +138,30 @@ selftest.define("javascript hot code push", function (options) { // The server and client both restart if a shared js file is added // or removed. + run.waitSecs(HACK_DELAY); s.write("test.js", "jsVar = 'foo'"); run.match("server restarted"); run.match("client connected: 0"); run.match("jsVar: foo"); run.match("sessionVar: true"); + run.waitSecs(HACK_DELAY); s.unlink("test.js"); run.match("server restarted"); run.match("client connected: 0"); run.match("jsVar: undefined"); + // Only the client should refresh if a client js file is added. Thus, // "client connected" variable will be incremented. + run.waitSecs(HACK_DELAY); s.mkdir("client"); s.write("client/test.js", "jsVar = 'bar'"); run.match("client connected: 1"); run.match("jsVar: bar"); + run.waitSecs(HACK_DELAY); s.unlink("client/test.js"); run.match("client connected: 2"); run.match("jsVar: undefined"); @@ -158,15 +169,18 @@ selftest.define("javascript hot code push", function (options) { // When we change a server file the client should not refresh. We observe // this by changing a server file and then a client file and verifying // that the client has only connected once. + run.waitSecs(HACK_DELAY); s.mkdir("server"); s.write("server/test.js", "jsVar = 'bar'"); run.match("server restarted"); + run.waitSecs(HACK_DELAY); s.write("client/empty.js", ""); run.match("client connected: 0"); // We should not be able to access a server variable from the client. run.match("jsVar: undefined"); + run.waitSecs(HACK_DELAY); s.unlink("client/empty.js"); run.waitSecs(5); run.match("client connected: 1"); @@ -177,19 +191,23 @@ selftest.define("javascript hot code push", function (options) { // it only affects the client. But this is a regression test for a bug where // fixing the HTML file wouldn't actually restart the server; that's the // important part of this test.) + run.waitSecs(HACK_DELAY); s.write("hot-code-push-test.html", ">"); run.match("Errors prevented startup"); run.match("bad formatting in HTML template"); // Fix it. It should notice, and restart. The client will restart too. + run.waitSecs(HACK_DELAY); s.write("hot-code-push-test.html", ""); run.match("server restarted"); run.match("client connected: 0"); // Write something else to it. The client should restart. + run.waitSecs(HACK_DELAY); s.write("hot-code-push-test.html", "foo"); run.match("Client modified -- refreshing"); run.match("client connected: 1"); run.match("jsVar: undefined"); + run.waitSecs(HACK_DELAY); s.write(".meteor/packages", "standard-app-packages \n my-package"); run.match("added my-package"); run.match("server restarted"); @@ -197,28 +215,33 @@ selftest.define("javascript hot code push", function (options) { run.match("jsVar: undefined"); run.match("packageVar: foo"); + run.waitSecs(HACK_DELAY); s.write("packages/my-package/foo.js", "packageVar = 'bar'"); run.match("client connected: 1"); run.match("jsVar: undefined"); run.match("packageVar: bar"); // Add appcache and ensure that the browser still reloads. + run.waitSecs(HACK_DELAY); s.write(".meteor/packages", "standard-app-packages \n appcache"); run.match("added appcache"); run.match("server restarted"); run.match("client connected: 0"); run.match("jsVar: undefined"); + run.waitSecs(HACK_DELAY); s.write("client/test.js", "jsVar = 'bar'"); run.match("client connected: 1"); run.match("jsVar: bar"); // Remove appcache and ensure that the browser still reloads. + run.waitSecs(HACK_DELAY); s.write(".meteor/packages", "standard-app-packages"); run.match("removed appcache"); run.match("server restarted"); run.match("client connected: 0"); + run.waitSecs(HACK_DELAY); s.write("client/test.js", "jsVar = 'baz'"); run.match("client connected: 1"); run.match("jsVar: baz"); @@ -227,12 +250,14 @@ selftest.define("javascript hot code push", function (options) { // Setting the autoupdateVersion to a different string should also // force the client to restart. + run.waitSecs(HACK_DELAY); s.write("server/test.js", "Package.autoupdate.Autoupdate.autoupdateVersion = 'random'"); run.match("server restarted"); run.match("client connected: 0"); run.match("jsVar: undefined"); + run.waitSecs(HACK_DELAY); s.unlink("server/test.js"); run.match("server restarted"); diff --git a/tools/tests/run.js b/tools/tests/run.js index c64d99940e..adf08a3561 100644 --- a/tools/tests/run.js +++ b/tools/tests/run.js @@ -217,7 +217,7 @@ selftest.define("run errors", function () { // This time, prevent the proxy from starting. (This time, leaving out the // interface name matches.) f = new Future; - server = net.createServer().listen(proxyPort, 'localhost', f.resolver()); + server = net.createServer().listen(proxyPort, f.resolver()); f.wait(); run = s.run("-p", proxyPort); diff --git a/tools/utils.js b/tools/utils.js index 6de1de2ca1..851f28da12 100644 --- a/tools/utils.js +++ b/tools/utils.js @@ -519,7 +519,7 @@ exports.Patience = function (options) { typeof(options.message) !== 'function') { throw Error("message must be string or function"); } - self._message = options.message; + self._message = "\n" + options.message; self._whenMessage = now + options.messageAfterMs; self._messageTimeout = setTimeout(function () { self._messageTimeout = null;