mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Progress bars and output formatting
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fibers": "1.0.1",
|
"fibers": "1.0.1",
|
||||||
|
"progress": "1.1.8",
|
||||||
|
"chalk": "0.5.1",
|
||||||
"underscore": "1.5.2",
|
"underscore": "1.5.2",
|
||||||
"source-map-support": "0.2.5",
|
"source-map-support": "0.2.5",
|
||||||
"semver": "2.2.1"
|
"semver": "2.2.1"
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
var Fiber = require('fibers');
|
||||||
|
var Future = require('fibers/future');
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
var files = require('./files.js');
|
var files = require('./files.js');
|
||||||
var parseStack = require('./parse-stack.js');
|
var parseStack = require('./parse-stack.js');
|
||||||
var fiberHelpers = require('./fiber-helpers.js');
|
var fiberHelpers = require('./fiber-helpers.js');
|
||||||
|
var Progress = require('./progress.js').Progress;
|
||||||
|
|
||||||
var debugBuild = !!process.env.METEOR_DEBUG_BUILD;
|
var debugBuild = !!process.env.METEOR_DEBUG_BUILD;
|
||||||
|
|
||||||
@@ -154,9 +157,46 @@ _.extend(MessageSet.prototype, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// XXX: This is now a little bit silly... ideas:
|
||||||
|
// Can we just have one hierarchical state?
|
||||||
|
// Can we combined job & messageSet
|
||||||
|
// Can we infer nesting level?
|
||||||
var currentMessageSet = new fiberHelpers.EnvironmentVariable;
|
var currentMessageSet = new fiberHelpers.EnvironmentVariable;
|
||||||
var currentJob = new fiberHelpers.EnvironmentVariable;
|
var currentJob = new fiberHelpers.EnvironmentVariable;
|
||||||
var currentNestingLevel = new fiberHelpers.EnvironmentVariable(0);
|
var currentNestingLevel = new fiberHelpers.EnvironmentVariable(0);
|
||||||
|
var currentProgress = new fiberHelpers.EnvironmentVariable;
|
||||||
|
|
||||||
|
var rootProgress = new Progress();
|
||||||
|
|
||||||
|
var getRootProgress = function () {
|
||||||
|
return rootProgress;
|
||||||
|
};
|
||||||
|
|
||||||
|
var reportProgress = function (state) {
|
||||||
|
var progress = currentProgress.get();
|
||||||
|
if (progress) {
|
||||||
|
progress.reportProgress(state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var reportProgressDone = function () {
|
||||||
|
var progress = currentProgress.get();
|
||||||
|
if (progress) {
|
||||||
|
progress.reportProgressDone();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var getCurrentProgressTracker = function () {
|
||||||
|
var progress = currentProgress.get();
|
||||||
|
return progress ? progress : rootProgress;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var addChildTracker = function (title) {
|
||||||
|
var options = {};
|
||||||
|
options.title = title;
|
||||||
|
return getCurrentProgressTracker().addChildTask(options);
|
||||||
|
};
|
||||||
|
|
||||||
// Create a new MessageSet, run `f` with that as the current
|
// Create a new MessageSet, run `f` with that as the current
|
||||||
// MessageSet for the purpose of accumulating and recovering from
|
// MessageSet for the purpose of accumulating and recovering from
|
||||||
@@ -169,24 +209,51 @@ var currentNestingLevel = new fiberHelpers.EnvironmentVariable(0);
|
|||||||
// `options`.
|
// `options`.
|
||||||
var capture = function (options, f) {
|
var capture = function (options, f) {
|
||||||
var messageSet = new MessageSet;
|
var messageSet = new MessageSet;
|
||||||
currentMessageSet.withValue(messageSet, function () {
|
var parentMessageSet = currentMessageSet.get();
|
||||||
var job = null;
|
|
||||||
if (typeof options === "object") {
|
|
||||||
job = new Job(options);
|
|
||||||
messageSet.jobs.push(job);
|
|
||||||
} else {
|
|
||||||
f = options; // options not actually provided
|
|
||||||
}
|
|
||||||
|
|
||||||
currentJob.withValue(job, function () {
|
{
|
||||||
var nestingLevel = currentNestingLevel.get();
|
var parentProgress = currentProgress.get();
|
||||||
currentNestingLevel.withValue(nestingLevel + 1, function () {
|
if (!parentProgress) {
|
||||||
debugBuild && console.log("START CAPTURE", nestingLevel, options.title);
|
parentProgress = rootProgress;
|
||||||
try {
|
}
|
||||||
f();
|
var childOptions = {};
|
||||||
} finally {
|
if (typeof options === "object") {
|
||||||
debugBuild && console.log("END CAPTURE", nestingLevel, options.title);
|
if (options.title) {
|
||||||
}
|
childOptions.title = options.title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var progress = parentProgress.addChildTask(childOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentProgress.withValue(progress, function () {
|
||||||
|
currentMessageSet.withValue(messageSet, function () {
|
||||||
|
var job = null;
|
||||||
|
if (typeof options === "object") {
|
||||||
|
job = new Job(options);
|
||||||
|
messageSet.jobs.push(job);
|
||||||
|
} else {
|
||||||
|
f = options; // options not actually provided
|
||||||
|
}
|
||||||
|
|
||||||
|
currentJob.withValue(job, function () {
|
||||||
|
var nestingLevel = currentNestingLevel.get();
|
||||||
|
currentNestingLevel.withValue(nestingLevel + 1, function () {
|
||||||
|
var start;
|
||||||
|
if (debugBuild) {
|
||||||
|
start = Date.now();
|
||||||
|
console.log("START CAPTURE", nestingLevel, options.title, "took " + (end - start));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} finally {
|
||||||
|
progress.reportProgressDone();
|
||||||
|
|
||||||
|
if (debugBuild) {
|
||||||
|
var end = Date.now();
|
||||||
|
console.log("END CAPTURE", nestingLevel, options.title, "took " + (end - start));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -211,24 +278,57 @@ var enterJob = function (options, f) {
|
|||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! currentMessageSet.get()) {
|
var progress;
|
||||||
return f();
|
{
|
||||||
|
var parentProgress = currentProgress.get();
|
||||||
|
if (!parentProgress) {
|
||||||
|
parentProgress = rootProgress;
|
||||||
|
}
|
||||||
|
var progressOptions = {};
|
||||||
|
// XXX: Just pass all the options?
|
||||||
|
if (typeof options === "object") {
|
||||||
|
if (options.title) {
|
||||||
|
progressOptions.title = options.title;
|
||||||
|
}
|
||||||
|
if (options.forkJoin) {
|
||||||
|
progressOptions.forkJoin = options.forkJoin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
progress = parentProgress.addChildTask(progressOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
var job = new Job(options);
|
currentProgress.withValue(progress, function () {
|
||||||
var originalJob = currentJob.get();
|
if (!currentMessageSet.get()) {
|
||||||
originalJob && originalJob.children.push(job);
|
|
||||||
currentMessageSet.get().jobs.push(job);
|
|
||||||
|
|
||||||
return currentJob.withValue(job, function () {
|
|
||||||
var nestingLevel = currentNestingLevel.get();
|
|
||||||
return currentNestingLevel.withValue(nestingLevel + 1, function () {
|
|
||||||
debugBuild && console.log("START", nestingLevel, options.title);
|
|
||||||
try {
|
try {
|
||||||
return f();
|
return f();
|
||||||
} finally {
|
} finally {
|
||||||
debugBuild && console.log("DONE", nestingLevel, options.title);
|
progress.reportProgressDone();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var job = new Job(options);
|
||||||
|
var originalJob = currentJob.get();
|
||||||
|
originalJob && originalJob.children.push(job);
|
||||||
|
currentMessageSet.get().jobs.push(job);
|
||||||
|
|
||||||
|
return currentJob.withValue(job, function () {
|
||||||
|
var nestingLevel = currentNestingLevel.get();
|
||||||
|
return currentNestingLevel.withValue(nestingLevel + 1, function () {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -366,6 +466,74 @@ var assertInCapture = function () {
|
|||||||
throw new Error("Expected to be in a buildmessage capture");
|
throw new Error("Expected to be in a buildmessage capture");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Like _.each, but runs each operation in a separate job
|
||||||
|
var forkJoin = function (options, iterable, fn) {
|
||||||
|
if (!_.isFunction(fn)) {
|
||||||
|
fn = iterable;
|
||||||
|
iterable = options;
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var futures = [];
|
||||||
|
var results = [];
|
||||||
|
// XXX: We could check whether the sub-jobs set estimates, and if not
|
||||||
|
// assume they each take the same amount of time and auto-report their completion
|
||||||
|
var errors = [];
|
||||||
|
var firstError = null;
|
||||||
|
|
||||||
|
options.forkJoin = true;
|
||||||
|
|
||||||
|
enterJob(options, function () {
|
||||||
|
var job = currentJob.get();
|
||||||
|
var messageSet = currentMessageSet.get();
|
||||||
|
var progress = currentProgress.get();
|
||||||
|
|
||||||
|
_.each(iterable, function (/*arguments*/) {
|
||||||
|
var fut = new Future();
|
||||||
|
var fnArguments = arguments;
|
||||||
|
Fiber(function () {
|
||||||
|
currentProgress.withValue(progress, function () {
|
||||||
|
currentMessageSet.withValue(messageSet, function () {
|
||||||
|
currentJob.withValue(job, function () {
|
||||||
|
try {
|
||||||
|
var result = enterJob({title: (options.title || '') + ' child' }, function () {
|
||||||
|
return fn.apply(null, fnArguments);
|
||||||
|
});
|
||||||
|
fut['return'](result);
|
||||||
|
} catch (e) {
|
||||||
|
fut['throw'](e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).run();
|
||||||
|
futures.push(fut);
|
||||||
|
});
|
||||||
|
|
||||||
|
_.each(futures, function (future) {
|
||||||
|
try {
|
||||||
|
var result = future.wait();
|
||||||
|
results.push(result);
|
||||||
|
errors.push(null);
|
||||||
|
} catch (e) {
|
||||||
|
results.push(null);
|
||||||
|
errors.push(e);
|
||||||
|
|
||||||
|
if (firstError === null) {
|
||||||
|
firstError = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (firstError) {
|
||||||
|
throw firstError;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var buildmessage = exports;
|
var buildmessage = exports;
|
||||||
_.extend(exports, {
|
_.extend(exports, {
|
||||||
capture: capture,
|
capture: capture,
|
||||||
@@ -375,5 +543,11 @@ _.extend(exports, {
|
|||||||
exception: exception,
|
exception: exception,
|
||||||
jobHasMessages: jobHasMessages,
|
jobHasMessages: jobHasMessages,
|
||||||
assertInJob: assertInJob,
|
assertInJob: assertInJob,
|
||||||
assertInCapture: assertInCapture
|
assertInCapture: assertInCapture,
|
||||||
|
forkJoin: forkJoin,
|
||||||
|
getRootProgress: getRootProgress,
|
||||||
|
reportProgress: reportProgress,
|
||||||
|
reportProgressDone: reportProgressDone,
|
||||||
|
getCurrentProgressTracker: getCurrentProgressTracker,
|
||||||
|
addChildTracker: addChildTracker
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -138,16 +138,11 @@ _.extend(OfficialCatalog.prototype, {
|
|||||||
self._refreshFiber = Fiber.current;
|
self._refreshFiber = Fiber.current;
|
||||||
self._currentRefreshIsLoud = !options.silent;
|
self._currentRefreshIsLoud = !options.silent;
|
||||||
|
|
||||||
var patience = new utils.Patience({
|
var thrownError = null;
|
||||||
messageAfterMs: 2000,
|
|
||||||
message: function () {
|
buildmessage.enterJob({
|
||||||
if (self._currentRefreshIsLoud) {
|
title: 'Refreshing package metadata.'
|
||||||
console.log("Refreshing package metadata. This may take a moment.");
|
}, function () {
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try {
|
|
||||||
var thrownError = null;
|
|
||||||
try {
|
try {
|
||||||
self._refresh();
|
self._refresh();
|
||||||
// Force the complete catalog (which is layered on top of our data) to
|
// Force the complete catalog (which is layered on top of our data) to
|
||||||
@@ -156,9 +151,7 @@ _.extend(OfficialCatalog.prototype, {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
thrownError = e;
|
thrownError = e;
|
||||||
}
|
}
|
||||||
} finally {
|
});
|
||||||
patience.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (self._refreshFutures.length) {
|
while (self._refreshFutures.length) {
|
||||||
var fut = self._refreshFutures.pop();
|
var fut = self._refreshFutures.pop();
|
||||||
@@ -897,9 +890,9 @@ _.extend(CompleteCatalog.prototype, {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Load the package sources for packages and their tests into packageSources.
|
// Load the package sources for packages and their tests into packageSources.
|
||||||
_.each(self.effectiveLocalPackages, function (x) {
|
buildmessage.forkJoin({ 'title': 'Initializing packages'}, self.effectiveLocalPackages, function (x) {
|
||||||
initSourceFromDir(x);
|
initSourceFromDir(x);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove all packages from the catalog that have the same name as
|
// Remove all packages from the catalog that have the same name as
|
||||||
// a local package, along with all of their versions and builds.
|
// a local package, along with all of their versions and builds.
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ var compiler = require('./compiler.js');
|
|||||||
var unipackage = require('./unipackage.js');
|
var unipackage = require('./unipackage.js');
|
||||||
var tropohouse = require('./tropohouse.js');
|
var tropohouse = require('./tropohouse.js');
|
||||||
var httpHelpers = require('./http-helpers.js');
|
var httpHelpers = require('./http-helpers.js');
|
||||||
|
var Console = require('./console.js').Console;
|
||||||
|
|
||||||
// XXX hard-coded the use of default tropohouse
|
// XXX hard-coded the use of default tropohouse
|
||||||
var tropo = tropohouse.default;
|
var tropo = tropohouse.default;
|
||||||
@@ -45,7 +46,7 @@ var setVerboseness = cordova.setVerboseness = function (v) {
|
|||||||
};
|
};
|
||||||
var verboseLog = cordova.verboseLog = function (/* args */) {
|
var verboseLog = cordova.verboseLog = function (/* args */) {
|
||||||
if (verboseness)
|
if (verboseness)
|
||||||
process.stderr.write('%% ' + util.format.apply(null, arguments) + '\n');
|
Console.stderr.write('%% ' + util.format.apply(null, arguments) + '\n');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -306,7 +307,7 @@ cordova.ensureCordovaProject = function (localPath, appName) {
|
|||||||
if (err instanceof main.ExitWithCode) {
|
if (err instanceof main.ExitWithCode) {
|
||||||
process.exit(err.code);
|
process.exit(err.code);
|
||||||
}
|
}
|
||||||
process.stderr.write("Error creating Cordova project: " +
|
Console.stderr.write("Error creating Cordova project: " +
|
||||||
err.message + "\n" + err.stack + "\n");
|
err.message + "\n" + err.stack + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,7 +383,7 @@ var installPlugin = function (cordovaPath, name, version, settings) {
|
|||||||
additionalArgs.push(variable + '=' + JSON.stringify(value));
|
additionalArgs.push(variable + '=' + JSON.stringify(value));
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stdout.write(' installing ' + pluginInstallCommand + '\n');
|
Console.stdout.write(' installing ' + pluginInstallCommand + '\n');
|
||||||
var execRes = execFileSyncOrThrow(localCordova,
|
var execRes = execFileSyncOrThrow(localCordova,
|
||||||
['plugin', 'add', pluginInstallCommand].concat(additionalArgs),
|
['plugin', 'add', pluginInstallCommand].concat(additionalArgs),
|
||||||
{ cwd: cordovaPath });
|
{ cwd: cordovaPath });
|
||||||
@@ -528,7 +529,7 @@ var ensureCordovaPlugins = function (localPath, options) {
|
|||||||
files.rm_recursive(path.join(cordovaPath, 'platforms'));
|
files.rm_recursive(path.join(cordovaPath, 'platforms'));
|
||||||
cordova.ensureCordovaPlatforms(localPath);
|
cordova.ensureCordovaPlatforms(localPath);
|
||||||
};
|
};
|
||||||
process.stdout.write("Initializing Cordova plugins...\n");
|
Console.stdout.write("Initializing Cordova plugins...\n");
|
||||||
uninstallAllPlugins();
|
uninstallAllPlugins();
|
||||||
|
|
||||||
// Now install all of the plugins.
|
// Now install all of the plugins.
|
||||||
@@ -922,7 +923,7 @@ main.registerCommand({
|
|||||||
cordova.checkIsValidPlatform(platform);
|
cordova.checkIsValidPlatform(platform);
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write(err.message + "\n");
|
Console.stderr.write(err.message + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -950,7 +951,7 @@ main.registerCommand({
|
|||||||
}
|
}
|
||||||
|
|
||||||
_.each(platforms, function (platform) {
|
_.each(platforms, function (platform) {
|
||||||
process.stdout.write("added platform " + platform + "\n");
|
Console.stdout.write("added platform " + platform + "\n");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -966,9 +967,9 @@ main.registerCommand({
|
|||||||
|
|
||||||
_.each(platforms, function (platform) {
|
_.each(platforms, function (platform) {
|
||||||
if (_.contains(currentPlatforms, platform)) {
|
if (_.contains(currentPlatforms, platform)) {
|
||||||
process.stdout.write("removed platform " + platform + "\n");
|
Console.stdout.write("removed platform " + platform + "\n");
|
||||||
} else {
|
} else {
|
||||||
process.stdout.write(platform + " is not in this project\n");
|
Console.stdout.write(platform + " is not in this project\n");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
project.removeCordovaPlatforms(platforms);
|
project.removeCordovaPlatforms(platforms);
|
||||||
@@ -989,11 +990,11 @@ main.registerCommand({
|
|||||||
requiresApp: true
|
requiresApp: true
|
||||||
}, function () {
|
}, function () {
|
||||||
var platforms = project.getCordovaPlatforms();
|
var platforms = project.getCordovaPlatforms();
|
||||||
process.stdout.write(platforms.join("\n"));
|
Console.stdout.write(platforms.join("\n"));
|
||||||
|
|
||||||
// print nothing at all if no platforms
|
// print nothing at all if no platforms
|
||||||
if (platforms.length) {
|
if (platforms.length) {
|
||||||
process.stdout.write("\n");
|
Console.stdout.write("\n");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,7 @@ var unipackage = require('./unipackage.js');
|
|||||||
var cordova = require('./commands-cordova.js');
|
var cordova = require('./commands-cordova.js');
|
||||||
var commandsPackages = require('./commands-packages.js');
|
var commandsPackages = require('./commands-packages.js');
|
||||||
var execFileSync = require('./utils.js').execFileSync;
|
var execFileSync = require('./utils.js').execFileSync;
|
||||||
|
var Console = require('./console.js').Console;
|
||||||
|
|
||||||
// The architecture used by Galaxy servers; it's the architecture used
|
// The architecture used by Galaxy servers; it's the architecture used
|
||||||
// by 'meteor deploy'.
|
// by 'meteor deploy'.
|
||||||
@@ -103,7 +104,7 @@ main.registerCommand({
|
|||||||
if (release.current === null) {
|
if (release.current === null) {
|
||||||
if (! options.appDir)
|
if (! options.appDir)
|
||||||
throw new Error("missing release, but not in an app?");
|
throw new Error("missing release, but not in an app?");
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"This project was created with a checkout of Meteor, rather than an\n" +
|
"This project was created with a checkout of Meteor, rather than an\n" +
|
||||||
"official release, and doesn't have a release number associated with\n" +
|
"official release, and doesn't have a release number associated with\n" +
|
||||||
"it. You can set its release with 'meteor update'.\n");
|
"it. You can set its release with 'meteor update'.\n");
|
||||||
@@ -111,7 +112,7 @@ main.registerCommand({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (release.current.isCheckout()) {
|
if (release.current.isCheckout()) {
|
||||||
process.stderr.write("Unreleased (running from a checkout)\n");
|
Console.stderr.write("Unreleased (running from a checkout)\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,15 +125,15 @@ main.registerCommand({
|
|||||||
requiresRelease: false
|
requiresRelease: false
|
||||||
}, function (options) {
|
}, function (options) {
|
||||||
if (files.inCheckout()) {
|
if (files.inCheckout()) {
|
||||||
process.stderr.write("checkout\n");
|
Console.stderr.write("checkout\n");
|
||||||
return 1;
|
return 1;
|
||||||
} else if (release.current === null) {
|
} else if (release.current === null) {
|
||||||
// .meteor/release says "none" but not in a checkout.
|
// .meteor/release says "none" but not in a checkout.
|
||||||
process.stderr.write("none\n");
|
Console.stderr.write("none\n");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
process.stdout.write(release.current.name + "\n");
|
Console.stdout.write(release.current.name + "\n");
|
||||||
process.stdout.write(files.getToolsVersion() + "\n");
|
Console.stdout.write(files.getToolsVersion() + "\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -186,7 +187,7 @@ main.registerCommand({
|
|||||||
project.getVersions(); // #StructuredProjectInitialization
|
project.getVersions(); // #StructuredProjectInitialization
|
||||||
});
|
});
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stderr.write(messages.formatMessages());
|
Console.stderr.write(messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,10 +198,10 @@ main.registerCommand({
|
|||||||
var parsedHostPort = parseHostPort(options.port);
|
var parsedHostPort = parseHostPort(options.port);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (options.verbose) {
|
if (options.verbose) {
|
||||||
process.stderr.write('Error while parsing --port option: '
|
Console.stderr.write('Error while parsing --port option: '
|
||||||
+ err.stack + '\n');
|
+ err.stack + '\n');
|
||||||
} else {
|
} else {
|
||||||
process.stderr.write(err.message + '\n');
|
Console.stderr.write(err.message + '\n');
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -227,7 +228,7 @@ main.registerCommand({
|
|||||||
cordova.verboseLog('A run on a device requested');
|
cordova.verboseLog('A run on a device requested');
|
||||||
// ... and if you didn't specify your ip address as host, print a warning
|
// ... and if you didn't specify your ip address as host, print a warning
|
||||||
if (parsedMobileHostPort.host === DEFAULT_BUILD_HOST)
|
if (parsedMobileHostPort.host === DEFAULT_BUILD_HOST)
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"WARN: You are testing your app on a remote device but your host option\n" +
|
"WARN: You are testing your app on a remote device but your host option\n" +
|
||||||
"WARN: is set to 'localhost'. Perhaps you want to change it to your local\n" +
|
"WARN: is set to 'localhost'. Perhaps you want to change it to your local\n" +
|
||||||
"WARN: network's IP address with the -p or --mobile-port option?\n");
|
"WARN: network's IP address with the -p or --mobile-port option?\n");
|
||||||
@@ -263,10 +264,10 @@ main.registerCommand({
|
|||||||
runners = runners.concat(cordova.buildPlatformRunners(localPath, options.args, options));
|
runners = runners.concat(cordova.buildPlatformRunners(localPath, options.args, options));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (options.verbose) {
|
if (options.verbose) {
|
||||||
process.stderr.write('Error while running for mobile platforms ' +
|
Console.stderr.write('Error while running for mobile platforms ' +
|
||||||
err.stack + '\n');
|
err.stack + '\n');
|
||||||
} else {
|
} else {
|
||||||
process.stderr.write(err.message + '\n');
|
Console.stderr.write(err.message + '\n');
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -276,7 +277,7 @@ main.registerCommand({
|
|||||||
if (options['app-port']) {
|
if (options['app-port']) {
|
||||||
var appPortMatch = options['app-port'].match(/^(?:(.+):)?([0-9]+)?$/);
|
var appPortMatch = options['app-port'].match(/^(?:(.+):)?([0-9]+)?$/);
|
||||||
if (!appPortMatch) {
|
if (!appPortMatch) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"run: --app-port must be a number or be of the form 'host:port' where\n" +
|
"run: --app-port must be a number or be of the form 'host:port' where\n" +
|
||||||
"port is a number. Try 'meteor help run' for help.\n");
|
"port is a number. Try 'meteor help run' for help.\n");
|
||||||
return 1;
|
return 1;
|
||||||
@@ -344,12 +345,12 @@ main.registerCommand({
|
|||||||
|
|
||||||
// No package examples exist yet.
|
// No package examples exist yet.
|
||||||
if (options.list && options.example) {
|
if (options.list && options.example) {
|
||||||
process.stderr.write("No package examples exist at this time.\n\n");
|
Console.stderr.write("No package examples exist at this time.\n\n");
|
||||||
throw new main.ShowUsage;
|
throw new main.ShowUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!packageName) {
|
if (!packageName) {
|
||||||
process.stderr.write("Please specify the name of the package. \n");
|
Console.stderr.write("Please specify the name of the package. \n");
|
||||||
throw new main.ShowUsage;
|
throw new main.ShowUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,7 +363,7 @@ main.registerCommand({
|
|||||||
var inYourApp = options.appDir ? " in your app" : "";
|
var inYourApp = options.appDir ? " in your app" : "";
|
||||||
|
|
||||||
if (fs.existsSync(packageDir)) {
|
if (fs.existsSync(packageDir)) {
|
||||||
process.stderr.write(packageName + ": Already exists" + inYourApp + "\n");
|
Console.stderr.write(packageName + ": Already exists" + inYourApp + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,11 +403,11 @@ main.registerCommand({
|
|||||||
ignore: [/^local$/]
|
ignore: [/^local$/]
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write("Could not create package: " + err.message + "\n");
|
Console.stderr.write("Could not create package: " + err.message + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.write(packageName + ": created" + inYourApp + "\n");
|
Console.stdout.write(packageName + ": created" + inYourApp + "\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,11 +435,11 @@ main.registerCommand({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (options.list) {
|
if (options.list) {
|
||||||
process.stdout.write("Available examples:\n");
|
Console.stdout.write("Available examples:\n");
|
||||||
_.each(examples, function (e) {
|
_.each(examples, function (e) {
|
||||||
process.stdout.write(" " + e + "\n");
|
Console.stdout.write(" " + e + "\n");
|
||||||
});
|
});
|
||||||
process.stdout.write("\n" +
|
Console.stdout.write("\n" +
|
||||||
"Create a project from an example with 'meteor create --example <name>'.\n");
|
"Create a project from an example with 'meteor create --example <name>'.\n");
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
@@ -452,12 +453,12 @@ main.registerCommand({
|
|||||||
throw new main.ShowUsage;
|
throw new main.ShowUsage;
|
||||||
|
|
||||||
if (fs.existsSync(appPath)) {
|
if (fs.existsSync(appPath)) {
|
||||||
process.stderr.write(appPath + ": Already exists\n");
|
Console.stderr.write(appPath + ": Already exists\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (files.findAppDir(appPath)) {
|
if (files.findAppDir(appPath)) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"You can't create a Meteor project inside another Meteor project.\n");
|
"You can't create a Meteor project inside another Meteor project.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -468,8 +469,8 @@ main.registerCommand({
|
|||||||
|
|
||||||
if (options.example) {
|
if (options.example) {
|
||||||
if (examples.indexOf(options.example) === -1) {
|
if (examples.indexOf(options.example) === -1) {
|
||||||
process.stderr.write(options.example + ": no such example\n\n");
|
Console.stderr.write(options.example + ": no such example\n\n");
|
||||||
process.stderr.write("List available applications with 'meteor create --list'.\n");
|
Console.stderr.write("List available applications with 'meteor create --list'.\n");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
files.cp_r(path.join(exampleDir, options.example), appPath, {
|
files.cp_r(path.join(exampleDir, options.example), appPath, {
|
||||||
@@ -509,7 +510,7 @@ main.registerCommand({
|
|||||||
project.appendFinishedUpgrader(upgrader);
|
project.appendFinishedUpgrader(upgrader);
|
||||||
});
|
});
|
||||||
|
|
||||||
var messages = buildmessage.capture(function () {
|
var messages = buildmessage.capture({ title: "Updating dependencies" }, function () {
|
||||||
// Run the constraint solver. Override the assumption that using '--release'
|
// Run the constraint solver. Override the assumption that using '--release'
|
||||||
// means we shouldn't update .meteor/versions.
|
// means we shouldn't update .meteor/versions.
|
||||||
project._ensureDepsUpToDate({alwaysRecord: true});
|
project._ensureDepsUpToDate({alwaysRecord: true});
|
||||||
@@ -517,16 +518,19 @@ main.registerCommand({
|
|||||||
|
|
||||||
|
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stderr.write(messages.formatMessages());
|
Console.stderr.write(messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.write(appPath + ": created");
|
{
|
||||||
if (options.example && options.example !== appPath)
|
var message = appPath + ": created";
|
||||||
process.stderr.write(" (from '" + options.example + "' template)");
|
if (options.example && options.example !== appPath)
|
||||||
process.stdout.write(".\n\n");
|
message += (" (from '" + options.example + "' template)");
|
||||||
|
message += ".\n";
|
||||||
|
Console.info(message);
|
||||||
|
}
|
||||||
|
|
||||||
process.stdout.write(
|
Console.stdout.write(
|
||||||
"To run your new app:\n" +
|
"To run your new app:\n" +
|
||||||
" cd " + appPath + "\n" +
|
" cd " + appPath + "\n" +
|
||||||
" meteor\n");
|
" meteor\n");
|
||||||
@@ -588,8 +592,8 @@ main.registerCommand(_.extend({ name: 'build' }, buildCommands),
|
|||||||
["os.osx.x86_64", "os.linux.x86_64", "os.linux.x86_32"];
|
["os.osx.x86_64", "os.linux.x86_64", "os.linux.x86_32"];
|
||||||
if (options.architecture &&
|
if (options.architecture &&
|
||||||
_.indexOf(VALID_ARCHITECTURES, options.architecture) === -1) {
|
_.indexOf(VALID_ARCHITECTURES, options.architecture) === -1) {
|
||||||
process.stderr.write("Invalid architecture: " + options.architecture + "\n");
|
Console.stderr.write("Invalid architecture: " + options.architecture + "\n");
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"Please use one of the following: " + VALID_ARCHITECTURES + "\n");
|
"Please use one of the following: " + VALID_ARCHITECTURES + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -603,11 +607,10 @@ main.registerCommand(_.extend({ name: 'build' }, buildCommands),
|
|||||||
var appName = path.basename(options.appDir);
|
var appName = path.basename(options.appDir);
|
||||||
|
|
||||||
if (! _.isEmpty(mobilePlatforms)) {
|
if (! _.isEmpty(mobilePlatforms)) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var parsedHostPort = parseHostPort(options.port);
|
var parsedHostPort = parseHostPort(options.port);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write(err.message);
|
Console.stderr.write(err.message);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,8 +641,8 @@ main.registerCommand(_.extend({ name: 'build' }, buildCommands),
|
|||||||
loader = project.getPackageLoader();
|
loader = project.getPackageLoader();
|
||||||
});
|
});
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stderr.write("Errors prevented bundling your app:\n");
|
Console.stderr.write("Errors prevented bundling your app:\n");
|
||||||
process.stderr.write(messages.formatMessages());
|
Console.stderr.write(messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,7 +650,7 @@ main.registerCommand(_.extend({ name: 'build' }, buildCommands),
|
|||||||
stats.recordPackages("sdk.bundle");
|
stats.recordPackages("sdk.bundle");
|
||||||
});
|
});
|
||||||
if (statsMessages.hasMessages()) {
|
if (statsMessages.hasMessages()) {
|
||||||
process.stdout.write("Error recording package list:\n" +
|
Console.stdout.write("Error recording package list:\n" +
|
||||||
statsMessages.formatMessages());
|
statsMessages.formatMessages());
|
||||||
// ... but continue;
|
// ... but continue;
|
||||||
}
|
}
|
||||||
@@ -667,8 +670,8 @@ main.registerCommand(_.extend({ name: 'build' }, buildCommands),
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (bundleResult.errors) {
|
if (bundleResult.errors) {
|
||||||
process.stderr.write("Errors prevented bundling:\n");
|
Console.stderr.write("Errors prevented bundling:\n");
|
||||||
process.stderr.write(bundleResult.errors.formatMessages());
|
Console.stderr.write(bundleResult.errors.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,7 +682,7 @@ main.registerCommand(_.extend({ name: 'build' }, buildCommands),
|
|||||||
files.createTarball(path.join(buildDir, 'bundle'), outputTar);
|
files.createTarball(path.join(buildDir, 'bundle'), outputTar);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(JSON.stringify(err));
|
console.log(JSON.stringify(err));
|
||||||
process.stderr.write("Couldn't create tarball\n");
|
Console.stderr.write("Couldn't create tarball\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,7 +702,7 @@ main.registerCommand(_.extend({ name: 'build' }, buildCommands),
|
|||||||
main.registerCommand(_.extend({ name: 'bundle', hidden: true }, buildCommands),
|
main.registerCommand(_.extend({ name: 'bundle', hidden: true }, buildCommands),
|
||||||
function (options) {
|
function (options) {
|
||||||
cordova.setVerboseness(options.verbose);
|
cordova.setVerboseness(options.verbose);
|
||||||
process.stdout.write("WARNING: 'bundle' has been deprecated. " +
|
Console.stdout.write("WARNING: 'bundle' has been deprecated. " +
|
||||||
"Use 'build' instead.\n");
|
"Use 'build' instead.\n");
|
||||||
// XXX if they pass a file that doesn't end in .tar.gz or .tgz, add
|
// XXX if they pass a file that doesn't end in .tar.gz or .tgz, add
|
||||||
// the former for them
|
// the former for them
|
||||||
@@ -718,8 +721,8 @@ main.registerCommand(_.extend({ name: 'bundle', hidden: true }, buildCommands),
|
|||||||
["os.osx.x86_64", "os.linux.x86_64", "os.linux.x86_32"];
|
["os.osx.x86_64", "os.linux.x86_64", "os.linux.x86_32"];
|
||||||
if (options.architecture &&
|
if (options.architecture &&
|
||||||
_.indexOf(VALID_ARCHITECTURES, options.architecture) === -1) {
|
_.indexOf(VALID_ARCHITECTURES, options.architecture) === -1) {
|
||||||
process.stderr.write("Invalid architecture: " + options.architecture + "\n");
|
Console.stderr.write("Invalid architecture: " + options.architecture + "\n");
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"Please use one of the following: " + VALID_ARCHITECTURES + "\n");
|
"Please use one of the following: " + VALID_ARCHITECTURES + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -735,8 +738,8 @@ main.registerCommand(_.extend({ name: 'bundle', hidden: true }, buildCommands),
|
|||||||
loader = project.getPackageLoader();
|
loader = project.getPackageLoader();
|
||||||
});
|
});
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stderr.write("Errors prevented bundling your app:\n");
|
Console.stderr.write("Errors prevented bundling your app:\n");
|
||||||
process.stderr.write(messages.formatMessages());
|
Console.stderr.write(messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,7 +747,7 @@ main.registerCommand(_.extend({ name: 'bundle', hidden: true }, buildCommands),
|
|||||||
stats.recordPackages("sdk.bundle");
|
stats.recordPackages("sdk.bundle");
|
||||||
});
|
});
|
||||||
if (statsMessages.hasMessages()) {
|
if (statsMessages.hasMessages()) {
|
||||||
process.stdout.write("Error recording package list:\n" +
|
Console.stdout.write("Error recording package list:\n" +
|
||||||
statsMessages.formatMessages());
|
statsMessages.formatMessages());
|
||||||
// ... but continue;
|
// ... but continue;
|
||||||
}
|
}
|
||||||
@@ -763,8 +766,8 @@ main.registerCommand(_.extend({ name: 'bundle', hidden: true }, buildCommands),
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (bundleResult.errors) {
|
if (bundleResult.errors) {
|
||||||
process.stderr.write("Errors prevented bundling:\n");
|
Console.stderr.write("Errors prevented bundling:\n");
|
||||||
process.stderr.write(bundleResult.errors.formatMessages());
|
Console.stderr.write(bundleResult.errors.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,7 +776,7 @@ main.registerCommand(_.extend({ name: 'bundle', hidden: true }, buildCommands),
|
|||||||
files.createTarball(path.join(buildDir, 'bundle'), outputPath);
|
files.createTarball(path.join(buildDir, 'bundle'), outputPath);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(JSON.stringify(err));
|
console.log(JSON.stringify(err));
|
||||||
process.stderr.write("Couldn't create tarball\n");
|
Console.stderr.write("Couldn't create tarball\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
files.rm_recursive(buildDir);
|
files.rm_recursive(buildDir);
|
||||||
@@ -806,7 +809,7 @@ main.registerCommand({
|
|||||||
// specified?
|
// specified?
|
||||||
|
|
||||||
if (! mongoPort) {
|
if (! mongoPort) {
|
||||||
process.stdout.write(
|
Console.stdout.write(
|
||||||
"mongo: Meteor isn't running a local MongoDB server.\n" +
|
"mongo: Meteor isn't running a local MongoDB server.\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"This command only works while Meteor is running your application\n" +
|
"This command only works while Meteor is running your application\n" +
|
||||||
@@ -862,7 +865,7 @@ main.registerCommand({
|
|||||||
requiresApp: true
|
requiresApp: true
|
||||||
}, function (options) {
|
}, function (options) {
|
||||||
if (options.args.length !== 0) {
|
if (options.args.length !== 0) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"meteor reset only affects the locally stored database.\n" +
|
"meteor reset only affects the locally stored database.\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"To reset a deployed application use\n" +
|
"To reset a deployed application use\n" +
|
||||||
@@ -879,7 +882,7 @@ main.registerCommand({
|
|||||||
require(path.join(__dirname, 'run-mongo.js')).findMongoPort;
|
require(path.join(__dirname, 'run-mongo.js')).findMongoPort;
|
||||||
var isRunning = !! findMongoPort(options.appDir);
|
var isRunning = !! findMongoPort(options.appDir);
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"reset: Meteor is running.\n" +
|
"reset: Meteor is running.\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"This command does not work while Meteor is running your application.\n" +
|
"This command does not work while Meteor is running your application.\n" +
|
||||||
@@ -890,7 +893,7 @@ main.registerCommand({
|
|||||||
var localDir = path.join(options.appDir, '.meteor', 'local');
|
var localDir = path.join(options.appDir, '.meteor', 'local');
|
||||||
files.rm_recursive(localDir);
|
files.rm_recursive(localDir);
|
||||||
|
|
||||||
process.stdout.write("Project reset.\n");
|
Console.stdout.write("Project reset.\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -945,19 +948,19 @@ main.registerCommand({
|
|||||||
// issues are concurrency-related, or possibly some weird order-of-execution
|
// issues are concurrency-related, or possibly some weird order-of-execution
|
||||||
// of interaction that we are failing to understand. This seems to fix it in a
|
// of interaction that we are failing to understand. This seems to fix it in a
|
||||||
// clear and understandable fashion.)
|
// clear and understandable fashion.)
|
||||||
var messages = buildmessage.capture(function () {
|
var messages = buildmessage.capture({ title: "Resolving versions" }, function () {
|
||||||
project.getVersions(); // #StructuredProjectInitialization
|
project.getVersions(); // #StructuredProjectInitialization
|
||||||
});
|
});
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stderr.write(messages.formatMessages());
|
Console.stderr.write(messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.password) {
|
if (options.password) {
|
||||||
if (useGalaxy) {
|
if (useGalaxy) {
|
||||||
process.stderr.write("Galaxy does not support --password.\n");
|
Console.stderr.write("Galaxy does not support --password.\n");
|
||||||
} else {
|
} else {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"Setting passwords on apps is no longer supported. Now there are\n" +
|
"Setting passwords on apps is no longer supported. Now there are\n" +
|
||||||
"user accounts and your apps are associated with your account so that\n" +
|
"user accounts and your apps are associated with your account so that\n" +
|
||||||
"only you (and people you designate) can access them. See the\n" +
|
"only you (and people you designate) can access them. See the\n" +
|
||||||
@@ -969,14 +972,14 @@ main.registerCommand({
|
|||||||
var starball = options.star;
|
var starball = options.star;
|
||||||
if (starball && ! useGalaxy) {
|
if (starball && ! useGalaxy) {
|
||||||
// XXX it would be nice to support this for non-Galaxy deploys too
|
// XXX it would be nice to support this for non-Galaxy deploys too
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"--star: only supported when deploying to Galaxy.\n");
|
"--star: only supported when deploying to Galaxy.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loggedIn = auth.isLoggedIn();
|
var loggedIn = auth.isLoggedIn();
|
||||||
if (! loggedIn) {
|
if (! loggedIn) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"To instantly deploy your app on a free testing server, just enter your\n" +
|
"To instantly deploy your app on a free testing server, just enter your\n" +
|
||||||
"email address!\n" +
|
"email address!\n" +
|
||||||
"\n");
|
"\n");
|
||||||
@@ -988,9 +991,9 @@ main.registerCommand({
|
|||||||
// Override architecture iff applicable.
|
// Override architecture iff applicable.
|
||||||
var buildArch = DEPLOY_ARCH;
|
var buildArch = DEPLOY_ARCH;
|
||||||
if (options['override-architecture-with-local']) {
|
if (options['override-architecture-with-local']) {
|
||||||
process.stdout.write(
|
Console.stdout.write(
|
||||||
"\n => WARNING: OVERRIDING DEPLOY ARCHITECTURE WITH LOCAL ARCHITECTURE\n");
|
"\n => WARNING: OVERRIDING DEPLOY ARCHITECTURE WITH LOCAL ARCHITECTURE\n");
|
||||||
process.stdout.write(
|
Console.stdout.write(
|
||||||
" => If your app contains binary code, it may break terribly and you will be sad.\n\n");
|
" => If your app contains binary code, it may break terribly and you will be sad.\n\n");
|
||||||
buildArch = archinfo.host();
|
buildArch = archinfo.host();
|
||||||
}
|
}
|
||||||
@@ -1081,13 +1084,13 @@ main.registerCommand({
|
|||||||
}, function (options) {
|
}, function (options) {
|
||||||
|
|
||||||
if (options.add && options.remove) {
|
if (options.add && options.remove) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"Sorry, you can only add or remove one user at a time.\n");
|
"Sorry, you can only add or remove one user at a time.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((options.add || options.remove) && options.list) {
|
if ((options.add || options.remove) && options.list) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"Sorry, you can't change the users at the same time as you're listing them.\n");
|
"Sorry, you can't change the users at the same time as you're listing them.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1097,7 +1100,7 @@ main.registerCommand({
|
|||||||
var site = qualifySitename(options.args[0]);
|
var site = qualifySitename(options.args[0]);
|
||||||
|
|
||||||
if (hostedWithGalaxy(site)) {
|
if (hostedWithGalaxy(site)) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"Sites hosted on Galaxy do not have an authorized user list.\n" +
|
"Sites hosted on Galaxy do not have an authorized user list.\n" +
|
||||||
"Instead, go to your Galaxy dashboard to change the authorized users\n" +
|
"Instead, go to your Galaxy dashboard to change the authorized users\n" +
|
||||||
"of your Galaxy.\n");
|
"of your Galaxy.\n");
|
||||||
@@ -1105,7 +1108,7 @@ main.registerCommand({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! auth.isLoggedIn()) {
|
if (! auth.isLoggedIn()) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"You must be logged in for that. Try 'meteor login'.\n");
|
"You must be logged in for that. Try 'meteor login'.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1132,7 +1135,7 @@ main.registerCommand({
|
|||||||
var site = qualifySitename(options.args[0]);
|
var site = qualifySitename(options.args[0]);
|
||||||
|
|
||||||
if (! auth.isLoggedIn()) {
|
if (! auth.isLoggedIn()) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"You must be logged in to claim sites. Use 'meteor login' to log in.\n" +
|
"You must be logged in to claim sites. Use 'meteor login' to log in.\n" +
|
||||||
"If you don't have a Meteor developer account yet, create one by clicking\n" +
|
"If you don't have a Meteor developer account yet, create one by clicking\n" +
|
||||||
"'Sign in' and then 'Create account' at www.meteor.com.\n\n");
|
"'Sign in' and then 'Create account' at www.meteor.com.\n\n");
|
||||||
@@ -1140,7 +1143,7 @@ main.registerCommand({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hostedWithGalaxy(site)) {
|
if (hostedWithGalaxy(site)) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"Sorry, you can't claim sites that are hosted on Galaxy.\n");
|
"Sorry, you can't claim sites that are hosted on Galaxy.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1194,7 +1197,7 @@ main.registerCommand({
|
|||||||
try {
|
try {
|
||||||
var parsedHostPort = parseHostPort(options.port);
|
var parsedHostPort = parseHostPort(options.port);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write(err.message);
|
Console.stderr.write(err.message);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1213,7 +1216,7 @@ main.registerCommand({
|
|||||||
localPackages = packages.localPackages;
|
localPackages = packages.localPackages;
|
||||||
options.localPackageNames = packages.localPackages;
|
options.localPackageNames = packages.localPackages;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write('\n' + err.message);
|
Console.stderr.write('\n' + err.message);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1276,7 +1279,7 @@ main.registerCommand({
|
|||||||
runners = runners.concat(cordova.buildPlatformRunners(
|
runners = runners.concat(cordova.buildPlatformRunners(
|
||||||
localPath, mobilePlatforms, options));
|
localPath, mobilePlatforms, options));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write(err.message + '\n');
|
Console.stderr.write(err.message + '\n');
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1378,7 +1381,7 @@ var getPackagesForTest = function (packages) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stderr.write("\n" + messages.formatMessages());
|
Console.stderr.write("\n" + messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1416,7 +1419,7 @@ var runTestAppForPackages = function (testPackages, testRunnerAppDir, options) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stderr.write(messages.formatMessages());
|
Console.stderr.write(messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
project.forceEditPackages(tests, 'add');
|
project.forceEditPackages(tests, 'add');
|
||||||
@@ -1429,7 +1432,7 @@ var runTestAppForPackages = function (testPackages, testRunnerAppDir, options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stderr.write(messages.formatMessages());
|
Console.stderr.write(messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1519,7 +1522,7 @@ main.registerCommand({
|
|||||||
if (count)
|
if (count)
|
||||||
console.log("Built " + count + " packages.");
|
console.log("Built " + count + " packages.");
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stderr.write("\n" + messages.formatMessages());
|
Console.stderr.write("\n" + messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1571,18 +1574,18 @@ main.registerCommand({
|
|||||||
var loggedInAccountsConnectionOrPrompt = function (action) {
|
var loggedInAccountsConnectionOrPrompt = function (action) {
|
||||||
var token = auth.getSessionToken(config.getAccountsDomain());
|
var token = auth.getSessionToken(config.getAccountsDomain());
|
||||||
if (! token) {
|
if (! token) {
|
||||||
process.stderr.write("You must be logged in to " + action + ".\n");
|
Console.stderr.write("You must be logged in to " + action + ".\n");
|
||||||
auth.doUsernamePasswordLogin({ retry: true });
|
auth.doUsernamePasswordLogin({ retry: true });
|
||||||
process.stdout.write("\n");
|
Console.stdout.write("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
token = auth.getSessionToken(config.getAccountsDomain());
|
token = auth.getSessionToken(config.getAccountsDomain());
|
||||||
var conn = auth.loggedInAccountsConnection(token);
|
var conn = auth.loggedInAccountsConnection(token);
|
||||||
if (conn === null) {
|
if (conn === null) {
|
||||||
// Server rejected our token.
|
// Server rejected our token.
|
||||||
process.stderr.write("You must be logged in to " + action + ".\n");
|
Console.stderr.write("You must be logged in to " + action + ".\n");
|
||||||
auth.doUsernamePasswordLogin({ retry: true });
|
auth.doUsernamePasswordLogin({ retry: true });
|
||||||
process.stdout.write("\n");
|
Console.stdout.write("\n");
|
||||||
token = auth.getSessionToken(config.getAccountsDomain());
|
token = auth.getSessionToken(config.getAccountsDomain());
|
||||||
conn = auth.loggedInAccountsConnection(token);
|
conn = auth.loggedInAccountsConnection(token);
|
||||||
}
|
}
|
||||||
@@ -1599,9 +1602,9 @@ main.registerCommand({
|
|||||||
|
|
||||||
var token = auth.getSessionToken(config.getAccountsDomain());
|
var token = auth.getSessionToken(config.getAccountsDomain());
|
||||||
if (! token) {
|
if (! token) {
|
||||||
process.stderr.write("You must be logged in to list your organizations.\n");
|
Console.stderr.write("You must be logged in to list your organizations.\n");
|
||||||
auth.doUsernamePasswordLogin({ retry: true });
|
auth.doUsernamePasswordLogin({ retry: true });
|
||||||
process.stdout.write("\n");
|
Console.stdout.write("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = config.getAccountsApiUrl() + "/organizations";
|
var url = config.getAccountsApiUrl() + "/organizations";
|
||||||
@@ -1614,13 +1617,13 @@ main.registerCommand({
|
|||||||
});
|
});
|
||||||
var body = JSON.parse(result.body);
|
var body = JSON.parse(result.body);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write("Error listing organizations.\n");
|
Console.stderr.write("Error listing organizations.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.response.statusCode === 401 &&
|
if (result.response.statusCode === 401 &&
|
||||||
body && body.error === "invalid_credential") {
|
body && body.error === "invalid_credential") {
|
||||||
process.stderr.write("You must be logged in to list your organizations.\n");
|
Console.stderr.write("You must be logged in to list your organizations.\n");
|
||||||
// XXX It would be nice to do a username/password prompt here like
|
// XXX It would be nice to do a username/password prompt here like
|
||||||
// we do for the other orgs commands.
|
// we do for the other orgs commands.
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1628,14 +1631,14 @@ main.registerCommand({
|
|||||||
|
|
||||||
if (result.response.statusCode !== 200 ||
|
if (result.response.statusCode !== 200 ||
|
||||||
! body || ! body.organizations) {
|
! body || ! body.organizations) {
|
||||||
process.stderr.write("Error listing organizations.\n");
|
Console.stderr.write("Error listing organizations.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body.organizations.length === 0) {
|
if (body.organizations.length === 0) {
|
||||||
process.stdout.write("You are not a member of any organizations.\n");
|
Console.stdout.write("You are not a member of any organizations.\n");
|
||||||
} else {
|
} else {
|
||||||
process.stdout.write(_.pluck(body.organizations, "name").join("\n") + "\n");
|
Console.stdout.write(_.pluck(body.organizations, "name").join("\n") + "\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
@@ -1652,7 +1655,7 @@ main.registerCommand({
|
|||||||
}, function (options) {
|
}, function (options) {
|
||||||
|
|
||||||
if (options.add && options.remove) {
|
if (options.add && options.remove) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"Sorry, you can only add or remove one member at a time.\n");
|
"Sorry, you can only add or remove one member at a time.\n");
|
||||||
throw new main.ShowUsage;
|
throw new main.ShowUsage;
|
||||||
}
|
}
|
||||||
@@ -1671,13 +1674,13 @@ main.registerCommand({
|
|||||||
options.add ? "addOrganizationMember": "removeOrganizationMember",
|
options.add ? "addOrganizationMember": "removeOrganizationMember",
|
||||||
options.args[0], username);
|
options.args[0], username);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write("Error " +
|
Console.stderr.write("Error " +
|
||||||
(options.add ? "adding" : "removing") +
|
(options.add ? "adding" : "removing") +
|
||||||
" member: " + err.reason + "\n");
|
" member: " + err.reason + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.write(username + " " +
|
Console.stdout.write(username + " " +
|
||||||
(options.add ? "added to" : "removed from") +
|
(options.add ? "added to" : "removed from") +
|
||||||
" organization " + options.args[0] + ".\n");
|
" organization " + options.args[0] + ".\n");
|
||||||
} else {
|
} else {
|
||||||
@@ -1685,14 +1688,14 @@ main.registerCommand({
|
|||||||
try {
|
try {
|
||||||
var result = conn.call("showOrganization", options.args[0]);
|
var result = conn.call("showOrganization", options.args[0]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write("Error showing organization: " +
|
Console.stderr.write("Error showing organization: " +
|
||||||
err.reason + "\n");
|
err.reason + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var members = _.pluck(result, "username");
|
var members = _.pluck(result, "username");
|
||||||
|
|
||||||
process.stdout.write(members.join("\n") + "\n");
|
Console.stdout.write(members.join("\n") + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1739,7 +1742,7 @@ main.registerCommand({
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!(e instanceof SyntaxError))
|
if (!(e instanceof SyntaxError))
|
||||||
throw e;
|
throw e;
|
||||||
process.stderr.write("Bad regular expression: " + options.args[0] + "\n");
|
Console.stderr.write("Bad regular expression: " + options.args[0] + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1770,7 +1773,7 @@ main.registerCommand({
|
|||||||
}, function (options) {
|
}, function (options) {
|
||||||
auth.pollForRegistrationCompletion();
|
auth.pollForRegistrationCompletion();
|
||||||
if (! auth.isLoggedIn()) {
|
if (! auth.isLoggedIn()) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"You must be logged in for that. Try 'meteor login'.\n");
|
"You must be logged in for that. Try 'meteor login'.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1803,10 +1806,10 @@ main.registerCommand({
|
|||||||
return 'none';
|
return 'none';
|
||||||
};
|
};
|
||||||
|
|
||||||
process.stdout.write(p('email') + " " + p('port') + " " + p('changed') +
|
Console.stdout.write(p('email') + " " + p('port') + " " + p('changed') +
|
||||||
" " + p('args') + "\n");
|
" " + p('args') + "\n");
|
||||||
if (options.url)
|
if (options.url)
|
||||||
process.stdout.write('url\n');
|
Console.stdout.write('url\n');
|
||||||
if (options['delete'])
|
if (options['delete'])
|
||||||
process.stdout.write('delete\n');
|
Console.stdout.write('delete\n');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -797,7 +797,7 @@ compiler.compile = function (packageSource, options) {
|
|||||||
versions: buildTimeDeps.pluginDependencies[info.name],
|
versions: buildTimeDeps.pluginDependencies[info.name],
|
||||||
catalog: packageSource.catalog
|
catalog: packageSource.catalog
|
||||||
});
|
});
|
||||||
loader.downloadMissingPackages({serverArch: archinfo.host()});
|
loader.downloadMissingPackages({serverArch: archinfo.host() });
|
||||||
|
|
||||||
var buildResult = bundler.buildJsImage({
|
var buildResult = bundler.buildJsImage({
|
||||||
name: info.name,
|
name: info.name,
|
||||||
|
|||||||
301
tools/console.js
Normal file
301
tools/console.js
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
///
|
||||||
|
/// utility functions for formatting output to the screen
|
||||||
|
///
|
||||||
|
|
||||||
|
var _ = require('underscore');
|
||||||
|
var Fiber = require('fibers');
|
||||||
|
var Future = require('fibers/future');
|
||||||
|
var ProgressBar = require('progress');
|
||||||
|
var buildmessage = require('./buildmessage.js');
|
||||||
|
// XXX: Are we happy with chalk (and its sub-dependencies)?
|
||||||
|
var chalk = require('chalk');
|
||||||
|
|
||||||
|
PROGRESS_DEBUG = !!process.env.METEOR_PROGRESS_DEBUG;
|
||||||
|
USE_PRETTY = (process.env.METEOR_PRETTY_OUTPUT != '0');
|
||||||
|
|
||||||
|
var Console = function (options) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
self._progressBar = null;
|
||||||
|
self._progressBarText = null;
|
||||||
|
self._watching = null;
|
||||||
|
|
||||||
|
self._lastStatusPoll = 0;
|
||||||
|
|
||||||
|
// Legacy helpers
|
||||||
|
self.stdout = {};
|
||||||
|
self.stderr = {};
|
||||||
|
self.stdout.write = function (msg) {
|
||||||
|
self._legacyWrite(LEVEL_INFO, msg);
|
||||||
|
};
|
||||||
|
self.stderr.write = function (msg) {
|
||||||
|
self._legacyWrite(LEVEL_WARN, msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
self._stream =process.stdout;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
PROGRESS_BAR_WIDTH = 20;
|
||||||
|
PROGRESS_BAR_FORMAT = '[:bar] :percent :etas';
|
||||||
|
STATUS_POSITION = PROGRESS_BAR_WIDTH + 15;
|
||||||
|
STATUS_MAX_LENGTH = 40;
|
||||||
|
|
||||||
|
|
||||||
|
// Message to show when we don't know what we're doing
|
||||||
|
// XXX: ? FALLBACK_STATUS = 'Pondering';
|
||||||
|
FALLBACK_STATUS = '';
|
||||||
|
|
||||||
|
// This function returns a future which resolves after a timeout. This
|
||||||
|
// demonstrates manually resolving futures.
|
||||||
|
function sleep(ms) {
|
||||||
|
var future = new Future;
|
||||||
|
setTimeout(function() {
|
||||||
|
future.return();
|
||||||
|
}, ms);
|
||||||
|
return future.wait();
|
||||||
|
};
|
||||||
|
|
||||||
|
LEVEL_CODE_ERROR = 4;
|
||||||
|
LEVEL_CODE_WARN = 3;
|
||||||
|
LEVEL_CODE_INFO = 2;
|
||||||
|
LEVEL_CODE_DEBUG = 1;
|
||||||
|
|
||||||
|
LEVEL_ERROR = { code: LEVEL_CODE_ERROR };
|
||||||
|
LEVEL_WARN = { code: LEVEL_CODE_WARN };
|
||||||
|
LEVEL_INFO = { code: LEVEL_CODE_INFO };
|
||||||
|
LEVEL_DEBUG = { code: LEVEL_CODE_DEBUG };
|
||||||
|
|
||||||
|
_.extend(Console.prototype, {
|
||||||
|
hideProgressBar: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (!self._progressBar) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self._progressBar.terminate();
|
||||||
|
},
|
||||||
|
|
||||||
|
_renderProgressBar: function () {
|
||||||
|
var self = this;
|
||||||
|
if (self._progressBar) {
|
||||||
|
self._progressBar.render();
|
||||||
|
if (self._progressBarText) {
|
||||||
|
var text = self._progressBarText;
|
||||||
|
if (text > STATUS_MAX_LENGTH) {
|
||||||
|
text = text.substring(0, STATUS_MAX_LENGTH - 3) + "...";
|
||||||
|
} else {
|
||||||
|
while (text.length < STATUS_MAX_LENGTH) {
|
||||||
|
text = text + ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self._stream.cursorTo(STATUS_POSITION);
|
||||||
|
self._stream.write(chalk.bold(text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_statusPoll: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self._lastStatusPoll = Date.now();
|
||||||
|
|
||||||
|
var rootProgress = buildmessage.getRootProgress();
|
||||||
|
if (PROGRESS_DEBUG) {
|
||||||
|
rootProgress.dump(process.stdout, {skipDone: true});
|
||||||
|
}
|
||||||
|
var current = (rootProgress ? rootProgress.getCurrentProgress() : null);
|
||||||
|
if (self._watching === current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self._watching = current;
|
||||||
|
var title = (current != null ? current._title : null) || FALLBACK_STATUS;
|
||||||
|
if (title != self._progressBarText) {
|
||||||
|
self._progressBarText = title;
|
||||||
|
self._renderProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
self._watchProgress();
|
||||||
|
},
|
||||||
|
|
||||||
|
statusPollMaybe: function () {
|
||||||
|
var self = this;
|
||||||
|
var now = Date.now();
|
||||||
|
|
||||||
|
if ((now - self._lastStatusPoll) < 50) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self._statusPoll();
|
||||||
|
},
|
||||||
|
|
||||||
|
enableStatusPoll: function () {
|
||||||
|
var self = this;
|
||||||
|
Fiber(function () {
|
||||||
|
while (true) {
|
||||||
|
sleep(10);
|
||||||
|
|
||||||
|
self._statusPoll();
|
||||||
|
}
|
||||||
|
}).run();
|
||||||
|
},
|
||||||
|
|
||||||
|
info: function(/*arguments*/) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var message = self._format(arguments);
|
||||||
|
self._print(LEVEL_INFO, message);
|
||||||
|
},
|
||||||
|
|
||||||
|
warn: function(/*arguments*/) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var message = self._format(arguments);
|
||||||
|
self._print(LEVEL_WARN, message);
|
||||||
|
},
|
||||||
|
|
||||||
|
error: function(/*arguments*/) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var message = self._format(arguments);
|
||||||
|
self._print(LEVEL_ERROR, message);
|
||||||
|
},
|
||||||
|
|
||||||
|
_legacyWrite: function (level, message) {
|
||||||
|
var self = this;
|
||||||
|
if(message.substr(-1) == '\n') {
|
||||||
|
message = message.substr(0, message.length - 1);
|
||||||
|
}
|
||||||
|
self._print(level, message);
|
||||||
|
},
|
||||||
|
|
||||||
|
_print: function(level, message) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var progressBar = self._progressBar;
|
||||||
|
if (progressBar) {
|
||||||
|
//progressBar.terminate();
|
||||||
|
self._stream.clearLine();
|
||||||
|
self._stream.cursorTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dest = process.stdout;
|
||||||
|
var style = null;
|
||||||
|
|
||||||
|
if (level && USE_PRETTY) {
|
||||||
|
switch (level.code) {
|
||||||
|
case LEVEL_CODE_ERROR:
|
||||||
|
dest = process.stderr;
|
||||||
|
style = chalk.bold.red;
|
||||||
|
break;
|
||||||
|
case LEVEL_CODE_WARN:
|
||||||
|
dest = process.stderr;
|
||||||
|
style = chalk.red;
|
||||||
|
break;
|
||||||
|
//case LEVEL_CODE_INFO:
|
||||||
|
// style = chalk.blue;
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (style) {
|
||||||
|
dest.write(style(message + '\n'));
|
||||||
|
} else {
|
||||||
|
dest.write(message + '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progressBar) {
|
||||||
|
self._renderProgressBar();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_format: function (logArguments) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var message = '';
|
||||||
|
var format = logArguments[0];
|
||||||
|
message = format;
|
||||||
|
return message;
|
||||||
|
},
|
||||||
|
|
||||||
|
printMessages: function (messages) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (messages.hasMessages()) {
|
||||||
|
self._print(null, "\n" + messages.formatMessages());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
showProgressBar: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (self._progressBar) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!self._stream.isTTY || !USE_PRETTY) return;
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
complete: '=',
|
||||||
|
incomplete: ' ',
|
||||||
|
width: PROGRESS_BAR_WIDTH,
|
||||||
|
total: 100,
|
||||||
|
clear: true,
|
||||||
|
stream: self._stream
|
||||||
|
};
|
||||||
|
|
||||||
|
var progressBar = new ProgressBar(PROGRESS_BAR_FORMAT, options);
|
||||||
|
progressBar.start = new Date;
|
||||||
|
|
||||||
|
self._progressBar = progressBar;
|
||||||
|
},
|
||||||
|
|
||||||
|
_watchProgress: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var progress = self._watching;
|
||||||
|
if (!progress) return;
|
||||||
|
|
||||||
|
progress.addWatcher(function (state) {
|
||||||
|
//console.log(state);
|
||||||
|
if (progress != self._watching) {
|
||||||
|
// No longer active
|
||||||
|
//console.log("NOT WATCHING");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var progressBar = self._progressBar;
|
||||||
|
if (!progressBar) {
|
||||||
|
//console.log("NOT PROGRESS BAR");
|
||||||
|
// Progress bar disabled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fraction;
|
||||||
|
if (state.done) {
|
||||||
|
fraction = 1.0;
|
||||||
|
} else {
|
||||||
|
var current = state.current;
|
||||||
|
var end = state.end;
|
||||||
|
if (end === undefined || end == 0 || current == 0) {
|
||||||
|
// Arbitrary end-point
|
||||||
|
fraction = progressBar.curr / 100;
|
||||||
|
} else {
|
||||||
|
fraction = current / end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNaN(fraction) && fraction >= 0) {
|
||||||
|
progressBar.curr = Math.floor(fraction * progressBar.total);
|
||||||
|
self._renderProgressBar();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Console.warning = Console.warn;
|
||||||
|
|
||||||
|
exports.Console = new Console;
|
||||||
117
tools/deploy.js
117
tools/deploy.js
@@ -15,6 +15,7 @@ var utils = require('./utils.js');
|
|||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
var Future = require('fibers/future');
|
var Future = require('fibers/future');
|
||||||
var stats = require('./stats.js');
|
var stats = require('./stats.js');
|
||||||
|
var Console = require('./console.js').Console;
|
||||||
|
|
||||||
// Make a synchronous RPC to the "classic" MDG deploy API. The deploy
|
// Make a synchronous RPC to the "classic" MDG deploy API. The deploy
|
||||||
// API has the following contract:
|
// API has the following contract:
|
||||||
@@ -65,6 +66,7 @@ var deployRpc = function (options) {
|
|||||||
if (options.headers.cookie)
|
if (options.headers.cookie)
|
||||||
throw new Error("sorry, can't combine cookie headers yet");
|
throw new Error("sorry, can't combine cookie headers yet");
|
||||||
|
|
||||||
|
var progress = buildmessage.addChildTracker("Uploading");
|
||||||
try {
|
try {
|
||||||
var result = httpHelpers.request(_.extend(options, {
|
var result = httpHelpers.request(_.extend(options, {
|
||||||
url: config.getDeployUrl() + '/' + options.operation +
|
url: config.getDeployUrl() + '/' + options.operation +
|
||||||
@@ -72,13 +74,16 @@ var deployRpc = function (options) {
|
|||||||
method: options.method || 'GET',
|
method: options.method || 'GET',
|
||||||
bodyStream: options.bodyStream,
|
bodyStream: options.bodyStream,
|
||||||
useAuthHeader: true,
|
useAuthHeader: true,
|
||||||
encoding: 'utf8' // Hack, but good enough for the deploy server..
|
encoding: 'utf8', // Hack, but good enough for the deploy server..
|
||||||
|
progress: progress
|
||||||
}));
|
}));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {
|
return {
|
||||||
statusCode: null,
|
statusCode: null,
|
||||||
errorMessage: "Connection error (" + e.message + ")"
|
errorMessage: "Connection error (" + e.message + ")"
|
||||||
};
|
};
|
||||||
|
} finally {
|
||||||
|
progress.reportProgressDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = result.response;
|
var response = result.response;
|
||||||
@@ -254,7 +259,7 @@ var authedRpc = function (options) {
|
|||||||
// password-protected app, instruct them to claim it with 'meteor
|
// password-protected app, instruct them to claim it with 'meteor
|
||||||
// claim'.
|
// claim'.
|
||||||
var printLegacyPasswordMessage = function (site) {
|
var printLegacyPasswordMessage = function (site) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"\nThis site was deployed with an old version of Meteor that used\n" +
|
"\nThis site was deployed with an old version of Meteor that used\n" +
|
||||||
"site passwords instead of user accounts. Now we have a much better\n" +
|
"site passwords instead of user accounts. Now we have a much better\n" +
|
||||||
"system, Meteor developer accounts.\n\n" +
|
"system, Meteor developer accounts.\n\n" +
|
||||||
@@ -267,7 +272,7 @@ var printLegacyPasswordMessage = function (site) {
|
|||||||
// --add' or switch accounts.
|
// --add' or switch accounts.
|
||||||
var printUnauthorizedMessage = function () {
|
var printUnauthorizedMessage = function () {
|
||||||
var username = auth.loggedInUsername();
|
var username = auth.loggedInUsername();
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"Sorry, that site belongs to a different user.\n" +
|
"Sorry, that site belongs to a different user.\n" +
|
||||||
(username ? "You are currently logged in as " + username + ".\n" : "") +
|
(username ? "You are currently logged in as " + username + ".\n" : "") +
|
||||||
"\nEither have the site owner use 'meteor authorized --add' to add you\n" +
|
"\nEither have the site owner use 'meteor authorized --add' to add you\n" +
|
||||||
@@ -288,7 +293,7 @@ var canonicalizeSite = function (site) {
|
|||||||
// characters (url.parse will do something very strange if a component is
|
// characters (url.parse will do something very strange if a component is
|
||||||
// larger than 63, which is the maximum legal length).
|
// larger than 63, which is the maximum legal length).
|
||||||
if (site.length > 63) {
|
if (site.length > 63) {
|
||||||
process.stdout.write(
|
Console.stdout.write(
|
||||||
"The maximum hostname length currently supported is 63 characters.\n" +
|
"The maximum hostname length currently supported is 63 characters.\n" +
|
||||||
site + " is too long.\n" +
|
site + " is too long.\n" +
|
||||||
"Please try again with a shorter URL for your site.\n");
|
"Please try again with a shorter URL for your site.\n");
|
||||||
@@ -302,14 +307,14 @@ site + " is too long.\n" +
|
|||||||
var parsed = require('url').parse(url);
|
var parsed = require('url').parse(url);
|
||||||
|
|
||||||
if (! parsed.hostname) {
|
if (! parsed.hostname) {
|
||||||
process.stdout.write(
|
Console.stdout.write(
|
||||||
"Please specify a domain to connect to, such as www.example.com or\n" +
|
"Please specify a domain to connect to, such as www.example.com or\n" +
|
||||||
"http://www.example.com/\n");
|
"http://www.example.com/\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsed.pathname != '/' || parsed.hash || parsed.query) {
|
if (parsed.pathname != '/' || parsed.hash || parsed.query) {
|
||||||
process.stdout.write(
|
Console.stdout.write(
|
||||||
"Sorry, Meteor does not yet support specific path URLs, such as\n" +
|
"Sorry, Meteor does not yet support specific path URLs, such as\n" +
|
||||||
"http://www.example.com/blog . Please specify the root of a domain.\n");
|
"http://www.example.com/blog . Please specify the root of a domain.\n");
|
||||||
return false;
|
return false;
|
||||||
@@ -362,14 +367,14 @@ var bundleAndDeploy = function (options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (preflight.errorMessage) {
|
if (preflight.errorMessage) {
|
||||||
process.stderr.write("\nError deploying application: " +
|
Console.stderr.write("\nError deploying application: " +
|
||||||
preflight.errorMessage + "\n");
|
preflight.errorMessage + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preflight.protection === "password") {
|
if (preflight.protection === "password") {
|
||||||
printLegacyPasswordMessage(site);
|
printLegacyPasswordMessage(site);
|
||||||
process.stderr.write("If it's not your site, please try a different name!\n");
|
Console.stderr.write("If it's not your site, please try a different name!\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
} else if (preflight.protection === "account" &&
|
} else if (preflight.protection === "account" &&
|
||||||
@@ -381,7 +386,7 @@ var bundleAndDeploy = function (options) {
|
|||||||
var buildDir = path.join(options.appDir, '.meteor', 'local', 'build_tar');
|
var buildDir = path.join(options.appDir, '.meteor', 'local', 'build_tar');
|
||||||
var bundlePath = path.join(buildDir, 'bundle');
|
var bundlePath = path.join(buildDir, 'bundle');
|
||||||
|
|
||||||
process.stdout.write('Deploying to ' + site + '. Bundling...\n');
|
Console.stdout.write('Deploying to ' + site + '. Bundling...\n');
|
||||||
|
|
||||||
var settings = null;
|
var settings = null;
|
||||||
var messages = buildmessage.capture({
|
var messages = buildmessage.capture({
|
||||||
@@ -396,11 +401,11 @@ var bundleAndDeploy = function (options) {
|
|||||||
var bundler = require('./bundler.js');
|
var bundler = require('./bundler.js');
|
||||||
|
|
||||||
if (options.recordPackageUsage) {
|
if (options.recordPackageUsage) {
|
||||||
var statsMessages = buildmessage.capture(function () {
|
var statsMessages = buildmessage.capture({ title: 'Reporting statistics' }, function () {
|
||||||
stats.recordPackages("sdk.deploy", site);
|
stats.recordPackages("sdk.deploy", site);
|
||||||
});
|
});
|
||||||
if (statsMessages.hasMessages()) {
|
if (statsMessages.hasMessages()) {
|
||||||
process.stdout.write("Error recording package list:\n" +
|
Console.stdout.write("Error recording package list:\n" +
|
||||||
statsMessages.formatMessages());
|
statsMessages.formatMessages());
|
||||||
// ... but continue;
|
// ... but continue;
|
||||||
}
|
}
|
||||||
@@ -416,25 +421,29 @@ var bundleAndDeploy = function (options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
process.stdout.write("\nErrors prevented deploying:\n");
|
Console.stdout.write("\nErrors prevented deploying:\n");
|
||||||
process.stdout.write(messages.formatMessages());
|
Console.stdout.write(messages.formatMessages());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.write('Uploading...\n');
|
Console.stdout.write('Uploading...\n');
|
||||||
|
|
||||||
var result = authedRpc({
|
var result;
|
||||||
method: 'POST',
|
buildmessage.enterJob({ title: "Uploading" }, function () {
|
||||||
operation: 'deploy',
|
result = authedRpc({
|
||||||
site: site,
|
method: 'POST',
|
||||||
qs: settings !== null ? { settings: settings } : {},
|
operation: 'deploy',
|
||||||
bodyStream: files.createTarGzStream(path.join(buildDir, 'bundle')),
|
site: site,
|
||||||
expectPayload: ['url'],
|
qs: settings !== null ? {settings: settings} : {},
|
||||||
preflightPassword: preflight.preflightPassword
|
bodyStream: files.createTarGzStream(path.join(buildDir, 'bundle')),
|
||||||
|
expectPayload: ['url'],
|
||||||
|
preflightPassword: preflight.preflightPassword
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (result.errorMessage) {
|
if (result.errorMessage) {
|
||||||
process.stderr.write("\nError deploying application: " +
|
Console.stderr.write("\nError deploying application: " +
|
||||||
result.errorMessage + "\n");
|
result.errorMessage + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -442,7 +451,7 @@ var bundleAndDeploy = function (options) {
|
|||||||
var deployedAt = require('url').parse(result.payload.url);
|
var deployedAt = require('url').parse(result.payload.url);
|
||||||
var hostname = deployedAt.hostname;
|
var hostname = deployedAt.hostname;
|
||||||
|
|
||||||
process.stdout.write('Now serving at ' + hostname + '\n');
|
Console.stdout.write('Now serving at ' + hostname + '\n');
|
||||||
files.rm_recursive(buildDir);
|
files.rm_recursive(buildDir);
|
||||||
|
|
||||||
if (! hostname.match(/meteor\.com$/)) {
|
if (! hostname.match(/meteor\.com$/)) {
|
||||||
@@ -451,11 +460,11 @@ var bundleAndDeploy = function (options) {
|
|||||||
if (err || cnames[0] !== 'origin.meteor.com') {
|
if (err || cnames[0] !== 'origin.meteor.com') {
|
||||||
dns.resolve(hostname, 'A', function (err, addresses) {
|
dns.resolve(hostname, 'A', function (err, addresses) {
|
||||||
if (err || addresses[0] !== '107.22.210.133') {
|
if (err || addresses[0] !== '107.22.210.133') {
|
||||||
process.stdout.write('-------------\n');
|
Console.stdout.write('-------------\n');
|
||||||
process.stdout.write("You've deployed to a custom domain.\n");
|
Console.stdout.write("You've deployed to a custom domain.\n");
|
||||||
process.stdout.write("Please be sure to CNAME your hostname to origin.meteor.com,\n");
|
Console.stdout.write("Please be sure to CNAME your hostname to origin.meteor.com,\n");
|
||||||
process.stdout.write("or set an A record to 107.22.210.133.\n");
|
Console.stdout.write("or set an A record to 107.22.210.133.\n");
|
||||||
process.stdout.write('-------------\n');
|
Console.stdout.write('-------------\n');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -478,12 +487,12 @@ var deleteApp = function (site) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result.errorMessage) {
|
if (result.errorMessage) {
|
||||||
process.stderr.write("Couldn't delete application: " +
|
Console.stderr.write("Couldn't delete application: " +
|
||||||
result.errorMessage + "\n");
|
result.errorMessage + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.write("Deleted.\n");
|
Console.stdout.write("Deleted.\n");
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -504,7 +513,7 @@ var checkAuthThenSendRpc = function (site, operation, what) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (preflight.errorMessage) {
|
if (preflight.errorMessage) {
|
||||||
process.stderr.write("Couldn't " + what + ": " +
|
Console.stderr.write("Couldn't " + what + ": " +
|
||||||
preflight.errorMessage + "\n");
|
preflight.errorMessage + "\n");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -529,7 +538,7 @@ var checkAuthThenSendRpc = function (site, operation, what) {
|
|||||||
} else {
|
} else {
|
||||||
// Shouldn't ever get here because we set the retry flag on the
|
// Shouldn't ever get here because we set the retry flag on the
|
||||||
// login, but just in case.
|
// login, but just in case.
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"\nYou must be logged in to " + what + " for this app. Use 'meteor login'\n" +
|
"\nYou must be logged in to " + what + " for this app. Use 'meteor login'\n" +
|
||||||
"to log in.\n\n" +
|
"to log in.\n\n" +
|
||||||
"If you don't have a Meteor developer account yet, you can quickly\n" +
|
"If you don't have a Meteor developer account yet, you can quickly\n" +
|
||||||
@@ -537,7 +546,7 @@ var checkAuthThenSendRpc = function (site, operation, what) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else { // User is logged in but not authorized for this app
|
} else { // User is logged in but not authorized for this app
|
||||||
process.stderr.write("\n");
|
Console.stderr.write("\n");
|
||||||
printUnauthorizedMessage();
|
printUnauthorizedMessage();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -553,7 +562,7 @@ var checkAuthThenSendRpc = function (site, operation, what) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result.errorMessage) {
|
if (result.errorMessage) {
|
||||||
process.stderr.write("Couldn't " + what + ": " +
|
Console.stderr.write("Couldn't " + what + ": " +
|
||||||
result.errorMessage + "\n");
|
result.errorMessage + "\n");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -589,7 +598,7 @@ var logs = function (site) {
|
|||||||
if (result === null) {
|
if (result === null) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
process.stdout.write(result.message);
|
Console.stdout.write(result.message);
|
||||||
auth.maybePrintRegistrationLink({ leadingNewline: true });
|
auth.maybePrintRegistrationLink({ leadingNewline: true });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -606,33 +615,33 @@ var listAuthorized = function (site) {
|
|||||||
expectPayload: []
|
expectPayload: []
|
||||||
});
|
});
|
||||||
if (result.errorMessage) {
|
if (result.errorMessage) {
|
||||||
process.stderr.write("Couldn't get authorized users list: " +
|
Console.stderr.write("Couldn't get authorized users list: " +
|
||||||
result.errorMessage + "\n");
|
result.errorMessage + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
var info = result.payload;
|
var info = result.payload;
|
||||||
|
|
||||||
if (! _.has(info, 'protection')) {
|
if (! _.has(info, 'protection')) {
|
||||||
process.stdout.write("<anyone>\n");
|
Console.stdout.write("<anyone>\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.protection === "password") {
|
if (info.protection === "password") {
|
||||||
process.stdout.write("<password>\n");
|
Console.stdout.write("<password>\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.protection === "account") {
|
if (info.protection === "account") {
|
||||||
if (! _.has(info, 'authorized')) {
|
if (! _.has(info, 'authorized')) {
|
||||||
process.stderr.write("Couldn't get authorized users list: " +
|
Console.stderr.write("Couldn't get authorized users list: " +
|
||||||
"You are not authorized\n");
|
"You are not authorized\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.write((auth.loggedInUsername() || "<you>") + "\n");
|
Console.stdout.write((auth.loggedInUsername() || "<you>") + "\n");
|
||||||
_.each(info.authorized, function (username) {
|
_.each(info.authorized, function (username) {
|
||||||
if (username)
|
if (username)
|
||||||
process.stdout.write(username + "\n");
|
Console.stdout.write(username + "\n");
|
||||||
});
|
});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -654,12 +663,12 @@ var changeAuthorized = function (site, action, username) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result.errorMessage) {
|
if (result.errorMessage) {
|
||||||
process.stderr.write("Couldn't change authorized users: " +
|
Console.stderr.write("Couldn't change authorized users: " +
|
||||||
result.errorMessage + "\n");
|
result.errorMessage + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.write(site + ": " +
|
Console.stdout.write(site + ": " +
|
||||||
(action === "add" ? "added " : "removed ")
|
(action === "add" ? "added " : "removed ")
|
||||||
+ username + "\n");
|
+ username + "\n");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -680,7 +689,7 @@ var claim = function (site) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (infoResult.statusCode === 404) {
|
if (infoResult.statusCode === 404) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"There isn't a site deployed at that address. Use 'meteor deploy' if\n" +
|
"There isn't a site deployed at that address. Use 'meteor deploy' if\n" +
|
||||||
"you'd like to deploy your app here.\n");
|
"you'd like to deploy your app here.\n");
|
||||||
return 1;
|
return 1;
|
||||||
@@ -688,15 +697,15 @@ var claim = function (site) {
|
|||||||
|
|
||||||
if (infoResult.payload && infoResult.payload.protection === "account") {
|
if (infoResult.payload && infoResult.payload.protection === "account") {
|
||||||
if (infoResult.payload.authorized)
|
if (infoResult.payload.authorized)
|
||||||
process.stderr.write("That site already belongs to you.\n");
|
Console.stderr.write("That site already belongs to you.\n");
|
||||||
else
|
else
|
||||||
process.stderr.write("Sorry, that site belongs to someone else.\n");
|
Console.stderr.write("Sorry, that site belongs to someone else.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (infoResult.payload &&
|
if (infoResult.payload &&
|
||||||
infoResult.payload.protection === "password") {
|
infoResult.payload.protection === "password") {
|
||||||
process.stdout.write(
|
Console.stdout.write(
|
||||||
"To claim this site and transfer it to your account, enter the\n" +
|
"To claim this site and transfer it to your account, enter the\n" +
|
||||||
"site password one last time.\n\n");
|
"site password one last time.\n\n");
|
||||||
}
|
}
|
||||||
@@ -712,18 +721,18 @@ var claim = function (site) {
|
|||||||
auth.pollForRegistrationCompletion();
|
auth.pollForRegistrationCompletion();
|
||||||
if (! auth.loggedInUsername() &&
|
if (! auth.loggedInUsername() &&
|
||||||
auth.registrationUrl()) {
|
auth.registrationUrl()) {
|
||||||
process.stderr.write(
|
Console.stderr.write(
|
||||||
"You need to set a password on your Meteor developer account before\n" +
|
"You need to set a password on your Meteor developer account before\n" +
|
||||||
"you can claim sites. You can do that here in under a minute:\n\n" +
|
"you can claim sites. You can do that here in under a minute:\n\n" +
|
||||||
auth.registrationUrl() + "\n\n");
|
auth.registrationUrl() + "\n\n");
|
||||||
} else {
|
} else {
|
||||||
process.stderr.write("Couldn't claim site: " +
|
Console.stderr.write("Couldn't claim site: " +
|
||||||
result.errorMessage + "\n");
|
result.errorMessage + "\n");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.write(
|
Console.stdout.write(
|
||||||
site + ": " + "successfully transferred to your account.\n" +
|
site + ": " + "successfully transferred to your account.\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"Show authorized users with:\n" +
|
"Show authorized users with:\n" +
|
||||||
@@ -747,7 +756,7 @@ var listSites = function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result.errorMessage) {
|
if (result.errorMessage) {
|
||||||
process.stderr.write("Couldn't list sites: " +
|
Console.stderr.write("Couldn't list sites: " +
|
||||||
result.errorMessage + "\n");
|
result.errorMessage + "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -755,11 +764,11 @@ var listSites = function () {
|
|||||||
if (! result.payload ||
|
if (! result.payload ||
|
||||||
! result.payload.sites ||
|
! result.payload.sites ||
|
||||||
! result.payload.sites.length) {
|
! result.payload.sites.length) {
|
||||||
process.stdout.write("You don't have any sites yet.\n");
|
Console.stdout.write("You don't have any sites yet.\n");
|
||||||
} else {
|
} else {
|
||||||
result.payload.sites.sort();
|
result.payload.sites.sort();
|
||||||
_.each(result.payload.sites, function (site) {
|
_.each(result.payload.sites, function (site) {
|
||||||
process.stdout.write(site + "\n");
|
Console.stdout.write(site + "\n");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -13,6 +13,52 @@ var auth = require('./auth.js');
|
|||||||
var config = require('./config.js');
|
var config = require('./config.js');
|
||||||
var release = require('./release.js');
|
var release = require('./release.js');
|
||||||
|
|
||||||
|
|
||||||
|
// Helper that tracks bytes written to a writable
|
||||||
|
var WritableWithProgress = function (writable, listener) {
|
||||||
|
var self = this;
|
||||||
|
self._inner = writable;
|
||||||
|
self._listener = listener;
|
||||||
|
};
|
||||||
|
|
||||||
|
_.extend(WritableWithProgress.prototype, {
|
||||||
|
write: function (chunk, encoding, callback) {
|
||||||
|
var self = this;
|
||||||
|
self._listener(chunk.length, false);
|
||||||
|
return self._inner.write(chunk, encoding);
|
||||||
|
},
|
||||||
|
|
||||||
|
end: function (chunk, encoding, callback) {
|
||||||
|
var self = this;
|
||||||
|
self._listener(chunk ? chunk.length : 0, true);
|
||||||
|
return self._inner.end(chunk, encoding);
|
||||||
|
},
|
||||||
|
|
||||||
|
_progress: function (n, done) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var state = self._state;
|
||||||
|
state.current += n;
|
||||||
|
if (done) {
|
||||||
|
state.current.done = true;
|
||||||
|
}
|
||||||
|
self.progress.reportProgress(state);
|
||||||
|
},
|
||||||
|
|
||||||
|
on: function (name, callback) {
|
||||||
|
return this._inner.on(name, callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
once: function () {
|
||||||
|
return this._inner.once.apply(this._inner, arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
emit: function () {
|
||||||
|
return this._inner.emit.apply(this._inner, arguments);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Compose a User-Agent header.
|
// Compose a User-Agent header.
|
||||||
var getUserAgent = function () {
|
var getUserAgent = function () {
|
||||||
var version;
|
var version;
|
||||||
@@ -85,6 +131,16 @@ _.extend(exports, {
|
|||||||
delete options.bodyStream;
|
delete options.bodyStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var progress = null;
|
||||||
|
if (_.has(options, 'progress')) {
|
||||||
|
progress = options.progress;
|
||||||
|
delete options.progress;
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
throw new Error("Not safe to use progress with callback");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
options.headers = _.extend({
|
options.headers = _.extend({
|
||||||
'User-Agent': getUserAgent()
|
'User-Agent': getUserAgent()
|
||||||
}, options.headers || {});
|
}, options.headers || {});
|
||||||
@@ -161,13 +217,84 @@ _.extend(exports, {
|
|||||||
var request = require('request');
|
var request = require('request');
|
||||||
var req = request(options, callback);
|
var req = request(options, callback);
|
||||||
|
|
||||||
if (bodyStream)
|
var bodyStreamLength = 0;
|
||||||
bodyStream.pipe(req);
|
if (bodyStream) {
|
||||||
|
// XXX
|
||||||
|
bodyStreamLength += 4000000;
|
||||||
|
}
|
||||||
|
// XXX
|
||||||
|
var responseLength = 128 * 1024;
|
||||||
|
|
||||||
if (fut)
|
var totalProgress = { current: 0, end: bodyStreamLength + responseLength, done: false };
|
||||||
return fut.wait();
|
|
||||||
else
|
if (bodyStream) {
|
||||||
|
var dest = req;
|
||||||
|
if (progress) {
|
||||||
|
dest = new WritableWithProgress(dest, function (n, done) {
|
||||||
|
if (!totalProgress.done) {
|
||||||
|
totalProgress.current += n;
|
||||||
|
progress.reportProgress(totalProgress);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
bodyStream.pipe(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progress) {
|
||||||
|
httpHelpers._addProgressEvents(req);
|
||||||
|
req.on('progress', function (state) {
|
||||||
|
if (!totalProgress.done) {
|
||||||
|
totalProgress.current = bodyStreamLength + state.current;
|
||||||
|
totalProgress.end = bodyStreamLength + state.end;
|
||||||
|
totalProgress.done = state.done;
|
||||||
|
|
||||||
|
progress.reportProgress(totalProgress);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fut) {
|
||||||
|
try {
|
||||||
|
return fut.wait();
|
||||||
|
} finally {
|
||||||
|
if (progress) {
|
||||||
|
progress.reportProgressDone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return req;
|
return req;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Adds progress callbacks to a request
|
||||||
|
// Based on request-progress
|
||||||
|
_addProgressEvents: function (request) {
|
||||||
|
var state;
|
||||||
|
|
||||||
|
var emitProgress = function () {
|
||||||
|
request.emit('progress', state);
|
||||||
|
};
|
||||||
|
|
||||||
|
request
|
||||||
|
.on('response', function (response) {
|
||||||
|
state = {};
|
||||||
|
state.end = undefined;
|
||||||
|
state.done = false;
|
||||||
|
state.current = 0;
|
||||||
|
var contentLength = response.headers['content-length'];
|
||||||
|
if (contentLength) {
|
||||||
|
state.end = Number(contentLength);
|
||||||
|
}
|
||||||
|
emitProgress();
|
||||||
|
})
|
||||||
|
.on('data', function (data) {
|
||||||
|
state.current += data.length;
|
||||||
|
emitProgress();
|
||||||
|
})
|
||||||
|
.on('end', function (data) {
|
||||||
|
state.done = true;
|
||||||
|
emitProgress();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// A synchronous wrapper around request(...) that returns the response "body"
|
// A synchronous wrapper around request(...) that returns the response "body"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ if (showRequireProfile)
|
|||||||
|
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
var Fiber = require('fibers');
|
var Fiber = require('fibers');
|
||||||
|
var Console = require('./console.js').Console;
|
||||||
var files = require('./files.js');
|
var files = require('./files.js');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var warehouse = require('./warehouse.js');
|
var warehouse = require('./warehouse.js');
|
||||||
@@ -646,7 +647,7 @@ Fiber(function () {
|
|||||||
// One side effect of this: we really really expect them to all build, and
|
// One side effect of this: we really really expect them to all build, and
|
||||||
// we're fine with dying if they don't (there's no worries about needing to
|
// we're fine with dying if they don't (there's no worries about needing to
|
||||||
// springboard).
|
// springboard).
|
||||||
var messages = buildmessage.capture(function () {
|
var messages = buildmessage.capture({ title: "Initializing local packages" }, function () {
|
||||||
catalog.uniload.initialize({
|
catalog.uniload.initialize({
|
||||||
localPackageDirs: [path.join(files.getCurrentToolsDir(), 'packages')]
|
localPackageDirs: [path.join(files.getCurrentToolsDir(), 'packages')]
|
||||||
});
|
});
|
||||||
@@ -671,7 +672,7 @@ Fiber(function () {
|
|||||||
// build anything (except maybe, if running from a checkout, packages
|
// build anything (except maybe, if running from a checkout, packages
|
||||||
// that we need to uniload, which really ought to build) so it's OK
|
// that we need to uniload, which really ought to build) so it's OK
|
||||||
// to die on errors.
|
// to die on errors.
|
||||||
var messages = buildmessage.capture(function () {
|
var messages = buildmessage.capture({ title: "Initializing server catalog" }, function () {
|
||||||
catalog.official.initialize({
|
catalog.official.initialize({
|
||||||
offline: !!process.env.METEOR_OFFLINE_CATALOG
|
offline: !!process.env.METEOR_OFFLINE_CATALOG
|
||||||
});
|
});
|
||||||
@@ -814,7 +815,7 @@ Fiber(function () {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
var rel;
|
var rel;
|
||||||
var messages = buildmessage.capture(function () {
|
var messages = buildmessage.capture({ title: "Loading release" }, function () {
|
||||||
rel = release.load(releaseName);
|
rel = release.load(releaseName);
|
||||||
});
|
});
|
||||||
if (messages.hasMessages()) {
|
if (messages.hasMessages()) {
|
||||||
@@ -918,7 +919,7 @@ Fiber(function () {
|
|||||||
files.getCurrentToolsDir(), 'packages'));
|
files.getCurrentToolsDir(), 'packages'));
|
||||||
}
|
}
|
||||||
|
|
||||||
var messages = buildmessage.capture(function () {
|
var messages = buildmessage.capture({ title: "Initializing catalog" }, function () {
|
||||||
catalog.complete.initialize({
|
catalog.complete.initialize({
|
||||||
localPackageDirs: localPackageDirs
|
localPackageDirs: localPackageDirs
|
||||||
});
|
});
|
||||||
@@ -1227,10 +1228,15 @@ commandName + ": You're not in a Meteor project directory.\n" +
|
|||||||
if (showRequireProfile)
|
if (showRequireProfile)
|
||||||
require('./profile-require.js').printReport();
|
require('./profile-require.js').printReport();
|
||||||
|
|
||||||
|
Console.enableStatusPoll();
|
||||||
|
Console.showProgressBar();
|
||||||
|
|
||||||
// Run the command!
|
// Run the command!
|
||||||
try {
|
try {
|
||||||
var ret = command.func(options);
|
var ret = command.func(options);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
Console.hideProgressBar();
|
||||||
|
|
||||||
if (e === main.ShowUsage || e === main.WaitForExit ||
|
if (e === main.ShowUsage || e === main.WaitForExit ||
|
||||||
e === main.SpringboardToLatestRelease ||
|
e === main.SpringboardToLatestRelease ||
|
||||||
e === main.SpringboardToSpecificReleaseg ||
|
e === main.SpringboardToSpecificReleaseg ||
|
||||||
@@ -1278,6 +1284,8 @@ commandName + ": You're not in a Meteor project directory.\n" +
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.hideProgressBar();
|
||||||
|
|
||||||
// Exit. (We will not get here if the command threw an exception
|
// Exit. (We will not get here if the command threw an exception
|
||||||
// such as main.WaitForExit).
|
// such as main.WaitForExit).
|
||||||
if (ret === undefined)
|
if (ret === undefined)
|
||||||
|
|||||||
@@ -195,6 +195,14 @@ var writePackageDataToDisk = function (syncToken, data, options) {
|
|||||||
// - useShortPages: Boolean. Request short pages of ~3 records from the
|
// - useShortPages: Boolean. Request short pages of ~3 records from the
|
||||||
// server, instead of ~100 that it would send otherwise
|
// server, instead of ~100 that it would send otherwise
|
||||||
exports.updateServerPackageData = function (cachedServerData, options) {
|
exports.updateServerPackageData = function (cachedServerData, options) {
|
||||||
|
var results;
|
||||||
|
buildmessage.capture({ title: 'Updating package catalog' }, function () {
|
||||||
|
results = _updateServerPackageData(cachedServerData, options);
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
_updateServerPackageData = function (cachedServerData, options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
options = options || {};
|
options = options || {};
|
||||||
cachedServerData = cachedServerData || emptyCachedServerDataJson();
|
cachedServerData = cachedServerData || emptyCachedServerDataJson();
|
||||||
@@ -202,6 +210,10 @@ exports.updateServerPackageData = function (cachedServerData, options) {
|
|||||||
var done = false;
|
var done = false;
|
||||||
var ret = {resetData: false};
|
var ret = {resetData: false};
|
||||||
|
|
||||||
|
var start = undefined;
|
||||||
|
var state = { current: 0, end: 10, done: false};
|
||||||
|
buildmessage.reportProgress(state);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var conn = openPackageServerConnection(options.packageServerUrl);
|
var conn = openPackageServerConnection(options.packageServerUrl);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -210,8 +222,22 @@ exports.updateServerPackageData = function (cachedServerData, options) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Provide some progress indication for connection
|
||||||
|
// XXX though it is just a hack
|
||||||
|
state.current = 1;
|
||||||
|
buildmessage.reportProgress(state);
|
||||||
|
|
||||||
var getSomeData = function () {
|
var getSomeData = function () {
|
||||||
var syncToken = cachedServerData.syncToken;
|
var syncToken = cachedServerData.syncToken;
|
||||||
|
|
||||||
|
if (!start) {
|
||||||
|
start = syncToken.packages;
|
||||||
|
state.end = Date.now() - start;
|
||||||
|
}
|
||||||
|
// XXX: Is packages the best progress indicator?
|
||||||
|
state.current = syncToken.packages - start;
|
||||||
|
buildmessage.reportProgress(state);
|
||||||
|
|
||||||
var remoteData;
|
var remoteData;
|
||||||
try {
|
try {
|
||||||
remoteData = loadRemotePackageData(conn, syncToken, {
|
remoteData = loadRemotePackageData(conn, syncToken, {
|
||||||
@@ -272,6 +298,9 @@ exports.updateServerPackageData = function (cachedServerData, options) {
|
|||||||
conn.close();
|
conn.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.done = true;
|
||||||
|
buildmessage.reportProgress(state);
|
||||||
|
|
||||||
ret.data = cachedServerData;
|
ret.data = cachedServerData;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|||||||
278
tools/progress.js
Normal file
278
tools/progress.js
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
///
|
||||||
|
/// utility functions for computing progress of complex tasks
|
||||||
|
///
|
||||||
|
/// State callback here is an object with these keys:
|
||||||
|
/// done: bool, true if done
|
||||||
|
/// current: number, the current progress value
|
||||||
|
/// end: number, optional, the value of current where we expect to be done
|
||||||
|
///
|
||||||
|
|
||||||
|
var _ = require('underscore');
|
||||||
|
var Future = require('fibers/future');
|
||||||
|
var console = require('./console.js');
|
||||||
|
|
||||||
|
var Progress = function (options) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
self._lastState = null;
|
||||||
|
self._parent = options.parent;
|
||||||
|
self._watchers = options.watchers || [];
|
||||||
|
|
||||||
|
self._title = options.title;
|
||||||
|
|
||||||
|
//if (!self._title && self._parent) {
|
||||||
|
// throw new Error("No title passed");
|
||||||
|
//}
|
||||||
|
self._forkJoin = options.forkJoin;
|
||||||
|
|
||||||
|
// XXX: Rationalize this; we probably don't need _completedChildren
|
||||||
|
// XXX: or _activeChildTasks (?)
|
||||||
|
self._completedChildren = { current: 0, end: 0};
|
||||||
|
self._activeChildTasks = [];
|
||||||
|
self._allTasks = [];
|
||||||
|
|
||||||
|
self._selfState = { current: 0, end: 0, done: false };
|
||||||
|
if (options.estimate) {
|
||||||
|
self._selfState.end = options.estimate;
|
||||||
|
}
|
||||||
|
self._state = _.clone(self._selfState);
|
||||||
|
|
||||||
|
self._isDone = false;
|
||||||
|
|
||||||
|
self._selfActive = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
_.extend(Progress.prototype, {
|
||||||
|
toString: function() {
|
||||||
|
var self = this;
|
||||||
|
return "Progress [state=" + JSON.stringify(self._state) + "]";
|
||||||
|
},
|
||||||
|
|
||||||
|
reportProgressDone: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var state = _.clone(self._selfState);
|
||||||
|
state.done = true;
|
||||||
|
if (state.current === 0) {
|
||||||
|
state.current = 1;
|
||||||
|
}
|
||||||
|
if (!state.end || state.end < state.current) {
|
||||||
|
state.end = state.current;
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
// so we assume the top-level task has the title
|
||||||
|
// i.e. "Downloading packages", not "downloading supercool-1.0"
|
||||||
|
getCurrentProgress: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var isRoot = !self._parent;
|
||||||
|
|
||||||
|
if (self._isDone) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self._selfActive && !isRoot) {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self._forkJoin) {
|
||||||
|
// Don't descend into fork-join tasks
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self._allTasks.length) {
|
||||||
|
var active = _.map(self._allTasks, function (task) {
|
||||||
|
return task.getCurrentProgress();
|
||||||
|
});
|
||||||
|
active = _.filter(active, function (s) {
|
||||||
|
return !!s;
|
||||||
|
});
|
||||||
|
if (active.length == 1) {
|
||||||
|
return active[0];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (self._activeChildTasks.length) {
|
||||||
|
// var titles = _.map(self._activeChildTasks, function (task) {
|
||||||
|
// return task.getCurrent();
|
||||||
|
// });
|
||||||
|
// titles = _.filter(titles, function (s) { return !!s; });
|
||||||
|
// if (titles.length == 1) {
|
||||||
|
// return titles[0];
|
||||||
|
// }
|
||||||
|
// //if (titles.length > 1) {
|
||||||
|
// // console.log("Multiple titles: " + titles);
|
||||||
|
// //}
|
||||||
|
// return self._title;
|
||||||
|
//}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Creates a subtask that must be completed as part of this (bigger) task
|
||||||
|
addChildTask: function (options) {
|
||||||
|
var self = this;
|
||||||
|
options = options || {};
|
||||||
|
var options = _.extend({ parent: self }, options);
|
||||||
|
var child = new Progress(options);
|
||||||
|
self._activeChildTasks.push(child);
|
||||||
|
self._allTasks.push(child);
|
||||||
|
self._reportChildState(child, child._state);
|
||||||
|
return child;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Dumps the tree, for debug
|
||||||
|
dump: function (stream, options, prefix) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
if (options.skipDone && self._isDone) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefix) {
|
||||||
|
stream.write(prefix);
|
||||||
|
}
|
||||||
|
var end = self._state.end;
|
||||||
|
if (!end) {
|
||||||
|
end = '?';
|
||||||
|
}
|
||||||
|
stream.write("Task [" + self._title + "] " + self._state.current + "/" + end
|
||||||
|
+ (self._isDone ? " done" : "")
|
||||||
|
+ (self._selfActive ? " active" : "") +"\n");
|
||||||
|
if (self._allTasks.length) {
|
||||||
|
_.each(self._allTasks, function (child) {
|
||||||
|
child.dump(stream, options, (prefix || '') + ' ');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Receives a state report indicating progress of self
|
||||||
|
reportProgress: function (state) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self._selfState = state;
|
||||||
|
self._selfActive = !state.done;
|
||||||
|
|
||||||
|
self._updateTotalState();
|
||||||
|
|
||||||
|
console.Console.statusPollMaybe();
|
||||||
|
|
||||||
|
self._notifyState();
|
||||||
|
},
|
||||||
|
|
||||||
|
// Subscribes a watcher to changes
|
||||||
|
addWatcher: function (watcher) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self._watchers.push(watcher);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Notifies watchers & parents
|
||||||
|
_notifyState: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (self._parent) {
|
||||||
|
self._parent._reportChildState(self, self._state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self._watchers.length) {
|
||||||
|
_.each(self._watchers, function (watcher) {
|
||||||
|
watcher(self._state);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Recomputes state, incorporating children's states
|
||||||
|
_updateTotalState: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var state = _.clone(self._selfState);
|
||||||
|
|
||||||
|
//state.current += self._completedChildren.current;
|
||||||
|
//if (state.end !== undefined) {
|
||||||
|
// state.end += self._completedChildren.end;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//var allChildrenDone = true;
|
||||||
|
//_.each(self._activeChildTasks, function (child) {
|
||||||
|
// var childState = child._state;
|
||||||
|
// state.current += childState.current;
|
||||||
|
// if (!state.done) {
|
||||||
|
// allChildrenDone = false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (state.done) {
|
||||||
|
// if (state.end !== undefined) {
|
||||||
|
// state.end += childState.current;
|
||||||
|
// }
|
||||||
|
// } else if (state.end !== undefined) {
|
||||||
|
// if (childState.end !== undefined) {
|
||||||
|
// state.end += childState.end;
|
||||||
|
// } else {
|
||||||
|
// state.end = undefined;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//});
|
||||||
|
//if (!allChildrenDone) {
|
||||||
|
// state.done = false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
var allChildrenDone = true;
|
||||||
|
var state = _.clone(self._selfState);
|
||||||
|
_.each(self._allTasks, function (child) {
|
||||||
|
var childState = child._state;
|
||||||
|
|
||||||
|
if (!child._isDone) {
|
||||||
|
allChildrenDone = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.current += childState.current;
|
||||||
|
if (state.end !== undefined) {
|
||||||
|
if (childState.done) {
|
||||||
|
state.end += childState.current;
|
||||||
|
} else if (childState.end !== undefined) {
|
||||||
|
state.end += childState.end;
|
||||||
|
} else {
|
||||||
|
state.end = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self._isDone = allChildrenDone && !self._selfActive;
|
||||||
|
if (!allChildrenDone) {
|
||||||
|
state.done = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.done && self._state.done) {
|
||||||
|
// This shouldn't happen
|
||||||
|
throw new Error("Progress transition from done => !done");
|
||||||
|
}
|
||||||
|
|
||||||
|
self._state = state;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Called by a child when its state changes
|
||||||
|
_reportChildState: function (child, state) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (state.done) {
|
||||||
|
self._activeChildTasks = _.without(self._activeChildTasks, child);
|
||||||
|
var weight = state.current;
|
||||||
|
self._completedChildren.current += weight;
|
||||||
|
self._completedChildren.end += weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
self._updateTotalState();
|
||||||
|
self._notifyState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.Progress = Progress;
|
||||||
@@ -12,6 +12,7 @@ var buildmessage = require('./buildmessage.js');
|
|||||||
var packageLoader = require('./package-loader.js');
|
var packageLoader = require('./package-loader.js');
|
||||||
var PackageSource = require('./package-source.js');
|
var PackageSource = require('./package-source.js');
|
||||||
var packageVersionParser = require('./package-version-parser.js');
|
var packageVersionParser = require('./package-version-parser.js');
|
||||||
|
var Console = require('./console.js').Console;
|
||||||
|
|
||||||
var project = exports;
|
var project = exports;
|
||||||
|
|
||||||
@@ -220,9 +221,9 @@ _.extend(Project.prototype, {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
// XXX This error handling is bogus. Use buildmessage instead, or
|
// XXX This error handling is bogus. Use buildmessage instead, or
|
||||||
// something. See also compiler.determineBuildTimeDependencies
|
// something. See also compiler.determineBuildTimeDependencies
|
||||||
process.stdout.write(
|
Console.warn(
|
||||||
"Could not resolve the specified constraints for this project:\n"
|
"Could not resolve the specified constraints for this project:\n"
|
||||||
+ (err.constraintSolverError ? err : err.stack) + "\n");
|
+ (err.constraintSolverError ? err : err.stack));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,8 +237,8 @@ _.extend(Project.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!setV.success) {
|
if (!setV.success) {
|
||||||
process.stdout.write(
|
Console.warn(
|
||||||
"Could not install all the requested packages.\n");
|
"Could not install all the requested packages.");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,9 +364,9 @@ _.extend(Project.prototype, {
|
|||||||
options.onDiskPackages[packageName] !== version)) {
|
options.onDiskPackages[packageName] !== version)) {
|
||||||
// XXX maybe we shouldn't be letting the constraint solver choose
|
// XXX maybe we shouldn't be letting the constraint solver choose
|
||||||
// things that don't have the right arches?
|
// things that don't have the right arches?
|
||||||
process.stderr.write("Package " + packageName +
|
Console.warn("Package " + packageName +
|
||||||
" has no compatible build for version " +
|
" has no compatible build for version " +
|
||||||
version + "\n");
|
version);
|
||||||
failed = true;
|
failed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -396,7 +397,7 @@ _.extend(Project.prototype, {
|
|||||||
if ((!self.muted && !_.isEmpty(versions))
|
if ((!self.muted && !_.isEmpty(versions))
|
||||||
|| options.alwaysShow) {
|
|| options.alwaysShow) {
|
||||||
_.each(messageLog, function (msg) {
|
_.each(messageLog, function (msg) {
|
||||||
process.stdout.write(msg + "\n");
|
Console.info(msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pay special attention to non-backwards-compatible changes.
|
// Pay special attention to non-backwards-compatible changes.
|
||||||
@@ -448,11 +449,11 @@ _.extend(Project.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!_.isEmpty(incompatibleUpdates)) {
|
if (!_.isEmpty(incompatibleUpdates)) {
|
||||||
process.stderr.write(
|
Console.warn(
|
||||||
"\nThe following packages have been updated to new versions that are not " +
|
"\nThe following packages have been updated to new versions that are not " +
|
||||||
"backwards compatible:\n");
|
"backwards compatible:");
|
||||||
process.stderr.write(utils.formatList(incompatibleUpdates));
|
Console.warn(utils.formatList(incompatibleUpdates));
|
||||||
process.stderr.write("\n");
|
Console.warn("\n");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -152,11 +152,24 @@ _.extend(exports.Tropohouse.prototype, {
|
|||||||
downloadBuildToTempDir: function (versionInfo, buildRecord) {
|
downloadBuildToTempDir: function (versionInfo, buildRecord) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var targetDirectory = files.mkdtemp();
|
var targetDirectory = files.mkdtemp();
|
||||||
var packageTarball = httpHelpers.getUrl({
|
|
||||||
url: buildRecord.build.url,
|
var url = buildRecord.build.url;
|
||||||
encoding: null
|
|
||||||
});
|
var progress = buildmessage.addChildTracker("Download build");
|
||||||
files.extractTarGz(packageTarball, targetDirectory);
|
try {
|
||||||
|
buildmessage.capture({}, function () {
|
||||||
|
var packageTarball = httpHelpers.getUrl({
|
||||||
|
url: url,
|
||||||
|
encoding: null,
|
||||||
|
progress: progress,
|
||||||
|
wait: false
|
||||||
|
});
|
||||||
|
files.extractTarGz(packageTarball, targetDirectory);
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
progress.reportProgressDone();
|
||||||
|
}
|
||||||
|
|
||||||
return targetDirectory;
|
return targetDirectory;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -239,21 +252,9 @@ _.extend(exports.Tropohouse.prototype, {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX replace with a real progress bar in downloadMissingPackages
|
buildmessage.enterJob({
|
||||||
var header = " downloading " + packageName + " at version " + version + " ...";
|
title: " downloading " + packageName + " at version " + version + " ...",
|
||||||
if (!options.silent) {
|
}, function() {
|
||||||
var animationFrame = 0;
|
|
||||||
var spinner = ['..-', '..\\', '..|', '../'];
|
|
||||||
|
|
||||||
var printUpdate = function () {
|
|
||||||
process.stderr.write(header + spinner[animationFrame] + "\r");
|
|
||||||
animationFrame = (animationFrame + 1) % spinner.length;
|
|
||||||
};
|
|
||||||
printUpdate();
|
|
||||||
var dlTimer = setInterval(printUpdate, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
var buildTempDirs = [];
|
var buildTempDirs = [];
|
||||||
// If there's already a package in the tropohouse, start with it.
|
// If there's already a package in the tropohouse, start with it.
|
||||||
if (packageLinkTarget) {
|
if (packageLinkTarget) {
|
||||||
@@ -263,8 +264,7 @@ _.extend(exports.Tropohouse.prototype, {
|
|||||||
// XXX how does concurrency work here? we could just get errors if we try
|
// XXX how does concurrency work here? we could just get errors if we try
|
||||||
// to rename over the other thing? but that's the same as in warehouse?
|
// to rename over the other thing? but that's the same as in warehouse?
|
||||||
_.each(buildsToDownload, function (build) {
|
_.each(buildsToDownload, function (build) {
|
||||||
buildTempDirs.push(self.downloadBuildToTempDir(
|
buildTempDirs.push(self.downloadBuildToTempDir({packageName: packageName, version: version}, build));
|
||||||
{packageName: packageName, version: version}, build));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// We need to turn our builds into a single unipackage.
|
// We need to turn our builds into a single unipackage.
|
||||||
@@ -290,12 +290,7 @@ _.extend(exports.Tropohouse.prototype, {
|
|||||||
if (packageLinkTarget) {
|
if (packageLinkTarget) {
|
||||||
files.rm_recursive(self.packagePath(packageName, packageLinkTarget));
|
files.rm_recursive(self.packagePath(packageName, packageLinkTarget));
|
||||||
}
|
}
|
||||||
} finally {
|
});
|
||||||
if (!options.silent) {
|
|
||||||
clearInterval(dlTimer);
|
|
||||||
process.stderr.write(header + " done\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
@@ -316,7 +311,8 @@ _.extend(exports.Tropohouse.prototype, {
|
|||||||
options = options || {};
|
options = options || {};
|
||||||
var serverArch = options.serverArch || archinfo.host();
|
var serverArch = options.serverArch || archinfo.host();
|
||||||
var downloadedPackages = {};
|
var downloadedPackages = {};
|
||||||
_.each(versionMap, function (version, name) {
|
buildmessage.forkJoin({ title: 'Downloading packages'},
|
||||||
|
versionMap, function (version, name) {
|
||||||
try {
|
try {
|
||||||
self.maybeDownloadPackageForArchitectures({
|
self.maybeDownloadPackageForArchitectures({
|
||||||
packageName: name,
|
packageName: name,
|
||||||
|
|||||||
Reference in New Issue
Block a user