| author | |
| committer | |
| log | be6f76655fb355426dc8f3824368376608bc0ba1 |
| tree | 87a1557f767a12f8577feda20bf603037c166429 |
| parent | 27b34a5b77623b106ae1e1c7c4a466608a10905e |
| parent | 9f363cd679a60be6d9a4378f9a50c050fde9708d |
| signature |
11 files changed, 264 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/build.zig.zon created+61| ... | @@ -0,0 +1,61 @@ | ||
| 1 | .{ | ||
| 2 | .name = "$", | ||
| 3 | // This is a [Semantic Version](https://semver.org/). | ||
| 4 | // In a future version of Zig it will be used for package deduplication. | ||
| 5 | .version = "0.0.0", | ||
| 6 | |||
| 7 | // This field is optional. | ||
| 8 | // This is currently advisory only; Zig does not yet do anything | ||
| 9 | // with this value. | ||
| 10 | //.minimum_zig_version = "0.11.0", | ||
| 11 | |||
| 12 | // This field is optional. | ||
| 13 | // Each dependency must either provide a `url` and `hash`, or a `path`. | ||
| 14 | // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. | ||
| 15 | // Once all dependencies are fetched, `zig build` no longer requires | ||
| 16 | // Internet connectivity. | ||
| 17 | .dependencies = .{ | ||
| 18 | // A future version of Zig will provide a `zig add <url>` subcommand | ||
| 19 | // for easily adding dependencies. | ||
| 20 | //.example = .{ | ||
| 21 | // // When updating this field to a new URL, be sure to delete the corresponding | ||
| 22 | // // `hash`, otherwise you are communicating that you expect to find the old hash at | ||
| 23 | // // the new URL. | ||
| 24 | // .url = "https://example.com/foo.tar.gz", | ||
| 25 | // | ||
| 26 | // // This is computed from the file contents of the directory of files that is | ||
| 27 | // // obtained after fetching `url` and applying the inclusion rules given by | ||
| 28 | // // `paths`. | ||
| 29 | // // | ||
| 30 | // // This field is the source of truth; packages do not come from an `url`; they | ||
| 31 | // // come from a `hash`. `url` is just one of many possible mirrors for how to | ||
| 32 | // // obtain a package matching this `hash`. | ||
| 33 | // // | ||
| 34 | // // Uses the [multihash](https://multiformats.io/multihash/) format. | ||
| 35 | // .hash = "...", | ||
| 36 | // | ||
| 37 | // // When this is provided, the package is found in a directory relative to the | ||
| 38 | // // build root. In this case the package's hash is irrelevant and therefore not | ||
| 39 | // // computed. | ||
| 40 | // .path = "foo", | ||
| 41 | //}, | ||
| 42 | }, | ||
| 43 | |||
| 44 | // Specifies the set of files and directories that are included in this package. | ||
| 45 | // Only files and directories listed here are included in the `hash` that | ||
| 46 | // is computed for this package. | ||
| 47 | // Paths are relative to the build root. Use the empty string (`""`) to refer to | ||
| 48 | // the build root itself. | ||
| 49 | // A directory listed here means that all files within, recursively, are included. | ||
| 50 | .paths = .{ | ||
| 51 | // This makes *all* files, recursively, included in this package. It is generally | ||
| 52 | // better to explicitly list the files and directories instead, to insure that | ||
| 53 | // fetching from tarballs, file system paths, and version control all result | ||
| 54 | // in the same contents hash. | ||
| 55 | "", | ||
| 56 | // For example... | ||
| 57 | //"build.zig", | ||
| 58 | //"build.zig.zon", | ||
| 59 | //"src", | ||
| 60 | }, | ||
| 61 | } | ||
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| ... | @@ -2564,12 +2564,28 @@ pub const Dir = struct { | ... | @@ -2564,12 +2564,28 @@ pub const Dir = struct { |
| 2564 | }; | 2564 | }; |
| 2565 | } | 2565 | } |
| 2566 | 2566 | ||
| 2567 | /// Writes content to the file system, creating a new file if it does not exist, truncating | 2567 | pub const WriteFileError = File.WriteError || File.OpenError; |
| 2568 | /// if it already exists. | 2568 | |
| 2569 | pub fn writeFile(self: Dir, sub_path: []const u8, data: []const u8) !void { | 2569 | /// Deprecated: use `writeFile2`. |
| 2570 | var file = try self.createFile(sub_path, .{}); | 2570 | pub fn writeFile(self: Dir, sub_path: []const u8, data: []const u8) WriteFileError!void { |
| 2571 | return writeFile2(self, .{ | ||
| 2572 | .sub_path = sub_path, | ||
| 2573 | .data = data, | ||
| 2574 | .flags = .{}, | ||
| 2575 | }); | ||
| 2576 | } | ||
| 2577 | |||
| 2578 | pub const WriteFileOptions = struct { | ||
| 2579 | sub_path: []const u8, | ||
| 2580 | data: []const u8, | ||
| 2581 | flags: File.CreateFlags = .{}, | ||
| 2582 | }; | ||
| 2583 | |||
| 2584 | /// Writes content to the file system, using the file creation flags provided. | ||
| 2585 | pub fn writeFile2(self: Dir, options: WriteFileOptions) WriteFileError!void { | ||
| 2586 | var file = try self.createFile(options.sub_path, options.flags); | ||
| 2571 | defer file.close(); | 2587 | defer file.close(); |
| 2572 | try file.writeAll(data); | 2588 | try file.writeAll(options.data); |
| 2573 | } | 2589 | } |
| 2574 | 2590 | ||
| 2575 | pub const AccessError = os.AccessError; | 2591 | pub const AccessError = os.AccessError; |
src/main.zig+49-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,52 @@ pub fn cmdInit( | ... | @@ -4892,46 +4881,52 @@ 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 | "build.zig.zon", | ||
| 4887 | "src" ++ s ++ "main.zig", | ||
| 4888 | "src" ++ s ++ "root.zig", | ||
| 4897 | }; | 4889 | }; |
| 4898 | var modified_build_zig_contents = try std.ArrayList(u8).initCapacity(arena, build_zig_contents.len); | 4890 | var ok_count: usize = 0; |
| 4899 | for (build_zig_contents) |c| { | 4891 | |
| 4900 | if (c == '$') { | 4892 | for (template_paths) |template_path| { |
| 4901 | try modified_build_zig_contents.appendSlice(cwd_basename); | 4893 | if (fs.path.dirname(template_path)) |dirname| { |
| 4902 | } else { | 4894 | fs.cwd().makePath(dirname) catch |err| { |
| 4903 | try modified_build_zig_contents.append(c); | 4895 | fatal("unable to make path '{s}': {s}", .{ dirname, @errorName(err) }); |
| 4896 | }; | ||
| 4904 | } | 4897 | } |
| 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 | 4898 | ||
| 4924 | try src_dir.writeFile("main.zig", main_zig_contents); | 4899 | const contents = template_dir.readFileAlloc(arena, template_path, max_bytes) catch |err| { |
| 4925 | try fs.cwd().writeFile("build.zig", modified_build_zig_contents.items); | 4900 | fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) }); |
| 4901 | }; | ||
| 4902 | var modified_contents = try std.ArrayList(u8).initCapacity(arena, contents.len); | ||
| 4903 | for (contents) |c| { | ||
| 4904 | if (c == '$') { | ||
| 4905 | try modified_contents.appendSlice(cwd_basename); | ||
| 4906 | } else { | ||
| 4907 | try modified_contents.append(c); | ||
| 4908 | } | ||
| 4909 | } | ||
| 4926 | 4910 | ||
| 4927 | std.log.info("Created build.zig", .{}); | 4911 | if (fs.cwd().writeFile2(.{ |
| 4928 | std.log.info("Created src" ++ s ++ "main.zig", .{}); | 4912 | .sub_path = template_path, |
| 4913 | .data = modified_contents.items, | ||
| 4914 | .flags = .{ .exclusive = true }, | ||
| 4915 | })) |_| { | ||
| 4916 | std.log.info("created {s}", .{template_path}); | ||
| 4917 | ok_count += 1; | ||
| 4918 | } else |err| switch (err) { | ||
| 4919 | error.PathAlreadyExists => std.log.info("preserving already existing file: {s}", .{ | ||
| 4920 | template_path, | ||
| 4921 | }), | ||
| 4922 | else => std.log.err("unable to write {s}: {s}\n", .{ template_path, @errorName(err) }), | ||
| 4923 | } | ||
| 4924 | } | ||
| 4929 | 4925 | ||
| 4930 | switch (output_mode) { | 4926 | if (ok_count == template_paths.len) { |
| 4931 | .Lib => std.log.info("Next, try `zig build --help` or `zig build test`", .{}), | 4927 | 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 | } | 4928 | } |
| 4929 | return cleanExit(); | ||
| 4935 | } | 4930 | } |
| 4936 | 4931 | ||
| 4937 | pub const usage_build = | 4932 | pub const usage_build = |
test/tests.zig+8-30| ... | @@ -776,39 +776,17 @@ pub fn addCliTests(b: *std.Build) *Step { | ... | @@ -776,39 +776,17 @@ 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 build.zig.zon\n" ++ |
| 811 | "info: Next, try `zig build --help` or `zig build run`\n"); | 787 | "info: created src" ++ s ++ "main.zig\n" ++ |
| 788 | "info: created src" ++ s ++ "root.zig\n" ++ | ||
| 789 | "info: see `zig build --help` for a menu of options\n"); | ||
| 812 | 790 | ||
| 813 | // Test missing output path. | 791 | // Test missing output path. |
| 814 | const bad_out_arg = "-femit-bin=does" ++ s ++ "not" ++ s ++ "exist" ++ s ++ "foo.exe"; | 792 | const bad_out_arg = "-femit-bin=does" ++ s ++ "not" ++ s ++ "exist" ++ s ++ "foo.exe"; |