aboutsummaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2021-05-24 10:49:41 +0200
committerHampusM <hampus@hampusmat.com>2021-05-24 10:49:41 +0200
commit518bd58c5aba1a6eaa645074f3ae2d780c45f6dc (patch)
treea99acd3b434422e019bc76064ad0798c8472f07d /api
parent21e52ba2fa323e8aebf291882083c1eca9f6a5af (diff)
Restructured the whole project & added Nodemon and Concurrently
Diffstat (limited to 'api')
-rw-r--r--api/git.js237
-rw-r--r--api/sanitization.js14
-rw-r--r--api/v1.js74
3 files changed, 0 insertions, 325 deletions
diff --git a/api/git.js b/api/git.js
deleted file mode 100644
index dad7cc6..0000000
--- a/api/git.js
+++ /dev/null
@@ -1,237 +0,0 @@
-const { formatDistance } = require('date-fns');
-const fs = require('fs');
-const git = require("nodegit");
-
-function addRepoDirSuffix(repo_name)
-{
- if(!repo_name.endsWith(".git")) {
- return repo_name + ".git";
- }
- return repo_name;
-}
-
-async function getLog(base_dir, repo_name)
-{
- const repo = await git.Repository.openBare(`${base_dir}/${repo_name}`)
-
- const walker = git.Revwalk.create(repo);
- walker.pushHead();
-
- const raw_commits = await walker.getCommits();
-
- const commits = Promise.all(raw_commits.map(async commit => ({
- commit: commit.sha(),
- author_full: commit.author().toString(),
- author_name: commit.author().name(),
- author_email: commit.author().email(),
- date: commit.date(),
- message: commit.message().replace(/\n/g, ""),
- insertions: (await (await commit.getDiff())[0].getStats()).insertions(),
- deletions: (await (await commit.getDiff())[0].getStats()).deletions(),
- files_changed: (await (await commit.getDiff())[0].getStats()).filesChanged()
- })));
-
- return await commits;
-}
-
-async function getTimeSinceLatestCommit(base_dir, repo_name)
-{
- const repo = await git.Repository.openBare(`${base_dir}/${repo_name}`)
- const master_commit = await repo.getMasterCommit();
-
- return formatDistance(new Date(), master_commit.date());
-}
-
-function getRepoFile(base_dir, repo, file)
-{
- return new Promise(resolve =>
- {
- fs.readFile(`${base_dir}/${repo}/${file}`, async (err, content) =>
- {
- if(!err) {
- resolve(content.toString().replace(/\n/g, ""));
- return;
- }
- resolve("");
- });
- });
-}
-
-function getRepos(base_dir)
-{
- return new Promise((resolve) =>
- {
- fs.readdir(base_dir, (err, dir_content) =>
- {
- if(err) {
- resolve({ "error": err });
- return;
- }
-
- dir_content.filter(repo => repo.endsWith(".git")).reduce((acc, repo) =>
- {
- return acc.then((repos) =>
- {
- return getRepoFile(base_dir, repo, "description").then((description) =>
- {
- return getRepoFile(base_dir, repo, "owner").then((owner) =>
- {
- return getTimeSinceLatestCommit(base_dir, repo).then((last_commit_date) =>
- {
- repos[repo.slice(0, -4)] = { "description": description, "owner": owner, "last_updated": last_commit_date };
- return repos;
- });
- });
- });
- });
- }, Promise.resolve({})).then((repos) =>
- {
- resolve(repos);
- });
- });
- });
-}
-
-function parseHunkAddDel(hunk)
-{
- let new_lines = [];
- let deleted_lines = [];
-
- hunk.forEach((line, index) =>
- {
- if(line.charAt(0) === '+') {
- hunk[index] = line.slice(1);
- new_lines.push(index);
- }
- else if(line.charAt(0) === '-') {
- hunk[index] = line.slice(1);
- deleted_lines.push(index);
- }
- });
-
- return { new: new_lines, deleted: deleted_lines, hunk: hunk.join("\n") };
-}
-
-async function getCommit(base_dir, repo_name, commit_oid)
-{
- repo_name = addRepoDirSuffix(repo_name);
-
- const repo = await git.Repository.openBare(`${base_dir}/${repo_name}`)
- const commit = await repo.getCommit(commit_oid);
- const diff = (await commit.getDiff())[0];
- const all_patches = (await diff.toBuf(1)).split('\n');
-
- // Get the count of lines for all of patches's headers
- const patch_headers = (await diff.toBuf(2)).split('\n');
- const patch_header_data = await patch_headers.reduce((acc, line, index) =>
- {
- return acc.then((arr) =>
- {
- if(/^diff --git/.test(line)) {
- arr[0].push(all_patches.indexOf(line));
-
- if(arr[2] != undefined) {
- arr[1].push(patch_headers.slice(arr[2], index).length);
- }
- arr[2] = index;
- }
- else if(index == patch_headers.length - 1 && arr[2] != undefined) {
- arr[1].push(patch_headers.slice(arr[2], index).length);
- }
- return arr;
- });
- }, Promise.resolve([ [], [], undefined ]));
-
- console.log(patch_header_data);
-
- const patches = await diff.patches();
- const parsed_patches = patches.reduce((acc, patch, patch_index) =>
- {
- return acc.then((arr) =>
- {
- return patch.hunks().then((hunks) =>
- {
- console.log("\n" + patch.newFile().path());
-
- const patch_start = patch_header_data[0][patch_index] + patch_header_data[1][patch_index];
- const patch_end = (patch_header_data[0][patch_index + 1] !== undefined) ? patch_header_data[0][patch_index + 1] : all_patches.length - 1;
- const patch_content = all_patches.slice(patch_start, patch_end);
-
- const line_lengths = patch_content.map((line) => line.length).reduce((acc, length) => acc + length);
-
- if(patch_content.length > 5000 || line_lengths > 5000) {
- console.log("Too large!");
-
- arr.push({
- from: patch.oldFile().path(),
- to: patch.newFile().path(),
- additions: patch.lineStats()["total_additions"],
- deletions: patch.lineStats()["total_deletions"],
- too_large: true,
- hunks: null
- });
- return arr;
- }
-
- // Go through all of the patch's hunks
- // Patches are split into parts of where in the file the change is made. Those parts are called hunks.
- return hunks.reduce((acc, hunk, hunk_index) =>
- {
- return acc.then((hunks_data) =>
- {
- const hunk_header = hunk.header();
- const hunk_header_index = patch_content.indexOf(hunk_header.replace(/\n/g, ""));
-
- if(hunks_data[0] !== undefined) {
- const prev_hunk = hunks[hunk_index - 1];
- hunks_data[1].push(Object.assign({
- new_start: prev_hunk.newStart(),
- new_lines: prev_hunk.newLines(),
- old_start: prev_hunk.oldStart(),
- old_lines: prev_hunk.oldLines(),
- }, parseHunkAddDel(patch_content.slice(hunks_data[0], hunk_header_index))));
-
- hunks_data[2] = hunks_data + patch_content.slice(hunks_data[0], hunk_header_index).length;
- }
-
- hunks_data[0] = hunk_header_index;
- return hunks_data;
- });
- }, Promise.resolve([ undefined, [], 0 ])).then((hunks_data) =>
- {
- const prev_hunk = hunks[hunks.length - 1];
- hunks_data[1].push(Object.assign({
- new_start: prev_hunk.newStart(),
- new_lines: prev_hunk.newLines(),
- old_start: prev_hunk.oldStart(),
- old_lines: prev_hunk.oldLines(),
- }, parseHunkAddDel(patch_content.slice(hunks_data[0], patch_end))));
-
- arr.push({
- from: patch.oldFile().path(),
- to: patch.isDeleted() ? "/dev/null" : patch.newFile().path(),
- additions: patch.lineStats()["total_additions"],
- deletions: patch.lineStats()["total_deletions"],
- too_large: false,
- hunks: hunks_data[1]
- });
-
- return arr;
- });
- });
- });
- }, Promise.resolve([]));
-
- return {
- hash: commit.sha(),
- author: commit.author().toString(),
- message: commit.message(),
- date: commit.date(),
- patches: await parsed_patches
- };
-}
-
-module.exports.getLog = getLog;
-module.exports.getRepos = getRepos;
-module.exports.getRepoFile = getRepoFile;
-module.exports.getCommit = getCommit; \ No newline at end of file
diff --git a/api/sanitization.js b/api/sanitization.js
deleted file mode 100644
index 95c8810..0000000
--- a/api/sanitization.js
+++ /dev/null
@@ -1,14 +0,0 @@
-function sanitizeRepoName(dirty)
-{
- const valid_repo_name = /^[a-zA-Z0-9\.\-_]+$/;
- return valid_repo_name.test(dirty);
-}
-
-function sanitizeCommitID(dirty)
-{
- const valid_commit_id = /^[a-fA-F0-9]{40}$/;
- return valid_commit_id.test(dirty);
-}
-
-module.exports.sanitizeRepoName = sanitizeRepoName;
-module.exports.sanitizeCommitID = sanitizeCommitID; \ No newline at end of file
diff --git a/api/v1.js b/api/v1.js
deleted file mode 100644
index 7920afc..0000000
--- a/api/v1.js
+++ /dev/null
@@ -1,74 +0,0 @@
-const express = require("express");
-const git = require("./git");
-const sanitization = require("./sanitization");
-
-const router = express.Router();
-
-router.get("/info", function(req, res)
-{
- res.json({ "data": req.settings });
- return;
-});
-
-router.get("/repos", async function(req, res)
-{
- let repos = await git.getRepos(req.settings["base_dir"]);
-
- if(repos["error"]) {
- res.status(500).send("Internal server error!");
- return;
- }
-
- res.json({ "data": repos });
-});
-
-router.use("/repos/:repo", async function(req, res, next)
-{
- if(!sanitization.sanitizeRepoName(req.params.repo)) {
- res.status(400).json({ "error": "Unacceptable git repository name!" });
- return;
- }
- next();
-});
-
-router.get("/repos/:repo", async function(req, res)
-{
- const repo = `${req.params.repo}.git`;
- const desc = await git.getRepoFile(req.settings["base_dir"], repo, "description");
-
- res.json({ "data": { "name": req.params.repo, "description": desc } });
-});
-
-router.get("/repos/:repo/log", async function(req, res)
-{
- const repo = `${req.params.repo}.git`;
- const log = await git.getLog(req.settings["base_dir"], repo);
-
- if(log["error"]) {
- if(typeof log["error"] === "string") {
- res.status(500).json({ "error": log["error"] });
- return;
- }
- switch(log["error"]) {
- case 404:
- res.status(404).json({ "error": "Git repository doesn't exist!" });
- return;
- }
- return;
- }
- res.json({ data: log });
-});
-
-router.get("/repos/:repo/log/:commit", async function(req, res)
-{
- if(!sanitization.sanitizeCommitID(req.params.commit)) {
- res.status(400).json({ "error": "Unacceptable commit id!" });
- return;
- }
-
- const commit = await git.getCommit(req.settings["base_dir"], req.params.repo, req.params.commit);
-
- res.json({ data: commit });
-});
-
-module.exports = router; \ No newline at end of file