From 583ed54ee355913db2dd931b0bb9b16d06903641 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 21 Oct 2022 05:13:13 -0300 Subject: [PATCH] feat: write default config.toml if it doesn't exist also resolves panic on missing /zba or /zba/save directory by ensuring those directories exist as soon as we know the data directory --- build.zig | 1 + src/main.zig | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/build.zig b/build.zig index cb25e70..746f2bf 100644 --- a/build.zig +++ b/build.zig @@ -13,6 +13,7 @@ pub fn build(b: *std.build.Builder) void { const mode = b.standardReleaseOptions(); const exe = b.addExecutable("zba", "src/main.zig"); + exe.setMainPkgPath("."); // Necessary so that src/main.zig can embed example.toml exe.setTarget(target); // Known Folders (%APPDATA%, XDG, etc.) diff --git a/src/main.zig b/src/main.zig index 3b373e7..cff0ce0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -37,7 +37,10 @@ pub fn main() anyerror!void { const data_path = blk: { const result = known_folders.getPath(allocator, .data); const option = result catch |e| exitln("interrupted while attempting to find a data directory: {}", .{e}); - break :blk option orelse exitln("no valid data directory could be found", .{}); + const path = option orelse exitln("no valid data directory could be found", .{}); + ensureDirectoriesExist(path) catch |e| exitln("failed to create directories under \"{s}\": {}", .{ path, e }); + + break :blk path; }; defer allocator.free(data_path); @@ -86,7 +89,7 @@ pub fn handleArguments(allocator: Allocator, data_path: []const u8, result: *con const bios_path = result.args.bios; if (bios_path) |path| log.info("BIOS path: {s}", .{path}) else log.warn("No BIOS provided", .{}); - const save_path = try savePath(allocator, data_path); + const save_path = try std.fs.path.join(allocator, &[_][]const u8{ data_path, "zba", "save" }); log.info("Save path: {s}", .{save_path}); return .{ @@ -103,25 +106,27 @@ fn configFilePath(allocator: Allocator, data_path: []const u8) ![]const u8 { // We try to create the file exclusively, meaning that we err out if the file already exists. // All we care about is a file being there so we can just ignore that error in particular and // continue down the happy pathj - std.fs.accessAbsolute(path, .{}) catch { - const file_handle = try std.fs.createFileAbsolute(path, .{}); - defer file_handle.close(); + std.fs.accessAbsolute(path, .{}) catch |e| { + if (e != error.FileNotFound) return e; - // TODO: Write Default valeus to config file + const config_file = try std.fs.createFileAbsolute(path, .{}); + defer config_file.close(); + + try config_file.writeAll(@embedFile("../example.toml")); }; return path; } -fn savePath(allocator: Allocator, data_path: []const u8) ![]const u8 { +fn ensureDirectoriesExist(data_path: []const u8) !void { var dir = try std.fs.openDirAbsolute(data_path, .{}); defer dir.close(); - // Will either make the path recursively, or just exit early since it already exists - try dir.makePath("zba" ++ [_]u8{std.fs.path.sep} ++ "save"); + // We want to make sure: %APPDATA%/zba and %APPDATA%/zba/save exist + // (~/.local/share/zba/save for linux, ??? for macOS) - // FIXME: Do we have to allocate? :sad: - return try std.fs.path.join(allocator, &[_][]const u8{ data_path, "zba", "save" }); + // Will recursively create directories + try dir.makePath("zba" ++ [_]u8{std.fs.path.sep} ++ "save"); } fn romPath(result: *const clap.Result(clap.Help, ¶ms, clap.parsers.default)) []const u8 {