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:
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);
};
};