aboutsummaryrefslogtreecommitdiff
path: root/packages/server/src/git/repository.ts
blob: ff2376149049630c9d9ac932164f98c32c89cd60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { Object as NodeGitObject, Oid as NodeGitOid, Repository as NodeGitRepository, Revwalk as NodeGitRevwalk } from "nodegit";
import { Request, connect } from "./http";
import { basename, dirname } from "path";
import { getDirectory, getFile } from "./misc";
import { Branch } from "./branch";
import { Commit } from "./commit";
import { FastifyReply } from "fastify";
import { Tag } from "./tag";
import { Tree } from "./tree";

function getFullRepositoryName(repo_name: string) {
	return repo_name.endsWith(".git") ? repo_name : `${repo_name}.git`;
}

type RepositoryName = {
	short: string,
	full: string,
}

type RepositoryConstructorData = {
	description: string | null,
	owner: string | null
}

export class Repository {
	private _ng_repository: NodeGitRepository;

	public name: RepositoryName;
	public base_dir: string;
	public description: string | null;
	public owner: string | null;

	constructor(repository: NodeGitRepository, data: RepositoryConstructorData) {
		this._ng_repository = repository;
		this.name = {
			short: basename(repository.path()).slice(0, -4),
			full: basename(repository.path())
		};
		this.base_dir = dirname(repository.path());
		this.description = data.description;
		this.owner = data.owner;
	}

	public async commits(): Promise<Commit[]> {
		const walker = NodeGitRevwalk.create(this._ng_repository);
		walker.pushHead();

		return Promise.all((await walker.getCommitsUntil(() => true)).map(commit => new Commit(this, commit)));
	}

	public async tree(): Promise<Tree> {
		const master_commit = await this._ng_repository.getMasterCommit();
		const tree = await master_commit.getTree();
		return new Tree(this, tree);
	}

	public lookupExists(id: string): Promise<boolean> {
		return NodeGitObject.lookup(this._ng_repository, NodeGitOid.fromString(id), NodeGitObject.TYPE.ANY)
			.then(() => true)
			.catch(() => false);
	}

	public async branches(): Promise<Branch[]> {
		const references = await this._ng_repository.getReferences();
		return references.filter(ref => ref.isBranch()).map(branch => new Branch(this, branch));
	}

	public async tags(): Promise<Tag[]> {
		const references = await this._ng_repository.getReferences();
		return references.filter(ref => ref.isTag()).map(tag => new Tag(this, tag));
	}

	public async latestCommit(): Promise<Commit> {
		return new Commit(this, await this._ng_repository.getMasterCommit());
	}

	public HTTPconnect(req: Request, reply: FastifyReply): void {
		connect(this, req, reply);
	}

	public get nodegitRepository(): NodeGitRepository {
		return this._ng_repository;
	}

	public static async open(base_dir: string, repository: string): Promise<Repository> {
		const ng_repository = await NodeGitRepository.openBare(`${base_dir}/${getFullRepositoryName(repository)}`);

		return new Repository(ng_repository, {
			description: await getFile(base_dir, getFullRepositoryName(repository), "description"),
			owner: await getFile(base_dir, getFullRepositoryName(repository), "owner")
		});
	}

	public static async openAll(base_dir: string): Promise<Repository[] | null> {
		const dir_content = await getDirectory(base_dir);

		if(dir_content.length === 0) {
			return null;
		}

		const repositories = dir_content.filter(dir_entry => dir_entry.endsWith(".git"));

		return Promise.all(repositories.map(repository => this.open(base_dir, repository)));
	}
}