Skip to content

Commit

Permalink
Cleaned up the settings implementation & renamed base_dir project-wid…
Browse files Browse the repository at this point in the history
…e to git_dir
  • Loading branch information
HampusMat committed Aug 12, 2021
1 parent 30f0b2e commit d41b27f
Show file tree
Hide file tree
Showing 31 changed files with 115 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.DS_Store
node_modules
dist
settings.yml
settings.json
/coverage
/docs

Expand Down
8 changes: 8 additions & 0 deletions docs_src/hacking.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ This package contains interfaces and types shared by the server and client packa
### Eslint-config-base
This package contains a base Eslint configuration for the server and client packages. Aswell as for the test environment.

## Important notes
You may want to add the following to your settings.json
```
"dev": {
"port": (Port for the Vue.js development server)
}
```

## Development utilities
You can use the following command to run a live-updating instance of Githermit.

Expand Down
16 changes: 8 additions & 8 deletions docs_src/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ And finally, build the project.

`$ yarn build`

The final step is to create a file called `settings.yml` with the following content.
The final step is to create a file called `settings.json` with the following content.
```
host: (Host address)
port: (Port)
dev_port: (Port for development server)
production: (Set this to true unless you're doing changes to Githermit)
title: (Title of your Githermit instance)
about: (Short description of your Githermit instance)
base_dir: (Directory where all of your bare Git repositories are located)
{
"host": "(Host address)",
"port": (Port),
"title": "(Title of your Githermit instance)",
"about": "(Short description of your Githermit instance)",
"git_dir: "(Directory where all of your bare Git repositories are located)"
}
```

## Starting
Expand Down
3 changes: 1 addition & 2 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"core-js": "^3.6.5",
"date-fns": "^2.22.1",
"highlight.js": "^11.0.1",
"js-yaml": "^4.1.0",
"marked": "^2.1.3",
"vue": "^3.0.0",
"vue-loading-overlay": "^4.0.3",
Expand All @@ -32,6 +31,7 @@
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-standard": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"api": "^1.0.0",
"eslint": "^7.31.0",
"eslint-config-base": "^1.0.0",
"eslint-plugin-import": "^2.23.4",
Expand All @@ -40,7 +40,6 @@
"eslint-plugin-vue": "^7.14.0",
"sass": "^1.26.5",
"sass-loader": "^12.1.0",
"api": "^1.0.0",
"typescript": "^4.3.5",
"vue-eslint-parser": "^7.9.0",
"webpack": "^5.46.0"
Expand Down
5 changes: 2 additions & 3 deletions packages/client/vue.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
const yaml = require("js-yaml");
const fs = require("fs");
const path = require("path");

const settings = yaml.load(fs.readFileSync(path.join(__dirname, "/../../settings.yml"), "utf8"));
const settings = JSON.parse(fs.readFileSync(path.join(__dirname, "/../../settings.json"), "utf-8"));

