diff --git a/LICENSE.txt b/LICENSE.txt index 87b924676c..e9721dcedf 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1130,6 +1130,13 @@ This product includes software developed at The Apache Software Foundation (http://www.apache.org/). +---------- +ip: https://github.com/indutny/node-ip +---------- + +Copyright Fedor Indutny, 2012 + + ====================== Eclipse Public License diff --git a/meteor b/meteor index 76874b08fb..04cf25173b 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/bin/bash -BUNDLE_VERSION=0.3.55 # XXX: 0.3.56 is used on the cordova-0.9.4 branch +BUNDLE_VERSION=0.3.56 # OS Check. Put here because here is where we download the precompiled # bundles that are arch specific. diff --git a/packages/autoupdate/autoupdate_cordova.js b/packages/autoupdate/autoupdate_cordova.js index d29dee3546..a87b7e7583 100644 --- a/packages/autoupdate/autoupdate_cordova.js +++ b/packages/autoupdate/autoupdate_cordova.js @@ -1,3 +1,15 @@ +var DEBUG_TAG = 'METEOR CORDOVA DEBUG (autoupdate_cordova.js) '; +var log = function (msg) { + console.log(DEBUG_TAG + msg); +}; + +// This constant was picked by testing on iOS 7.1 +// We limit the number of concurrent downloads because iOS gets angry on the +// application when a certain limit is exceeded and starts timing-out the +// connections in 1-2 minutes which makes the whole HCP really slow. +var MAX_NUM_CONCURRENT_DOWNLOADS = 30; +var MAX_RETRY_COUNT = 5; + var autoupdateVersionCordova = __meteor_runtime_config__.autoupdateVersionCordova || "unknown"; // The collection of acceptable client versions. @@ -35,25 +47,18 @@ var writeFile = function (directoryPath, fileName, content, cb) { }; var restartServer = function (location) { - console.log('restartserver with location ' + location); - var fail = function (err) { console.log('something failed: ' + err.message) }; - var httpd = cordova && cordova.plugins && cordova.plugins.CorHttpd; + log('restartServer with location ' + location); + var fail = function (err) { log("Unexpected error in restartServer: " + err.message) }; + var httpd = cordova && cordova.plugins && cordova.plugins.CordovaUpdate; if (! httpd) { fail(new Error('no httpd')); return; } - var startServer = function (cordovajsRoot, prevUrl) { - var port; - if (prevUrl) { - var parts = prevUrl.split(':'); - if (parts.length) - port = parseInt(parts[parts.length - 1], 10); - } + var startServer = function (cordovajsRoot) { httpd.startServer({ 'www_root' : location, - 'port' : port, 'cordovajs_root': cordovajsRoot }, function (url) { Package.reload.Reload._reload(); @@ -61,17 +66,7 @@ var restartServer = function (location) { }; httpd.getCordovajsRoot(function (cordovajsRoot) { - httpd.getURL(function (url) { - if (url.length > 0) { - // already have a server running, stop it - httpd.stopServer(function () { - startServer(cordovajsRoot, url); - }, fail); - } else { - // just start a server - startServer(cordovajsRoot); - } - }, fail); + startServer(cordovajsRoot); }, fail); }; @@ -86,7 +81,7 @@ var onNewVersion = function () { HTTP.get(urlPrefix + '/manifest.json', function (err, res) { if (err || ! res.data) { - console.log('failed to download the manifest ' + (err && err.message) + ' ' + (res && res.content)); + log('Failed to download the manifest ' + (err && err.message) + ' ' + (res && res.content)); return; } @@ -97,20 +92,25 @@ var onNewVersion = function () { manifest.push({ url: '/index.html?' + Random.id() }); - var downloads = 0; - _.each(manifest, function (item) { - if (item.url) downloads++; - }); - var versionPrefix = localPathPrefix + version; - var afterAllFilesDownloaded = _.after(downloads, function () { + var queue = []; + _.each(manifest, function (item) { + if (! item.url) return; + + var url = item.url; + url = url.replace(/\?.+$/, ''); + + queue.push(url); + }); + + var afterAllFilesDownloaded = _.after(queue.length, function () { writeFile(versionPrefix, 'manifest.json', JSON.stringify(program, undefined, 2), function (err) { if (err) { - console.log("Failed to write manifest.json"); + log("Failed to write manifest.json: " + err); // XXX do something smarter? return; } @@ -120,7 +120,7 @@ var onNewVersion = function () { writeFile(localPathPrefix, 'version', version, function (err) { if (err) { - console.log("Failed to write version"); + log("Failed to write version: " + err); return; } @@ -134,12 +134,8 @@ var onNewVersion = function () { }); }); - _.each(manifest, function (item) { - if (! item.url) return; - - var url = item.url; - url = url.replace(/\?.+$/, ''); - + var dowloadUrl = function (url) { + console.log(DEBUG_TAG + "start dowloading " + url); // Add a cache buster to ensure that we don't cache an old asset. var uri = encodeURI(urlPrefix + url + '?' + Random.id()); @@ -148,20 +144,31 @@ var onNewVersion = function () { var tryDownload = function () { ft.download(uri, versionPrefix + url, function (entry) { if (entry) { + console.log(DEBUG_TAG + "done dowloading " + url); + // start downloading next queued url + if (queue.length) + dowloadUrl(queue.shift()); afterAllFilesDownloaded(); } }, function (err) { // It failed, try again if we have tried less than 5 times. - if (tries++ < 5) { + if (tries++ < MAX_RETRY_COUNT) { + log("Download error, will retry (#" + tries + "): " + uri); tryDownload(); } else { - console.log('fail source: ', error.source); - console.log('fail target: ', error.target); + log('Download failed: ' + err + ", source=" + err.source + ", target=" + err.target); } }); }; tryDownload(); + }; + + _.times(Math.min(MAX_NUM_CONCURRENT_DOWNLOADS, queue.length), function () { + var nextUrl = queue.shift(); + // XXX defer the next download so iOS doesn't rate limit us on concurrent + // downloads + Meteor.setTimeout(dowloadUrl.bind(null, nextUrl), 50); }); }); }; @@ -174,8 +181,8 @@ var failures = 0; Autoupdate._retrySubscription = function () { Meteor.subscribe("meteor_autoupdate_clientVersions", { - onError: function (error) { - Meteor._debug("autoupdate subscription failed:", error); + onError: function (err) { + Meteor._debug("autoupdate subscription failed:", err); failures++; retry.retryLater(failures, function () { // Just retry making the subscription, don't reload the whole diff --git a/packages/meteor-platform/package.js b/packages/meteor-platform/package.js index 34de81047c..ca8f719143 100644 --- a/packages/meteor-platform/package.js +++ b/packages/meteor-platform/package.js @@ -68,5 +68,5 @@ Package.on_use(function(api) { Cordova.depends({ 'org.apache.cordova.device': '0.2.11', - 'com.rjfun.cordova.httpd': 'https://github.com/meteor/cordova-httpd/tarball/0f1c8bc17e567c57a68427b0fe5e692ab6568d7f' + 'com.meteor.cordova-update': 'https://github.com/meteor/com.meteor.cordova-update/tarball/587af6eb67f8f3994309e17a90e8694b93ad47fe' }); diff --git a/scripts/dev-bundle-package.json b/scripts/dev-bundle-package.json index 390d0b1961..4b8a4b5955 100644 --- a/scripts/dev-bundle-package.json +++ b/scripts/dev-bundle-package.json @@ -7,6 +7,7 @@ "chalk": "0.5.1", "underscore": "1.5.2", "source-map-support": "0.2.5", - "semver": "2.2.1" + "semver": "2.2.1", + "ip": "0.3.2" } } diff --git a/tools/client/meteor_cordova_loader.js b/tools/client/meteor_cordova_loader.js index 39052fcace..e3f15f65c4 100644 --- a/tools/client/meteor_cordova_loader.js +++ b/tools/client/meteor_cordova_loader.js @@ -7,6 +7,10 @@ */ (function () { + var DEBUG_TAG = 'METEOR CORDOVA DEBUG (meteor_cordova_loader.js) '; + var log = function (msg) { + console.log(DEBUG_TAG + msg); + }; var readFile = function (url, cb) { window.resolveLocalFileSystemURL(url, function (fileEntry) { @@ -20,12 +24,12 @@ reader.readAsText(file); }; var fail = function (evt) { - cb(new Error("Failed to load entry"), null); + cb(new Error("Failed to load entry: " + url), null); }; fileEntry.file(success, fail); }, // error callback - function (err) { cb(new Error("Failed to load entry"), null); } + function (err) { cb(new Error("Failed to resolve entry: " + url), null); } ); }; @@ -41,47 +45,33 @@ return p.slice(1); }; - var randomInt = function (min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - }; - var loadTries = 0; var loadFromLocation = function (location) { var cordovaRoot = decodeURI(window.location.href).replace(/\/index.html$/, '/').replace(/^file:\/\/?/, ''); - var httpd = cordova && cordova.plugins && cordova.plugins.CorHttpd; - var port = randomInt(10000, 50000); + var httpd = cordova && cordova.plugins && cordova.plugins.CordovaUpdate; var retry = function () { loadTries++; if (loadTries > 10) { - console.log('Giving up on starting the server.'); + // XXX: If this means the app fails, we should probably do exponential backoff + // or at least show a message + log('Failed to start the server (too many retries)'); } else { - console.log('Retrying to to start the server.'); + log('Starting the server (retry #' + loadTries + ')'); loadFromLocation(location); } }; - httpd.getURL(function(url){ - if (url.length > 0) { - // if server is already running, stop it and retry - httpd.stopServer(retry, retry); - } else { - console.log('Starting the server on port ' + port); - httpd.startServer({ - 'www_root' : location, - 'port' : port, - 'cordovajs_root': cordovaRoot - }, function (url) { - // go to the new proxy url - window.location = url; - }, function (error) { - // failed to start a server, is port already in use? - retry(); - }); - } - - }, function () { - // failed to call to server: retry + httpd.startServer({ + 'www_root' : location, + 'cordovajs_root': cordovaRoot + }, function (url) { + // go to the new proxy url + log("Loading from url: " + url); + window.location = url; + }, function (error) { + // failed to start a server, is port already in use? + log("Failed to start the server: " + error); retry(); }); }; @@ -91,10 +81,9 @@ // no error is passed, then we simply do not have any new versions. var fallback = function (err) { if (err) { - console.log('Couldn\'t load from the manifest, ' + - 'falling back to the bundled assets.'); + log("Couldn't load from the manifest, falling back to the bundled assets."); } else { - console.log('No new versions saved to disk.'); + log('No new versions saved to disk.'); } loadFromLocation('application'); @@ -141,7 +130,8 @@ readFile(localPathPrefix + 'version', function (err, version) { if (err) { - fallback(); + log("Error reading version file " + err); + fallback(err); return; } @@ -162,10 +152,10 @@ // around on disk removeDirectory(localPathPrefix + name + '/', function (err) { if (err) { - console.log('Failed to remove an old cache folder ' - + name + ':' + err.message); + log('Failed to remove an old cache folder ' + + name + ':' + err.message); } else { - console.log('Successfully removed an old cache folder ' + name); + log('Successfully removed an old cache folder ' + name); } }); }); diff --git a/tools/commands-cordova.js b/tools/commands-cordova.js index eff8bc599d..f98c1ab54a 100644 --- a/tools/commands-cordova.js +++ b/tools/commands-cordova.js @@ -327,8 +327,13 @@ cordova.ensureCordovaPlatforms = function (localPath) { verboseLog('Ensuring that platforms in cordova build project are in sync'); var cordovaPath = path.join(localPath, 'cordova-build'); var platforms = project.getCordovaPlatforms(); - var platformsList = execFileSyncOrThrow(localCordova, ['platform', 'list'], - { cwd: cordovaPath }); + var platformsList = execFileSyncOrThrow( + localCordova, ['platform', 'list'], { cwd: cordovaPath }); + + // skip iOS platform if not on darwin + if (process.platform !== 'darwin') { + platforms = _.difference(platforms, ['ios']); + } verboseLog('The output of `cordova platforms list`:', platformsList.stdout); @@ -396,13 +401,26 @@ var installPlugin = function (cordovaPath, name, version, settings) { { cwd: cordovaPath }); if (! execRes.success) throw new Error("Failed to install plugin " + name + ": " + execRes.stderr); + + if (utils.isUrlWithSha(version)) { + var lock = getTarballPluginsLock(cordovaPath); + lock[name] = version; + writeTarballPluginsLock(cordovaPath, lock); + } }; -var uninstallPlugin = function (cordovaPath, name) { +var uninstallPlugin = function (cordovaPath, name, isFromTarballUrl) { verboseLog('Uninstalling a plugin', name); try { execFileSyncOrThrow(localCordova, ['plugin', 'rm', name], { cwd: cordovaPath }); + + if (isFromTarballUrl) { + // also remove from tarball-url-based plugins lock + var lock = getTarballPluginsLock(cordovaPath); + delete lock[name]; + writeTarballPluginsLock(cordovaPath, lock); + } } catch (err) { // Catch when an uninstall fails, because it might just be a dependency // issue. For example, plugin A depends on plugin B and we try to remove @@ -411,6 +429,43 @@ var uninstallPlugin = function (cordovaPath, name) { } }; +var getTarballPluginsLock = function (cordovaPath) { + verboseLog('Will check for cordova-tarball-plugins.json' + + ' for tarball-url-based plugins previously installed.'); + + var tarballPluginsLockPath = + path.join(cordovaPath, 'cordova-tarball-plugins.json'); + + var tarballPluginsLock; + try { + var text = fs.readFileSync(tarballPluginsLockPath, 'utf8'); + tarballPluginsLock = JSON.parse(text); + + verboseLog('The tarball plugins lock:', tarballPluginsLock); + } catch (err) { + if (err.code !== 'ENOENT') + throw err; + + verboseLog('The tarball plugins file was not found.'); + tarballPluginsLock = {}; + } + + return tarballPluginsLock; +}; + +var writeTarballPluginsLock = function (cordovaPath, tarballPluginsLock) { + verboseLog('Will write cordova-tarball-plugins.json'); + + var tarballPluginsLockPath = + path.join(cordovaPath, 'cordova-tarball-plugins.json'); + + fs.writeFileSync( + tarballPluginsLockPath, + JSON.stringify(tarballPluginsLock), + 'utf8' + ); +}; + // Returns the list of installed plugins as a hash from plugin name to version. var getInstalledPlugins = function (cordovaPath) { verboseLog('Getting installed plugins for project'); @@ -433,6 +488,11 @@ var getInstalledPlugins = function (cordovaPath) { }); } + // override the values of the plugins installed from tarballs + _.each(getTarballPluginsLock(cordovaPath), function (url, name) { + installedPlugins[name] = url; + }); + return installedPlugins; }; @@ -461,25 +521,30 @@ var ensureCordovaPlugins = function (localPath, options) { var cordovaPath = path.join(localPath, 'cordova-build'); var settingsFile = path.join(cordovaPath, 'cordova-settings.json'); - var newSettings; - if (options.settings) { - newSettings = - JSON.parse(fs.readFileSync(options.settings, "utf8")).cordova; - fs.writeFileSync(settingsFile, JSON.stringify(newSettings, null, 2), - 'utf8'); - } - var oldSettings; try { - oldSettings = JSON.parse(fs.readFileSync(settingsFile, 'utf8')); + oldSettings = JSON.parse(fs.readFileSync(settingsFile, 'utf8')) || {}; } catch(err) { if (err.code !== 'ENOENT') throw err; oldSettings = {}; } - // XXX compare the latest used sha's with the currently required sha's for - // plugins fetched from a github/tarball url. + var newSettings; + if (options.settings) { + var settingsText = fs.readFileSync(options.settings, "utf8"); + var parsedSettings = {}; + try { + parsedSettings = JSON.parse(settingsText); + } catch (err) { + throw new Error( + 'Passed --settings are not a valid JSON: ' + settingsText); + } + + newSettings = parsedSettings.cordova || {}; + fs.writeFileSync(settingsFile, JSON.stringify(newSettings, null, 2), + 'utf8'); + } var installedPlugins = getInstalledPlugins(cordovaPath); @@ -502,8 +567,7 @@ var ensureCordovaPlugins = function (localPath, options) { // XXX there is a hack here that never updates a package if you are // trying to install it from a URL, because we can't determine if // it's the right version or not - if (! _.has(installedPlugins, name) || - (installedPlugins[name] !== version && ! utils.isUrlWithSha(version))) { + if (! _.has(installedPlugins, name) || installedPlugins[name] !== version) { // The version of the plugin has changed, or we do not contain a plugin. shouldReinstallPlugins = true; } @@ -524,8 +588,8 @@ var ensureCordovaPlugins = function (localPath, options) { var uninstallAllPlugins = function () { installedPlugins = getInstalledPlugins(cordovaPath); while (_.size(installedPlugins)) { - _.each(_.keys(installedPlugins), function (name) { - uninstallPlugin(cordovaPath, name); + _.each(installedPlugins, function (version, name) { + uninstallPlugin(cordovaPath, name, utils.isUrlWithSha(version)); }); installedPlugins = getInstalledPlugins(cordovaPath); } @@ -629,8 +693,26 @@ var buildCordova = function (localPath, buildCommand, options) { verboseLog('Running the build command:', buildCommand); // Give the buffer more space as the output of the build is really huge - execFileSyncOrThrow(localCordova, [buildCommand], - { cwd: cordovaPath, maxBuffer: 2000*1024 }); + try { + execFileSyncOrThrow(localCordova, [buildCommand], + { cwd: cordovaPath, maxBuffer: 2000*1024 }); + } catch (err) { + // "ld: 100000 duplicate symbols for architecture i386" is a common error + // message that occurs when you run an iOS project compilation from /tmp or + // whenever there is a symbolic link cycle reachable for ld to multiple + // object files. + if (err.message.match(/ld: \d+ duplicate symbols/g)) { + // XXX a better message + var message = "Can't build an iOS project from the /tmp directory."; + + if (verboseness) + message = err.message + '\n' + message; + + throw new Error(message); + } else { + throw err; + } + } verboseLog('Done building the cordova build project'); }; @@ -755,16 +837,35 @@ var execCordovaOnPlatform = function (localPath, platformName, options) { var Log = getLoadedPackages().logging.Log; + var isDebugOutput = function (line) { + // Skip the debug output produced by Meteor Core components. + return /^METEOR CORDOVA DEBUG /.test(line) || /^HTTPD DEBUG /.test(line); + }; + var androidMapper = function (line) { // remove the annoying prefix line = line.replace(/^.\/CordovaLog\(\s*\d+\s*\):\s+/, ''); // remove a part of file url we don't like line = line.replace(/^file:\/\/\/android_asset\/www\//, ''); + line = line.replace(/^http:\/\/\d+\.\d+\.\d+\.\d+:\d+\//, ''); + + // ignore annoying lines that we see all the time but don't bring any value + if (line.match(/^--------- beginning of /) || + line.match(/^Changing log level to/) || + line.match(/^Found start page location: /)) { + return null; + } + + if (isDebugOutput(line) && ! verboseness) + return null; + // filename.js?hashsha1: Line 123 : message goes here - var parsedLine = line.match(/^([^?]+)(\?[a-zA-Z0-9]+)?: Line (\d+) : (.*)$/); + var parsedLine = + line.match(/^([^?]*)(\?[a-zA-Z0-9]+)?: Line (\d+) : (.*)$/); if (! parsedLine) - return Log.format(Log.objFromText(line), { color: true }); + return Log.format( + Log.objFromText(line), { metaColor: 'green', color: true }); var output = { time: new Date, @@ -780,11 +881,34 @@ var execCordovaOnPlatform = function (localPath, platformName, options) { }); }; + // In case of verboseness don't skip any logs. Otherwise skip all the scary + // stuff that gets printed before the app load. + var appLogsStarted = false || verboseness; var iosMapper = function (line) { if (line.match(/^[0-9]+-[0-9]+-[0-9].*/)) { // if the line starts with the date, we remove the prefix line = line.replace(/^\S+\s\S+\s\S+\s/, ''); } + + var finishedRegexp = + /Finished load of: http:\/\/[0-9]+.[0-9]+.[0-9]+.[0-9]+:[0-9]+/g; + + if (finishedRegexp.test(line)) + appLogsStarted = true; + + if (! appLogsStarted) + return null; + + // Skip the success messages from File Transfer. There are a lot of them on + // Hot-Code Push, but we are interested only in failures. + if (/File Transfer Finished with response code 200/.test(line) + && ! verboseness) { + return null; + } + + if (isDebugOutput(line) && ! verboseness) + return null; + return Log.format(Log.objFromText(line, { program: 'ios' }), { metaColor: 'cyan', color: true @@ -859,7 +983,7 @@ cordova.filterPackages = function (packages) { }; var getTermsForPlatform = function (platform) { - var url = 'http://s3.amazonaws.com/android-bundle/license_cordova_' + platform + '.txt'; + var url = 'https://warehouse.meteor.com/cordova/license_cordova_' + platform + '.txt'; var result = httpHelpers.request({ url: url }); diff --git a/tools/commands.js b/tools/commands.js index d1895df568..5d2ebb47fc 100644 --- a/tools/commands.js +++ b/tools/commands.js @@ -2,6 +2,7 @@ var main = require('./main.js'); var path = require('path'); var _ = require('underscore'); var fs = require('fs'); +var ip = require('ip'); var files = require('./files.js'); var deploy = require('./deploy.js'); var buildmessage = require('./buildmessage.js'); @@ -224,15 +225,20 @@ main.registerCommand({ options.httpProxyPort = options['http-proxy-port']; - // If we are targeting the remote devices + // If we are targeting the remote devices, warn about ports and same network if (_.intersection(options.args, ['ios-device', 'android-device']).length) { cordova.verboseLog('A run on a device requested'); - // ... and if you didn't specify your ip address as host, print a warning - if (parsedMobileHostPort.host === DEFAULT_BUILD_HOST) - Console.stderr.write( - "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: network's IP address with the -p or --mobile-port option?\n"); + Console.stderr.write([ +"WARNING: You are testing your app on a remote device.", +" For the mobile app to be able to connect to the local server, make", +" sure your device is on the same network, and that the network", +" configuration allows clients to talk to each other", +" (no client isolation).", +"", +" You can pass the host and the port in -p or --mobile-port argument.", +" For example: --mobile-port " + + ip.address() + ":" + parsedMobileHostPort.port + "\n\n" +].join("\n")); } // Always bundle for the browser by default. @@ -578,7 +584,19 @@ var buildCommands = { }; main.registerCommand(_.extend({ name: 'build' }, buildCommands), + function (options) { + return buildCommand(options); +}); + +// Deprecated -- identical functionality to 'build' +main.registerCommand(_.extend({ name: 'bundle', hidden: true }, buildCommands), function (options) { + Console.stdout.write("WARNING: 'bundle' has been deprecated. " + + "Use 'build' instead.\n"); + return buildCommand(options); +}); + +var buildCommand = function (options) { cordova.setVerboseness(options.verbose); // XXX output, to stderr, the name of the file written to (for human // comfort, especially since we might change the name) @@ -620,8 +638,11 @@ main.registerCommand(_.extend({ name: 'build' }, buildCommands), // warn about it. var cordovaBuildHost = parsedHostPort.host || DEFAULT_BUILD_HOST; if (cordovaBuildHost === DEFAULT_BUILD_HOST) { - process.stdout.write("WARNING: Building your app with host: localhost.\n" + - "Pass a -p argument to specify a host URL.\n"); + // XXX better error message? + process.stdout.write( + "Supply the server hostname and port argument in the -p option\n" + + "for the mobile apps builds.\n"); + return 1; } var cordovaSettings = {}; @@ -698,91 +719,7 @@ main.registerCommand(_.extend({ name: 'build' }, buildCommands), }); files.rm_recursive(buildDir); -}); - -// Deprecated -- identical functionality to 'build' -main.registerCommand(_.extend({ name: 'bundle', hidden: true }, buildCommands), - function (options) { - cordova.setVerboseness(options.verbose); - Console.stdout.write("WARNING: 'bundle' has been deprecated. " + - "Use 'build' instead.\n"); - // XXX if they pass a file that doesn't end in .tar.gz or .tgz, add - // the former for them - - // XXX output, to stderr, the name of the file written to (for human - // comfort, especially since we might change the name) - - // XXX name the root directory in the bundle based on the basename - // of the file, not a constant 'bundle' (a bit obnoxious for - // machines, but worth it for humans) - - // Error handling for options.architecture. We must pass in only one of three - // architectures. See archinfo.js for more information on what the - // architectures are, what they mean, et cetera. - var VALID_ARCHITECTURES = - ["os.osx.x86_64", "os.linux.x86_64", "os.linux.x86_32"]; - if (options.architecture && - _.indexOf(VALID_ARCHITECTURES, options.architecture) === -1) { - Console.stderr.write("Invalid architecture: " + options.architecture + "\n"); - Console.stderr.write( - "Please use one of the following: " + VALID_ARCHITECTURES + "\n"); - return 1; - } - var bundleArch = options.architecture || archinfo.host(); - - var buildDir = path.join(options.appDir, '.meteor', 'local', 'build_tar'); - var outputPath = path.resolve(options.args[0]); // get absolute path - var bundlePath = options['directory'] ? - outputPath : path.join(buildDir, 'bundle'); - - var loader; - var messages = buildmessage.capture(function () { - loader = project.getPackageLoader(); - }); - if (messages.hasMessages()) { - Console.stderr.write("Errors prevented bundling your app:\n"); - Console.stderr.write(messages.formatMessages()); - return 1; - } - - var statsMessages = buildmessage.capture(function () { - stats.recordPackages("sdk.bundle"); - }); - if (statsMessages.hasMessages()) { - Console.stdout.write("Error recording package list:\n" + - statsMessages.formatMessages()); - // ... but continue; - } - - var bundler = require(path.join(__dirname, 'bundler.js')); - var bundleResult = bundler.bundle({ - outputPath: bundlePath, - buildOptions: { - minify: ! options.debug, - // XXX is this a good idea, or should linux be the default since - // that's where most people are deploying - // default? i guess the problem with using DEPLOY_ARCH as default - // is then 'meteor bundle' with no args fails if you have any local - // packages with binary npm dependencies - serverArch: bundleArch - } - }); - if (bundleResult.errors) { - Console.stderr.write("Errors prevented bundling:\n"); - Console.stderr.write(bundleResult.errors.formatMessages()); - return 1; - } - - if (!options['directory']) { - try { - files.createTarball(path.join(buildDir, 'bundle'), outputPath); - } catch (err) { - console.log(JSON.stringify(err)); - Console.stderr.write("Couldn't create tarball\n"); - } - } - files.rm_recursive(buildDir); -}); +}; /////////////////////////////////////////////////////////////////////////////// // mongo diff --git a/tools/cordova-scripts/ensure_android_bundle.sh b/tools/cordova-scripts/ensure_android_bundle.sh index c2db0330a6..59f7c7daac 100755 --- a/tools/cordova-scripts/ensure_android_bundle.sh +++ b/tools/cordova-scripts/ensure_android_bundle.sh @@ -95,7 +95,7 @@ install_android_bundle () { rm -rf "$BUNDLE_TMPDIR" mkdir "$BUNDLE_TMPDIR" - ANDROID_BUNDLE_URL_ROOT="http://s3.amazonaws.com/android-bundle/" + ANDROID_BUNDLE_URL_ROOT="https://warehouse.meteor.com/cordova/" if [ -f "$DEST_DIR/$TARBALL" ] ; then echo "Skipping download and installing kit from $DEST_DIR/$TARBALL" >&2 diff --git a/tools/utils.js b/tools/utils.js index 851f28da12..7251b85307 100644 --- a/tools/utils.js +++ b/tools/utils.js @@ -461,7 +461,8 @@ exports.execFileAsync = function (file, args, opts) { var logOutput = fiberHelpers.bindEnvironment(function (line) { if (opts.verbose) { line = mapper(line); - console.log(line); + if (line) + console.log(line); } });