aboutsummaryrefslogtreecommitdiff
path: root/packages/server/src/git
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2021-07-29 15:39:31 +0200
committerHampusM <hampus@hampusmat.com>2021-07-29 15:59:52 +0200
commit8d42b6f44ca5b0eeb54938e1cf9509d1f8294f00 (patch)
treeb3bae9c6160bb11436a7f2875f27191780156353 /packages/server/src/git
parent4f47dbfeb6edd984b2e912f00993db6e4eb2193d (diff)
Refactored & improved the backend yet again
Diffstat (limited to 'packages/server/src/git')
-rw-r--r--packages/server/src/git/blob.ts2
-rw-r--r--packages/server/src/git/tag.ts58
-rw-r--r--packages/server/src/git/tree.ts36
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