From d1a1b7dc947063aef5f8375a6a1e03246b272c84 Mon Sep 17 00:00:00 2001 From: HampusM Date: Wed, 18 Aug 2021 17:29:55 +0200 Subject: Implemented caching for certain API endpoints, Added documentation & made backend-fixes --- packages/server/src/git/branch.ts | 5 +++++ packages/server/src/git/commit.ts | 17 +++++++++++----- packages/server/src/git/diff.ts | 6 +++++- packages/server/src/git/error/index.ts | 3 ++- packages/server/src/git/error/types.ts | 12 ++++++++++++ packages/server/src/git/patch.ts | 18 ++++++++++++----- packages/server/src/git/repository.ts | 36 +++++++++++++++++++++++++++------- packages/server/src/git/tree_entry.ts | 8 ++++---- 8 files changed, 82 insertions(+), 23 deletions(-) (limited to 'packages/server/src/git') diff --git a/packages/server/src/git/branch.ts b/packages/server/src/git/branch.ts index dacabda..85f83be 100644 --- a/packages/server/src/git/branch.ts +++ b/packages/server/src/git/branch.ts @@ -10,6 +10,10 @@ import { createError, ErrorWhere, FailedError, NotFoundError, UnknownError } fro * @extends Reference */ export class Branch extends Reference { + public async repository(): Promise { + return this._owner.withBranch(this.name); + } + /** * Returns the branch's latest commit * @@ -41,6 +45,7 @@ export class Branch extends Reference { } throw(createError(ErrorWhere.Branch, UnknownError)); }); + return new Branch(owner, reference); } diff --git a/packages/server/src/git/commit.ts b/packages/server/src/git/commit.ts index 6ef02ef..7062304 100644 --- a/packages/server/src/git/commit.ts +++ b/packages/server/src/git/commit.ts @@ -207,21 +207,28 @@ export class Commit { * @returns An instance of a commit */ public static async branchCommit(owner: Repository): Promise { - return new Commit(owner, await owner.ng_repository.getBranchCommit(owner.branch_name)); + return new Commit(owner, await owner.ng_repository.getBranchCommit(owner.branch)); } /** * Returns a number of commits in a repository * * @param owner - The repository which the commits are in - * @param [count=20] - The number of commits to get + * @param [amount=20] - The number of commits to get or whether or not to get all commits * @returns An array of commit instances */ - public static async getMultiple(owner: Repository, count = 20): Promise { + public static async getMultiple(owner: Repository, amount: number | boolean = 20): Promise { const walker = NodeGitRevwalk.create(owner.ng_repository); - walker.pushRef(`refs/heads/${owner.branch_name}`); + walker.pushRef(`refs/heads/${owner.branch}`); - return Promise.all((await walker.getCommits(count)).map(commit => new Commit(owner, commit))); + if(typeof amount === "boolean") { + return Promise.all((await (amount + ? walker.getCommitsUntil(() => true) + : walker.getCommits(20) + )).map(commit => new Commit(owner, commit))); + } + + return Promise.all((await walker.getCommits(amount)).map(commit => new Commit(owner, commit))); } } \ No newline at end of file diff --git a/packages/server/src/git/diff.ts b/packages/server/src/git/diff.ts index d084e5d..a2c8829 100644 --- a/packages/server/src/git/diff.ts +++ b/packages/server/src/git/diff.ts @@ -1,5 +1,5 @@ import { Diff as NodeGitDiff } from "nodegit"; -import { createError, ErrorWhere, NotFoundError } from "./error"; +import { createError, DiffTooLargeError, ErrorWhere, NotFoundError } from "./error"; import { Patch } from "./patch"; type PatchHeaderData = { @@ -63,6 +63,10 @@ export class Diff { * @returns An array of patch instances */ public async patches(): Promise { + if((await this.rawPatches()).split("\n").length > 50000) { + throw(createError(ErrorWhere.Diff, DiffTooLargeError)); + } + return (await this.ng_diff.patches()).map((patch, index) => new Patch(this, patch, index)); } diff --git a/packages/server/src/git/error/index.ts b/packages/server/src/git/error/index.ts index b8994d3..55a3aef 100644 --- a/packages/server/src/git/error/index.ts +++ b/packages/server/src/git/error/index.ts @@ -21,7 +21,8 @@ export enum ErrorWhere { Commit = "commit", Diff = "diff", Misc = "misc", - Blob = "blob" + Blob = "blob", + Patch = "patch" } /** diff --git a/packages/server/src/git/error/types.ts b/packages/server/src/git/error/types.ts index b8c860b..19ad710 100644 --- a/packages/server/src/git/error/types.ts +++ b/packages/server/src/git/error/types.ts @@ -42,4 +42,16 @@ export class NotInKeyringError extends ErrorType { constructor(email: string) { super(500, `A public key for '${email}' doesn't exist in the server pgp keyring!`); } +} + +export class PatchTooLargeError extends ErrorType { + constructor() { + super(500, "Patch is too large for parsing!"); + } +} + +export class DiffTooLargeError extends ErrorType { + constructor() { + super(500, "Diff is too large for parsing!"); + } } \ No newline at end of file diff --git a/packages/server/src/git/patch.ts b/packages/server/src/git/patch.ts index 4239ce4..4527d03 100644 --- a/packages/server/src/git/patch.ts +++ b/packages/server/src/git/patch.ts @@ -1,5 +1,6 @@ import { Diff } from "./diff"; import { ConvenientPatch as NodeGitPatch } from "nodegit"; +import { createError, ErrorWhere, PatchTooLargeError } from "./error"; type Hunk = { new_start: number, @@ -87,10 +88,9 @@ export class Patch { * * These bounds are in the context of it's whole diff * - * @returns A patch bounds instance which contains a start & an end property + * @returns The patch's bounds */ - private async _bounds(): Promise { - const raw_patches = (await this._diff.rawPatches()).split("\n"); + private async _bounds(raw_patches: string[]): Promise { const patch_header_data = await this._diff.patchHeaderData(); return { @@ -104,7 +104,7 @@ export class Patch { */ private async _content(): Promise { const raw_patches = (await this._diff.rawPatches()).split("\n"); - const bounds = await this._bounds(); + const bounds = await this._bounds(raw_patches); return raw_patches.slice(bounds.start, bounds.end).join("\n"); } @@ -115,10 +115,14 @@ export class Patch { * @returns Whether or not the patch is too large */ public async isTooLarge(): Promise { + if(this.additions > 2000 || this.deletions > 2000) { + return true; + } + const content = (await this._content()).split("\n"); const line_lengths = content.map(line => line.length).reduce((result, length) => result + length); - if(content.length > 5000 || line_lengths > 5000) { + if(content.length > 10000 || line_lengths > 10000) { return true; } @@ -131,6 +135,10 @@ export class Patch { * @returns An array of hunk instances */ public async getHunks(): Promise { + if(await this.isTooLarge()) { + throw(createError(ErrorWhere.Patch, PatchTooLargeError)); + } + const content = (await this._content()).split("\n"); const hunks = await this._ng_patch.hunks(); diff --git a/packages/server/src/git/repository.ts b/packages/server/src/git/repository.ts index c1410ab..53245be 100644 --- a/packages/server/src/git/repository.ts +++ b/packages/server/src/git/repository.ts @@ -38,7 +38,7 @@ export class Repository { public name: RepositoryName; public git_dir: string; - public branch_name: string; + private _branch: string; /** * @param repository - An instance of a Nodegit repository @@ -52,7 +52,7 @@ export class Repository { }; this.git_dir = dirname(repository.path()); - this.branch_name = branch; + this._branch = branch; } /** @@ -69,23 +69,31 @@ export class Repository { return getFile(this.git_dir, this.name.full, "owner"); } + get branch(): string { + return this._branch; + } + + set branch(branch: string) { + this._branch = branch; + } + /** * Returns the repository's branch * * @returns An instance of a branch */ - public branch(): Promise { - return Branch.lookup(this, this.branch_name); + public getBranch(): Promise { + return Branch.lookup(this, this._branch); } /** * Returns the repository's commits * - * @param [count=20] - The number of commits to get + * @param [amount=20] - The number of commits to get or whether or not to get all commits * @returns An array of commit instances */ - public async commits(count?: number): Promise { - return Commit.getMultiple(this, count); + public async commits(amount?: number | boolean): Promise { + return Commit.getMultiple(this, amount); } /** @@ -118,6 +126,20 @@ export class Repository { .catch(() => false); } + /** + * Returns this repository instance with a different branch + * + * @param branch - The branch to switch to + * @returns An instance of a repository + */ + public async withBranch(branch: string): Promise { + if(!await Branch.lookupExists(this.ng_repository, branch)) { + throw(createError(ErrorWhere.Repository, NotFoundError, "branch")); + } + + return new Repository(this.ng_repository, branch); + } + /** * Returns the repository's branches * diff --git a/packages/server/src/git/tree_entry.ts b/packages/server/src/git/tree_entry.ts index b03ea9e..cdcb0d3 100644 --- a/packages/server/src/git/tree_entry.ts +++ b/packages/server/src/git/tree_entry.ts @@ -31,11 +31,11 @@ export abstract class BaseTreeEntry { */ public async latestCommit(): Promise { const rev_walk = NodeGitRevwalk.create(this._owner.ng_repository); - rev_walk.pushRef(`refs/heads/${this._owner.branch_name}`); + rev_walk.pushRef(`refs/heads/${this._owner.branch}`); const commit_cnt = (await rev_walk.getCommitsUntil(() => true)).length; - rev_walk.pushRef(`refs/heads/${this._owner.branch_name}`); + rev_walk.pushRef(`refs/heads/${this._owner.branch}`); const file_hist = await rev_walk.fileHistoryWalk(this.path, commit_cnt); return new Commit(this._owner, file_hist[0].commit); @@ -48,11 +48,11 @@ export abstract class BaseTreeEntry { */ public async history(count?: number): Promise { const rev_walk = NodeGitRevwalk.create(this._owner.ng_repository); - rev_walk.pushRef(`refs/heads/${this._owner.branch_name}`); + rev_walk.pushRef(`refs/heads/${this._owner.branch}`); const commit_cnt = (await rev_walk.getCommitsUntil(() => true)).length; - rev_walk.pushRef(`refs/heads/${this._owner.branch_name}`); + rev_walk.pushRef(`refs/heads/${this._owner.branch}`); const file_hist = await rev_walk.fileHistoryWalk(this.path, commit_cnt); const commit_history = await Promise.all(file_hist.map(async hist_entry => new Commit(this._owner, await NodeGitCommit.lookup(this._owner.ng_repository, hist_entry.commit)))); -- cgit v1.2.3-18-g5258