From 57fe767a7052ac0d115800d60e1d14a5d522cf8e Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Wed, 19 Jan 2022 18:54:33 +0100 Subject: [PATCH] Working add to repo functionality --- src/main.v | 17 ++++--- src/{pkg.v => package.v} | 21 ++++++-- src/repo.v | 107 ++++++++++++++++++++++++--------------- 3 files changed, 94 insertions(+), 51 deletions(-) rename src/{pkg.v => package.v} (94%) diff --git a/src/main.v b/src/main.v index 835b822..dc515ea 100644 --- a/src/main.v +++ b/src/main.v @@ -4,7 +4,6 @@ import web import os import log import io -import pkg import repo const port = 8000 @@ -103,12 +102,16 @@ fn reader_to_file(mut reader io.BufferedReader, length int, path string) ? { // } fn main() { + r := repo.new('data/repo', 'data/pkgs') or { return } + print(r.add_from_path('test/homebank-5.5.1-1-x86_64.pkg.tar.zst') or { panic('you fialed') }) + // archive.list_filenames() - res := pkg.read_pkg('test/jjr-joplin-desktop-2.6.10-4-x86_64.pkg.tar.zst') or { - eprintln(err.msg) - return - } + // res := pkg.read_pkg('test/jjr-joplin-desktop-2.6.10-4-x86_64.pkg.tar.zst') or { + // eprintln(err.msg) + // return + // } // println(info) - println('hey') - print(res.to_desc()) + // println('hey') + // print(res.to_desc()) + // print(res.to_files()) } diff --git a/src/pkg.v b/src/package.v similarity index 94% rename from src/pkg.v rename to src/package.v index 2598179..12480b3 100644 --- a/src/pkg.v +++ b/src/package.v @@ -1,4 +1,4 @@ -module pkg +module package import time import os @@ -45,7 +45,9 @@ fn C.archive_entry_new() &C.archive_entry fn C.archive_entry_pathname(&C.archive_entry) &char // Get an entry's file size -// Note: this function actually returns an i64, but as this can't be used as an arugment to malloc, we'll just roll with it & assume an entry is never bigger than 4 gigs +// Note: this function actually returns an i64, but as this can't be used as an +// arugment to malloc, we'll just roll with it & assume an entry is never +// bigger than 4 gigs fn C.archive_entry_size(&C.archive_entry) int #include @@ -63,7 +65,7 @@ pub: // Represents the contents of a .PKGINFO file struct PkgInfo { -mut: +pub mut: // Single values name string base string @@ -212,13 +214,19 @@ fn format_entry(key string, value string) string { return '\n%$key%\n$value\n' } +pub fn (pkg &Pkg) filename() string { + p := pkg.info + + return '$p.name-$p.version-${p.arch}.pkg.tar.zst' +} + // to_desc returns a desc file valid string representation // TODO calculate md5 & sha256 instead of believing the file pub fn (pkg &Pkg) to_desc() string { p := pkg.info // filename - mut desc := '%FILENAME%\n$p.name-$p.version-${p.arch}.pkg.tar.zst\n' + mut desc := '%FILENAME%\n$pkg.filename()\n' desc += format_entry('NAME', p.name) desc += format_entry('BASE', p.base) @@ -286,3 +294,8 @@ pub fn (pkg &Pkg) to_desc() string { return '$desc\n' } + +// to_files returns a files file valid string representation +pub fn (pkg &Pkg) to_files() string { + return '%FILES%\n$pkg.files.join_lines()\n' +} diff --git a/src/repo.v b/src/repo.v index f3ebfd4..c7b7db5 100644 --- a/src/repo.v +++ b/src/repo.v @@ -1,8 +1,13 @@ module repo import os +import package -const pkgs_subpath = 'pkgs' +// subpath where the uncompressed version of the files archive is stored +const files_subpath = 'files' + +// subpath where the uncompressed version of the repo archive is stored +const repo_subpath = 'repo' // Dummy struct to work around the fact that you can only share structs, maps & // arrays @@ -21,46 +26,68 @@ pub: pkg_dir string [required] } -// contains returns whether the repository contains the given package. -pub fn (r &Repo) contains(pkg string) bool { - return os.exists(os.join_path(r.repo_dir, 'files', pkg)) -} - -// add adds the given package to the repo. If false, the package was already -// present in the repository. -pub fn (r &Repo) add(pkg string) ?bool { - return false -} - -// generate re-generates the db & files archives. -fn (r &Repo) genenerate() ? { -} - -// pkg_path 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_single(r.pkg_dir, pkg) -} - -// exists checks whether a package file exists -pub fn (r &Repo) exists(pkg string) bool { - return os.exists(r.pkg_path(pkg)) -} - -// db_path returns the full path to the database file -pub fn (r &Repo) db_path() string { - return os.join_path_single(r.repo_dir, 'repo.tar.gz') -} - -// add_package adds a package to the repository -pub fn (r &Repo) add_package(pkg_path string) ? { - mut res := os.Result{} - - lock r.mutex { - res = os.execute("repo-add '$r.db_path()' '$pkg_path'") +pub fn new(repo_dir string, pkg_dir string) ?Repo { + if !os.is_dir(repo_dir) { + os.mkdir_all(repo_dir) or { return error('Failed to create repo directory.') } } - if res.exit_code != 0 { - println(res.output) - return error('repo-add failed.') + if !os.is_dir(pkg_dir) { + os.mkdir_all(pkg_dir) or { return error('Failed to create package directory.') } + } + + return Repo{ + repo_dir: repo_dir + pkg_dir: pkg_dir } } + +// add_from_path adds a package from an arbitrary path & moves it into the pkgs +// directory if necessary. +pub fn (r &Repo) add_from_path(pkg_path string) ?bool { + pkg := package.read_pkg(pkg_path) or { return error('Failed to read package file.') } + + added := r.add(pkg) ? + + // If the add was successful, we move the file to the packages directory + if added { + dest_path := os.real_path(os.join_path_single(r.pkg_dir, pkg.filename())) + + // Only move the file if it's not already in the package directory + if dest_path != os.real_path(pkg_path) { + os.mv(pkg_path, dest_path) ? + } + } + + return true +} + +// add adds a given Pkg to the repository +fn (r &Repo) add(pkg &package.Pkg) ?bool { + pkg_dir := r.pkg_path(pkg) + + // We can't add the same package twice + if os.exists(pkg_dir) { + return false + } + + os.mkdir(pkg_dir) or { return error('Failed to create package directory.') } + + os.write_file(os.join_path_single(pkg_dir, 'desc'), pkg.to_desc()) or { + os.rmdir_all(pkg_dir) ? + + return error('Failed to write desc file.') + } + os.write_file(os.join_path_single(pkg_dir, 'files'), pkg.to_files()) or { + os.rmdir_all(pkg_dir) ? + + return error('Failed to write files file.') + } + // TODO generate database archive + + return true +} + +// Returns the path where the given package's desc & files files are stored +fn (r &Repo) pkg_path(pkg &package.Pkg) string { + return os.join_path(r.repo_dir, '$pkg.info.name-$pkg.info.version') +}