aboutsummaryrefslogtreecommitdiff
path: root/api/git.js
diff options
context:
space:
mode:
Diffstat (limited to 'api/git.js')
-rw-r--r--api/git.js107
1 files changed, 58 insertions, 49 deletions
diff --git a/api/git.js b/api/git.js
index 72ca5a1..a44356e 100644
--- a/api/git.js
+++ b/api/git.js
@@ -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)