diff --git a/Makefile b/Makefile index f6cd653f..6c677332 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: run run: - API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG v run vieter + API_KEY=test REPO_DIR=data LOG_LEVEL=DEBUG v -cg run vieter .PHONY: watch watch: diff --git a/vieter/main.v b/vieter/main.v index 7d88ec50..8c2c38fa 100644 --- a/vieter/main.v +++ b/vieter/main.v @@ -14,9 +14,10 @@ const db_name = 'pieter.db.tar.gz' struct App { web.Context +pub: api_key string [required; web_global] - repo_dir string [required; web_global] - repo shared repo.Repo [required] +pub mut: + repo repo.Repo [required; web_global] } [noreturn] @@ -91,9 +92,9 @@ fn main() { web.run(&App{ logger: logger api_key: key - repo_dir: repo_dir repo: repo.Repo{ - path: os.join_path_single(repo_dir, db_name) + dir: repo_dir + name: db_name } }, port) } diff --git a/vieter/repo.v b/vieter/repo.v index a0902071..0777bf30 100644 --- a/vieter/repo.v +++ b/vieter/repo.v @@ -2,12 +2,37 @@ module repo import os +const pkgs_subpath = 'pkgs' + +// Handles management of a repository. Package files are stored in '$dir/pkgs' +// & moved there if necessary. pub struct Repo { - path string + mutex shared int = 0 +pub: + dir string [required] + name string [required] +} + +// Returns path to the given package, prepended with the repo's path. +pub fn (r Repo) pkg_path(pkg string) string { + return os.join_path(r.dir, pkgs_subpath, pkg) +} + +pub fn (r Repo) exists(pkg string) bool { + return os.exists(r.pkg_path(pkg)) +} + +// Returns the full path to the database file +pub fn (r Repo) db_path() string { + return os.join_path_single(r.dir, '${r.name}.tar.gz') } pub fn (r Repo) add_package(pkg_path string) ? { - res := os.execute("repo-add '$r.path' '$pkg_path'") + mut res := os.Result{} + + lock r.mutex { + res = os.execute("repo-add '$r.db_path()' '$pkg_path'") + } if res.exit_code != 0 { println(res.output) diff --git a/vieter/routes.v b/vieter/routes.v index 2b149206..75370400 100644 --- a/vieter/routes.v +++ b/vieter/routes.v @@ -6,17 +6,18 @@ import repo ['/pkgs/:pkg'; put] fn (mut app App) put_package(pkg string) web.Result { - full_path := os.join_path_single(app.repo_dir, pkg) - - if os.exists(full_path) { + if app.repo.exists(pkg) { app.lwarn("Tried to upload duplicate package '$pkg'") return app.text('File already exists.') } + pkg_path := app.repo.pkg_path(pkg) + if length := app.req.header.get(.content_length) { app.ldebug("Uploading $length bytes to package '$pkg'") - reader_to_file(mut app.reader, length.int(), full_path) or { + println(pkg_path) + reader_to_file(mut app.reader, length.int(), pkg_path) or { app.lwarn("Failed to upload package '$pkg'") return app.text('Failed to upload file.') @@ -26,18 +27,15 @@ fn (mut app App) put_package(pkg string) web.Result { return app.text("Content-Type header isn't set.") } - lock app.repo { - app.repo.add_package(full_path) or { - app.linfo("Failed to add package '$pkg' to database.") + app.repo.add_package(pkg_path) or { + app.linfo("Failed to add package '$pkg' to database.") - os.rm(full_path) or { println('Failed to remove $full_path') } + os.rm(pkg_path) or { println('Failed to remove $pkg_path') } - return app.text('Failed to add package to repo.') - } - - app.linfo("Added '$pkg' to repository.") + return app.text('Failed to add package to repo.') } + app.linfo("Added '$pkg' to repository.") app.linfo("Uploaded package '$pkg'.") return app.text('Package added successfully.')