diff options
author | HampusM <hampus@hampusmat.com> | 2021-07-29 15:39:31 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2021-07-29 15:59:52 +0200 |
commit | 8d42b6f44ca5b0eeb54938e1cf9509d1f8294f00 (patch) | |
tree | b3bae9c6160bb11436a7f2875f27191780156353 /packages/server/src/git | |
parent | 4f47dbfeb6edd984b2e912f00993db6e4eb2193d (diff) |
Refactored & improved the backend yet again
Diffstat (limited to 'packages/server/src/git')
-rw-r--r-- | packages/server/src/git/blob.ts | 2 | ||||
-rw-r--r-- | packages/server/src/git/tag.ts | 58 | ||||
-rw-r--r-- | packages/server/src/git/tree.ts | 36 |
3 files changed, 55 insertions, 41 deletions
diff --git a/packages/server/src/git/blob.ts b/packages/server/src/git/blob.ts index 4dadc01..5d1d892 100644 --- a/packages/server/src/git/blob.ts +++ b/packages/server/src/git/blob.ts @@ -23,7 +23,7 @@ export class Blob { * Returns the blob's content */ public async content(): Promise<string> { - return (await this._tree_entry.ng_tree_entry.getBlob()).content.toString(); + return (await this._tree_entry.ng_tree_entry.getBlob()).content().toString(); } /** diff --git a/packages/server/src/git/tag.ts b/packages/server/src/git/tag.ts index b01ac98..2c1f6ae 100644 --- a/packages/server/src/git/tag.ts +++ b/packages/server/src/git/tag.ts @@ -1,33 +1,13 @@ import { Object as NodeGitObject, Tag as NodeGitTag } from "nodegit"; -import { Pack, pack } from "tar-stream"; import { Commit } from "./commit"; import { FastifyReply } from "fastify"; import { Reference } from "./reference"; import { Repository } from "./repository"; -import { BlobTreeEntry, TreeEntry } from "./tree_entry"; import { createGzip } from "zlib"; import { pipeline } from "stream"; import { createError, TagError } from "./error"; import { Author } from "../../../shared_types/src"; -import { Tree } from "./tree"; - -/** - * Recursively go through a repository and add it's content to a archive - * - * @param tree - A tree to add archive entries from - * @param repository - The repository which the tree is in - * @param archive - A tar archive pack - */ -async function addArchiveEntries(tree: Tree, repository: string, archive: Pack) { - for(const tree_entry of tree.entries()) { - if(tree_entry instanceof BlobTreeEntry) { - archive.entry({ name: `${repository}/${tree_entry.path}` }, (await (await tree_entry.blob()).content())); - } - else if(tree_entry instanceof TreeEntry) { - await addArchiveEntries((await tree_entry.tree()), repository, archive); - } - } -} +import { promisify } from "util"; /** * A representation of a tag @@ -67,29 +47,35 @@ export class Tag extends Reference { const commit = await Commit.lookup(this._owner, (await this._ng_reference.peel(NodeGitObject.TYPE.COMMIT)).id()); const tree = await commit.tree(); - const archive = pack(); - const gzip = createGzip(); - reply.raw.writeHead(200, { "Content-Encoding": "gzip", "Content-Type": "application/gzip", "Content-Disposition": `attachment; filename="${this._owner.name.short}-${this._owner.name.short}.tar.gz"` }); - pipeline(archive, gzip, reply.raw, () => reply.raw.end()); + const archive = await tree.createArchive().catch((err: Error) => err); + + if(archive instanceof Error) { + console.log(archive); + reply.raw.end(); + return; + } + + const gzip = createGzip(); + + promisify(pipeline)(archive, gzip, reply.raw); - gzip.on("close", () => reply.raw.end()); - gzip.on("error", () => reply.raw.end()); - archive.on("error", () => reply.raw.end()); + // Gzip error + gzip.on("error", err => { + console.log(err); + reply.raw.end(); + }); - addArchiveEntries(tree, this._owner.name.short, archive) - .then(() => { - archive.finalize(); - }) - .catch(() => { - archive.finalize(); - reply.raw.end(); - }); + // Tar error + archive.on("error", err => { + console.log(err); + reply.raw.end(); + }); } /** diff --git a/packages/server/src/git/tree.ts b/packages/server/src/git/tree.ts index 6c08e1a..2d3888e 100644 --- a/packages/server/src/git/tree.ts +++ b/packages/server/src/git/tree.ts @@ -1,7 +1,8 @@ import { Tree as NodeGitTree } from "nodegit"; import { Repository } from "./repository"; -import { BaseTreeEntry, createTreeEntry, TreeEntry } from "./tree_entry"; +import { BaseTreeEntry, BlobTreeEntry, createTreeEntry, TreeEntry } from "./tree_entry"; import { createError, TreeError } from "./error"; +import { pack, Pack } from "tar-stream"; /** * A representation of a git tree @@ -27,8 +28,8 @@ export class Tree { * * @returns An array of tree entry instances */ - public entries(): TreeEntry[] { - return this._ng_tree.entries().map(entry => new TreeEntry(this._owner, entry)); + public entries(): BaseTreeEntry[] { + return this._ng_tree.entries().map(entry => createTreeEntry(this._owner, entry)); } /** @@ -40,7 +41,7 @@ export class Tree { public async find(path: string): Promise<BaseTreeEntry> { const entry = await this._ng_tree.getEntry(path).catch(err => { if(err.errno === -3) { - throw(createError(TreeError, 404, "Path not found")); + throw(createError(TreeError, 404, `Path '${path}' not found`)); } throw(createError(TreeError, 500, "Failed to get tree path")); }); @@ -61,6 +62,33 @@ export class Tree { } /** + * Returns an archive made from the tree + * + * @returns An instance of a tar pack + */ + async createArchive(): Promise<Pack> { + const archive = pack(); + const repository = this._owner.name.short; + + async function addEntries(tree: Tree) { + for(const tree_entry of tree.entries()) { + if(tree_entry instanceof BlobTreeEntry) { + archive.entry({ name: `${repository}/${tree_entry.path}` }, (await (await tree_entry.blob()).content())); + } + else if(tree_entry instanceof TreeEntry) { + await addEntries(await tree_entry.tree()); + } + } + } + + await addEntries(this); + + archive.finalize(); + + return archive; + } + + /** * Returns the tree of a repository * * @remarks |