Handle shebang in ScriptFileStorage load/save

Before this change, ScriptFileStorage.load was returning source code
including shebang (#!/usr/bin/node). This prevented the front-end
from matching the file on disk with the script loaded in Node/V8.
As a result, `node-debug _mocha` did not show the breakpoint in
the _mocha file.

ScriptFileStorage.save is preserving shebang when saving the updated
file now, so that live edit works as expected.
This commit is contained in:
Miroslav Bajtoš 2014-02-26 11:49:34 -08:00
Родитель ffbfbe9e92
Коммит 5f95f5b201
2 изменённых файлов: 50 добавлений и 6 удалений

Просмотреть файл

@ -37,9 +37,18 @@ $class.save = function(path, content, callback) {
return;
}
var newSource = match[1];
fs.writeFile(path, newSource, function(err) {
callback(err);
});
async.waterfall([
fs.readFile.bind(fs, path, 'utf-8'),
function(oldContent, cb) {
var match = /^(\#\!.*)/.exec(oldContent);
if (match)
newSource = match[1] + newSource;
fs.writeFile(path, newSource, cb);
}
],
callback);
};
/**
@ -52,6 +61,10 @@ $class.load = function(path, callback) {
{ encoding: 'utf-8' },
function(err, content) {
if (err) return callback(err);
// remove shebang
content = content.replace(/^\#\!.*/, '');
var source = MODULE_HEADER + content + MODULE_TRAILER;
return callback(null, source);
}

Просмотреть файл

@ -30,6 +30,21 @@ describe('ScriptFileStorage', function() {
});
});
it('preserves shebang when saving new content', function(done) {
runLiveEdit(
function(content) { return '#!/usr/bin/node\n' + content; },
function(debuggerClient, originalScript, runtimeScript) {
var storage = new ScriptFileStorage();
storage.save(TEMP_FILE, edited(runtimeScript), function(err) {
if (err) throw err;
var newScript = fs.readFileSync(TEMP_FILE, { encoding: 'utf-8' });
expect(newScript).to.equal(edited(originalScript));
done();
});
}
);
});
it('loads content with node.js module wrapper', function(done) {
fs.writeFileSync(TEMP_FILE, '/* content */');
storage.load(TEMP_FILE, function(err, content) {
@ -40,6 +55,16 @@ describe('ScriptFileStorage', function() {
});
});
it('loads content without shebang', function(done) {
fs.writeFileSync(TEMP_FILE, '#!/usr/bin/env/node\n/* content */');
storage.load(TEMP_FILE, function(err, content) {
if (err) throw err;
expect(content).to.not.contain('#!');
expect(content).to.contain('/* content */');
done();
});
});
it('finds application root for subdir/app.js by checking package.json file in parent',
function(done) {
givenTempFiles('subdir/', 'subdir/app.js', 'package.json');
@ -217,8 +242,13 @@ describe('ScriptFileStorage', function() {
return source.replace(';', '; /* edited */');
}
function runLiveEdit(callback) {
var originalScript = createTempFileAsCopyOf('LiveEdit.js');
function runLiveEdit(transformSource, callback) {
if (!callback) {
callback = transformSource;
transformSource = null;
}
var originalScript = createTempFileAsCopyOf('LiveEdit.js', transformSource);
launcher.startDebugger(TEMP_FILE, function(childProcess, debuggerClient) {
getScriptSourceByName(debuggerClient, TEMP_FILE, function(source) {
callback(debuggerClient, originalScript, source);
@ -226,9 +256,10 @@ describe('ScriptFileStorage', function() {
});
}
function createTempFileAsCopyOf(fixture) {
function createTempFileAsCopyOf(fixture, transform) {
var sourcePath = path.join(__dirname, 'fixtures', fixture);
var content = fs.readFileSync(sourcePath, { encoding: 'utf-8' });
if (transform) content = transform(content);
fs.writeFileSync(TEMP_FILE, content);
return content;
}