dep

Package manager for embedded C libraries
git clone git://git.finwo.net/app/dep
Log | Files | Refs | README | LICENSE

commit 851854e45b4a0290fc88cfb8a1a6bddc0cd226ad
parent 6f5da36e0423a6eadc64bfac67b12f5a029afdec
Author: finwo <finwo@pm.me>
Date:   Fri, 13 Mar 2026 15:49:42 +0100

Handle .dep.chain for shims

Diffstat:
Msrc/command/install/main.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+), 0 deletions(-)

diff --git a/src/command/install/main.c b/src/command/install/main.c @@ -58,6 +58,47 @@ static char *trim_whitespace(char *str) { return str; } +static char *spec_to_url(const char *name, const char *spec) { + if (strlen(spec) > 0 && is_url(spec)) { + return strdup(spec); + } + + char *full_ref = NULL; + + if (strlen(spec) > 0) { + full_ref = query_github_matching_ref(name, spec); + if (!full_ref) { + fprintf(stderr, "Error: ref '%s' not found for %s\n", spec, name); + return NULL; + } + } else { + char *branch = query_github_default_branch(name); + if (!branch) { + fprintf(stderr, "Warning: could not determine default branch for %s, using 'main'\n", name); + branch = strdup("main"); + } + full_ref = malloc(256); + if (full_ref) { + snprintf(full_ref, 256, "refs/heads/%s", branch); + } + free(branch); + } + + if (!full_ref) { + fprintf(stderr, "Error: could not determine ref for %s\n", name); + return NULL; + } + + char *url = malloc(2048); + if (!url) { + free(full_ref); + return NULL; + } + snprintf(url, 2048, "https://github.com/%s/archive/%s.tar.gz", name, full_ref); + free(full_ref); + return url; +} + static int mem_read(mtar_t *tar, void *data, unsigned size) { membuffer_t *buf = (membuffer_t *)tar->stream; if (buf->pos + size > buf->size) { @@ -386,6 +427,60 @@ static int install_dependency(const char *name, const char *spec) { return -1; } + // Process .dep.chain recursively + char dep_chain_path[PATH_MAX]; + while (1) { + // Build .dep.chain path + snprintf(dep_chain_path, sizeof(dep_chain_path), "%s/.dep.chain", lib_path); + + // Check if .dep.chain exists + FILE *chain_file = fopen(dep_chain_path, "r"); + if (!chain_file) { + break; // No more chaining + } + + // Read spec (single line) + char spec[1024] = {0}; + if (!fgets(spec, sizeof(spec), chain_file)) { + fclose(chain_file); + fprintf(stderr, "Error: failed to read .dep.chain\n"); + return -1; + } + fclose(chain_file); + + // Delete .dep.chain file + if (remove(dep_chain_path) != 0) { + fprintf(stderr, "Warning: failed to remove .dep.chain\n"); + // Continue anyway - spec was read + } + + // Trim whitespace/newline from spec + char *trimmed = trim_whitespace(spec); + if (strlen(trimmed) == 0) { + fprintf(stderr, "Warning: empty spec in .dep.chain\n"); + continue; + } + + printf("Found .dep.chain, chaining to: %s\n", trimmed); + + // Resolve spec to URL + char *overlay_url = spec_to_url(name, trimmed); + if (!overlay_url) { + fprintf(stderr, "Error: failed to resolve chained spec '%s'\n", trimmed); + return -1; + } + + // Overlay extract (directly over existing files) + printf("Overlaying %s from %s\n", name, overlay_url); + if (download_and_extract(overlay_url, lib_path) != 0) { + fprintf(stderr, "Error: failed to overlay chained dependency\n"); + free(overlay_url); + return -1; + } + free(overlay_url); + // Loop continues to check for new .dep.chain + } + printf("Installed %s\n", name); return 0; }