From a737bc4695f99b05a3c4807c88fc30b1a1eb89b5 Mon Sep 17 00:00:00 2001 From: HampusM Date: Mon, 26 Jul 2021 17:33:54 +0200 Subject: Refactored the git tree, tree entry & blob classes --- packages/server/src/git/blob.ts | 24 ++++++++++++++----- packages/server/src/git/tag.ts | 18 +++++--------- packages/server/src/git/tree.ts | 16 +++++++------ packages/server/src/git/tree_entry.ts | 31 +++++++++++++++++-------- packages/server/src/routes/api/v1/repo/index.ts | 6 ++--- 5 files changed, 57 insertions(+), 38 deletions(-) (limited to 'packages/server/src') diff --git a/packages/server/src/git/blob.ts b/packages/server/src/git/blob.ts index e44a979..ef9f9ab 100644 --- a/packages/server/src/git/blob.ts +++ b/packages/server/src/git/blob.ts @@ -1,17 +1,29 @@ -import { TreeEntry as NodeGitTreeEntry } from "nodegit"; import { BlobError, createError } from "./error"; +import { Tree } from "./tree"; +import { BlobTreeEntry } from "./tree_entry"; export class Blob { - private _ng_tree_entry: NodeGitTreeEntry; + private _tree_entry: BlobTreeEntry; - constructor(entry: NodeGitTreeEntry) { - this._ng_tree_entry = entry; + public path; + + constructor(entry: BlobTreeEntry, path: string) { + this._tree_entry = entry; + + this.path = path; } public async content(): Promise { - if(!this._ng_tree_entry.isBlob()) { + return this._tree_entry.content(); + } + + public static async fromPath(tree: Tree, path: string): Promise { + const entry = await tree.find(path); + + if(!(entry instanceof BlobTreeEntry)) { throw(createError(BlobError, 500, "Not a blob")); } - return this._ng_tree_entry.isBlob() ? (await this._ng_tree_entry.getBlob()).toString() : ""; + + return new Blob(entry, path); } } \ No newline at end of file diff --git a/packages/server/src/git/tag.ts b/packages/server/src/git/tag.ts index 3063a25..473c62d 100644 --- a/packages/server/src/git/tag.ts +++ b/packages/server/src/git/tag.ts @@ -1,28 +1,22 @@ import { Object as NodeGitObject, Tag as NodeGitTag } from "nodegit"; import { Pack, pack } from "tar-stream"; -import { Blob } from "./blob"; import { Commit } from "./commit"; import { FastifyReply } from "fastify"; import { Reference } from "./reference"; import { Repository } from "./repository"; -import { Tree } from "./tree"; -import { TreeEntry } from "./tree_entry"; +import { BaseTreeEntry, BlobTreeEntry, TreeEntry } from "./tree_entry"; import { createGzip } from "zlib"; import { pipeline } from "stream"; import { createError, TagError } from "./error"; import { Author } from "../../../shared_types/src"; -async function addArchiveEntries(entries: TreeEntry[], repository: string, archive: Pack) { +async function addArchiveEntries(entries: BaseTreeEntry[], repository: string, archive: Pack) { for(const tree_entry of entries) { - const peeled = (await tree_entry.peel()); - - if(tree_entry.type === "blob") { - if(peeled instanceof Blob) { - archive.entry({ name: `${repository}/${tree_entry.path}` }, await peeled.content()); - } + if(tree_entry instanceof BlobTreeEntry) { + archive.entry({ name: `${repository}/${tree_entry.path}` }, await tree_entry.content()); } - else if(peeled instanceof Tree) { - await addArchiveEntries(peeled.entries(), repository, archive); + else if(tree_entry instanceof TreeEntry) { + await addArchiveEntries((await tree_entry.tree()).entries(), repository, archive); } } } diff --git a/packages/server/src/git/tree.ts b/packages/server/src/git/tree.ts index 2cec528..ca645ef 100644 --- a/packages/server/src/git/tree.ts +++ b/packages/server/src/git/tree.ts @@ -1,23 +1,25 @@ -import { Blob } from "./blob"; import { Tree as NodeGitTree } from "nodegit"; import { Repository } from "./repository"; -import { TreeEntry } from "./tree_entry"; +import { BaseTreeEntry, createTreeEntry, TreeEntry } from "./tree_entry"; import { createError, TreeError } from "./error"; export class Tree { - private _ng_tree: NodeGitTree; - private _owner: Repository; + protected _owner: Repository; + protected _ng_tree: NodeGitTree; + + public path: string; constructor(owner: Repository, tree: NodeGitTree) { - this._ng_tree = tree; this._owner = owner; + this._ng_tree = tree; + this.path = tree.path(); } public entries(): TreeEntry[] { return this._ng_tree.entries().map(entry => new TreeEntry(this._owner, entry)); } - public async find(path: string): Promise { + public async find(path: string): Promise { const entry = await this._ng_tree.getEntry(path).catch(err => { if(err.errno === -3) { throw(createError(TreeError, 404, "Path not found")); @@ -25,7 +27,7 @@ export class Tree { throw(createError(TreeError, 500, "Failed to get tree path")); }); - return entry.isBlob() ? new Blob(entry) : new Tree(this._owner, await entry.getTree()); + return createTreeEntry(this._owner, entry); } public findExists(path: string): Promise { diff --git a/packages/server/src/git/tree_entry.ts b/packages/server/src/git/tree_entry.ts index d4eac40..e4780c8 100644 --- a/packages/server/src/git/tree_entry.ts +++ b/packages/server/src/git/tree_entry.ts @@ -1,24 +1,21 @@ -import { Blob } from "./blob"; import { Commit } from "./commit"; import { TreeEntry as NodeGitTreeEntry } from "nodegit"; import { Repository } from "./repository"; -import { Tree } from "./tree"; import { dirname } from "path"; import { findAsync } from "./misc"; +import { Tree } from "./tree"; -export class TreeEntry { - private _ng_tree_entry: NodeGitTreeEntry; - private _owner: Repository; +export abstract class BaseTreeEntry { + protected _ng_tree_entry: NodeGitTreeEntry; + protected _owner: Repository; public path: string; - public type: "blob" | "tree"; constructor(owner: Repository, entry: NodeGitTreeEntry) { this._ng_tree_entry = entry; this._owner = owner; this.path = entry.path(); - this.type = entry.isBlob() ? "blob" : "tree"; } public async latestCommit(): Promise { @@ -28,13 +25,27 @@ export class TreeEntry { const diff = await commit.diff(); const patches = await diff.patches(); - return Boolean(this.type === "blob" + return Boolean(this instanceof TreeEntry ? patches.find(patch => patch.to === this.path) : patches.find(patch => dirname(patch.to).startsWith(this.path))); }); } +} - public async peel(): Promise { - return this.type === "blob" ? new Blob(this._ng_tree_entry) : new Tree(this._owner, await this._ng_tree_entry.getTree()); +export class TreeEntry extends BaseTreeEntry { + public async tree(): Promise { + return new Tree(this._owner, await this._ng_tree_entry.getTree()); } +} + +export class BlobTreeEntry extends BaseTreeEntry { + public async content(): Promise { + return (await this._ng_tree_entry.getBlob()).toString(); + } +} + +export function createTreeEntry(owner: Repository, entry: NodeGitTreeEntry): BaseTreeEntry { + return entry.isBlob() + ? new BlobTreeEntry(owner, entry) + : new TreeEntry(owner, entry); } \ No newline at end of file diff --git a/packages/server/src/routes/api/v1/repo/index.ts b/packages/server/src/routes/api/v1/repo/index.ts index 0042b60..395c108 100644 --- a/packages/server/src/routes/api/v1/repo/index.ts +++ b/packages/server/src/routes/api/v1/repo/index.ts @@ -3,7 +3,7 @@ import { FastifyInstance, FastifyPluginOptions } from "fastify"; import { Blob } from "../../../../git/blob"; import { Repository } from "../../../../git/repository"; import { Tag } from "../../../../git/tag"; -import { TreeEntry } from "../../../../git/tree_entry"; +import { BaseTreeEntry, TreeEntry } from "../../../../git/tree_entry"; import { basename } from "path"; import branches from "./branches"; import log from "./log"; @@ -36,11 +36,11 @@ function addHooks(fastify: FastifyInstance, opts: FastifyPluginOptions): void { } }); } -async function treeEntryMap(entry: TreeEntry) { +async function treeEntryMap(entry: BaseTreeEntry) { const latest_commit = await entry.latestCommit(); return { name: basename(entry.path), - type: entry.type, + type: entry instanceof TreeEntry ? "tree" : "blob", latest_commit: { id: latest_commit.id, message: latest_commit.message, -- cgit v1.2.3-18-g5258