module.exports = {
devServer: {
host: settings.host,
port: settings.dev_port,
port: settings.dev.port,
proxy: {
"^/api": {
target: `http://${settings.host}:${settings.port}`,
Expand Down
1 change: 0 additions & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"date-fns": "^2.22.1",
"fastify": "^3.17.0",
"fastify-static": "^4.2.2",
"js-yaml": "^4.1.0",
"nodegit": "^0.27.0",
"openpgp": "^5.0.0-5",
"tar-stream": "^2.2.0",
Expand Down
17 changes: 15 additions & 2 deletions packages/server/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import { fastify as fastifyFactory, FastifyInstance } from "fastify";
import fastifyStatic from "fastify-static";
import { Settings } from "./types";
import repo from "./routes/repo";
import { join } from "path";
import { readdirSync } from "fs";
import { exit } from "process";

export default function buildApp(settings: Settings, dist_dir: string): FastifyInstance {
export default function buildApp(settings: Settings): FastifyInstance {
const fastify = fastifyFactory();

fastify.setErrorHandler((err, req, reply) => {
Expand All @@ -16,7 +19,17 @@ export default function buildApp(settings: Settings, dist_dir: string): FastifyI
reply.code(404).send("Page not found!");
});

if(settings.production) {
if(!settings.dev) {
const dist_dir = join(__dirname, "/../../client/dist");

try {
readdirSync(dist_dir);
}
catch {
console.error("Error: Client dist directory doesn't exist!");
exit(1);
}

fastify.register(fastifyStatic, { root: dist_dir });

fastify.route({
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/git/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function connect(repository: Repository, req: Request, reply: FastifyRepl

reply.raw.writeHead(200, { "Content-Type": content_type });

const spawn_args = [ "--stateless-rpc", join(repository.base_dir, repository.name.full) ];
const spawn_args = [ "--stateless-rpc", join(repository.git_dir, repository.name.full) ];

if(is_discovery) {
spawn_args.push("--advertise-refs");
Expand Down
6 changes: 3 additions & 3 deletions packages/server/src/git/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ export async function findAsync<T>(arr: T[], callback: (t: T) => Promise<boolean
/**
* Returns the content of a file inside a repository
*
* @param base_dir - The directory which the repository is in
* @param git_dir - The directory which the repository is in
* @param repository - The directory of a bare repository
* @param file - The path of a file
*/
export function getFile(base_dir: string, repository: string, file: string): Promise<string> {
export function getFile(git_dir: string, repository: string, file: string): Promise<string> {
return new Promise((resolve, reject) => {
readFile(`${base_dir}/${repository}/${file}`, (err, content) => {
readFile(`${git_dir}/${repository}/${file}`, (err, content) => {
if(err) {
reject(createError(MiscError, 500, "Failed to open repository file " + file));
return;
Expand Down
22 changes: 11 additions & 11 deletions packages/server/src/git/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class Repository {
public ng_repository: NodeGitRepository;

public name: RepositoryName;
public base_dir: string;
public git_dir: string;
public branch_name: string;

/**
Expand All @@ -50,7 +50,7 @@ export class Repository {
short: basename(repository.path()).slice(0, -4),
full: basename(repository.path())
};
this.base_dir = dirname(repository.path());
this.git_dir = dirname(repository.path());

this.branch_name = branch;
}
Expand All @@ -59,14 +59,14 @@ export class Repository {
* Returns the repository's description
*/
public description(): Promise<string> {
return getFile(this.base_dir, this.name.full, "description");
return getFile(this.git_dir, this.name.full, "description");
}

/**
* Returns the repository's owner
*/
public owner(): Promise<string> {
return getFile(this.base_dir, this.name.full, "owner");
return getFile(this.git_dir, this.name.full, "owner");
}

/**
Expand Down Expand Up @@ -154,13 +154,13 @@ export class Repository {
/**
* Opens a bare git repository
*
* @param base_dir - The directory that contains the repository
* @param git_dir - The directory that contains the repository
* @param repository - The directory of a bare repository
* @param branch - A branch to use
* @returns An instance of a git repository
*/
public static async open(base_dir: string, repository: string, branch?: string): Promise<Repository> {
let ng_repository = await NodeGitRepository.openBare(`${base_dir}/${getFullRepositoryName(repository)}`).catch((err: WeirdError) => {
public static async open(git_dir: string, repository: string, branch?: string): Promise<Repository> {
let ng_repository = await NodeGitRepository.openBare(`${git_dir}/${getFullRepositoryName(repository)}`).catch((err: WeirdError) => {
if(err.errno === -3) {
throw(createError(RepositoryError, 404, "Repository not found"));
}
Expand All @@ -180,18 +180,18 @@ export class Repository {
/**
* Opens all of the git repositories inside a directory
*
* @param base_dir - The directory that contains the repositories
* @param git_dir - The directory that contains the repositories
* @returns An array of repository instances
*/
public static async openAll(base_dir: string): Promise<Repository[]> {
const dir_content = await getDirectory(base_dir);
public static async openAll(git_dir: string): Promise<Repository[]> {
const dir_content = await getDirectory(git_dir);

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

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

return Promise.all(repositories.map(repository => this.open(base_dir, repository)));
return Promise.all(repositories.map(repository => this.open(git_dir, repository)));
}
}
4 changes: 2 additions & 2 deletions packages/server/src/routes/api/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function reposEndpoints(fastify: FastifyInstance, opts: FastifyPluginOptions, do
method: "GET",
url: "/repos",
handler: async(req, reply) => {
const repos = await Repository.openAll(opts.config.settings.base_dir);
const repos = await Repository.openAll(opts.config.settings.git_dir);

if(!repos) {
reply.send({ data: [] });
Expand Down Expand Up @@ -49,7 +49,7 @@ function reposEndpoints(fastify: FastifyInstance, opts: FastifyPluginOptions, do
return;
}

const repository: Repository | BaseError = await Repository.open(opts.config.settings.base_dir, req.params.repo).catch(err => err);
const repository: Repository | BaseError = await Repository.open(opts.config.settings.git_dir, req.params.repo).catch(err => err);

if(repository instanceof BaseError) {
reply.code(repository.code).send({ error: repository.message });
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/routes/api/v1/repo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ declare module "fastify" {

function addHooks(fastify: FastifyInstance, opts: FastifyPluginOptions): void {
fastify.addHook("preHandler", async(req: CoolFastifyRequest, reply) => {
const repository = await Repository.open(opts.config.settings.base_dir, req.params.repo, req.query.branch).catch((err: BaseError) => err);
const repository = await Repository.open(opts.config.settings.git_dir, req.params.repo, req.query.branch).catch((err: BaseError) => err);

if(repository instanceof BaseError) {
reply.code(repository.code).send({ error: repository.message });
Expand Down
6 changes: 3 additions & 3 deletions packages/server/src/routes/repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
return;
}

const repository = await Repository.open(opts.config.settings.base_dir, req.params.repo);
const repository = await Repository.open(opts.config.settings.git_dir, req.params.repo);
repository.HTTPconnect(req, reply);
}
});
Expand All @@ -44,7 +44,7 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
method: "POST",
url: "/git-upload-pack",
handler: async(req, reply) => {
const repository = await Repository.open(opts.config.settings.base_dir, req.params.repo);
const repository = await Repository.open(opts.config.settings.git_dir, req.params.repo);
repository.HTTPconnect(req, reply);
}
});
Expand All @@ -62,7 +62,7 @@ export default function(fastify: FastifyInstance, opts: FastifyPluginOptions, do
method: "GET",
url: "/refs/tags/:tag",
handler: async(req, reply) => {
const repository = await Repository.open(opts.config.settings.base_dir, req.params.repo).catch((err: BaseError) => err);
const repository = await Repository.open(opts.config.settings.git_dir, req.params.repo).catch((err: BaseError) => err);

if(repository instanceof BaseError) {
reply.code(repository.code).send(repository.message);
Expand Down
42 changes: 12 additions & 30 deletions packages/server/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,41 @@
import { readFileSync, readdirSync } from "fs";
import { join } from "path";
import { load } from "js-yaml";
import { exit } from "process";
import { Settings } from "./types";
import buildApp from "./app";

const settings = load(readFileSync(join(__dirname, "/../../../settings.yml"), "utf8")) as Settings;
const settings = JSON.parse(readFileSync(join(__dirname, "/../../../settings.json"), "utf-8")) as Settings;

const settings_keys = Object.keys(settings);

const mandatory_settings = [ "host", "port", "dev_port", "title", "about", "base_dir", "production" ];
const mandatory_settings = [ "host", "port", "title", "about", "git_dir" ];

// Make sure that all the required settings are present
// Get missing mandatory settings
const settings_not_included = mandatory_settings.filter(x => !settings_keys.includes(x));

// Error out and exit if there's any missing settings
if(settings_not_included.length !== 0) {
console.log(`Error: settings.yml is missing ${(settings_not_included.length > 1) ? "keys" : "key"}:`);
console.log(`Error: settings file is missing ${(settings_not_included.length > 1) ? "keys" : "key"}:`);
console.log(settings_not_included.join(", "));
exit(1);
}

// Make sure that there's not an excessive amount of settings
const mandatory_not_included = settings_keys.filter(x => !mandatory_settings.includes(x));
if(mandatory_not_included.length !== 0) {
console.log(`Error: settings.yml includes ${(mandatory_not_included.length > 1) ? "pointless keys" : "a pointless key"}:`);
console.log(mandatory_not_included.join(", "));
exit(1);
}

// Make sure that the base directory specified in the settings actually exists
// Make sure that the git directory specified in the settings actually exists
try {
readdirSync(settings.base_dir);
readdirSync(settings.git_dir);
}
catch {
console.error(`Error: Tried opening the base directory. No such directory: ${settings.base_dir}`);
console.error(`Error: Git directory ${settings.git_dir} doesn't exist!`);
exit(1);
}

const dist_dir = join(__dirname, "/../../client/dist");

if(settings.production) {
try {
readdirSync(dist_dir);
}
catch {
console.error("Error: Tried opening the dist directory but it doesn't exist.\nDid you accidentally turn on the production setting?");
exit(1);
}
}

const app = buildApp(settings, dist_dir);
const app = buildApp(settings);

app.listen(settings.port, settings.host, (err: Error, addr: string) => {
if(err) {
console.error(err);
exit(1);
}

console.log(`App is running on ${addr}`);
console.log(`Githermit is running on ${addr}`);
});
7 changes: 4 additions & 3 deletions packages/server/src/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
export type Settings = {
host: string,
port: number,
dev_port: number,
title: string,
about: string,
base_dir: string,
production: boolean
git_dir: string,
dev: {
port: number
}
}
11 changes: 6 additions & 5 deletions test/int/api.int.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ describe("API", () => {
app = buildApp({
host: host,
port: port,
dev_port: 0,
title: "Bob's cool projects",
about: "All of my personal projects. Completely FOSS.",
base_dir: env.BASE_DIR,
production: false
}, "");
git_dir: env.GIT_DIR,
dev: {
port: 0
}
});

await app.listen(port);

Expand Down Expand Up @@ -265,7 +266,7 @@ describe("API", () => {
beforeAll(async() => {
const body = new Readable({ read: () => null });

let head = (await readFile(`${env.BASE_DIR}/${env.AVAIL_REPO}/FETCH_HEAD`)).toString();
let head = (await readFile(`${env.GIT_DIR}/${env.AVAIL_REPO}/FETCH_HEAD`)).toString();

const find_head = /^[a-f0-9]+/.exec(head);

Expand Down
Loading

0 comments on commit d41b27f

Please sign in to comment.