Skip to content

Commit

Permalink
Merge pull request #3753 from bryan-m-hughes/timob-12364
Browse files Browse the repository at this point in the history
Timob 12364 iOS Logging fixes
  • Loading branch information
cb1kenobi committed Jan 22, 2013
2 parents 18adf4f + 74fbe81 commit abf0d65
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 66 deletions.
129 changes: 64 additions & 65 deletions iphone/cli/hooks/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,43 @@ var appc = require('node-appc'),
path = require('path'),
parallel = require('async').parallel,
cp = require('child_process'),
Readable = require('readable-stream'),
exec = cp.exec,
spawn = cp.spawn;

exports.cliVersion = '>=3.X';

exports.init = function (logger, config, cli) {

cli.addHook('build.post.compile', {
priority: 10000,
post: function (build, finished) {
if (cli.argv.target != 'simulator') return finished();

if (cli.argv['build-only']) {
logger.info(__('Performed build only, skipping running of the application'));
return finished();
}

logger.info(__('Running application in iOS Simulator'));

var simulatorDir = afs.resolvePath('~/Library/Application Support/iPhone Simulator/' + build.iosSimVersion + '/Applications'),
logFile = build.tiapp.guid + '.log';

parallel([
function (next) {
logger.debug(__('Terminating all iOS simulators'));
exec('/usr/bin/killall ios-sim', next);
},

function (next) {
exec('/usr/bin/killall "iPhone Simulator"', next);
},

function (next) {
setTimeout(next, 2000);
},

function (next) {
// sometimes the simulator doesn't remove old log files in which case we get
// our logging jacked - we need to remove them before running the simulator
Expand All @@ -60,7 +61,7 @@ exports.init = function (logger, config, cli) {
fs.unlinkSync(file);
}
});

next();
}
], function () {
Expand Down Expand Up @@ -90,122 +91,120 @@ exports.init = function (logger, config, cli) {
simErr = [],
stripLogLevelRE = new RegExp('[(?:' + logger.getLevels().join('|') + ')] '),
logProcess;

cli.argv.retina && cmd.push('--retina');
cmd = cmd.join(' ');

logger.info(__('Launching application in iOS Simulator'));
logger.debug(__('Simulator command: %s', cmd.cyan));

simProcess = spawn('/bin/sh', ['-c', cmd], {
cwd: build.titaniumIosSdkPath,
env: {
DYLD_FRAMEWORK_PATH: path.join(build.xcodeEnv.path, 'Platforms', 'iPhoneSimulator.platform', 'Developer', 'Library', 'PrivateFrameworks') +
':' + afs.resolvePath(build.xcodeEnv.path, '..', 'OtherFrameworks')
}
});

simProcess.stderr.on('data', function (data) {
data.toString().split('\n').forEach(function (line) {
line.length && simErr.push(line.replace(stripLogLevelRE, ''));
}, this);
}.bind(this));

simProcess.on('exit', function (code, signal) {
clearTimeout(simActivateTimer);
clearTimeout(findLogTimer);
logProcess && logProcess.kill();

if (code) {
finished(new appc.exception(__('An error occurred running the iOS Simulator'), simErr));
} else {
logger.info(__('Application has exited from iOS Simulator'));
finished();
}
}.bind(this));

function findLogFile() {
var files = fs.readdirSync(simulatorDir),
file,
i = 0,
l = files.length,
logLevelRE = new RegExp('(\u001b\\[\\d+m)?\\[?(' + logger.getLevels().join('|') + ')\\]?\s*(\u001b\\[\\d+m)?(.*)', 'i');

for (; i < l; i++) {
file = path.join(simulatorDir, files[i], 'Documents', logFile);
if (afs.exists(file)) {
logger.debug(__('Found iPhone Simulator log file: %s', file.cyan));
logger.info(__('iPhone Simulator log:'));

var stat = fs.lstatSync(file),
bytesRead = 0,
queue = [ stat.size ],
buffer = '';

function pump(callback) {
if (queue.length >= 1) {
var readTo = queue[0];

var stream = fs.createReadStream(file, {
start: bytesRead,
end: readTo - 1,
encoding: 'utf-8',
bufferSize: 16
});

stream.on('error', function(error) {
console.log('Tail error: ' + error);
});

stream.on('end', function() {
bytesRead = readTo;
queue.shift();
if (queue.length >= 1) {
pump();
} else {
callback && callback();
}
});

stream.on('data', function (data) {
buffer += data;
var lines = buffer.split('\n');

var bytesRead = 0,
buffer = '',
stream;

(function pump() {
function processBuffer() {
var lines,
m,
newData = stream.read();
if (newData) {
buffer += newData;
bytesRead += newData.length;
lines = buffer.split('\n');
buffer = lines.pop(); // keep the last line because it could be incomplete
lines.forEach(function (line) {
if (line) {
var m = line.match(logLevelRE);
m = line.match(logLevelRE);
if (m) {
logger[m[2].toLowerCase()](m[4].trim());
} else {
logger.debug(line);
}
}
});
});
}
}

pump(function () {
fs.watch(file, { persistent: false }, function () {
queue.push(fs.lstatSync(file).size);
if (queue.length == 1) {
pump();
}
}

stream = new Readable();
stream.wrap(fs.createReadStream(file, {
start: bytesRead,
encoding: 'utf-8',
bufferSize: 16
}));
processBuffer();

stream.on('end', function() {
// Remove the event listeners to prevent possible memory leaks (readable-stream is still
// experimental, and I've seen memory leaks happen a few times)
stream.removeAllListeners('end');
stream.removeAllListeners('readable');
pump();
});

stream.on('readable', function () {
processBuffer();
});
})();

simProcess.on('exit', function() {
if (stream) {
stream.removeAllListeners('end');
stream.removeAllListeners('readable');
}
});

// we found the log file, no need to keep searching for it
return;
}
}

// didn't find any log files, try again in 250ms
findLogTimer = setTimeout(findLogFile, 250);
}

afs.exists(simulatorDir) && findLogFile();
});
}
});

};
3 changes: 2 additions & 1 deletion support/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"titanium-sdk": ">=0.1.0",
"uglify-js": "2.2.x",
"wrench": "1.3.x",
"xmldom": "0.1.11"
"xmldom": "0.1.11",
"readable-stream": "0.2.x"
},
"engines": {
"node": ">=0.6.6"
Expand Down

0 comments on commit abf0d65

Please sign in to comment.