feat: init command.

This commit is contained in:
2026-06-10 19:25:50 -04:00
parent d3eb4e84f9
commit 90f7176e47
4 changed files with 82 additions and 8 deletions

2
.envrc
View File

@@ -1,4 +1,4 @@
use flake use flake
ROOT="." ROOT="/home/spencer/github.com/envr-zig"
export PATH=".:${ROOT}/deps/zig:${ROOT}/deps/zls:$PATH" export PATH=".:${ROOT}/deps/zig:${ROOT}/deps/zls:$PATH"

View File

@@ -61,6 +61,7 @@ pub const ScanConfig = struct {
}; };
/// Load the Config from the file at path /// Load the Config from the file at path
/// TODO: Use a concrete error set
pub fn load( pub fn load(
io: std.Io, io: std.Io,
gpa: std.mem.Allocator, gpa: std.mem.Allocator,

View File

@@ -34,13 +34,6 @@ fn run(
return envr.root.help(stdout_writer); return envr.root.help(stdout_writer);
}, },
.version => {
var stdout_buffer: [1024]u8 = undefined;
var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer);
const stdout_writer = &stdout_file_writer.interface;
return version(stdout_writer);
},
.deps => { .deps => {
var stdout_buffer: [1024]u8 = undefined; var stdout_buffer: [1024]u8 = undefined;
var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer); var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer);
@@ -52,6 +45,22 @@ fn run(
environ_map.get("PATH").?, environ_map.get("PATH").?,
); );
}, },
.init => {
var stdout_buffer: [1024]u8 = undefined;
var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer);
const stdout_writer = &stdout_file_writer.interface;
try envr.init_cmd(
io,
arena,
stdout_writer,
environ_map.get("HOME").?,
.{
// TODO: Actually parse this
.force = false,
},
);
},
.list => { .list => {
var stdout_buffer: [page_size]u8 = undefined; var stdout_buffer: [page_size]u8 = undefined;
var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer); var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer);
@@ -66,6 +75,13 @@ fn run(
"/tmp", "/tmp",
); );
}, },
.version => {
var stdout_buffer: [1024]u8 = undefined;
var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer);
const stdout_writer = &stdout_file_writer.interface;
return version(stdout_writer);
},
.unknown => { .unknown => {
return fallback_to_go(io, arena, args); return fallback_to_go(io, arena, args);
}, },

View File

@@ -52,6 +52,19 @@ pub const root: Command = .new(.{
\\ The deps command reports which binaries are available and which are not." \\ The deps command reports which binaries are available and which are not."
, ,
}, },
.{
.name = "init",
.short = "Set up envr",
.long =
\\The init command generates your initial config and saves it to
\\~/.envr/config in JSON format.
\\
\\During setup, you will be prompted to select one or more ssh keys with which to
\\encrypt your databse. **Make 100% sure** that you have **a remote copy** of this
\\key somewhere, otherwise your data could be lost forever.
,
//.flags = struct { force: bool }
},
.{ .{
.name = "list", .name = "list",
.short = "View your tracked files", .short = "View your tracked files",
@@ -120,6 +133,50 @@ const Features = packed struct {
} }
}; };
pub fn init_cmd(
io: Io,
arena: std.mem.Allocator,
out: *std.Io.Writer,
home: []const u8,
flags: struct { force: bool },
) !void {
// TODO: Don't hardcode
const cfgPath = try std.fs.path.join(arena, &.{ home, ".envr", "config.json" });
defer arena.free(cfgPath);
if (flags.force or !file_exists(io, cfgPath)) {
// Setup
const keys = try select_ssh_keys();
const cfg: Config = .{ .keys = keys };
// TODO: How to handle this error?
try cfg.save(io, cfgPath);
try out.print(
"Config initialized with %d SSH key(s). You are ready to use envr.\n",
.{keys.len},
);
} else {
try out.writeAll(
\\You have already initialized envr.
\\Run again with the --force flag if you want to reinitialize.
\\
,
);
}
}
/// Returns true if the file exists
fn file_exists(io: std.Io, path: []const u8) bool {
if (std.Io.Dir.cwd().access(io, path, .{ .read = true })) {
return true;
} else |_| {
return false;
}
}
fn select_ssh_keys() ![]Config.SSHKeyPair {}
pub fn list( pub fn list(
io: Io, io: Io,
arena: std.mem.Allocator, arena: std.mem.Allocator,