/*
pkgit - package it!
Copyright (C) 2026 dacctal
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include "common.h"
#include "files.h"
#include "log.h"
#include "pkg.h"
#include "state.h"
#include "str.h"
static str get_destdir(str *cwd, str *arg) {
str result = {0};
if (is_directory(arg->data)) {
result = str_format("%.*s", str_fmt(arg));
} else if (str_first(arg) == '.' && arg->len == 1) {
result = str_format("%.*s/%.*s",
str_fmt(&config.inst_dirs.src), str_fmt(cwd));
} else { str name = {0};
if (str_find_char(arg, '/') != 0)
name = str_from_after_delim(arg, '/');
else str_copy_into(&name, arg);
result = str_format("%.*s/%.*s",
str_fmt(&config.inst_dirs.src), str_fmt(&name));
str_free(&name);
}
return result;
}
static void set_pkgsrc(package_t *pkg, str *cwd, bool is_installed_locally) {
pkg->root = str_format("%.*s/%.*s",
str_fmt(&config.inst_dirs.src), str_fmt(&pkg->name));
if (is_installed_locally) str_copy_into(&pkg->src, cwd);
else if (pkg->is_local) pkg->src = pkg->root;
else pkg->src = str_format("%.*s/%.*s/%.*s",
str_fmt(&config.inst_dirs.src), str_fmt(&pkg->name),
str_fmt(&pkg->version));
}
static void assign_pkg_version(package_t *pkg, str *new_arg_str) {
if (str_find_char(new_arg_str, '@')) {
pkg->version = str_from_after_delim(new_arg_str, '@');
pkg->name.len -= pkg->version.len + 1;
} else str_copy_cstr_into(&pkg->version, "master");;
}
package_t pkg_create(str *arg) {
package_t pkg = { .is_local = false, };
assign_pkg_version(&pkg, arg);
char cwd_cstr[MAX_PATH_LEN];
getcwd(cwd_cstr, MAX_PATH_LEN);
str cwd = mstr(cwd_cstr);
str destdir = get_destdir(&cwd, arg);
bool is_installed_locally = is_directory(destdir.data);
if (strncmp(arg->data, "http", 4) == 0
|| strncmp(arg->data, "ssh", 3) == 0) {
str_copy_into(&pkg.url, arg);
pkg.name = str_from_after_delim(arg, '/');
} else if (str_equal_cstr(arg, ".")) {
str_copy_cstr_into(&pkg.url, "");
pkg.name = str_from_after_delim(&cwd, '/');
pkg.is_local = true;
} else if (pkg_exists(arg)) {
str_copy_into(&pkg.name, arg);
pkg.url = pkg_get_url(&pkg);
} else if (is_installed_locally) {
str_copy_cstr_into(&pkg.url, "");
pkg.name = str_from_after_delim(&destdir, '/');
pkg.is_local = true;
} else {
log_error("'%.*s' is not a valid package", str_fmt(arg));
str_free(&cwd);
str_free(&destdir);
str_free(arg);
exit(1);
}
set_pkgsrc(&pkg, &cwd, is_installed_locally);
str_free(&cwd);
str_free(&destdir);
return pkg;
}
void pkg_free(package_t *pkg) {
str_free(&pkg->name);
str_free(&pkg->version);
str_free(&pkg->url);
str_free(&pkg->src);
str_free(&pkg->root);
}