diff options
Diffstat (limited to 'api/git.js')
-rw-r--r-- | api/git.js | 107 |
1 files changed, 58 insertions, 49 deletions
@@ -1,58 +1,64 @@ -const { exec } = require("child_process"); +const { spawn } = require("child_process"); const { differenceInMilliseconds } = require('date-fns'); const fs = require('fs'); -const log_format='{"hash": "%H", "author": "%an", "author_email": "%ae", "date": "%at", "subject": "%s"}'; - -function execGit(path, action , format, args = "") +function execGit(path, action, args = [""], error) { - return new Promise((resolve) => + const git = spawn("git", ["-C", path, action, args].concat(args)); + + git.on("error", (err) => { - exec(`git -C ${path} ${action} ${args} --format=format:'${format}'`, (error, stdout, stderr) => - { - if(error) { - const no_such_fileor_dir = new RegExp(`cannot change to '${path.replace('/', "\/")}': No such file or directory\\n$`); - - if(no_such_fileor_dir.test(error.message)) { - resolve({ "error": 404 }); - return; - } - resolve({ "error": error.message }); - return; - } - if(stderr) { - resolve({ "error": "Failed to communicate with git!" }); - return; - } + const no_such_file_or_dir = new RegExp(`cannot change to '${path.replace('/', "\/")}': No such file or directory\\n$`); - resolve({ "data": stdout }); - }); + if(no_such_file_or_dir.test(err.toString())) { + error({ "error": 404 }) + return; + } + error({ "error": err }); }); + + git.stderr.on("data", () => error({ "error": "Failed to communicate with git!" })); + + return git; } -async function getLog(base_dir, path) +function getLog(base_dir, path) { - let log = await execGit(`${base_dir}/${path}`, "log", log_format); + return new Promise((resolve) => + { + let log = []; - if(!log["error"]) { - log["data"] = log["data"].split('\n'); - log["data"].forEach((entry, index) => log["data"][index] = JSON.parse(entry)); - } + const log_format='{"hash":"%H","author":"%an","author_email":"%ae","date":"%at","subject":"%s"}'; + const git = execGit(`${base_dir}/${path}`, "log", [`--format=format:${log_format}`, "--shortstat"], (err) => resolve(err)); + + git.stdout.on("data", (data) => + { + data = data.toString().split('\n').filter((item) => item != ""); + data[0] = JSON.parse(data[0]); + + ["files changed", "insertions", "deletions"].forEach((stat) => + { + const stat_nr = new RegExp(`(\\d+)\\ ${stat.replaceAll(/s(?=(\ |$))/g, "s?")}`).exec(data[1]); + data[0][stat.replaceAll(" ", "_")] = stat_nr ? stat_nr[1] : 0; + }); - return log; + log.push(data[0]); + }); + + git.on("close", (code) => + { + if(code === 0) { + resolve({ "data": log }); + return; + } + resolve({ "error": "Failed to communicate with git!" }); + }); + }) } function getOptimalDateDifference(difference) { - const time_values = { - "second": 1000, - "minute": 60000, - "hour": 3600000, - "day": 86400000, - "week": 604800000, - "month": 2629800000, - "year": 31557600000 - }; + const time_values = { "second": 1000, "minute": 60000, "hour": 3600000, "day": 86400000, "week": 604800000, "month": 2629800000, "year": 31557600000 }; let last; for(const [key, value] of Object.entries(time_values)) { @@ -66,21 +72,24 @@ function getOptimalDateDifference(difference) return `${Math.round(difference / time_values[last])} ${last}s`; } -async function getTimeSinceLatestCommit(path) +function getTimeSinceLatestCommit(path) { - let commit_timestamp = (await execGit(path, "log", "%at", "-n 1")); + return new Promise((resolve) => + { + const git = execGit(path, "log", [`--format=format:%at`, "-n 1"], (err) => resolve(err)); - if(!commit_timestamp["error"]) { - commit_timestamp = commit_timestamp["data"] * 1000; + const commit = []; - const commit_date = new Date(commit_timestamp); - const now_date = new Date(); + git.stdout.on("data", (data) => commit.push(data)); - const difference = getOptimalDateDifference(differenceInMilliseconds(now_date, commit_date)); + git.on("close", (code) => + { + const commit_timestamp = new Date(Number(Buffer.concat(commit).toString()) * 1000); + const now_date = new Date(); - return difference; - } - return commit_timestamp; + resolve(getOptimalDateDifference(differenceInMilliseconds(now_date, commit_timestamp))); + }); + }); } function getRepoFile(base_dir, repo, file) |