package

simple and robust package manager
Log | Files | Refs | README

commit 2272f13ce0e227720e95128988c480d7bf02c863
parent cc0a1a31b4b895fd0a859fd48347d0cecef4b605
Author: Josuah Demangeon <mail@josuah.net>
Date:   Sun, 20 Jan 2019 02:23:17 +0100

sum-up dependencies and handle download time dependencies

append the version-specific dependencies instead of
replacing the default dependencies.

handle download-time dependencies by building them first.

Diffstat:
Mbin/package-http | 2++
Mpackage-add.c | 22+++++++++++++---------
Mpackage-build.c | 75++++-----------------------------------------------------------------------
Mpackage-get.c | 2++
Mpackage.c | 210+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Mpackage.h | 8+++++++-
6 files changed, 202 insertions(+), 117 deletions(-)

diff --git a/bin/package-http b/bin/package-http @@ -1,5 +1,7 @@ #!/bin/sh -ex +env 1>&2 + cd "$(mktemp -d)" trap "rm -rf '$PWD'" EXIT INT TERM diff --git a/package-add.c b/package-add.c @@ -112,33 +112,37 @@ main(int argc, char **argv) log_fatal_sys_1(103, "could not resolve package dependencies"); if (!genalloc_append(&ga, p)) die_nomem(); - // download everything + // download and build download-time dependencies for (size_t i = 0; i < genalloc_len(&ga, package); ++i) { package *p = genalloc_get(&ga, package, i); - + if (!p->dep_download) continue; if ((x = get(p, def, pkg)) != 0) return x; + if ((x = build(p, def, pkg)) != 0) return x; } - // build everything and install build-time dependencies + // download everything for (size_t i = 0; i < genalloc_len(&ga, package); ++i) { package *p = genalloc_get(&ga, package, i); + if ((x = get(p, def, pkg)) != 0) return x; + } + // build everything + for (size_t i = 0; i < genalloc_len(&ga, package); ++i) + { + package *p = genalloc_get(&ga, package, i); if ((x = build(p, def, pkg)) != 0) return x; - if (p->dep_build) - if ((x = install(p, def, pkg, root)) != 0) goto error; } if (flag_n) return 0; - // install run-time dependencies and main argument + // install run-time dependencies for (size_t i = 0; i < genalloc_len(&ga, package); ++i) { package *p = genalloc_get(&ga, package, i); - - if (p->dep_run) - if ((x = install(p, def, pkg, root)) != 0) goto error; + if (!p->dep_run) continue; + if ((x = install(p, def, pkg, root)) != 0) goto error; } return 0; diff --git a/package-build.c b/package-build.c @@ -148,75 +148,6 @@ error: return ret; } -static int -env_sane_name(char const *name, char const *path) -{ - char buf[NAME_MAX]; - int len; - - for (len = 0; name[len] != '\0'; ++len) - buf[len] = isalnum(name[len]) ? name[len] : '_'; - buf[len] = '\0'; - return env_set(buf, path); -} - -static int -env(package *p, char const *def, char const *pkg, char const *id) -{ - stralloc sa = STRALLOC_ZERO; - stralloc line = STRALLOC_ZERO; - buffer b; - char buf[1024]; - size_t r; - size_t n; - int fd = -1; - int ret = 0; - - stralloc_init(&sa); - if (!stralloc_cats(&sa, pkg)) goto error; - if (!stralloc_cats(&sa, "/")) goto error; - if (!stralloc_cats(&sa, p->name)) goto error; - if (!stralloc_cats(&sa, "/")) goto error; - if (!stralloc_cats(&sa, p->ver)) goto error; - if (!stralloc_cats(&sa, "/")) goto error; - if (!stralloc_cats(&sa, id)) goto error; - if (!stralloc_cats(&sa, "/build")) goto error; - if (!stralloc_cat0(&sa)) goto error; - if (!env_sane_name("PREFIX", sa.x)) goto error; - - errno = 0; - fd = package_opendepfile(p, def); - if (fd == -1) { ret = (errno == ENOTDIR || errno == ENOENT); goto error; } - - stralloc_init(&line); - buffer_init(&b, &read, fd, buf, sizeof buf); - while (stralloc_zero(&line), (r = buffer_getline(&b, &line)) > 0) - { - package new; - - line.n -= (line.x[line.n - 1] == '\n'); - if (!stralloc_cat0(&line)) goto error; - n = package_dep_scan(&new, line.x, line.n); if (n == 0 || line.x[n] != '\0') goto error; - if (!package_version(&new, def)) goto error; - - stralloc_zero(&sa); - if (!stralloc_cats(&sa, pkg)) goto error; - if (!stralloc_cats(&sa, "/")) goto error; - if (!stralloc_cats(&sa, new.name)) goto error; - if (!stralloc_cats(&sa, "/")) goto error; - if (!stralloc_cats(&sa, new.ver)) goto error; - if (!stralloc_cats(&sa, "/current/build")) goto error; - if (!stralloc_cat0(&sa)) goto error; - if (!env_sane_name(new.name, sa.x)) goto error; - } - ret = (r == 0); -error: - stralloc_free(&sa); - stralloc_free(&line); - if (fd >= 0) close(fd); - return ret; -} - int main(int argc, char **argv) { @@ -298,8 +229,10 @@ main(int argc, char **argv) write(1, "=== end ===\n", 12); write(1, "\n=== setenv ===\n", 16); - if (!env(&p, def, pkg, id)) - log_fatal_sys_2(100, "could not set environment variables for ", *argv); + if (!package_env_prefix(&p, pkg, id)) + log_fatal_sys_1(100, "setting PREFIX environment variable"); + if (!package_env_dep(&p, def, pkg)) + log_fatal_sys_1(100, "setting dependencies environment variables"); write(1, "=== end ===\n", 12); write(1, "\n=== build ===\n", 15); diff --git a/package-get.c b/package-get.c @@ -52,6 +52,8 @@ main(int argc, char **argv) log_fatal_2(1, "invalid package format: ", *argv); if (!package_version(&p, def)) log_fatal_sys_2(101, "package_version ", p.name); + if (!package_env_dep(&p, def, pkg)) + log_fatal_sys_1(100, "setting dependencies environment variables"); stralloc_init(&sa); if (!stralloc_cats(&sa, def)) die_nomem(); diff --git a/package.c b/package.c @@ -16,6 +16,129 @@ #include <stdio.h> +int +package_env_prefix(package *p, char const *pkg, char const *id) +{ + stralloc sa; + int ret = 0; + + stralloc_init(&sa); + if (!stralloc_cats(&sa, pkg)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->ver)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, id)) goto error; + if (!stralloc_cats(&sa, "/build")) goto error; + if (!stralloc_cat0(&sa)) goto error; + if (!env_set("PREFIX", sa.x)) goto error; + ret = 1; +error: + stralloc_free(&sa); + return ret; +} + +int +package_env_dep_l(package const *p, char const *pkg) +{ + stralloc sa; + char buf[NAME_MAX]; + int len; + int ret = 0; + + if (!p->dep_lib) return 1; + + stralloc_init(&sa); + if (!stralloc_cats(&sa, pkg)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->ver)) goto error; + if (!stralloc_cats(&sa, "/current/build")) goto error; + if (!stralloc_cat0(&sa)) goto error; + + for (len = 0; p->name[len] != '\0'; ++len) + buf[len] = isalnum(p->name[len]) ? p->name[len] : '_'; + buf[len] = '\0'; + ret = env_set(buf, sa.x); +error: + stralloc_free(&sa); + return ret; +} + +static int +package_env_dep_bd(package const *p, char const *pkg) +{ + stralloc sa; + char *path; + int ret = 0; + + if (!p->dep_build && !p->dep_download) return 1; + if ((path = env_get("PATH")) == NULL) return 0; + + stralloc_init(&sa); + if (!stralloc_cats(&sa, pkg)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->ver)) goto error; + if (!stralloc_cats(&sa, "/current/build/bin:")) goto error; + if (!stralloc_cats(&sa, path)) goto error; + if (!stralloc_cat0(&sa)) goto error; + + ret = env_set("PATH", sa.x); +error: + return ret; +} + +int +package_env_dep(package *p, char const *def, char const *pkg) +{ + stralloc sa = STRALLOC_ZERO; + stralloc line = STRALLOC_ZERO; + buffer b; + char buf[1024]; + size_t r; + size_t n; + int fd[2] = { -1, -1 }; + int ret = 0; + + errno = 0; + fd[0] = package_dep_open_default(p, def); + if (fd[0] == -1 && errno != ENOTDIR && errno != ENOENT) goto error; + fd[1] = package_dep_open_version(p, def); + if (fd[1] == -1 && errno != ENOTDIR && errno != ENOENT) goto error; + + for (int i = 0; i < 2; ++i) + { + if (fd[i] == -1) continue; + + stralloc_init(&line); + buffer_init(&b, &read, fd[i], buf, sizeof buf); + while (stralloc_zero(&line), (r = buffer_getline(&b, &line)) > 0) + { + package new; + + line.n -= (line.x[line.n - 1] == '\n'); + if (!stralloc_cat0(&line)) goto error; + n = package_dep_scan(&new, line.x, line.n); + if (n == 0 || line.x[n] != '\0') goto error; + if (!package_version(&new, def)) goto error; + if (!package_env_dep_l(&new, pkg)) goto error; + if (!package_env_dep_bd(&new, pkg)) goto error; + } + if (r != 0) goto error; + } + ret = 1; +error: + stralloc_free(&sa); + stralloc_free(&line); + if (fd[0] >= 0) close(fd[0]); + if (fd[1] >= 0) close(fd[1]); + return ret; +} + size_t package_fmt(package const *p, char *buf) { @@ -79,6 +202,7 @@ package_dep_scan(package *p, char const *s, size_t n) { switch (s[i]) { + case 'd': p->dep_download = 1; break; case 'b': p->dep_build = 1; break; case 'l': p->dep_lib = 1; break; case 'r': p->dep_run = 1; break; @@ -140,32 +264,39 @@ error: } int -package_opendepfile(package const *p, char const *def) +package_dep_open_default(package const *p, char const *def) { stralloc sa; - size_t n; int fd = -1; stralloc_init(&sa); - if (!stralloc_copys(&sa, def)) goto error; - if (!stralloc_append(&sa, '/')) goto error; + if (!stralloc_cats(&sa, def)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; if (!stralloc_cats(&sa, p->name)) goto error; - if (!stralloc_append(&sa, '/')) goto error; - n = sa.n; + if (!stralloc_cats(&sa, "/default/dependencies")) goto error; + if (!stralloc_cat0(&sa)) goto error; + fd = open_read(sa.x); + +error: + stralloc_free(&sa); + return fd; +} + +int +package_dep_open_version(package const *p, char const *def) +{ + stralloc sa; + int fd = -1; + + stralloc_init(&sa); + if (!stralloc_cats(&sa, def)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; if (!stralloc_cats(&sa, p->ver)) goto error; if (!stralloc_cats(&sa, "/dependencies")) goto error; - if (!stralloc_append(&sa, '\0')) goto error; - - errno = 0; + if (!stralloc_cat0(&sa)) goto error; fd = open_read(sa.x); - if (errno == ENOTDIR || errno == ENOENT) - { - sa.n = n; - if (!stralloc_cats(&sa, "default/dependencies")) goto error; - if (!stralloc_append(&sa, '\0')) goto error; - errno = 0; - fd = open_read(sa.x); - } error: stralloc_free(&sa); @@ -179,32 +310,39 @@ package_dep(package const *p, genalloc *packages, char const *def) buffer b; char buf[1024]; size_t r; - int fd = -1; + int fd[2] = { -1, -1 }; int ret = 0; errno = 0; - fd = package_opendepfile(p, def); - if (fd == -1) return (errno == ENOTDIR || errno == ENOENT); + fd[0] = package_dep_open_version(p, def); + if (errno != 0 && errno != ENOTDIR && errno != ENOENT) goto error; + fd[1] = package_dep_open_default(p, def); + if (errno != 0 && errno != ENOTDIR && errno != ENOENT) goto error; - buffer_init(&b, &read, fd, buf, sizeof buf); - stralloc_init(&sa); - while (stralloc_zero(&sa), (r = buffer_getline(&b, &sa)) > 0) + for (int i = 0; i < 2; ++i) { - package new; - size_t n; - - n = package_dep_scan(&new, sa.x, sa.n); - if (sa.x[n] != '\n' && sa.n != n) goto error; - if (!package_version(&new, def)) goto error; - if (package_hasdep(&new, packages)) continue; - if (!package_dep(&new, packages, def)) goto error; - if (!genalloc_append(packages, new)) goto error; - } - - ret = (r == 0); + if (fd[i] == -1) continue; + buffer_init(&b, &read, fd[i], buf, sizeof buf); + stralloc_init(&sa); + while (stralloc_zero(&sa), (r = buffer_getline(&b, &sa)) > 0) + { + package new; + size_t n; + + n = package_dep_scan(&new, sa.x, sa.n); + if (sa.x[n] != '\n' && sa.n != n) goto error; + if (!package_version(&new, def)) goto error; + if (package_hasdep(&new, packages)) continue; + if (!package_dep(&new, packages, def)) goto error; + if (!genalloc_append(packages, new)) goto error; + } + if (r != 0) goto error; + } + ret = 1; error: + if (fd[0] >= 0) close(fd[0]); + if (fd[1] >= 0) close(fd[1]); stralloc_free(&sa); - close(fd); return ret; } diff --git a/package.h b/package.h @@ -15,10 +15,16 @@ typedef struct { char dep_build; char dep_run; char dep_lib; + char dep_download; } package; int package_dep(package const *, genalloc *, char const *); -int package_opendepfile(package const *, char const *); +int package_dep_open_default(package const *, char const *); +int package_dep_open_version(package const *, char const *); +int package_env_dep(package *, char const *, char const *); +int package_env_dep_build_download(package const *, char const *); +int package_env_dep_lib(package const *, char const *); +int package_env_prefix(package *, char const *, char const *); int package_version(package *, char const *); size_t package_dep_scan(package *, char const *, size_t); size_t package_fmt(package const *, char *);