Once the build script has it, it can pass the information to the application via a build-option which also passes it as buildtime information (which can be used at comptime).
Yea thats how I do it right now. But app-only usage is a little shorter, tho you still need to touch the build script to add the module. So maybe I am doing too much. Going to try to figure it out before giving up and switching to build script only. I was curious if I could make it work for both cases, and I kinda did, so maybe thats enough ![]()
Instead of exporting
pub const Ghext = @import("src/ghext.zig");
in the build.zig my suggestion would be to create a module that somebody can use if they want to use it in their application and if they want to use it in a build script you could provide that by creating an application (that internally uses that module for its implementation but wraps a cli interface around it) and then use that tool with addRunArtifact.
I think it would be a combination of this:
https://ziglang.org/learn/build-system/#project-tools and what is described by Zig Build System Basics
The benefit would be that all the code runs purely at runtime (within a build context or not) could be shared between application and build-time usages and there would be no reason to try to do anything at comptime or avoiding allocation.
(I haven’t fully understood why you try to avoid allocation, seemingly because you try to do things at comptime, which in my opinion doesn’t make sense, because long-term comptime will be locked down more and more and this code shouldn’t need comptime anyway)
Thanks, Ill check it out! Right now the usage with the build script is
const build_options = b.addOptions();
exe.root_module.addOptions("build_options", build_options);
build_options.addOption([]const u8, "head_hash", try hash());
fn hash() ![]const u8 {
const gxt = @import("ghext").Ghext.init(std.heap.page_allocator) catch
unreachable;
return gxt.head;
}
The reason I tried to keep everything in comptime is to make sure the hash is being pulled during builds exclusively (build and app usage). But If I am dropping app usage then yea comptime is not important at all.
Decided to stay away from build system since goodbye sane testing.
This passes all tests including Checked, but the output is bogus:
pub fn hash(
self: *Ghext,
comptime length: HashLen,
check: Worktree,
) []const u8 {
var arr = std.BoundedArray(u8, 80).init(0) catch return switch (length) {
.Short => self.head[0..7],
.Long => self.head,
};
switch (length) {
.Short => arr.appendSlice(self.head[0..7]) catch return self.head[0..7],
.Long => arr.appendSlice(self.head) catch return self.head,
}
switch (check) {
.Checked => {
if (self.dirty == null) {
arr.appendSlice("-unverified") catch
return arr.slice();
} else {
if (self.dirty.?) arr.appendSlice("-dirty") catch
return arr.slice();
}
return arr.slice();
},
.Unchecked => {
return arr.slice();
},
}
}
version 1.1.1 �K�
But if I inline hash() its all good ![]()
I think you are having an issue with stack memory.
BoundedArray allocates to the stack. so it is possible that something is clobering it. When you inline it, the stack memory is preserved. You may want to try having the caller pass in a backing array from which you can return a slice.
That was my first idea; had a similar case a couple of years ago. This is probably mem.trimRight() inside readWithGit(). I don’t want to add another function parameter, so maybe Ill just leave it as is since this looks like an expected behavior (too hacky?).