| author | |
| committer | |
| log | f645022d16361865e24582d28f1e62312fbc73bb |
| tree | 7a7f03aff7bc7b9dc3f4ba1b3be57bd17caae1b7 |
| parent | 8ca4a5240e0258c84e437ed4a37972c8fff7842d |
Instead of `zig init-lib` and `zig init-exe`, now there is only
`zig init`, which initializes any of the template files that do not
already exist, and makes a package that contains both an executable and
a static library. The idea is that the user can delete whatever they
don't want. In fact, I think even more things should be added to the
build.zig template.10 files changed, 201 insertions(+), 240 deletions(-)
lib/init-exe/build.zig deleted-70| ... | @@ -1,70 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | // Although this function looks imperative, note that its job is to | ||
| 4 | // declaratively construct a build graph that will be executed by an external | ||
| 5 | // runner. | ||
| 6 | pub fn build(b: *std.Build) void { | ||
| 7 | // Standard target options allows the person running `zig build` to choose | ||
| 8 | // what target to build for. Here we do not override the defaults, which | ||
| 9 | // means any target is allowed, and the default is native. Other options | ||
| 10 | // for restricting supported target set are available. | ||
| 11 | const target = b.standardTargetOptions(.{}); | ||
| 12 | |||
| 13 | // Standard optimization options allow the person running `zig build` to select | ||
| 14 | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not | ||
| 15 | // set a preferred release mode, allowing the user to decide how to optimize. | ||
| 16 | const optimize = b.standardOptimizeOption(.{}); | ||
| 17 | |||
| 18 | const exe = b.addExecutable(.{ | ||
| 19 | .name = "$", | ||
| 20 | // In this case the main source file is merely a path, however, in more | ||
| 21 | // complicated build scripts, this could be a generated file. | ||
| 22 | .root_source_file = .{ .path = "src/main.zig" }, | ||
| 23 | .target = target, | ||
| 24 | .optimize = optimize, | ||
| 25 | }); | ||
| 26 | |||
| 27 | // This declares intent for the executable to be installed into the | ||
| 28 | // standard location when the user invokes the "install" step (the default | ||
| 29 | // step when running `zig build`). | ||
| 30 | b.installArtifact(exe); | ||
| 31 | |||
| 32 | // This *creates* a Run step in the build graph, to be executed when another | ||
| 33 | // step is evaluated that depends on it. The next line below will establish | ||
| 34 | // such a dependency. | ||
| 35 | const run_cmd = b.addRunArtifact(exe); | ||
| 36 | |||
| 37 | // By making the run step depend on the install step, it will be run from the | ||
| 38 | // installation directory rather than directly from within the cache directory. | ||
| 39 | // This is not necessary, however, if the application depends on other installed | ||
| 40 | // files, this ensures they will be present and in the expected location. | ||
| 41 | run_cmd.step.dependOn(b.getInstallStep()); | ||
| 42 | |||
| 43 | // This allows the user to pass arguments to the application in the build | ||
| 44 | // command itself, like this: `zig build run -- arg1 arg2 etc` | ||
| 45 | if (b.args) |args| { | ||
| 46 | run_cmd.addArgs(args); | ||
| 47 | } | ||
| 48 | |||
| 49 | // This creates a build step. It will be visible in the `zig build --help` menu, | ||
| 50 | // and can be selected like this: `zig build run` | ||
| 51 | // This will evaluate the `run` step rather than the default, which is "install". | ||
| 52 | const run_step = b.step("run", "Run the app"); | ||
| 53 | run_step.dependOn(&run_cmd.step); | ||
| 54 | |||
| 55 | // Creates a step for unit testing. This only builds the test executable | ||
| 56 | // but does not run it. | ||
| 57 | const unit_tests = b.addTest(.{ | ||
| 58 | .root_source_file = .{ .path = "src/main.zig" }, | ||
| 59 | .target = target, | ||
| 60 | .optimize = optimize, | ||
| 61 | }); | ||
| 62 | |||
| 63 | const run_unit_tests = b.addRunArtifact(unit_tests); | ||
| 64 | |||
| 65 | // Similar to creating the run step earlier, this exposes a `test` step to | ||
| 66 | // the `zig build --help` menu, providing a way for the user to request | ||
| 67 | // running the unit tests. | ||
| 68 | const test_step = b.step("test", "Run unit tests"); | ||
| 69 | test_step.dependOn(&run_unit_tests.step); | ||
| 70 | } | ||
lib/init-exe/src/main.zig deleted-24| ... | @@ -1,24 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn main() !void { | ||
| 4 | // Prints to stderr (it's a shortcut based on `std.io.getStdErr()`) | ||
| 5 | std.debug.print("All your {s} are belong to us.\n", .{"codebase"}); | ||
| 6 | |||
| 7 | // stdout is for the actual output of your application, for example if you | ||
| 8 | // are implementing gzip, then only the compressed bytes should be sent to | ||
| 9 | // stdout, not any debugging messages. | ||
| 10 | const stdout_file = std.io.getStdOut().writer(); | ||
| 11 | var bw = std.io.bufferedWriter(stdout_file); | ||
| 12 | const stdout = bw.writer(); | ||
| 13 | |||
| 14 | try stdout.print("Run `zig build test` to run the tests.\n", .{}); | ||
| 15 | |||
| 16 | try bw.flush(); // don't forget to flush! | ||
| 17 | } | ||
| 18 | |||
| 19 | test "simple test" { | ||
| 20 | var list = std.ArrayList(i32).init(std.testing.allocator); | ||
| 21 | defer list.deinit(); // try commenting this out and see if zig detects the memory leak! | ||
| 22 | try list.append(42); | ||
| 23 | try std.testing.expectEqual(@as(i32, 42), list.pop()); | ||
| 24 | } | ||
lib/init-lib/build.zig deleted-47| ... | @@ -1,47 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | // Although this function looks imperative, note that its job is to | ||
| 4 | // declaratively construct a build graph that will be executed by an external | ||
| 5 | // runner. | ||
| 6 | pub fn build(b: *std.Build) void { | ||
| 7 | // Standard target options allows the person running `zig build` to choose | ||
| 8 | // what target to build for. Here we do not override the defaults, which | ||
| 9 | // means any target is allowed, and the default is native. Other options | ||
| 10 | // for restricting supported target set are available. | ||
| 11 | const target = b.standardTargetOptions(.{}); | ||
| 12 | |||
| 13 | // Standard optimization options allow the person running `zig build` to select | ||
| 14 | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not | ||
| 15 | // set a preferred release mode, allowing the user to decide how to optimize. | ||
| 16 | const optimize = b.standardOptimizeOption(.{}); | ||
| 17 | |||
| 18 | const lib = b.addStaticLibrary(.{ | ||
| 19 | .name = "$", | ||
| 20 | // In this case the main source file is merely a path, however, in more | ||
| 21 | // complicated build scripts, this could be a generated file. | ||
| 22 | .root_source_file = .{ .path = "src/main.zig" }, | ||
| 23 | .target = target, | ||
| 24 | .optimize = optimize, | ||
| 25 | }); | ||
| 26 | |||
| 27 | // This declares intent for the library to be installed into the standard | ||
| 28 | // location when the user invokes the "install" step (the default step when | ||
| 29 | // running `zig build`). | ||
| 30 | b.installArtifact(lib); | ||
| 31 | |||
| 32 | // Creates a step for unit testing. This only builds the test executable | ||
| 33 | // but does not run it. | ||
| 34 | const main_tests = b.addTest(.{ | ||
| 35 | .root_source_file = .{ .path = "src/main.zig" }, | ||
| 36 | .target = target, | ||
| 37 | .optimize = optimize, | ||
| 38 | }); | ||
| 39 | |||
| 40 | const run_main_tests = b.addRunArtifact(main_tests); | ||
| 41 | |||
| 42 | // This creates a build step. It will be visible in the `zig build --help` menu, | ||
| 43 | // and can be selected like this: `zig build test` | ||
| 44 | // This will evaluate the `test` step rather than the default, which is "install". | ||
| 45 | const test_step = b.step("test", "Run library tests"); | ||
| 46 | test_step.dependOn(&run_main_tests.step); | ||
| 47 | } | ||
lib/init-lib/src/main.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const testing = std.testing; | ||
| 3 | |||
| 4 | export fn add(a: i32, b: i32) i32 { | ||
| 5 | return a + b; | ||
| 6 | } | ||
| 7 | |||
| 8 | test "basic add functionality" { | ||
| 9 | try testing.expect(add(3, 7) == 10); | ||
| 10 | } | ||
lib/init/build.zig created+91| ... | @@ -0,0 +1,91 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | // Although this function looks imperative, note that its job is to | ||
| 4 | // declaratively construct a build graph that will be executed by an external | ||
| 5 | // runner. | ||
| 6 | pub fn build(b: *std.Build) void { | ||
| 7 | // Standard target options allows the person running `zig build` to choose | ||
| 8 | // what target to build for. Here we do not override the defaults, which | ||
| 9 | // means any target is allowed, and the default is native. Other options | ||
| 10 | // for restricting supported target set are available. | ||
| 11 | const target = b.standardTargetOptions(.{}); | ||
| 12 | |||
| 13 | // Standard optimization options allow the person running `zig build` to select | ||
| 14 | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not | ||
| 15 | // set a preferred release mode, allowing the user to decide how to optimize. | ||
| 16 | const optimize = b.standardOptimizeOption(.{}); | ||
| 17 | |||
| 18 | const lib = b.addStaticLibrary(.{ | ||
| 19 | .name = "$", | ||
| 20 | // In this case the main source file is merely a path, however, in more | ||
| 21 | // complicated build scripts, this could be a generated file. | ||
| 22 | .root_source_file = .{ .path = "src/root.zig" }, | ||
| 23 | .target = target, | ||
| 24 | .optimize = optimize, | ||
| 25 | }); | ||
| 26 | |||
| 27 | // This declares intent for the library to be installed into the standard | ||
| 28 | // location when the user invokes the "install" step (the default step when | ||
| 29 | // running `zig build`). | ||
| 30 | b.installArtifact(lib); | ||
| 31 | |||
| 32 | const exe = b.addExecutable(.{ | ||
| 33 | .name = "$", | ||
| 34 | .root_source_file = .{ .path = "src/main.zig" }, | ||
| 35 | .target = target, | ||
| 36 | .optimize = optimize, | ||
| 37 | }); | ||
| 38 | |||
| 39 | // This declares intent for the executable to be installed into the | ||
| 40 | // standard location when the user invokes the "install" step (the default | ||
| 41 | // step when running `zig build`). | ||
| 42 | b.installArtifact(exe); | ||
| 43 | |||
| 44 | // This *creates* a Run step in the build graph, to be executed when another | ||
| 45 | // step is evaluated that depends on it. The next line below will establish | ||
| 46 | // such a dependency. | ||
| 47 | const run_cmd = b.addRunArtifact(exe); | ||
| 48 | |||
| 49 | // By making the run step depend on the install step, it will be run from the | ||
| 50 | // installation directory rather than directly from within the cache directory. | ||
| 51 | // This is not necessary, however, if the application depends on other installed | ||
| 52 | // files, this ensures they will be present and in the expected location. | ||
| 53 | run_cmd.step.dependOn(b.getInstallStep()); | ||
| 54 | |||
| 55 | // This allows the user to pass arguments to the application in the build | ||
| 56 | // command itself, like this: `zig build run -- arg1 arg2 etc` | ||
| 57 | if (b.args) |args| { | ||
| 58 | run_cmd.addArgs(args); | ||
| 59 | } | ||
| 60 | |||
| 61 | // This creates a build step. It will be visible in the `zig build --help` menu, | ||
| 62 | // and can be selected like this: `zig build run` | ||
| 63 | // This will evaluate the `run` step rather than the default, which is "install". | ||
| 64 | const run_step = b.step("run", "Run the app"); | ||
| 65 | run_step.dependOn(&run_cmd.step); | ||
| 66 | |||
| 67 | // Creates a step for unit testing. This only builds the test executable | ||
| 68 | // but does not run it. | ||
| 69 | const lib_unit_tests = b.addTest(.{ | ||
| 70 | .root_source_file = .{ .path = "src/root.zig" }, | ||
| 71 | .target = target, | ||
| 72 | .optimize = optimize, | ||
| 73 | }); | ||
| 74 | |||
| 75 | const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); | ||
| 76 | |||
| 77 | const exe_unit_tests = b.addTest(.{ | ||
| 78 | .root_source_file = .{ .path = "src/main.zig" }, | ||
| 79 | .target = target, | ||
| 80 | .optimize = optimize, | ||
| 81 | }); | ||
| 82 | |||
| 83 | const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); | ||
| 84 | |||
| 85 | // Similar to creating the run step earlier, this exposes a `test` step to | ||
| 86 | // the `zig build --help` menu, providing a way for the user to request | ||
| 87 | // running the unit tests. | ||
| 88 | const test_step = b.step("test", "Run unit tests"); | ||
| 89 | test_step.dependOn(&run_lib_unit_tests.step); | ||
| 90 | test_step.dependOn(&run_exe_unit_tests.step); | ||
| 91 | } | ||
lib/init/src/main.zig created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn main() !void { | ||
| 4 | // Prints to stderr (it's a shortcut based on `std.io.getStdErr()`) | ||
| 5 | std.debug.print("All your {s} are belong to us.\n", .{"codebase"}); | ||
| 6 | |||
| 7 | // stdout is for the actual output of your application, for example if you | ||
| 8 | // are implementing gzip, then only the compressed bytes should be sent to | ||
| 9 | // stdout, not any debugging messages. | ||
| 10 | const stdout_file = std.io.getStdOut().writer(); | ||
| 11 | var bw = std.io.bufferedWriter(stdout_file); | ||
| 12 | const stdout = bw.writer(); | ||
| 13 | |||
| 14 | try stdout.print("Run `zig build test` to run the tests.\n", .{}); | ||
| 15 | |||
| 16 | try bw.flush(); // don't forget to flush! | ||
| 17 | } | ||
| 18 | |||
| 19 | test "simple test" { | ||
| 20 | var list = std.ArrayList(i32).init(std.testing.allocator); | ||
| 21 | defer list.deinit(); // try commenting this out and see if zig detects the memory leak! | ||
| 22 | try list.append(42); | ||
| 23 | try std.testing.expectEqual(@as(i32, 42), list.pop()); | ||
| 24 | } | ||
lib/init/src/root.zig created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const testing = std.testing; | ||
| 3 | |||
| 4 | export fn add(a: i32, b: i32) i32 { | ||
| 5 | return a + b; | ||
| 6 | } | ||
| 7 | |||
| 8 | test "basic add functionality" { | ||
| 9 | try testing.expect(add(3, 7) == 10); | ||
| 10 | } | ||
lib/std/fs.zig+21-5| ... | @@ -2562,12 +2562,28 @@ pub const Dir = struct { | ... | @@ -2562,12 +2562,28 @@ pub const Dir = struct { |
| 2562 | }; | 2562 | }; |
| 2563 | } | 2563 | } |
| 2564 | 2564 | ||
| 2565 | /// Writes content to the file system, creating a new file if it does not exist, truncating | 2565 | pub const WriteFileError = File.WriteError || File.OpenError; |
| 2566 | /// if it already exists. | 2566 | |
| 2567 | pub fn writeFile(self: Dir, sub_path: []const u8, data: []const u8) !void { | 2567 | /// Deprecated: use `writeFile2`. |
| 2568 | var file = try self.createFile(sub_path, .{}); | 2568 | pub fn writeFile(self: Dir, sub_path: []const u8, data: []const u8) WriteFileError!void { |
| 2569 | return writeFile2(self, .{ | ||
| 2570 | .sub_path = sub_path, | ||
| 2571 | .data = data, | ||
| 2572 | .flags = .{}, | ||
| 2573 | }); | ||
| 2574 | } | ||
| 2575 | |||
| 2576 | pub const WriteFileOptions = struct { | ||
| 2577 | sub_path: []const u8, | ||
| 2578 | data: []const u8, | ||
| 2579 | flags: File.CreateFlags = .{}, | ||
| 2580 | }; | ||
| 2581 | |||
| 2582 | /// Writes content to the file system, using the file creation flags provided. | ||
| 2583 | pub fn writeFile2(self: Dir, options: WriteFileOptions) WriteFileError!void { | ||
| 2584 | var file = try self.createFile(options.sub_path, options.flags); | ||
| 2569 | defer file.close(); | 2585 | defer file.close(); |
| 2570 | try file.writeAll(data); | 2586 | try file.writeAll(options.data); |
| 2571 | } | 2587 | } |
| 2572 | 2588 | ||
| 2573 | pub const AccessError = os.AccessError; | 2589 | pub const AccessError = os.AccessError; |
src/main.zig+48-54| ... | @@ -86,8 +86,7 @@ const normal_usage = | ... | @@ -86,8 +86,7 @@ const normal_usage = |
| 86 | \\ | 86 | \\ |
| 87 | \\ build Build project from build.zig | 87 | \\ build Build project from build.zig |
| 88 | \\ fetch Copy a package into global cache and print its hash | 88 | \\ fetch Copy a package into global cache and print its hash |
| 89 | \\ init-exe Initialize a `zig build` application in the cwd | 89 | \\ init Initialize a Zig package in the current directory |
| 90 | \\ init-lib Initialize a `zig build` library in the cwd | ||
| 91 | \\ | 90 | \\ |
| 92 | \\ ast-check Look for simple compile errors in any set of files | 91 | \\ ast-check Look for simple compile errors in any set of files |
| 93 | \\ build-exe Create executable from source or object files | 92 | \\ build-exe Create executable from source or object files |
| ... | @@ -320,10 +319,8 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -320,10 +319,8 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 320 | return cmdFetch(gpa, arena, cmd_args); | 319 | return cmdFetch(gpa, arena, cmd_args); |
| 321 | } else if (mem.eql(u8, cmd, "libc")) { | 320 | } else if (mem.eql(u8, cmd, "libc")) { |
| 322 | return cmdLibC(gpa, cmd_args); | 321 | return cmdLibC(gpa, cmd_args); |
| 323 | } else if (mem.eql(u8, cmd, "init-exe")) { | 322 | } else if (mem.eql(u8, cmd, "init")) { |
| 324 | return cmdInit(gpa, arena, cmd_args, .Exe); | 323 | return cmdInit(gpa, arena, cmd_args); |
| 325 | } else if (mem.eql(u8, cmd, "init-lib")) { | ||
| 326 | return cmdInit(gpa, arena, cmd_args, .Lib); | ||
| 327 | } else if (mem.eql(u8, cmd, "targets")) { | 324 | } else if (mem.eql(u8, cmd, "targets")) { |
| 328 | const info = try detectNativeTargetInfo(.{}); | 325 | const info = try detectNativeTargetInfo(.{}); |
| 329 | const stdout = io.getStdOut().writer(); | 326 | const stdout = io.getStdOut().writer(); |
| ... | @@ -4835,8 +4832,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { | ... | @@ -4835,8 +4832,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4835 | } | 4832 | } |
| 4836 | 4833 | ||
| 4837 | pub const usage_init = | 4834 | pub const usage_init = |
| 4838 | \\Usage: zig init-exe | 4835 | \\Usage: zig init |
| 4839 | \\ zig init-lib | ||
| 4840 | \\ | 4836 | \\ |
| 4841 | \\ Initializes a `zig build` project in the current working | 4837 | \\ Initializes a `zig build` project in the current working |
| 4842 | \\ directory. | 4838 | \\ directory. |
| ... | @@ -4847,12 +4843,7 @@ pub const usage_init = | ... | @@ -4847,12 +4843,7 @@ pub const usage_init = |
| 4847 | \\ | 4843 | \\ |
| 4848 | ; | 4844 | ; |
| 4849 | 4845 | ||
| 4850 | pub fn cmdInit( | 4846 | pub fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4851 | gpa: Allocator, | ||
| 4852 | arena: Allocator, | ||
| 4853 | args: []const []const u8, | ||
| 4854 | output_mode: std.builtin.OutputMode, | ||
| 4855 | ) !void { | ||
| 4856 | _ = gpa; | 4847 | _ = gpa; |
| 4857 | { | 4848 | { |
| 4858 | var i: usize = 0; | 4849 | var i: usize = 0; |
| ... | @@ -4877,14 +4868,12 @@ pub fn cmdInit( | ... | @@ -4877,14 +4868,12 @@ pub fn cmdInit( |
| 4877 | defer zig_lib_directory.handle.close(); | 4868 | defer zig_lib_directory.handle.close(); |
| 4878 | 4869 | ||
| 4879 | const s = fs.path.sep_str; | 4870 | const s = fs.path.sep_str; |
| 4880 | const template_sub_path = switch (output_mode) { | 4871 | const template_sub_path = "init"; |
| 4881 | .Obj => unreachable, | ||
| 4882 | .Lib => "init-lib", | ||
| 4883 | .Exe => "init-exe", | ||
| 4884 | }; | ||
| 4885 | var template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| { | 4872 | var template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| { |
| 4886 | const path = zig_lib_directory.path orelse "."; | 4873 | const path = zig_lib_directory.path orelse "."; |
| 4887 | fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{ path, s, template_sub_path, @errorName(err) }); | 4874 | fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{ |
| 4875 | path, s, template_sub_path, @errorName(err), | ||
| 4876 | }); | ||
| 4888 | }; | 4877 | }; |
| 4889 | defer template_dir.close(); | 4878 | defer template_dir.close(); |
| 4890 | 4879 | ||
| ... | @@ -4892,46 +4881,51 @@ pub fn cmdInit( | ... | @@ -4892,46 +4881,51 @@ pub fn cmdInit( |
| 4892 | const cwd_basename = fs.path.basename(cwd_path); | 4881 | const cwd_basename = fs.path.basename(cwd_path); |
| 4893 | 4882 | ||
| 4894 | const max_bytes = 10 * 1024 * 1024; | 4883 | const max_bytes = 10 * 1024 * 1024; |
| 4895 | const build_zig_contents = template_dir.readFileAlloc(arena, "build.zig", max_bytes) catch |err| { | 4884 | const template_paths = [_][]const u8{ |
| 4896 | fatal("unable to read template file 'build.zig': {s}", .{@errorName(err)}); | 4885 | "build.zig", |
| 4886 | "src" ++ s ++ "main.zig", | ||
| 4887 | "src" ++ s ++ "root.zig", | ||
| 4897 | }; | 4888 | }; |
| 4898 | var modified_build_zig_contents = try std.ArrayList(u8).initCapacity(arena, build_zig_contents.len); | 4889 | var ok_count: usize = 0; |
| 4899 | for (build_zig_contents) |c| { | 4890 | |
| 4900 | if (c == '$') { | 4891 | for (template_paths) |template_path| { |
| 4901 | try modified_build_zig_contents.appendSlice(cwd_basename); | 4892 | if (fs.path.dirname(template_path)) |dirname| { |
| 4902 | } else { | 4893 | fs.cwd().makePath(dirname) catch |err| { |
| 4903 | try modified_build_zig_contents.append(c); | 4894 | fatal("unable to make path '{s}': {s}", .{ dirname, @errorName(err) }); |
| 4895 | }; | ||
| 4904 | } | 4896 | } |
| 4905 | } | ||
| 4906 | const main_zig_contents = template_dir.readFileAlloc(arena, "src" ++ s ++ "main.zig", max_bytes) catch |err| { | ||
| 4907 | fatal("unable to read template file 'main.zig': {s}", .{@errorName(err)}); | ||
| 4908 | }; | ||
| 4909 | if (fs.cwd().access("build.zig", .{})) |_| { | ||
| 4910 | fatal("existing build.zig file would be overwritten", .{}); | ||
| 4911 | } else |err| switch (err) { | ||
| 4912 | error.FileNotFound => {}, | ||
| 4913 | else => fatal("unable to test existence of build.zig: {s}\n", .{@errorName(err)}), | ||
| 4914 | } | ||
| 4915 | if (fs.cwd().access("src" ++ s ++ "main.zig", .{})) |_| { | ||
| 4916 | fatal("existing src" ++ s ++ "main.zig file would be overwritten", .{}); | ||
| 4917 | } else |err| switch (err) { | ||
| 4918 | error.FileNotFound => {}, | ||
| 4919 | else => fatal("unable to test existence of src" ++ s ++ "main.zig: {s}\n", .{@errorName(err)}), | ||
| 4920 | } | ||
| 4921 | var src_dir = try fs.cwd().makeOpenPath("src", .{}); | ||
| 4922 | defer src_dir.close(); | ||
| 4923 | 4897 | ||
| 4924 | try src_dir.writeFile("main.zig", main_zig_contents); | 4898 | const contents = template_dir.readFileAlloc(arena, template_path, max_bytes) catch |err| { |
| 4925 | try fs.cwd().writeFile("build.zig", modified_build_zig_contents.items); | 4899 | fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) }); |
| 4900 | }; | ||
| 4901 | var modified_contents = try std.ArrayList(u8).initCapacity(arena, contents.len); | ||
| 4902 | for (contents) |c| { | ||
| 4903 | if (c == '$') { | ||
| 4904 | try modified_contents.appendSlice(cwd_basename); | ||
| 4905 | } else { | ||
| 4906 | try modified_contents.append(c); | ||
| 4907 | } | ||
| 4908 | } | ||
| 4926 | 4909 | ||
| 4927 | std.log.info("Created build.zig", .{}); | 4910 | if (fs.cwd().writeFile2(.{ |
| 4928 | std.log.info("Created src" ++ s ++ "main.zig", .{}); | 4911 | .sub_path = template_path, |
| 4912 | .data = modified_contents.items, | ||
| 4913 | .flags = .{ .exclusive = true }, | ||
| 4914 | })) |_| { | ||
| 4915 | std.log.info("created {s}", .{template_path}); | ||
| 4916 | ok_count += 1; | ||
| 4917 | } else |err| switch (err) { | ||
| 4918 | error.PathAlreadyExists => std.log.info("preserving already existing file: {s}", .{ | ||
| 4919 | template_path, | ||
| 4920 | }), | ||
| 4921 | else => std.log.err("unable to write {s}: {s}\n", .{ template_path, @errorName(err) }), | ||
| 4922 | } | ||
| 4923 | } | ||
| 4929 | 4924 | ||
| 4930 | switch (output_mode) { | 4925 | if (ok_count == template_paths.len) { |
| 4931 | .Lib => std.log.info("Next, try `zig build --help` or `zig build test`", .{}), | 4926 | std.log.info("see `zig build --help` for a menu of options", .{}); |
| 4932 | .Exe => std.log.info("Next, try `zig build --help` or `zig build run`", .{}), | ||
| 4933 | .Obj => unreachable, | ||
| 4934 | } | 4927 | } |
| 4928 | return cleanExit(); | ||
| 4935 | } | 4929 | } |
| 4936 | 4930 | ||
| 4937 | pub const usage_build = | 4931 | pub const usage_build = |
test/tests.zig+7-30| ... | @@ -776,39 +776,16 @@ pub fn addCliTests(b: *std.Build) *Step { | ... | @@ -776,39 +776,16 @@ pub fn addCliTests(b: *std.Build) *Step { |
| 776 | const s = std.fs.path.sep_str; | 776 | const s = std.fs.path.sep_str; |
| 777 | 777 | ||
| 778 | { | 778 | { |
| 779 | 779 | // Test `zig init`. | |
| 780 | // Test `zig init-lib`. | ||
| 781 | const tmp_path = b.makeTempPath(); | ||
| 782 | const init_lib = b.addSystemCommand(&.{ b.zig_exe, "init-lib" }); | ||
| 783 | init_lib.setCwd(.{ .cwd_relative = tmp_path }); | ||
| 784 | init_lib.setName("zig init-lib"); | ||
| 785 | init_lib.expectStdOutEqual(""); | ||
| 786 | init_lib.expectStdErrEqual("info: Created build.zig\n" ++ | ||
| 787 | "info: Created src" ++ s ++ "main.zig\n" ++ | ||
| 788 | "info: Next, try `zig build --help` or `zig build test`\n"); | ||
| 789 | |||
| 790 | const run_test = b.addSystemCommand(&.{ b.zig_exe, "build", "test" }); | ||
| 791 | run_test.setCwd(.{ .cwd_relative = tmp_path }); | ||
| 792 | run_test.setName("zig build test"); | ||
| 793 | run_test.expectStdOutEqual(""); | ||
| 794 | run_test.step.dependOn(&init_lib.step); | ||
| 795 | |||
| 796 | const cleanup = b.addRemoveDirTree(tmp_path); | ||
| 797 | cleanup.step.dependOn(&run_test.step); | ||
| 798 | |||
| 799 | step.dependOn(&cleanup.step); | ||
| 800 | } | ||
| 801 | |||
| 802 | { | ||
| 803 | // Test `zig init-exe`. | ||
| 804 | const tmp_path = b.makeTempPath(); | 780 | const tmp_path = b.makeTempPath(); |
| 805 | const init_exe = b.addSystemCommand(&.{ b.zig_exe, "init-exe" }); | 781 | const init_exe = b.addSystemCommand(&.{ b.zig_exe, "init" }); |
| 806 | init_exe.setCwd(.{ .cwd_relative = tmp_path }); | 782 | init_exe.setCwd(.{ .cwd_relative = tmp_path }); |
| 807 | init_exe.setName("zig init-exe"); | 783 | init_exe.setName("zig init"); |
| 808 | init_exe.expectStdOutEqual(""); | 784 | init_exe.expectStdOutEqual(""); |
| 809 | init_exe.expectStdErrEqual("info: Created build.zig\n" ++ | 785 | init_exe.expectStdErrEqual("info: created build.zig\n" ++ |
| 810 | "info: Created src" ++ s ++ "main.zig\n" ++ | 786 | "info: created src" ++ s ++ "main.zig\n" ++ |
| 811 | "info: Next, try `zig build --help` or `zig build run`\n"); | 787 | "info: created src" ++ s ++ "root.zig\n" ++ |
| 788 | "info: see `zig build --help` for a menu of options\n"); | ||
| 812 | 789 | ||
| 813 | // Test missing output path. | 790 | // Test missing output path. |
| 814 | const bad_out_arg = "-femit-bin=does" ++ s ++ "not" ++ s ++ "exist" ++ s ++ "foo.exe"; | 791 | const bad_out_arg = "-femit-bin=does" ++ s ++ "not" ++ s ++ "exist" ++ s ++ "foo.exe"; |