Commit 19eb7acd by lxyang

feat: 上传改版新增parse-diff组件源码

parent 29774858
src/
node_modules/
dist/
fixtures/
.history/
\ No newline at end of file
{
"name": "babel-plugin-ry-istanbul",
"version": "0.0.4-bat",
"name": "babel-plugin-ry-istanbul-web",
"version": "0.0.3-bat",
"author": "Thai Pangsakulyanont @dtinth",
"license": "BSD-3-Clause",
"description": "A babel plugin that adds istanbul instrumentation to ES6 code",
......@@ -21,7 +21,6 @@
"cross-env": "^7.0.3",
"istanbul-lib-coverage": "^1.0.0",
"onchange": "^7.1.0",
"parse-diff": "^0.9.0",
"ry-istanbul-web": "^0.0.1",
"semver": "^6.3.0",
"test-exclude": "^6.0.0"
......@@ -31,24 +30,28 @@
"@babel/core": "^7.7.5",
"@babel/plugin-proposal-optional-chaining": "^7.16.7",
"@babel/plugin-transform-modules-commonjs": "^7.7.5",
"@babel/preset-env": "^7.19.3",
"@babel/register": "^7.7.4",
"chai": "^4.2.0",
"coveralls": "^3.0.9",
"cross-env": "^6.0.3",
"gaze": "^1.1.3",
"mocha": "^6.2.2",
"nyc": "^15.0.0",
"pmock": "^0.2.3",
"standard": "^14.3.1",
"babel-cli": "^6.3.17",
"babel-plugin-istanbul": "^2.0.3",
"babel-preset-es2015": "^6.3.13",
"babel-register": "^6.16.3",
"chai": "^4.2.0",
"clone": "^2.0.0",
"coveralls": "^3.0.9",
"cross-env": "^6.0.3",
"documentation": "^4.0.0-beta9",
"eslint": "^6.8.0",
"gaze": "^1.1.3",
"jest": "^29.1.2",
"js-yaml": "^3.3.1",
"jshint": "^2.8.0",
"mocha": "^6.2.2",
"nopt": "^3.0.6",
"nyc": "^15.0.0",
"pmock": "^0.2.3",
"prettier": "^2.7.1",
"standard": "^14.3.1",
"standard-version": "^3.0.0"
},
"scripts": {
......
......@@ -6,7 +6,7 @@ import { declare } from '@babel/helper-plugin-utils'
import { programVisitor } from 'istanbul-lib-instrument'
import TestExclude from 'test-exclude'
import schema from '@istanbuljs/schema'
import parseDiffData from 'parse-diff'
import parseDiffData from './parse-diff'
function getRealpath(n) {
try {
......@@ -138,7 +138,7 @@ export default declare(api => {
}
// instrumenttation (branch: git diff 跟那个分支对比, increment 是否开启增量代码检测) 拿配置到底是全量代码还是增量代码
if (!IS_PITCHING_PILE_DATA) {
return
return false
}
// const changeList = []
// 下面的是零时的
......@@ -151,6 +151,7 @@ export default declare(api => {
if (INCREMENT_DATA && BRANCH_DATA) {
const gitDiffCode = execSync(`git diff ${BRANCH_DATA}`)
const diffData = parseDiffData(gitDiffCode.toString())
console.log(diffData, 'diffData')
diffScreen = diffData.find(item => {
return realPath.indexOf(item.to) > -1
})
......
declare function parseDiff(input?: string | null): parseDiff.File[];
declare namespace parseDiff {
export interface File {
chunks: Chunk[];
deletions: number;
additions: number;
from?: string;
to?: string;
index?: string[];
deleted?: true;
new?: true;
}
export interface Chunk {
content: string;
changes: Change[];
oldStart: number;
oldLines: number;
newStart: number;
newLines: number;
}
export interface NormalChange {
type: 'normal';
ln1: number;
ln2: number;
normal: true;
content: string;
}
export interface AddChange {
type: 'add';
add: true;
ln: number;
content: string;
}
export interface DeleteChange {
type: 'del';
del: true;
ln: number;
content: string;
}
export type ChangeType = 'normal' | 'add' | 'del';
export type Change = NormalChange | AddChange | DeleteChange;
}
export = parseDiff;
"use strict";module.exports=input=>{if(!input)return[];if(typeof input!=="string"||input.match(/^\s+$/))return[];const lines=input.split("\n");if(lines.length===0)return[];const files=[];let currentFile=null;let currentChunk=null;let deletedLineCounter=0;let addedLineCounter=0;let currentFileChanges=null;const normal=line=>{var _currentChunk;(_currentChunk=currentChunk)===null||_currentChunk===void 0?void 0:_currentChunk.changes.push({type:"normal",normal:true,ln1:deletedLineCounter++,ln2:addedLineCounter++,content:line});currentFileChanges.oldLines--;currentFileChanges.newLines--};const start=line=>{const[fromFileName,toFileName]=parseFiles(line)??[];currentFile={chunks:[],deletions:0,additions:0,from:fromFileName,to:toFileName};files.push(currentFile)};const restart=()=>{if(!currentFile||currentFile.chunks.length)start()};const newFile=()=>{restart();currentFile.new=true;currentFile.from="/dev/null"};const deletedFile=()=>{restart();currentFile.deleted=true;currentFile.to="/dev/null"};const index=line=>{restart();currentFile.index=line.split(" ").slice(1)};const fromFile=line=>{restart();currentFile.from=parseOldOrNewFile(line)};const toFile=line=>{restart();currentFile.to=parseOldOrNewFile(line)};const toNumOfLines=number=>+(number||1);const chunk=(line,match)=>{if(!currentFile)return;const[oldStart,oldNumLines,newStart,newNumLines]=match.slice(1);deletedLineCounter=+oldStart;addedLineCounter=+newStart;currentChunk={content:line,changes:[],oldStart:+oldStart,oldLines:toNumOfLines(oldNumLines),newStart:+newStart,newLines:toNumOfLines(newNumLines)};currentFileChanges={oldLines:toNumOfLines(oldNumLines),newLines:toNumOfLines(newNumLines)};currentFile.chunks.push(currentChunk)};const del=line=>{if(!currentChunk)return;currentChunk.changes.push({type:"del",del:true,ln:deletedLineCounter++,content:line});currentFile.deletions++;currentFileChanges.oldLines--};const add=line=>{if(!currentChunk)return;currentChunk.changes.push({type:"add",add:true,ln:addedLineCounter++,content:line});currentFile.additions++;currentFileChanges.newLines--};const eof=line=>{if(!currentChunk)return;const[mostRecentChange]=currentChunk.changes.slice(-1);currentChunk.changes.push({type:mostRecentChange.type,[mostRecentChange.type]:true,ln1:mostRecentChange.ln1,ln2:mostRecentChange.ln2,ln:mostRecentChange.ln,content:line})};const schemaHeaders=[[/^diff\s/,start],[/^new file mode \d+$/,newFile],[/^deleted file mode \d+$/,deletedFile],[/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/,index],[/^---\s/,fromFile],[/^\+\+\+\s/,toFile],[/^@@\s+-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/,chunk],[/^\\ No newline at end of file$/,eof]];const schemaContent=[[/^-/,del],[/^\+/,add],[/^\s+/,normal]];const parseContentLine=line=>{for(const[pattern,handler]of schemaContent){const match=line.match(pattern);if(match){handler(line,match);break}}if(currentFileChanges.oldLines===0&&currentFileChanges.newLines===0){currentFileChanges=null}};const parseHeaderLine=line=>{for(const[pattern,handler]of schemaHeaders){const match=line.match(pattern);if(match){handler(line,match);break}}};const parseLine=line=>{if(currentFileChanges){parseContentLine(line)}else{parseHeaderLine(line)}return};for(const line of lines)parseLine(line);return files};const fileNameDiffRegex=/a\/.*(?=["']? ["']?b\/)|b\/.*$/g;const gitFileHeaderRegex=/^(a|b)\//;const parseFiles=line=>{let fileNames=line===null||line===void 0?void 0:line.match(fileNameDiffRegex);return fileNames===null||fileNames===void 0?void 0:fileNames.map(fileName=>fileName.replace(gitFileHeaderRegex,"").replace(/("|')$/,""))};const qoutedFileNameRegex=/^\\?['"]|\\?['"]$/g;const parseOldOrNewFile=line=>{let fileName=leftTrimChars(line,"-+").trim();fileName=removeTimeStamp(fileName);return fileName.replace(qoutedFileNameRegex,"").replace(gitFileHeaderRegex,"")};const leftTrimChars=(string,trimmingChars)=>{string=makeString(string);if(!trimmingChars&&String.prototype.trimLeft)return string.trimLeft();let trimmingString=formTrimmingString(trimmingChars);return string.replace(new RegExp(`^${trimmingString}+`),"")};const timeStampRegex=/\t.*|\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d(.\d+)?\s(\+|-)\d\d\d\d/;const removeTimeStamp=string=>{const timeStamp=timeStampRegex.exec(string);if(timeStamp){string=string.substring(0,timeStamp.index).trim()}return string};const formTrimmingString=trimmingChars=>{if(trimmingChars===null||trimmingChars===undefined)return"\\s";else if(trimmingChars instanceof RegExp)return trimmingChars.source;return`[${makeString(trimmingChars).replace(/([.*+?^=!:${}()|[\]/\\])/g,"\\$1")}]`};const makeString=itemToConvert=>(itemToConvert??"")+"";
module.exports = (input) => {
if (!input) return [];
if (typeof input !== "string" || input.match(/^\s+$/)) return [];
const lines = input.split("\n");
if (lines.length === 0) return [];
const files = [];
let currentFile = null;
let currentChunk = null;
let deletedLineCounter = 0;
let addedLineCounter = 0;
let currentFileChanges = null;
const normal = (line) => {
currentChunk?.changes.push({
type: "normal",
normal: true,
ln1: deletedLineCounter++,
ln2: addedLineCounter++,
content: line,
});
currentFileChanges.oldLines--;
currentFileChanges.newLines--;
};
const start = (line) => {
const [fromFileName, toFileName] = parseFiles(line) ?? [];
currentFile = {
chunks: [],
deletions: 0,
additions: 0,
from: fromFileName,
to: toFileName,
};
files.push(currentFile);
};
const restart = () => {
if (!currentFile || currentFile.chunks.length) start();
};
const newFile = () => {
restart();
currentFile.new = true;
currentFile.from = "/dev/null";
};
const deletedFile = () => {
restart();
currentFile.deleted = true;
currentFile.to = "/dev/null";
};
const index = (line) => {
restart();
currentFile.index = line.split(" ").slice(1);
};
const fromFile = (line) => {
restart();
currentFile.from = parseOldOrNewFile(line);
};
const toFile = (line) => {
restart();
currentFile.to = parseOldOrNewFile(line);
};
const toNumOfLines = (number) => +(number || 1);
const chunk = (line, match) => {
if (!currentFile) return;
const [oldStart, oldNumLines, newStart, newNumLines] = match.slice(1);
deletedLineCounter = +oldStart;
addedLineCounter = +newStart;
currentChunk = {
content: line,
changes: [],
oldStart: +oldStart,
oldLines: toNumOfLines(oldNumLines),
newStart: +newStart,
newLines: toNumOfLines(newNumLines),
};
currentFileChanges = {
oldLines: toNumOfLines(oldNumLines),
newLines: toNumOfLines(newNumLines),
};
currentFile.chunks.push(currentChunk);
};
const del = (line) => {
if (!currentChunk) return;
currentChunk.changes.push({
type: "del",
del: true,
ln: deletedLineCounter++,
content: line,
});
currentFile.deletions++;
currentFileChanges.oldLines--;
};
const add = (line) => {
if (!currentChunk) return;
currentChunk.changes.push({
type: "add",
add: true,
ln: addedLineCounter++,
content: line,
});
currentFile.additions++;
currentFileChanges.newLines--;
};
const eof = (line) => {
if (!currentChunk) return;
const [mostRecentChange] = currentChunk.changes.slice(-1);
currentChunk.changes.push({
type: mostRecentChange.type,
[mostRecentChange.type]: true,
ln1: mostRecentChange.ln1,
ln2: mostRecentChange.ln2,
ln: mostRecentChange.ln,
content: line,
});
};
const schemaHeaders = [
[/^diff\s/, start],
[/^new file mode \d+$/, newFile],
[/^deleted file mode \d+$/, deletedFile],
[/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/, index],
[/^---\s/, fromFile],
[/^\+\+\+\s/, toFile],
[/^@@\s+-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/, chunk],
[/^\\ No newline at end of file$/, eof],
];
const schemaContent = [
[/^-/, del],
[/^\+/, add],
[/^\s+/, normal],
];
const parseContentLine = (line) => {
for (const [pattern, handler] of schemaContent) {
const match = line.match(pattern);
if (match) {
handler(line, match);
break;
}
}
if (
currentFileChanges.oldLines === 0 &&
currentFileChanges.newLines === 0
) {
currentFileChanges = null;
}
};
const parseHeaderLine = (line) => {
for (const [pattern, handler] of schemaHeaders) {
const match = line.match(pattern);
if (match) {
handler(line, match);
break;
}
}
};
const parseLine = (line) => {
if (currentFileChanges) {
parseContentLine(line);
} else {
parseHeaderLine(line);
}
return;
};
for (const line of lines) parseLine(line);
return files;
};
const fileNameDiffRegex = /a\/.*(?=["']? ["']?b\/)|b\/.*$/g;
const gitFileHeaderRegex = /^(a|b)\//;
const parseFiles = (line) => {
let fileNames = line?.match(fileNameDiffRegex);
return fileNames?.map((fileName) =>
fileName.replace(gitFileHeaderRegex, "").replace(/("|')$/, "")
);
};
const qoutedFileNameRegex = /^\\?['"]|\\?['"]$/g;
const parseOldOrNewFile = (line) => {
let fileName = leftTrimChars(line, "-+").trim();
fileName = removeTimeStamp(fileName);
return fileName
.replace(qoutedFileNameRegex, "")
.replace(gitFileHeaderRegex, "");
};
const leftTrimChars = (string, trimmingChars) => {
string = makeString(string);
if (!trimmingChars && String.prototype.trimLeft) return string.trimLeft();
let trimmingString = formTrimmingString(trimmingChars);
return string.replace(new RegExp(`^${trimmingString}+`), "");
};
const timeStampRegex =
/\t.*|\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d(.\d+)?\s(\+|-)\d\d\d\d/;
const removeTimeStamp = (string) => {
const timeStamp = timeStampRegex.exec(string);
if (timeStamp) {
string = string.substring(0, timeStamp.index).trim();
}
return string;
};
const formTrimmingString = (trimmingChars) => {
if (trimmingChars === null || trimmingChars === undefined) return "\\s";
else if (trimmingChars instanceof RegExp) return trimmingChars.source;
return `[${makeString(trimmingChars).replace(
/([.*+?^=!:${}()|[\]/\\])/g,
"\\$1"
)}]`;
};
const makeString = (itemToConvert) => (itemToConvert ?? "") + "";
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment