Tue Mar 11 2025
tucker.mcknight@gmail.com
Also fix a bug where the last line of the "after" change was not getting included in the diff. addfile ./helpers.js
d814d7874ac357ff9f01a5fbeaf655780d1c0db7
import _ from 'lodash'
import * as Diff from 'diff'
const getDiffsFromPatchText = (patchText) => {
if (debug) {
console.log("PATCH TEXT")
console.log(patchText)
}
const lines = patchText.split("\n")
const hunks = []
let previousHunk = -1
lines.forEach((line, index) => {
if (line.startsWith("hunk") || index === lines.length - 1) {
if (debug) {
console.log(`line starts with hunk: ${line.startsWith("hunk")}`)
console.log(`index and lines.length are: ${index} ${lines.length}`)
}
if (previousHunk === -1) {
previousHunk = index
return
}
// get diff from previous hunk to this next one
const lastHunk = lines.slice(previousHunk, index + 1) // slice is non-inclusive for the end argument
let lastHunkBefore = lastHunk.filter(line => line.startsWith("-")).map(str => str.replace("-", "")).join("\n")
let lastHunkAfter = lastHunk.filter(line => line.startsWith("+")).map(str => str.replace("+", "")).join("\n")
lastHunkBefore = _.escape(lastHunkBefore)
lastHunkAfter = _.escape(lastHunkAfter)
const changeObject = Diff.diffWords(lastHunkBefore, lastHunkAfter)
changeObject.forEach((obj) => {
if (obj.added) {
lastHunkAfter = lastHunkAfter.replace(obj.value, `<span class=green>${obj.value}</span>`)
}
if (obj.removed) {
lastHunkBefore = lastHunkBefore.replace(obj.value, `<span class=red>${obj.value}</span>`)
}
})
let filename = lines[previousHunk].replace("hunk ./", "")
const regex = RegExp(/(.*) ([0-9]+)$/)
const matches = filename.match(regex)
hunks.push({
file: `${matches[1]}:${matches[2]}`,
before: lastHunkBefore,
after: lastHunkAfter,
changeObject,
})
previousHunk = index
}
})
return hunks
}
export {
getDiffsFromPatchText,
}