mili
Version:
Scaffolding with continuous control over the development of the project.
133 lines (132 loc) • 5.56 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.showRemoved = exports.showDiff = void 0;
const diff_1 = require("diff");
const chalk = require("chalk");
const R = require("ramda");
const infer_encoding_1 = require("./infer-encoding");
const createLineNumberFormater = (maxOldLineNumberLength, maxNewLineNumberLength) => (oldNumber, newNumber) => {
const oldNumberStr = R.isNil(oldNumber) ? ' ' : String(oldNumber);
const newNumberStr = R.isNil(newNumber) ? ' ' : String(newNumber);
const oldN = oldNumberStr.padEnd(maxOldLineNumberLength, ' ');
const newN = newNumberStr.padEnd(maxNewLineNumberLength, ' ');
return `${oldN}|${newN} `;
};
const createLineFormater = (maxOldLineNumber, maxNewLineNumber) => {
const maxOldLineNumberLength = String(maxOldLineNumber).length;
const maxNewLineNumberLength = String(maxNewLineNumber).length;
const formatLineNumber = createLineNumberFormater(maxOldLineNumberLength, maxNewLineNumberLength);
return (oldNumber, newNumber, tag, str, fold) => {
let lines = str.match(/((.*\n)|(.+$))/g) || [];
lines = lines
.map((line, i) => {
const oldNumberWithOffset = oldNumber && oldNumber + i;
const newNumberWithOffset = newNumber && newNumber + i;
const lineNumber = formatLineNumber(oldNumberWithOffset, newNumberWithOffset);
return `${lineNumber} ${tag} ${line.replace(/(\n$)/, '')}\n`;
});
if (fold && lines.length > 2) {
const dot = '...\n'.padStart(maxOldLineNumberLength + 3, ' ');
lines.splice(1, lines.length - 2, dot);
}
return lines.join('');
};
};
const createEndLineValider = (diffPairs) => {
const index = [...diffPairs].reverse().findIndex(item => !item.added && !item.removed);
const count = diffPairs.length - 1;
const lastSamePairIndex = index >= 0 ? count - index : index;
return i => {
if (lastSamePairIndex < i)
return true;
else if (lastSamePairIndex === diffPairs.length - 1 && lastSamePairIndex === i)
return true;
return false;
};
};
function diffBody(oldContent, newContent, options) {
let str = '';
let oldLineNumber = 1;
let newLineNumber = 1;
const maxOldLineNumber = oldContent.split('\n').length;
const maxNewLineNumber = oldContent.split('\n').length;
const formatLine = createLineFormater(maxOldLineNumber, maxNewLineNumber);
const diffPairs = (0, diff_1.diffLines)(oldContent, newContent);
const isEndLine = createEndLineValider(diffPairs);
diffPairs.forEach(({ added, removed, value }, i) => {
const needFillEndLine = isEndLine(i);
const inc = value.split('\n').length - 1;
if (added) {
const strWithoutColor = formatLine(null, newLineNumber, '+', value);
str += chalk.green(strWithoutColor);
newLineNumber += inc;
}
else if (removed) {
const strWithoutColor = formatLine(oldLineNumber, null, '-', value);
str += chalk.red(strWithoutColor);
oldLineNumber += inc;
}
else {
const strWithoutColor = formatLine(oldLineNumber, newLineNumber, ' ', value, options.fold);
str += chalk.grey(strWithoutColor);
newLineNumber += inc;
oldLineNumber += inc;
}
/**
* Add an empty line,
* if '\n' at the end of file.
* So, It's easy to tell if the last line end with '\n'
*/
if (needFillEndLine && /\n$/.test(value)) {
if (added) {
const strWithoutColor = formatLine(null, newLineNumber, '+', '\n');
str += chalk.green(strWithoutColor);
newLineNumber += 1;
}
else if (removed) {
const strWithoutColor = formatLine(oldLineNumber, null, '-', '\n');
str += chalk.red(strWithoutColor);
oldLineNumber += 1;
}
else {
const strWithoutColor = formatLine(oldLineNumber, newLineNumber, ' ', '\n');
str += chalk.grey(strWithoutColor);
newLineNumber += 1;
oldLineNumber += 1;
}
}
});
return str;
}
function showDiff(filename, oldBuffer, newBuffer, options = {}) {
let str = '';
if ((0, infer_encoding_1.inferEncoding)(filename) !== 'utf8') {
str = 'The file format is not supported';
}
else {
const oldContent = oldBuffer.toString('utf-8');
const newContent = newBuffer.toString('utf-8');
str = diffBody(oldContent, newContent, options);
}
const headerLength = filename.length + 4;
const header = chalk.yellow([
Array(headerLength).fill('=').join(''),
` ${filename} `,
Array(headerLength).fill('-').join(''),
].join('\n'));
const footer = chalk.yellow(Array(headerLength).fill('=').join(''));
return ['\n', header, str, footer].join('\n');
}
exports.showDiff = showDiff;
function showRemoved(filename) {
const str = 'The file should be remove';
const headerLength = filename.length + 4;
const header = chalk.red([
Array(headerLength).fill('=').join(''),
` ${filename} `,
Array(headerLength).fill('-').join(''),
].join('\n'));
const footer = chalk.red(Array(headerLength).fill('=').join(''));
return ['\n', header, str, footer].join('\n');
}
exports.showRemoved = showRemoved;