blob: a25c5b2753d8c31edc81485376628070f7bc3d34 [file] [log] [blame]
#!/usr/bin/env node
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* jshint node: true */
"use strict";
var shelljs = require("shelljs");
var optimist = require("optimist");
var fs = require("fs");
var path = require("path");
var util = require("../lib/util");
// constants
var DEVICE_ROW_PATTERN = /(emulator|device|host)/m;
var HEADING_LINE_PATTERN = /List of devices/m;
var DEFAULT_APP_PATH = "mobilespec";
// helpers
function logAndroid() {
var logCommand = "adb logcat -d";
var listCommand = "adb devices";
util.medicLog("running:");
util.medicLog(" " + listCommand);
// bail out if there is more/less than one device
var numDevices = 0;
var result = shelljs.exec(listCommand, {silent: false, async: false});
result.output.split('\n').forEach(function (line) {
if (!HEADING_LINE_PATTERN.test(line) && DEVICE_ROW_PATTERN.test(line)) {
numDevices += 1;
}
});
if (numDevices != 1) {
util.fatal("there must be exactly one emulator/device attached");
}
// log the output
util.medicLog("running:");
util.medicLog(" " + logCommand);
shelljs.exec(logCommand, {silent: false, async: false}, function (code, output) {
if (code > 0) {
util.fatal("Failed to run logcat command.");
}
});
}
function logBlackberry() {
return;
}
function logIOS(appPath) {
// We need to print out the system log for the simulator app. In order to figure
// out the path to that file, we need to find the ID of the simulator running
// mobilespec
// First, figure out the simulator that ran mobilespec. "cordova run"" just chooses
// the last simulator in this list that starts with the word "iPhone"
shelljs.pushd(appPath);
var findSimCommand = getLocalCLI() + " run --list --emulator | grep ^iPhone | tail -n1";
util.medicLog("running:");
util.medicLog(" " + findSimCommand);
var findSimResult = shelljs.exec(findSimCommand);
if (findSimResult.code > 0) {
util.fatal("Failed to find simulator we deployed to");
return;
}
var split = findSimResult.output.split(", ");
// Format of the output is "iPhone-6s-Plus, 9.1"
// Extract the device name and the version number
var device = split[0].replace(/-/g, " ").trim();
var version = split[1].trim();
// Next, figure out the ID of the simulator we found
var instrCommand = "instruments -s devices | grep ^iPhone";
util.medicLog("running:");
util.medicLog(" " + instrCommand);
var instrResult = shelljs.exec(instrCommand);
if (instrResult.code > 0) {
util.fatal("Failed to get the list of simulators");
return;
}
// This matches <device> (<version>) [<simulator-id>]
var simIdRegex = /^([a-zA-Z\d ]+) \(([\d.]+)\) \[([a-zA-Z\d\-]*)\]$/;
var simId = null;
var lines = instrResult.output.split(/\n/);
lines.forEach(function(line) {
var simIdMatch = simIdRegex.exec(line);
if (simIdMatch && simIdMatch.length === 4 && simIdMatch[1] === device && simIdMatch[2] === version) {
simId = encodeURIComponent(simIdMatch[3]);
}
});
if (simId) {
// Now we can print out the log file
var logPath = path.join("~", "Library", "Logs", "CoreSimulator", simId, "system.log");
var logCommand = "cat " + logPath;
util.medicLog("Attempting to print the iOS simulator system log");
var logResult = shelljs.exec(logCommand);
if (logResult.code > 0) {
util.fatal("Failed to cat the simulator log");
}
} else {
util.fatal("Failed to find ID of mobilespec simulator");
}
}
function logWindows(timeout) {
var logScriptPath = path.join("mobilespec", "platforms", "windows", "cordova", "log.bat");
if (fs.existsSync(logScriptPath)) {
var mins = util.DEFAULT_LOG_TIME;
if (timeout) {
mins = util.secToMin(timeout) + util.DEFAULT_LOG_TIME_ADDITIONAL;
}
shelljs.exec(logScriptPath + " --dump --mins " + mins, function (code, output) {
if (code > 0) {
util.fatal("Failed to run log command.");
}
});
}
}
function getLocalCLI() {
if (util.isWindows()) {
return "cordova.bat";
} else {
return "./cordova";
}
}
// main
function main() {
// shell config
shelljs.config.fatal = false;
shelljs.config.silent = false;
// command-specific args
var argv = optimist
.usage("Usage: $0 [options]")
.demand("platform")
.default("app", DEFAULT_APP_PATH)
.describe("platform", "Gather logs for this platform.")
.describe("app", "iOS only, path to a Cordova Application.")
.describe("timeout", "Windows only, gather logs for last n seconds.")
.argv;
var platform = argv.platform;
var timeout = argv.timeout;
var appPath = argv.app ? argv.app : DEFAULT_APP_PATH;
switch (platform) {
case util.ANDROID:
logAndroid();
break;
case util.BLACKBERRY:
logBlackberry();
break;
case util.IOS:
logIOS(appPath);
break;
case util.WINDOWS:
logWindows(timeout);
break;
default:
console.warn("Logging is unsupported for " + platform);
break;
}
}
main();