( stdout: string, maxFiles: number, )
| 14 | * @returns the totals and the kept rows |
| 15 | */ |
| 16 | export function parseNumstat( |
| 17 | stdout: string, |
| 18 | maxFiles: number, |
| 19 | ): Types.NumstatResult { |
| 20 | const files: Types.FileStat[] = [] |
| 21 | const stats = { filesCount: 0, linesAdded: 0, linesRemoved: 0 } |
| 22 | const records = stdout.split('\0') |
| 23 | let at = 0 |
| 24 | |
| 25 | while (at < records.length) { |
| 26 | const [addedField, removedField, ...pathFields] = (records[at] ?? '').split( |
| 27 | '\t', |
| 28 | ) |
| 29 | const inline = pathFields.join('\t') |
| 30 | const isRename = pathFields.length === 1 && inline === '' |
| 31 | const renamedFrom = isRename ? (records[at + 1] ?? null) : null |
| 32 | const path = isRename ? (records[at + 2] ?? '') : inline |
| 33 | at += isRename ? RENAME_RECORDS : 1 |
| 34 | const isRow = |
| 35 | addedField !== undefined && removedField !== undefined && path !== '' |
| 36 | |
| 37 | if (!isRow) { |
| 38 | continue |
| 39 | } |
| 40 | |
| 41 | const isBinary = addedField === '-' || removedField === '-' |
| 42 | const added = isBinary ? 0 : Number(addedField) || 0 |
| 43 | const removed = isBinary ? 0 : Number(removedField) || 0 |
| 44 | stats.filesCount += 1 |
| 45 | stats.linesAdded += added |
| 46 | stats.linesRemoved += removed |
| 47 | |
| 48 | if (files.length < maxFiles) { |
| 49 | files.push({ |
| 50 | path, |
| 51 | renamedFrom, |
| 52 | added, |
| 53 | removed, |
| 54 | isBinary, |
| 55 | isUntracked: false, |
| 56 | isPreSession: false, |
| 57 | }) |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | return { stats, files } |
| 62 | } |
nothing calls this directly
no outgoing calls
no test coverage detected