aboutsummaryrefslogtreecommitdiff
path: root/packages/server/src/git
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2021-08-18 17:29:55 +0200
committerHampusM <hampus@hampusmat.com>2021-08-18 17:29:55 +0200
commitd1a1b7dc947063aef5f8375a6a1e03246b272c84 (patch)
treef5cb9bd6d4b5463d9d022026ac6fea87cb6ebe02 /packages/server/src/git
parent6ed078de30a7bf35deace728857d1d293d59eb15 (diff)
Implemented caching for certain API endpoints, Added documentation & made backend-fixes
Diffstat (limited to 'packages/server/src/git')
-rw-r--r--packages/server/src/git/branch.ts5
-rw-r--r--packages/server/src/git/commit.ts17
-rw-r--r--packages/server/src/git/diff.ts6
-rw-r--r--packages/server/src/git/error/index.ts3
-rw-r--r--packages/server/src/git/error/types.ts12
-rw-r--r--packages/server/src/git/patch.ts18
-rw-r--r--packages/server/src/git/repository.ts36
-rw-r--r--packages/server/src/git/tree_entry.ts8
8 files changed, 82 insertions, 23 deletions
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<Repository> {
+ 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<Commit> {
- 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<Commit[]> {
+ public static async getMultiple(owner: Repository, amount: number | boolean = 20): Promise<Commit[]> {
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<Patch[]> {
+ 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<PatchBounds> {
- const raw_patches = (await this._diff.rawPatches()).split("\n");
+ private async _bounds(raw_patches: string[]): Promise<PatchBounds> {
const patch_header_data = await this._diff.patchHeaderData();
return {
@@ -104,7 +104,7 @@ export class Patch {
*/
private async _content(): Promise<string> {
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<boolean> {
+ 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<Hunk[]> {
+ 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<Branch> {
- return Branch.lookup(this, this.branch_name);
+ public getBranch(): Promise<Branch> {
+ 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<Commit[]> {
- return Commit.getMultiple(this, count);
+ public async commits(amount?: number | boolean): Promise<Commit[]> {
+ return Commit.getMultiple(this, amount);
}
/**
@@ -119,6 +127,20 @@ export class Repository {
}
/**
+ * 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<Repository> {
+ 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
*
* @returns An array of branch instances
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<Commit> {
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<Commit[]> {
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))));