hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 4621b2b89267006c4559358c1df76d0c288c97dc
parent 745f516ebe243f77c482adca582f744d47eadcbb
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 14 Mar 2021 12:18:56 -0400

hare::module: write manifests to the cache

Diffstat:
Mcmd/hare/plan.ha | 1-
Mhare/module/manifest.ha | 43++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/cmd/hare/plan.ha b/cmd/hare/plan.ha @@ -136,7 +136,6 @@ fn update_cache(plan: *plan, mod: modcache) void = { inputs = mod.version.inputs, versions = [mod.version], }; - fmt::errorfln("Updating module {}", ast::ident_unparse_s(mod.ident)); match (module::manifest_write(plan.context, &manifest)) { err: module::error => fmt::fatal( "Error updating module cache: {}", diff --git a/hare/module/manifest.ha b/hare/module/manifest.ha @@ -1,9 +1,20 @@ +use encoding::hex; use fmt; use fs; +use hare::ast; use io; use path; use time; +// The manifest file format is a series of line-oriented records. Lines starting +// with # are ignored. +// +// - "version" indicates the manifest format version, currently 1. +// - "input" is an input file, and its fields are the file hash, path, inode, +// and mtime as a Unix timestamp. +// - "module" is a version of a module, and includes the module hash and the set +// of input hashes which produce it. + // Writes a module manifest to the build cache. export fn manifest_write(ctx: *context, manifest: *manifest) (void | error) = { let ipath = ident_path(manifest.ident); @@ -20,8 +31,38 @@ export fn manifest_write(ctx: *context, manifest: *manifest) (void | error) = { let fd = fs::create(ctx.fs, mpath, 0o644)?; defer io::close(fd); + let ident = ast::ident_unparse_s(manifest.ident); + defer free(ident); + fmt::fprintfln(fd, "# {}", ident)?; + fmt::fprintln(fd, "# This file is an internal Hare implementation detail.")?; + fmt::fprintln(fd, "# The format is not stable.")?; + fmt::fprintln(fd, "version 1")?; for (let i = 0z; i < len(manifest.inputs); i += 1) { - void; // TODO: Write manifest + const input = manifest.inputs[i]; + let hash = hex::encode(input.hash); + defer free(hash); + + assert(input.stat.mask & fs::stat_mask::INODE == fs::stat_mask::INODE); + // TODO: Add mtime + fmt::fprintfln(fd, "input {} {} {}", + hash, input.path, input.stat.inode); + }; + + for (let i = 0z; i < len(manifest.versions); i += 1) { + const ver = manifest.versions[i]; + let hash = hex::encode(ver.hash); + defer free(hash); + + fmt::fprintf(fd, "module {}", hash); + + for (let j = 0z; j < len(ver.inputs); j += 1) { + let hash = hex::encode(ver.inputs[i].hash); + defer free(hash); + + fmt::fprintf(fd, " {}", hash); + }; + + fmt::fprintln(fd); }; };