mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'cordova-0.9.4' into release-0.9.4
Some Cordova fixes and the new on-device server
This commit is contained in:
@@ -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
|
||||
|
||||
2
meteor
2
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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user