repos.js
import util from 'util';
import childProcess from 'child_process'
const exec = util.promisify(childProcess.exec);
import darcsConfig from '../darcsconfig.js'
import xmlJs from 'xml-js'
import { getDiffsFromPatchText } from '../helpers.js'
let repos = null
export default async () => {
if (repos === null) {
repos = await Promise.all(Object.keys(darcsConfig.repos).map(async (repoName) => {
const branchNames = Object.keys(darcsConfig.repos[repoName].branches)
const branches = await Promise.all(branchNames.map(async (branchName) => {
const repoLocation = darcsConfig.repos[repoName].branches[branchName].location
const filesRes = await exec(`(cd ${repoLocation}; darcs show files)`)
const files = filesRes.stdout.split("\n").filter(item => item.length > 0 && item != ".")
const patches = new Map()
const totalPatchesCountRes = await exec(`(cd ${repoLocation}; darcs log --count)`)
const totalPatchesCount = parseInt(totalPatchesCountRes.stdout)
let hunkRegex = RegExp(/^ *hunk /)
// Get 100 patches at a time and parse those
for (let i = 1; i <= totalPatchesCount; i = i + 100) {
let patchesSubset = await exec(`(cd ${repoLocation}; darcs log --index=${i}-${i+100} -v)`)
patchesSubset = patchesSubset.stdout.split("\n")
do {
const nextPatchStart = patchesSubset.findIndex((line, index) => {
return index > 0 && line.startsWith("patch ")
})
const currentPatch = patchesSubset.slice(0, nextPatchStart - 1)
patchesSubset = patchesSubset.slice(nextPatchStart)
const hash = currentPatch[0].replace("patch ", "").trim()
const author = currentPatch[1].replace("Author: ", "").trim()
const date = currentPatch[2].replace("Date: ", "").trim()
const name = currentPatch[3].replace(" * ", "").trim()
const diffStart = currentPatch.findIndex((line) => {
return line.match(hunkRegex)
})
const description = currentPatch.slice(5, diffStart).map(str => str.replace(" ", "")).join("\n").trim()
const diffs = getDiffsFromPatchText(currentPatch.slice(diffStart).map(str => str.trimStart()).join("\n"))
patches.set(hash, {
name,
description,
author,
date,
hash,
diffs,
})
} while (patchesSubset.length > 1)
}
const info = {
files,
patches: [...patches.values()],
}
return [branchName, info]
}))
const branchObject = {}
branches.forEach((branch) => {
branchObject[branch[0]] = branch[1]
})
return [repoName, branchObject]
}))
const reposObject = {}
repos.forEach((repo) => {
reposObject[repo[0]] = repo[1]
})
repos = reposObject
}
return repos
}