Skip to content

Commit

Permalink
added shebang recognition: append any text *after* the initial sheban…
Browse files Browse the repository at this point in the history
…g, IFF the file has any. This fixes silesky/prepend-header#5
  • Loading branch information
GerHobbelt committed Aug 8, 2020
1 parent 539d6ce commit f9e181c
Showing 1 changed file with 57 additions and 2 deletions.
59 changes: 57 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,30 @@ function stripBOM(text) {
return text.toString().slice(1);
}

function hasHashBang(text) {
return /^#![^\r\n]+/.test(text.toString());
}

function prependHashBang(text, bang) {
return bang + '\n\n' + text;
}

function extractHashBang(text) {
const m = /^(#![^\r\n]+)/.exec(text.toString());
return m ? m[0] : '';
}

function stripHashBang(text) {
let s = text.toString();
const m = /^(#![^\r\n]+[\r\n]+)/.exec(s);
if (m) {
const bang = m[0];
s = s.slice(bang.length);
}

return s;
}

module.exports = async (filename, data) => {
if (await pathExists(filename)) {
let bomFound = false;
Expand Down Expand Up @@ -50,10 +74,41 @@ module.exports = async (filename, data) => {
}
});

let bangFound = false;
let bangPlaced = false;
let bangCache = null;

const checkStripHashBangTransformer = new Transform({
transform(chunk, encoding, callback) {
let fileData = chunk;

if (!bangFound) {
bangFound = hasHashBang(fileData);
bangCache = extractHashBang(fileData);
fileData = bangFound ? stripHashBang(fileData) : fileData;
}

callback(false, Buffer.from(fileData));
}
});

const checkPrependHashBangTransformer = new Transform({
transform(chunk, encoding, callback) {
let fileData = chunk.toString();

if (bangFound && !bangPlaced) {
fileData = prependHashBang(fileData, bangCache);
bangPlaced = true;
}

callback(false, Buffer.from(fileData));
}
});

const temporaryFile = await tempWrite(data);

await pipeline(fs.createReadStream(filename), checkStripBomTransformer, fs.createWriteStream(temporaryFile, {flags: 'a'}));
await pipeline(fs.createReadStream(temporaryFile), checkPrependBomTransformer, fs.createWriteStream(filename));
await pipeline(fs.createReadStream(filename), checkStripBomTransformer, checkStripHashBangTransformer, fs.createWriteStream(temporaryFile, {flags: 'a'}));
await pipeline(fs.createReadStream(temporaryFile), checkPrependHashBangTransformer, checkPrependBomTransformer, fs.createWriteStream(filename));

await fs.promises.unlink(temporaryFile);
} else {
Expand Down

0 comments on commit f9e181c

Please sign in to comment.