feat: query project files via git (part 1)

This commit is contained in:
CJ van den Berg 2025-04-21 21:43:29 +02:00
parent 4cb84e25b3
commit f76085325a
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
5 changed files with 75 additions and 21 deletions

View file

@ -7,37 +7,55 @@ pub const Error = error{ OutOfMemory, GitNotFound, GitCallFailed };
const log_execute = false;
pub fn workspace_path() Error!void {
pub fn workspace_path(context_: usize) Error!void {
const fn_name = @src().fn_name;
try git(.{ "rev-parse", "--show-toplevel" }, struct {
fn result(parent: tp.pid_ref, output: []const u8) void {
try git(context_, .{ "rev-parse", "--show-toplevel" }, struct {
fn result(context: usize, parent: tp.pid_ref, output: []const u8) void {
var it = std.mem.splitScalar(u8, output, '\n');
while (it.next()) |branch| if (branch.len > 0)
parent.send(.{ module_name, fn_name, branch }) catch {};
while (it.next()) |value| if (value.len > 0)
parent.send(.{ module_name, context, fn_name, value }) catch {};
}
}.result, exit_null_on_error(fn_name));
}
pub fn current_branch() Error!void {
pub fn current_branch(context_: usize) Error!void {
const fn_name = @src().fn_name;
try git(.{ "rev-parse", "--abbrev-ref", "HEAD" }, struct {
fn result(parent: tp.pid_ref, output: []const u8) void {
try git(context_, .{ "rev-parse", "--abbrev-ref", "HEAD" }, struct {
fn result(context: usize, parent: tp.pid_ref, output: []const u8) void {
var it = std.mem.splitScalar(u8, output, '\n');
while (it.next()) |branch| if (branch.len > 0)
parent.send(.{ module_name, fn_name, branch }) catch {};
while (it.next()) |value| if (value.len > 0)
parent.send(.{ module_name, context, fn_name, value }) catch {};
}
}.result, exit_null_on_error(fn_name));
}
pub fn workspace_files(context_: usize) Error!void {
const fn_name = @src().fn_name;
try git_err(context_, .{ "ls-files", "--cached", "--others", "--exclude-standard" }, struct {
fn result(context: usize, parent: tp.pid_ref, output: []const u8) void {
var it = std.mem.splitScalar(u8, output, '\n');
while (it.next()) |value| if (value.len > 0)
parent.send(.{ module_name, context, fn_name, value }) catch {};
}
}.result, struct {
fn result(_: usize, _: tp.pid_ref, output: []const u8) void {
var it = std.mem.splitScalar(u8, output, '\n');
while (it.next()) |line| std.log.err("{s}: {s}", .{ module_name, line });
}
}.result, exit_null_on_error(fn_name));
}
fn git(
context: usize,
cmd: anytype,
out: OutputHandler,
exit: ExitHandler,
) Error!void {
return git_err(cmd, out, noop, exit);
return git_err(context, cmd, out, noop, exit);
}
fn git_err(
context: usize,
cmd: anytype,
out: OutputHandler,
err: OutputHandler,
@ -54,6 +72,7 @@ fn git_err(
inline for (info.fields) |f|
try cbor.writeValue(writer, @field(cmd, f.name));
return shell.execute(allocator, .{ .buf = buf.items }, .{
.context = context,
.out = to_shell_output_handler(out),
.err = to_shell_output_handler(err),
.exit = exit,
@ -74,18 +93,18 @@ fn exit_null_on_error(comptime tag: []const u8) shell.ExitHandler {
}.exit;
}
const OutputHandler = fn (parent: tp.pid_ref, output: []const u8) void;
const OutputHandler = fn (context: usize, parent: tp.pid_ref, output: []const u8) void;
const ExitHandler = shell.ExitHandler;
fn to_shell_output_handler(handler: anytype) shell.OutputHandler {
return struct {
fn out(_: usize, parent: tp.pid_ref, _: []const u8, output: []const u8) void {
handler(parent, output);
fn out(context: usize, parent: tp.pid_ref, _: []const u8, output: []const u8) void {
handler(context, parent, output);
}
}.out;
}
fn noop(_: tp.pid_ref, _: []const u8) void {}
fn noop(_: usize, _: tp.pid_ref, _: []const u8) void {}
var git_path: ?struct {
path: ?[:0]const u8 = null,