diff --git a/.github/workflows/burrito-xcomp-check.yaml b/.github/workflows/burrito-xcomp-check.yaml index 56f3586..8c08a2b 100644 --- a/.github/workflows/burrito-xcomp-check.yaml +++ b/.github/workflows/burrito-xcomp-check.yaml @@ -20,7 +20,7 @@ jobs: elixir-version: 1.16.2 - uses: goto-bus-stop/setup-zig@v2 with: - version: 0.11.0 + version: 0.13.0 - name: Set up Homebrew if: matrix.host == 'macos-latest' id: set-up-homebrew diff --git a/.gitignore b/.gitignore index cd5e306..ba1d729 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ Temporary Items zig-cache/ zig-out/ +**.zig-cache/** build-*/ docgen_tmp/ @@ -51,4 +52,5 @@ erl_crash.dump *.beam /config/*.secret.exs .elixir_ls/ -**/burrito_out/** \ No newline at end of file +**/burrito_out/** + diff --git a/.tool-versions b/.tool-versions index f9613a9..425b8df 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -zig 0.11.0 -erlang 26.1.2 -elixir 1.15.6-otp-26 +zig 0.13.0 +erlang 26.2.2 +elixir 1.16.1-otp-26 diff --git a/README.md b/README.md index 92124ef..0cecce9 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ We support _targeting_ Windows (x86_64) from MacOS and Linux, we _do not_ offici You must have the following installed and in your PATH: -* Zig (0.11.0) -- `zig` +* Zig (0.13.0) -- `zig` * XZ -- `xz` * 7z -- `7z` (For Windows Targets) diff --git a/bin/fetch_zig.sh b/bin/fetch_zig.sh index bce047a..9abca27 100755 --- a/bin/fetch_zig.sh +++ b/bin/fetch_zig.sh @@ -1,5 +1,5 @@ #!/bin/sh -ZIG_VERSION="0.11.0" +ZIG_VERSION="0.13.0" #### diff --git a/build.zig b/build.zig index 48768f6..2bf1c31 100644 --- a/build.zig +++ b/build.zig @@ -8,15 +8,13 @@ const builtin = @import("builtin"); const log = std.log; -const Builder = std.build.Builder; +const Builder = std.Build; const CrossTarget = std.zig.CrossTarget; const Mode = std.builtin.Mode; const LibExeObjStep = std.build.LibExeObjStep; var builder: *Builder = undefined; -var target: *const CrossTarget = undefined; - -var wrapper_exe: *LibExeObjStep = undefined; +var wrapper_exe: *Builder.Step.Compile = undefined; // Memory allocator var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); @@ -26,7 +24,6 @@ pub fn build(b: *Builder) !void { log.info("Zig is building an Elixir binary... ⚡", .{}); builder = b; - target = &builder.standardTargetOptions(.{}); // Run build steps! _ = try run_archiver(); @@ -42,9 +39,9 @@ pub fn run_archiver() !void { try foilz.pack_directory(release_path, "./payload.foilz"); if (builtin.os.tag == .windows) { - _ = builder.exec(&[_][]const u8{ "cmd", "/C", "xz -9ez --check=crc32 --stdout --keep payload.foilz > src/payload.foilz.xz" }); + _ = builder.run(&[_][]const u8{ "cmd", "/C", "xz -9ez --check=crc32 --stdout --keep payload.foilz > src/payload.foilz.xz" }); } else { - _ = builder.exec(&[_][]const u8{ "/bin/sh", "-c", "xz -9ez --check=crc32 --stdout --keep payload.foilz > src/payload.foilz.xz" }); + _ = builder.run(&[_][]const u8{ "/bin/sh", "-c", "xz -9ez --check=crc32 --stdout --keep payload.foilz > src/payload.foilz.xz" }); } } @@ -64,18 +61,19 @@ pub fn build_wrapper() !void { var file = try std.fs.cwd().openFile("payload.foilz", .{}); defer file.close(); const uncompressed_size = try file.getEndPos(); + const target = builder.standardTargetOptions(.{}); wrapper_exe = builder.addExecutable(.{ .name = release_name, // In this case the main source file is merely a path, however, in more // complicated build scripts, this could be a generated file. - .root_source_file = .{ .path = "src/wrapper.zig" }, - .target = target.*, + .root_source_file = builder.path("src/wrapper.zig"), + .target = target, .optimize = opt_level, }); const exe_options = builder.addOptions(); - wrapper_exe.addOptions("build_options", exe_options); + wrapper_exe.root_module.addOptions("build_options", exe_options); exe_options.addOption([]const u8, "RELEASE_NAME", release_name); exe_options.addOption(u64, "UNCOMPRESSED_SIZE", uncompressed_size); @@ -83,8 +81,8 @@ pub fn build_wrapper() !void { exe_options.addOption(bool, "IS_PROD", std.mem.eql(u8, is_prod, "1")); exe_options.addOption([]const u8, "MUSL_RUNTIME_PATH", musl_runtime_path); - if (target.isWindows()) { - wrapper_exe.addIncludePath(.{ .path = "src/" }); + if (target.result.os.tag == .windows) { + wrapper_exe.addIncludePath(builder.path("src/")); } // Link standard C libary to the wrapper @@ -92,22 +90,21 @@ pub fn build_wrapper() !void { if (plugin_path) |plugin| { log.info("Plugin found! {s} 🔌", .{plugin}); - - const plugin_module = builder.createModule(.{ - .source_file = .{ .path = plugin }, + const plug_mod = builder.addModule("burrito_plugin", .{ + .root_source_file = .{ .cwd_relative = plugin }, }); - wrapper_exe.addModule("burrito_plugin", plugin_module); + wrapper_exe.root_module.addImport("burrito_plugin", plug_mod); } else { - const plugin_module = builder.createModule(.{ - .source_file = .{ .path = "_dummy_plugin.zig" }, + const plug_mod = builder.addModule("burrito_plugin", .{ + .root_source_file = builder.path("_dummy_plugin.zig"), }); - wrapper_exe.addModule("burrito_plugin", plugin_module); + wrapper_exe.root_module.addImport("burrito_plugin", plug_mod); } - wrapper_exe.addIncludePath(.{ .path = "src/xz" }); - wrapper_exe.addCSourceFile(.{ .file = .{ .path = "src/xz/xz_crc32.c" }, .flags = &[0][]const u8{} }); - wrapper_exe.addCSourceFile(.{ .file = .{ .path = "src/xz/xz_dec_lzma2.c" }, .flags = &[0][]const u8{} }); - wrapper_exe.addCSourceFile(.{ .file = .{ .path = "src/xz/xz_dec_stream.c" }, .flags = &[0][]const u8{} }); + wrapper_exe.addIncludePath(builder.path("src/xz")); + wrapper_exe.addCSourceFile(.{ .file = builder.path("src/xz/xz_crc32.c") }); + wrapper_exe.addCSourceFile(.{ .file = builder.path("src/xz/xz_dec_lzma2.c") }); + wrapper_exe.addCSourceFile(.{ .file = builder.path("src/xz/xz_dec_stream.c") }); builder.installArtifact(wrapper_exe); } diff --git a/examples/only_one/plugin/file_check.zig b/examples/only_one/plugin/file_check.zig index 4d977cc..e176b3d 100644 --- a/examples/only_one/plugin/file_check.zig +++ b/examples/only_one/plugin/file_check.zig @@ -6,10 +6,10 @@ pub fn burrito_plugin_entry(install_dir: []const u8, program_manifest_json: []co std.debug.print("Install Dir: {s}\n", .{install_dir}); std.debug.print(": {s}\n", .{program_manifest_json}); - var exists = if (std.fs.cwd().access("only_one.lock", .{ .mode = File.OpenMode.read_only })) true else |_| false; + const exists = if (std.fs.cwd().access("only_one.lock", .{ .mode = File.OpenMode.read_only })) true else |_| false; if (exists) { std.log.err("We found a lockfile! Can't run two of this application at one!\n", .{}); - std.os.exit(1); + std.process.exit(0); } } diff --git a/lib/burrito.ex b/lib/burrito.ex index daeacd5..e708e28 100644 --- a/lib/burrito.ex +++ b/lib/burrito.ex @@ -2,7 +2,7 @@ defmodule Burrito do alias Burrito.Builder alias Burrito.Builder.Log - @zig_version_expected %Version{major: 0, minor: 11, patch: 0} + @zig_version_expected %Version{major: 0, minor: 13, patch: 0} @spec wrap(Mix.Release.t()) :: Mix.Release.t() def wrap(%Mix.Release{} = release) do diff --git a/src/archiver.zig b/src/archiver.zig index 522cfa6..973d39b 100644 --- a/src/archiver.zig +++ b/src/archiver.zig @@ -54,7 +54,7 @@ pub fn pack_directory(path: []const u8, archive_path: []const u8) anyerror!void const arch_file = try fs.cwd().openFile(archive_path, .{ .mode = .read_write }); const foilz_writer = fs.File.writer(arch_file); - var dir = try fs.openIterableDirAbsolute(path, .{ .access_sub_paths = true }); + var dir = try fs.openDirAbsolute(path, .{ .access_sub_paths = true, .iterate = true }); var walker = try dir.walk(allocator); var count: u32 = 0; @@ -80,7 +80,7 @@ pub fn pack_directory(path: []const u8, archive_path: []const u8) anyerror!void // Allocate memory for the file var file_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer file_arena.deinit(); - var file_allocator = file_arena.allocator(); + const file_allocator = file_arena.allocator(); // Read the file const file_buffer = try file.readToEndAlloc(file_allocator, MAX_READ_SIZE); @@ -113,13 +113,13 @@ pub fn write_magic_number(foilz_writer: *const fs.File.Writer) !void { } pub fn write_file_record(foilz_writer: *const fs.File.Writer, name: []const u8, data: []const u8, mode: usize) !void { - _ = try foilz_writer.writeInt(u64, name.len, .Little); + _ = try foilz_writer.writeInt(u64, name.len, .little); _ = try foilz_writer.write(name); - _ = try foilz_writer.writeInt(u64, data.len, .Little); + _ = try foilz_writer.writeInt(u64, data.len, .little); if (data.len > 0) { _ = try foilz_writer.write(data); } - _ = try foilz_writer.writeInt(usize, mode, .Little); + _ = try foilz_writer.writeInt(usize, mode, .little); } pub fn validate_magic(first_bytes: []const u8) bool { @@ -169,23 +169,23 @@ pub fn unpack_files(data: []const u8, dest_path: []const u8, uncompressed_size: while (cursor < decompressed.len - 5) { ////// // Read the file name - var string_len = std.mem.readIntSliceLittle(u64, decompressed[cursor .. cursor + @sizeOf(u64)]); + const string_len = std.mem.readInt(u64, decompressed[cursor .. cursor + @sizeOf(u64)][0..8], .little); cursor = cursor + @sizeOf(u64); - var file_name = decompressed[cursor .. cursor + string_len]; + const file_name = decompressed[cursor .. cursor + string_len]; cursor = cursor + string_len; ////// // Read the file data from the payload - var file_len = std.mem.readIntSliceLittle(u64, decompressed[cursor .. cursor + @sizeOf(u64)]); + const file_len = std.mem.readInt(u64, decompressed[cursor .. cursor + @sizeOf(u64)][0..8], .little); cursor = cursor + @sizeOf(u64); - var file_data = decompressed[cursor .. cursor + file_len]; + const file_data = decompressed[cursor .. cursor + file_len]; cursor = cursor + file_len; ////// // Read the mode for this file - var file_mode = std.mem.readIntSliceLittle(usize, decompressed[cursor .. cursor + @sizeOf(usize)]); + const file_mode = std.mem.readInt(usize, decompressed[cursor .. cursor + @sizeOf(usize)][0..@sizeOf(usize)], .little); cursor = cursor + @sizeOf(usize); ////// @@ -229,15 +229,23 @@ fn create_dirs(dest_path: []const u8, sub_dir_names: []const u8, allocator: std. while (iterator.next()) |sub_dir| { full_dir_path = try fs.path.join(allocator, &[_][]const u8{ full_dir_path, sub_dir.name }); - os.mkdir(full_dir_path, 0o755) catch {}; + fs.makeDirAbsolute(full_dir_path) catch |err| { + switch (err) { + error.PathAlreadyExists => { + log.debug("Directory Exists: {s}", .{full_dir_path}); + continue; + }, + else => return err, + } + }; + log.debug("Created Directory: {s}", .{full_dir_path}); } } // Adapted from `std.log`, but without forcing a newline fn direct_log(comptime message: []const u8, args: anytype) void { - const stderrLock = std.debug.getStderrMutex(); - stderrLock.lock(); - defer stderrLock.unlock(); + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); const stderr = std.io.getStdErr().writer(); // Using the same IO as `std.log` nosuspend stderr.print(message, args) catch return; } diff --git a/src/erlang_launcher.zig b/src/erlang_launcher.zig index fece4c4..1218045 100644 --- a/src/erlang_launcher.zig +++ b/src/erlang_launcher.zig @@ -21,7 +21,7 @@ fn get_erl_exe_name() []const u8 { pub fn launch(install_dir: []const u8, env_map: *EnvMap, meta: *const MetaStruct, args_trimmed: []const []const u8) !void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - var allocator = arena.allocator(); + const allocator = arena.allocator(); // Computer directories we care about const release_cookie_path = try fs.path.join(allocator, &[_][]const u8{ install_dir, "releases", "COOKIE" }); @@ -71,7 +71,7 @@ pub fn launch(install_dir: []const u8, env_map: *EnvMap, meta: *const MetaStruct try env_map.put("RELEASE_SYS_CONFIG", config_sys_path_no_ext); try env_map.put("__BURRITO", "1"); - var win_child_proc = std.ChildProcess.init(final_args, allocator); + var win_child_proc = std.process.Child.init(final_args, allocator); win_child_proc.env_map = env_map; win_child_proc.stdout_behavior = .Inherit; win_child_proc.stdin_behavior = .Inherit; diff --git a/src/logger.zig b/src/logger.zig index e6fc865..6109128 100644 --- a/src/logger.zig +++ b/src/logger.zig @@ -6,36 +6,48 @@ var allocator = arena.allocator(); pub fn query(comptime message: []const u8, args: anytype) void { var stdout = std.io.getStdOut().writer(); - var out_string = std.fmt.allocPrint(allocator, message, args) catch { return; }; + const out_string = std.fmt.allocPrint(allocator, message, args) catch { + return; + }; stdout.print("[?] {s}", .{out_string}) catch {}; } pub fn log_stderr(comptime message: []const u8, args: anytype) void { var stderr = std.io.getStdErr().writer(); - var out_string = std.fmt.allocPrint(allocator, message, args) catch { return; }; + const out_string = std.fmt.allocPrint(allocator, message, args) catch { + return; + }; stderr.print("[l] {s}\n", .{out_string}) catch {}; } pub fn info(comptime message: []const u8, args: anytype) void { var stdout = std.io.getStdOut().writer(); - var out_string = std.fmt.allocPrint(allocator, message, args) catch { return; }; + const out_string = std.fmt.allocPrint(allocator, message, args) catch { + return; + }; stdout.print("[i] {s}\n", .{out_string}) catch {}; } pub fn warn(comptime message: []const u8, args: anytype) void { var stderr = std.io.getStdErr().writer(); - var out_string = std.fmt.allocPrint(allocator, message, args) catch { return; }; + const out_string = std.fmt.allocPrint(allocator, message, args) catch { + return; + }; stderr.print("[w] {s}\n", .{out_string}) catch {}; } pub fn err(comptime message: []const u8, args: anytype) void { var stderr = std.io.getStdErr().writer(); - var out_string = std.fmt.allocPrint(allocator, message, args) catch { return; }; + const out_string = std.fmt.allocPrint(allocator, message, args) catch { + return; + }; stderr.print("[!] {s}\n", .{out_string}) catch {}; } pub fn crit(comptime message: []const u8, args: anytype) void { var stderr = std.io.getStdErr().writer(); - var out_string = std.fmt.allocPrint(allocator, message, args) catch { return; }; + const out_string = std.fmt.allocPrint(allocator, message, args) catch { + return; + }; stderr.print("[!!] {s}\n", .{out_string}) catch {}; } diff --git a/src/maintenance.zig b/src/maintenance.zig index acbe4d7..f02f5a3 100644 --- a/src/maintenance.zig +++ b/src/maintenance.zig @@ -72,7 +72,7 @@ pub fn do_clean_old_versions(install_prefix_path: []const u8, current_install_pa defer arena.deinit(); const allocator = arena.allocator(); - const prefix_dir = try std.fs.openIterableDirAbsolute(install_prefix_path, .{ .access_sub_paths = true }); + const prefix_dir = try std.fs.openDirAbsolute(install_prefix_path, .{ .access_sub_paths = true, .iterate = true }); const current_install = try install.load_install_from_path(allocator, current_install_path); diff --git a/src/wrapper.zig b/src/wrapper.zig index d61a7d3..1908056 100644 --- a/src/wrapper.zig +++ b/src/wrapper.zig @@ -57,8 +57,8 @@ pub fn main() anyerror!void { var windows_arg_list = std.ArrayList([]u8).init(allocator); var i: usize = 0; while (i < arg_count) : (i += 1) { - var index = i; - var length = std.mem.len(raw_args.?[index]); + const index = i; + const length = std.mem.len(raw_args.?[index]); const argument = try std.unicode.utf16leToUtf8Alloc(allocator, raw_args.?[index][0..length]); try windows_arg_list.append(argument); } @@ -165,7 +165,7 @@ fn get_base_install_dir() ![]const u8 { logger.info("New install path is: {s}", .{new_path}); return try fs.path.join(allocator, &[_][]const u8{ new_path, install_suffix }); } else |err| switch (err) { - error.InvalidUtf8 => {}, + error.InvalidWtf8 => {}, error.EnvironmentVariableNotFound => {}, error.OutOfMemory => {}, } @@ -220,8 +220,8 @@ fn maybe_install_musl_runtime() anyerror!void { if (comptime IS_LINUX and !std.mem.eql(u8, build_options.MUSL_RUNTIME_PATH, "")) { // Check if the file was already extracted const cStr = try allocator.dupeZ(u8, build_options.MUSL_RUNTIME_PATH); - var statBuffer: std.os.Stat = undefined; - const statResult = std.os.system.stat(cStr, &statBuffer); + var statBuffer: std.c.Stat = undefined; + const statResult = std.c.stat(cStr, &statBuffer); if (statResult == 0) { // File exists