diff options
| -rw-r--r-- | src-self-hosted/arg.zig | 2 | ||||
| -rw-r--r-- | src-self-hosted/main.zig | 44 | ||||
| -rw-r--r-- | std/io.zig | 23 | ||||
| -rw-r--r-- | std/zig/render.zig | 2 |
4 files changed, 49 insertions, 22 deletions
diff --git a/src-self-hosted/arg.zig b/src-self-hosted/arg.zig index 2ab44e5fdf..99e6ecc17a 100644 --- a/src-self-hosted/arg.zig +++ b/src-self-hosted/arg.zig @@ -149,7 +149,7 @@ pub const Args = struct { } // e.g. --help - pub fn present(self: *Args, name: []const u8) bool { + pub fn present(self: *const Args, name: []const u8) bool { return self.flags.contains(name); } diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index e127fa4119..fde9ef670b 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -514,17 +514,22 @@ const usage_fmt = \\usage: zig fmt [file]... \\ \\ Formats the input files and modifies them in-place. + \\ Arguments can be files or directories, which are searched + \\ recursively. \\ \\Options: \\ --help Print this help and exit \\ --color [auto|off|on] Enable or disable colored error messages - \\ --stdin Format code from stdin + \\ --stdin Format code from stdin; output to stdout + \\ --check List non-conforming files and exit with an error + \\ if the list is non-empty \\ \\ ; const args_fmt_spec = []Flag{ Flag.Bool("--help"), + Flag.Bool("--check"), Flag.Option("--color", []const []const u8{ "auto", "off", @@ -640,6 +645,11 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { if (tree.errors.len != 0) { os.exit(1); } + if (flags.present("check")) { + const anything_changed = try std.zig.render(allocator, io.noop_out_stream, &tree); + const code = if (anything_changed) u8(1) else u8(0); + os.exit(code); + } _ = try std.zig.render(allocator, stdout, &tree); return; @@ -711,9 +721,11 @@ async fn asyncFmtMain( .loop = loop, }; + const check_mode = flags.present("check"); + var group = event.Group(FmtError!void).init(loop); for (flags.positionals.toSliceConst()) |file_path| { - try group.call(fmtPath, &fmt, file_path); + try group.call(fmtPath, &fmt, file_path, check_mode); } try await (async group.wait() catch unreachable); if (fmt.any_error) { @@ -721,7 +733,7 @@ async fn asyncFmtMain( } } -async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8) FmtError!void { +async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void { const file_path = try std.mem.dupe(fmt.loop.allocator, u8, file_path_ref); defer fmt.loop.allocator.free(file_path); @@ -746,7 +758,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8) FmtError!void { while (try dir.next()) |entry| { if (entry.kind == std.os.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) { const full_path = try os.path.join(fmt.loop.allocator, file_path, entry.name); - try group.call(fmtPath, fmt, full_path); + try group.call(fmtPath, fmt, full_path, check_mode); } } return await (async group.wait() catch unreachable); @@ -779,14 +791,22 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8) FmtError!void { return; } - // TODO make this evented - const baf = try io.BufferedAtomicFile.create(fmt.loop.allocator, file_path); - defer baf.destroy(); - - const anything_changed = try std.zig.render(fmt.loop.allocator, baf.stream(), &tree); - if (anything_changed) { - try stderr.print("{}\n", file_path); - try baf.finish(); + if (check_mode) { + const anything_changed = try std.zig.render(fmt.loop.allocator, io.noop_out_stream, &tree); + if (anything_changed) { + try stderr.print("{}\n", file_path); + fmt.any_error = true; + } + } else { + // TODO make this evented + const baf = try io.BufferedAtomicFile.create(fmt.loop.allocator, file_path); + defer baf.destroy(); + + const anything_changed = try std.zig.render(fmt.loop.allocator, baf.stream(), &tree); + if (anything_changed) { + try stderr.print("{}\n", file_path); + try baf.finish(); + } } } diff --git a/std/io.zig b/std/io.zig index cd32192ba2..72b61799e2 100644 --- a/std/io.zig +++ b/std/io.zig @@ -203,20 +203,20 @@ pub fn OutStream(comptime WriteError: type) type { writeFn: fn (self: *Self, bytes: []const u8) Error!void, - pub fn print(self: *Self, comptime format: []const u8, args: ...) !void { + pub fn print(self: *Self, comptime format: []const u8, args: ...) Error!void { return std.fmt.format(self, Error, self.writeFn, format, args); } - pub fn write(self: *Self, bytes: []const u8) !void { + pub fn write(self: *Self, bytes: []const u8) Error!void { return self.writeFn(self, bytes); } - pub fn writeByte(self: *Self, byte: u8) !void { + pub fn writeByte(self: *Self, byte: u8) Error!void { const slice = (*[1]u8)(&byte)[0..]; return self.writeFn(self, slice); } - pub fn writeByteNTimes(self: *Self, byte: u8, n: usize) !void { + pub fn writeByteNTimes(self: *Self, byte: u8, n: usize) Error!void { const slice = (*[1]u8)(&byte)[0..]; var i: usize = 0; while (i < n) : (i += 1) { @@ -225,23 +225,23 @@ pub fn OutStream(comptime WriteError: type) type { } /// Write a native-endian integer. - pub fn writeIntNe(self: *Self, comptime T: type, value: T) !void { + pub fn writeIntNe(self: *Self, comptime T: type, value: T) Error!void { return self.writeInt(builtin.endian, T, value); } - pub fn writeIntLe(self: *Self, comptime T: type, value: T) !void { + pub fn writeIntLe(self: *Self, comptime T: type, value: T) Error!void { var bytes: [@sizeOf(T)]u8 = undefined; mem.writeIntLE(T, &bytes, value); return self.writeFn(self, bytes); } - pub fn writeIntBe(self: *Self, comptime T: type, value: T) !void { + pub fn writeIntBe(self: *Self, comptime T: type, value: T) Error!void { var bytes: [@sizeOf(T)]u8 = undefined; mem.writeIntBE(T, &bytes, value); return self.writeFn(self, bytes); } - pub fn writeInt(self: *Self, endian: builtin.Endian, comptime T: type, value: T) !void { + pub fn writeInt(self: *Self, endian: builtin.Endian, comptime T: type, value: T) Error!void { var bytes: [@sizeOf(T)]u8 = undefined; mem.writeInt(bytes[0..], value, endian); return self.writeFn(self, bytes); @@ -249,6 +249,13 @@ pub fn OutStream(comptime WriteError: type) type { }; } +pub const noop_out_stream = &noop_out_stream_state; +const NoopOutStreamError = error{}; +var noop_out_stream_state = OutStream(NoopOutStreamError){ + .writeFn = noop_out_stream_write, +}; +fn noop_out_stream_write(self: *OutStream(NoopOutStreamError), bytes: []const u8) error{}!void {} + pub fn writeFile(path: []const u8, data: []const u8) !void { var file = try File.openWrite(path); defer file.close(); diff --git a/std/zig/render.zig b/std/zig/render.zig index 657efb32e7..832cb7fe86 100644 --- a/std/zig/render.zig +++ b/std/zig/render.zig @@ -133,7 +133,7 @@ fn renderRoot( } } -fn renderExtraNewline(tree: *ast.Tree, stream: var, start_col: *usize, node: *ast.Node) !void { +fn renderExtraNewline(tree: *ast.Tree, stream: var, start_col: *usize, node: *ast.Node) @typeOf(stream).Child.Error!void { const first_token = node.firstToken(); var prev_token = first_token; while (tree.tokens.at(prev_token - 1).id == Token.Id.DocComment) { |
