diff --git a/docs/api/source/includes/_repository.md b/docs/api/source/includes/_repository.md
index 9764e01..a846904 100644
--- a/docs/api/source/includes/_repository.md
+++ b/docs/api/source/includes/_repository.md
@@ -122,3 +122,58 @@ Parameter | Description
repo | Repository to delete package from
arch | Specific arch-repo to remove package from
pkg | Name of package to remove (without any version information)
+
+## Remove arch-repo
+
+
+
+```shell
+curl \
+ -H 'X-Api-Key: secret' \
+ -XDELETE \
+ https://example.com/vieter/x86_64
+```
+
+This endpoint allows remove an entire arch-repo.
+
+### HTTP Request
+
+`DELETE /:repo/:arch`
+
+### URL Parameters
+
+Parameter | Description
+--------- | -----------
+repo | Repository to delete arch-repo from
+arch | Specific architecture to remove package
+
+## Remove repo
+
+
+
+```shell
+curl \
+ -H 'X-Api-Key: secret' \
+ -XDELETE \
+ https://example.com/vieter
+```
+
+This endpoint allows remove an entire repo.
+
+### HTTP Request
+
+`DELETE /:repo`
+
+### URL Parameters
+
+Parameter | Description
+--------- | -----------
+repo | Repository to delete
diff --git a/src/repo/repo.v b/src/repo/add.v
similarity index 77%
rename from src/repo/repo.v
rename to src/repo/add.v
index 7de12cd..0985c7a 100644
--- a/src/repo/repo.v
+++ b/src/repo/add.v
@@ -154,51 +154,3 @@ fn (r &RepoGroupManager) add_pkg_in_arch_repo(repo string, arch string, pkg &pac
return true
}
-
-// remove_pkg_from_arch_repo removes a package from an arch-repo's database. It
-// returns false if the package wasn't present in the database. It also
-// optionally re-syncs the repo archives.
-pub fn (r &RepoGroupManager) remove_pkg_from_arch_repo(repo string, arch string, pkg_name string, sync bool) ?bool {
- repo_dir := os.join_path(r.repos_dir, repo, arch)
-
- // If the repository doesn't exist yet, the result is automatically false
- if !os.exists(repo_dir) {
- return false
- }
-
- // We iterate over every directory in the repo dir
- // TODO filter so we only check directories
- for d in os.ls(repo_dir)? {
- // Because a repository only allows a single version of each package,
- // we need only compare whether the name of the package is the same,
- // not the version.
- name := d.split('-')#[..-2].join('-')
-
- if name == pkg_name {
- // We lock the mutex here to prevent other routines from creating a
- // new archive while we remove an entry
- lock r.mutex {
- os.rmdir_all(os.join_path_single(repo_dir, d))?
- }
-
- // Also remove the package archive
- repo_pkg_dir := os.join_path(r.pkg_dir, repo, arch)
-
- archives := os.ls(repo_pkg_dir)?.filter(it.split('-')#[..-3].join('-') == name)
-
- for archive_name in archives {
- full_path := os.join_path_single(repo_pkg_dir, archive_name)
- os.rm(full_path)?
- }
-
- // Sync the db archives if requested
- if sync {
- r.sync(repo, arch)?
- }
-
- return true
- }
- }
-
- return false
-}
diff --git a/src/repo/remove.v b/src/repo/remove.v
new file mode 100644
index 0000000..add921c
--- /dev/null
+++ b/src/repo/remove.v
@@ -0,0 +1,85 @@
+module repo
+
+import os
+
+// remove_pkg_from_arch_repo removes a package from an arch-repo's database. It
+// returns false if the package wasn't present in the database. It also
+// optionally re-syncs the repo archives.
+pub fn (r &RepoGroupManager) remove_pkg_from_arch_repo(repo string, arch string, pkg_name string, sync bool) ?bool {
+ repo_dir := os.join_path(r.repos_dir, repo, arch)
+
+ // If the repository doesn't exist yet, the result is automatically false
+ if !os.exists(repo_dir) {
+ return false
+ }
+
+ // We iterate over every directory in the repo dir
+ // TODO filter so we only check directories
+ for d in os.ls(repo_dir)? {
+ // Because a repository only allows a single version of each package,
+ // we need only compare whether the name of the package is the same,
+ // not the version.
+ name := d.split('-')#[..-2].join('-')
+
+ if name == pkg_name {
+ // We lock the mutex here to prevent other routines from creating a
+ // new archive while we remove an entry
+ lock r.mutex {
+ os.rmdir_all(os.join_path_single(repo_dir, d))?
+ }
+
+ // Also remove the package archive
+ repo_pkg_dir := os.join_path(r.pkg_dir, repo, arch)
+
+ archives := os.ls(repo_pkg_dir)?.filter(it.split('-')#[..-3].join('-') == name)
+
+ for archive_name in archives {
+ full_path := os.join_path_single(repo_pkg_dir, archive_name)
+ os.rm(full_path)?
+ }
+
+ // Sync the db archives if requested
+ if sync {
+ r.sync(repo, arch)?
+ }
+
+ return true
+ }
+ }
+
+ return false
+}
+
+// remove_arch_repo removes an arch-repo & its packages.
+pub fn (r &RepoGroupManager) remove_arch_repo(repo string, arch string) ?bool {
+ repo_dir := os.join_path(r.repos_dir, repo, arch)
+
+ // If the repository doesn't exist yet, the result is automatically false
+ if !os.exists(repo_dir) {
+ return false
+ }
+
+ os.rmdir_all(repo_dir)?
+
+ pkg_dir := os.join_path(r.pkg_dir, repo, arch)
+ os.rmdir_all(pkg_dir)?
+
+ return true
+}
+
+// remove_repo removes a repo & its packages.
+pub fn (r &RepoGroupManager) remove_repo(repo string) ?bool {
+ repo_dir := os.join_path_single(r.repos_dir, repo)
+
+ // If the repository doesn't exist yet, the result is automatically false
+ if !os.exists(repo_dir) {
+ return false
+ }
+
+ os.rmdir_all(repo_dir)?
+
+ pkg_dir := os.join_path_single(r.pkg_dir, repo)
+ os.rmdir_all(pkg_dir)?
+
+ return true
+}
diff --git a/src/server/routes.v b/src/server/repo.v
similarity index 82%
rename from src/server/routes.v
rename to src/server/repo.v
index 3b86e20..fbf37df 100644
--- a/src/server/routes.v
+++ b/src/server/repo.v
@@ -57,29 +57,6 @@ fn (mut app App) get_repo_file(repo string, arch string, filename string) web.Re
return app.file(full_path)
}
-['/:repo/:arch/:pkg'; delete]
-fn (mut app App) delete_package(repo string, arch string, pkg string) web.Result {
- if !app.is_authorized() {
- return app.json(http.Status.unauthorized, new_response('Unauthorized.'))
- }
-
- res := app.repo.remove_pkg_from_arch_repo(repo, arch, pkg, true) or {
- app.lerror('Error while deleting package: $err.msg()')
-
- return app.json(http.Status.internal_server_error, new_response('Failed to delete package.'))
- }
-
- if res {
- app.linfo("Removed package '$pkg' from '$repo/$arch'")
-
- return app.json(http.Status.ok, new_response('Package removed.'))
- } else {
- app.linfo("Tried removing package '$pkg' from '$repo/$arch', but it doesn't exist.")
-
- return app.json(http.Status.not_found, new_response('Package not found.'))
- }
-}
-
// put_package handles publishing a package to a repository.
['/:repo/publish'; post]
fn (mut app App) put_package(repo string) web.Result {
diff --git a/src/server/repo_remove.v b/src/server/repo_remove.v
new file mode 100644
index 0000000..642f26f
--- /dev/null
+++ b/src/server/repo_remove.v
@@ -0,0 +1,77 @@
+module server
+
+import web
+import net.http
+import response { new_response }
+
+// delete_package tries to remove the given package.
+['/:repo/:arch/:pkg'; delete]
+fn (mut app App) delete_package(repo string, arch string, pkg string) web.Result {
+ if !app.is_authorized() {
+ return app.json(http.Status.unauthorized, new_response('Unauthorized.'))
+ }
+
+ res := app.repo.remove_pkg_from_arch_repo(repo, arch, pkg, true) or {
+ app.lerror('Error while deleting package: $err.msg()')
+
+ return app.json(http.Status.internal_server_error, new_response('Failed to delete package.'))
+ }
+
+ if res {
+ app.linfo("Removed package '$pkg' from '$repo/$arch'")
+
+ return app.json(http.Status.ok, new_response('Package removed.'))
+ } else {
+ app.linfo("Tried removing package '$pkg' from '$repo/$arch', but it doesn't exist.")
+
+ return app.json(http.Status.not_found, new_response('Package not found.'))
+ }
+}
+
+// delete_arch_repo tries to remove the given arch-repo.
+['/:repo/:arch'; delete]
+fn (mut app App) delete_arch_repo(repo string, arch string) web.Result {
+ if !app.is_authorized() {
+ return app.json(http.Status.unauthorized, new_response('Unauthorized.'))
+ }
+
+ res := app.repo.remove_arch_repo(repo, arch) or {
+ app.lerror('Error while deleting arch-repo: $err.msg()')
+
+ return app.json(http.Status.internal_server_error, new_response('Failed to delete arch-repo.'))
+ }
+
+ if res {
+ app.linfo("Removed '$repo/$arch'")
+
+ return app.json(http.Status.ok, new_response('Arch-repo removed.'))
+ } else {
+ app.linfo("Tried removing '$repo/$arch', but it doesn't exist.")
+
+ return app.json(http.Status.not_found, new_response('Arch-repo not found.'))
+ }
+}
+
+// delete_repo tries to remove the given repo.
+['/:repo'; delete]
+fn (mut app App) delete_repo(repo string) web.Result {
+ if !app.is_authorized() {
+ return app.json(http.Status.unauthorized, new_response('Unauthorized.'))
+ }
+
+ res := app.repo.remove_repo(repo) or {
+ app.lerror('Error while deleting repo: $err.msg()')
+
+ return app.json(http.Status.internal_server_error, new_response('Failed to delete repo.'))
+ }
+
+ if res {
+ app.linfo("Removed '$repo'")
+
+ return app.json(http.Status.ok, new_response('Repo removed.'))
+ } else {
+ app.linfo("Tried removing '$repo', but it doesn't exist.")
+
+ return app.json(http.Status.not_found, new_response('Repo not found.'))
+ }
+}