fix(cli): CLI structure, manifest, and asset fixes
- Fix commands.zig imports (logs.zig → log.zig, remove missing modules) - Fix manifest.writeManifest to accept allocator param - Add db.Stmt type alias for sqlite3_stmt - Fix rsync placeholder to be valid shell script (#!/bin/sh)
This commit is contained in:
parent
382c67edfc
commit
b1c9bc97fc
4 changed files with 68 additions and 40 deletions
|
|
@ -1 +1,2 @@
|
||||||
dummy
|
#!/bin/sh
|
||||||
|
exec /usr/bin/rsync "$@"
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,10 @@ pub const find = @import("commands/find.zig");
|
||||||
pub const info = @import("commands/info.zig");
|
pub const info = @import("commands/info.zig");
|
||||||
pub const init = @import("commands/init.zig");
|
pub const init = @import("commands/init.zig");
|
||||||
pub const jupyter = @import("commands/jupyter.zig");
|
pub const jupyter = @import("commands/jupyter.zig");
|
||||||
pub const logs = @import("commands/logs.zig");
|
pub const logs = @import("commands/log.zig");
|
||||||
pub const monitor = @import("commands/monitor.zig");
|
|
||||||
pub const narrative = @import("commands/narrative.zig");
|
|
||||||
pub const outcome = @import("commands/outcome.zig");
|
|
||||||
pub const prune = @import("commands/prune.zig");
|
pub const prune = @import("commands/prune.zig");
|
||||||
pub const queue = @import("commands/queue.zig");
|
pub const queue = @import("commands/queue.zig");
|
||||||
pub const requeue = @import("commands/requeue.zig");
|
pub const run = @import("commands/run.zig");
|
||||||
pub const status = @import("commands/status.zig");
|
pub const status = @import("commands/status.zig");
|
||||||
pub const sync = @import("commands/sync.zig");
|
pub const sync = @import("commands/sync.zig");
|
||||||
pub const validate = @import("commands/validate.zig");
|
pub const validate = @import("commands/validate.zig");
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
// SQLite C bindings
|
// SQLite C bindings
|
||||||
const c = @cImport({
|
pub const c = @cImport({
|
||||||
@cInclude("sqlite3.h");
|
@cInclude("sqlite3.h");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Public type alias for prepared statement
|
||||||
|
pub const Stmt = ?*c.sqlite3_stmt;
|
||||||
|
|
||||||
// SQLITE_TRANSIENT constant - use C wrapper to avoid Zig 0.15 C translation issue
|
// SQLITE_TRANSIENT constant - use C wrapper to avoid Zig 0.15 C translation issue
|
||||||
extern fn fetchml_sqlite_transient() c.sqlite3_destructor_type;
|
extern fn fetchml_sqlite_transient() c.sqlite3_destructor_type;
|
||||||
fn sqliteTransient() c.sqlite3_destructor_type {
|
fn sqliteTransient() c.sqlite3_destructor_type {
|
||||||
|
|
|
||||||
|
|
@ -59,82 +59,109 @@ pub const RunManifest = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Write manifest to JSON file
|
/// Write manifest to JSON file
|
||||||
pub fn writeManifest(manifest: RunManifest, path: []const u8) !void {
|
pub fn writeManifest(manifest: RunManifest, path: []const u8, allocator: std.mem.Allocator) !void {
|
||||||
var file = try std.fs.cwd().createFile(path, .{});
|
var file = try std.fs.cwd().createFile(path, .{});
|
||||||
defer file.close();
|
defer file.close();
|
||||||
|
|
||||||
const writer = file.writer();
|
|
||||||
|
|
||||||
// Write JSON manually to avoid std.json complexity with hash maps
|
// Write JSON manually to avoid std.json complexity with hash maps
|
||||||
try writer.writeAll("{\n");
|
try file.writeAll("{\n");
|
||||||
|
|
||||||
try writer.print(" \"run_id\": \"{s}\",\n", .{manifest.run_id});
|
const line1 = try std.fmt.allocPrint(allocator, " \"run_id\": \"{s}\",\n", .{manifest.run_id});
|
||||||
try writer.print(" \"experiment\": \"{s}\",\n", .{manifest.experiment});
|
defer allocator.free(line1);
|
||||||
try writer.print(" \"command\": \"{s}\",\n", .{manifest.command});
|
try file.writeAll(line1);
|
||||||
|
|
||||||
|
const line2 = try std.fmt.allocPrint(allocator, " \"experiment\": \"{s}\",\n", .{manifest.experiment});
|
||||||
|
defer allocator.free(line2);
|
||||||
|
try file.writeAll(line2);
|
||||||
|
|
||||||
|
const line3 = try std.fmt.allocPrint(allocator, " \"command\": \"{s}\",\n", .{manifest.command});
|
||||||
|
defer allocator.free(line3);
|
||||||
|
try file.writeAll(line3);
|
||||||
|
|
||||||
// Args array
|
// Args array
|
||||||
try writer.writeAll(" \"args\": [");
|
try file.writeAll(" \"args\": [");
|
||||||
for (manifest.args, 0..) |arg, i| {
|
for (manifest.args, 0..) |arg, i| {
|
||||||
if (i > 0) try writer.writeAll(", ");
|
if (i > 0) try file.writeAll(", ");
|
||||||
try writer.print("\"{s}\"", .{arg});
|
const arg_str = try std.fmt.allocPrint(allocator, "\"{s}\"", .{arg});
|
||||||
|
defer allocator.free(arg_str);
|
||||||
|
try file.writeAll(arg_str);
|
||||||
}
|
}
|
||||||
try writer.writeAll("],\n");
|
try file.writeAll("],\n");
|
||||||
|
|
||||||
// Commit ID (optional)
|
// Commit ID (optional)
|
||||||
if (manifest.commit_id) |cid| {
|
if (manifest.commit_id) |cid| {
|
||||||
try writer.print(" \"commit_id\": \"{s}\",\n", .{cid});
|
const cid_str = try std.fmt.allocPrint(allocator, " \"commit_id\": \"{s}\",\n", .{cid});
|
||||||
|
defer allocator.free(cid_str);
|
||||||
|
try file.writeAll(cid_str);
|
||||||
} else {
|
} else {
|
||||||
try writer.writeAll(" \"commit_id\": null,\n");
|
try file.writeAll(" \"commit_id\": null,\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
try writer.print(" \"started_at\": \"{s}\",\n", .{manifest.started_at});
|
const started_str = try std.fmt.allocPrint(allocator, " \"started_at\": \"{s}\",\n", .{manifest.started_at});
|
||||||
|
defer allocator.free(started_str);
|
||||||
|
try file.writeAll(started_str);
|
||||||
|
|
||||||
// Ended at (optional)
|
// Ended at (optional)
|
||||||
if (manifest.ended_at) |ended| {
|
if (manifest.ended_at) |ended| {
|
||||||
try writer.print(" \"ended_at\": \"{s}\",\n", .{ended});
|
const ended_str = try std.fmt.allocPrint(allocator, " \"ended_at\": \"{s}\",\n", .{ended});
|
||||||
|
defer allocator.free(ended_str);
|
||||||
|
try file.writeAll(ended_str);
|
||||||
} else {
|
} else {
|
||||||
try writer.writeAll(" \"ended_at\": null,\n");
|
try file.writeAll(" \"ended_at\": null,\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
try writer.print(" \"status\": \"{s}\",\n", .{manifest.status});
|
const status_str = try std.fmt.allocPrint(allocator, " \"status\": \"{s}\",\n", .{manifest.status});
|
||||||
|
defer allocator.free(status_str);
|
||||||
|
try file.writeAll(status_str);
|
||||||
|
|
||||||
// Exit code (optional)
|
// Exit code (optional)
|
||||||
if (manifest.exit_code) |code| {
|
if (manifest.exit_code) |code| {
|
||||||
try writer.print(" \"exit_code\": {d},\n", .{code});
|
const exit_str = try std.fmt.allocPrint(allocator, " \"exit_code\": {d},\n", .{code});
|
||||||
|
defer allocator.free(exit_str);
|
||||||
|
try file.writeAll(exit_str);
|
||||||
} else {
|
} else {
|
||||||
try writer.writeAll(" \"exit_code\": null,\n");
|
try file.writeAll(" \"exit_code\": null,\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params object
|
// Params object
|
||||||
try writer.writeAll(" \"params\": {");
|
try file.writeAll(" \"params\": {");
|
||||||
var params_first = true;
|
var params_first = true;
|
||||||
var params_iter = manifest.params.iterator();
|
var params_iter = manifest.params.iterator();
|
||||||
while (params_iter.next()) |entry| {
|
while (params_iter.next()) |entry| {
|
||||||
if (!params_first) try writer.writeAll(", ");
|
if (!params_first) try file.writeAll(", ");
|
||||||
params_first = false;
|
params_first = false;
|
||||||
try writer.print("\"{s}\": \"{s}\"", .{ entry.key_ptr.*, entry.value_ptr.* });
|
const param_str = try std.fmt.allocPrint(allocator, "\"{s}\": \"{s}\"", .{ entry.key_ptr.*, entry.value_ptr.* });
|
||||||
|
defer allocator.free(param_str);
|
||||||
|
try file.writeAll(param_str);
|
||||||
}
|
}
|
||||||
try writer.writeAll("},\n");
|
try file.writeAll("},\n");
|
||||||
|
|
||||||
// Metrics summary (optional)
|
// Metrics summary (optional)
|
||||||
if (manifest.metrics_summary) |summary| {
|
if (manifest.metrics_summary) |summary| {
|
||||||
try writer.writeAll(" \"metrics_summary\": {");
|
try file.writeAll(" \"metrics_summary\": {");
|
||||||
var summary_first = true;
|
var summary_first = true;
|
||||||
var summary_iter = summary.iterator();
|
var summary_iter = summary.iterator();
|
||||||
while (summary_iter.next()) |entry| {
|
while (summary_iter.next()) |entry| {
|
||||||
if (!summary_first) try writer.writeAll(", ");
|
if (!summary_first) try file.writeAll(", ");
|
||||||
summary_first = false;
|
summary_first = false;
|
||||||
try writer.print("\"{s}\": {d:.4}", .{ entry.key_ptr.*, entry.value_ptr.* });
|
const metric_str = try std.fmt.allocPrint(allocator, "\"{s}\": {d:.4}", .{ entry.key_ptr.*, entry.value_ptr.* });
|
||||||
|
defer allocator.free(metric_str);
|
||||||
|
try file.writeAll(metric_str);
|
||||||
}
|
}
|
||||||
try writer.writeAll("},\n");
|
try file.writeAll("},\n");
|
||||||
} else {
|
} else {
|
||||||
try writer.writeAll(" \"metrics_summary\": null,\n");
|
try file.writeAll(" \"metrics_summary\": null,\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
try writer.print(" \"artifact_path\": \"{s}\",\n", .{manifest.artifact_path});
|
const artifact_str = try std.fmt.allocPrint(allocator, " \"artifact_path\": \"{s}\",\n", .{manifest.artifact_path});
|
||||||
try writer.print(" \"synced\": {}", .{manifest.synced});
|
defer allocator.free(artifact_str);
|
||||||
|
try file.writeAll(artifact_str);
|
||||||
|
|
||||||
try writer.writeAll("\n}\n");
|
const synced_str = try std.fmt.allocPrint(allocator, " \"synced\": {}", .{manifest.synced});
|
||||||
|
defer allocator.free(synced_str);
|
||||||
|
try file.writeAll(synced_str);
|
||||||
|
|
||||||
|
try file.writeAll("\n}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read manifest from JSON file
|
/// Read manifest from JSON file
|
||||||
|
|
@ -265,7 +292,7 @@ pub fn updateManifestStatus(path: []const u8, status: []const u8, exit_code: ?i3
|
||||||
|
|
||||||
manifest.ended_at = try allocator.dupe(u8, timestamp);
|
manifest.ended_at = try allocator.dupe(u8, timestamp);
|
||||||
|
|
||||||
try writeManifest(manifest, path);
|
try writeManifest(manifest, path, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark manifest as synced
|
/// Mark manifest as synced
|
||||||
|
|
@ -274,7 +301,7 @@ pub fn markManifestSynced(path: []const u8, allocator: std.mem.Allocator) !void
|
||||||
defer manifest.deinit(allocator);
|
defer manifest.deinit(allocator);
|
||||||
|
|
||||||
manifest.synced = true;
|
manifest.synced = true;
|
||||||
try writeManifest(manifest, path);
|
try writeManifest(manifest, path, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build manifest path from experiment and run_id
|
/// Build manifest path from experiment and run_id
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue