| ... | ... | @@ -670,11 +670,12 @@ const FmtError = error{ |
| 670 | 670 | ReadOnlyFileSystem, |
| 671 | 671 | LinkQuotaExceeded, |
| 672 | 672 | FileBusy, |
| 673 | EndOfStream, |
| 673 | 674 | } || fs.File.OpenError; |
| 674 | 675 | |
| 675 | 676 | fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { |
| 676 | 677 | // get the real path here to avoid Windows failing on relative file paths with . or .. in them |
| 677 | | var real_path = fs.realpathAlloc(fmt.gpa, file_path) catch |err| { |
| 678 | const real_path = fs.realpathAlloc(fmt.gpa, file_path) catch |err| { |
| 678 | 679 | std.debug.warn("unable to open '{}': {}\n", .{ file_path, err }); |
| 679 | 680 | fmt.any_error = true; |
| 680 | 681 | return; |
| ... | ... | @@ -684,47 +685,65 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { |
| 684 | 685 | if (fmt.seen.exists(real_path)) return; |
| 685 | 686 | try fmt.seen.put(real_path); |
| 686 | 687 | |
| 687 | | const source_file = fs.cwd().openFile(real_path, .{}) catch |err| { |
| 688 | | std.debug.warn("unable to open '{}': {}\n", .{ file_path, err }); |
| 689 | | fmt.any_error = true; |
| 690 | | return; |
| 688 | fmtPathFile(fmt, file_path, check_mode, real_path) catch |err| switch (err) { |
| 689 | error.IsDir, error.AccessDenied => return fmtPathDir(fmt, file_path, check_mode, real_path), |
| 690 | else => { |
| 691 | std.debug.warn("unable to format '{}': {}\n", .{ file_path, err }); |
| 692 | fmt.any_error = true; |
| 693 | return; |
| 694 | }, |
| 691 | 695 | }; |
| 692 | | defer source_file.close(); |
| 696 | } |
| 693 | 697 | |
| 694 | | const stat = source_file.stat() catch |err| { |
| 695 | | std.debug.warn("unable to stat '{}': {}\n", .{ file_path, err }); |
| 696 | | fmt.any_error = true; |
| 697 | | return; |
| 698 | | }; |
| 698 | fn fmtPathDir(fmt: *Fmt, file_path: []const u8, check_mode: bool, parent_real_path: []const u8) FmtError!void { |
| 699 | var dir = try fs.cwd().openDir(parent_real_path, .{ .iterate = true }); |
| 700 | defer dir.close(); |
| 701 | |
| 702 | var dir_it = dir.iterate(); |
| 703 | while (try dir_it.next()) |entry| { |
| 704 | const is_dir = entry.kind == .Directory; |
| 705 | if (is_dir or mem.endsWith(u8, entry.name, ".zig")) { |
| 706 | const full_path = try fs.path.join(fmt.gpa, &[_][]const u8{ file_path, entry.name }); |
| 707 | const sub_real_path = fs.realpathAlloc(fmt.gpa, full_path) catch |err| { |
| 708 | std.debug.warn("unable to open '{}': {}\n", .{ file_path, err }); |
| 709 | fmt.any_error = true; |
| 710 | return; |
| 711 | }; |
| 712 | defer fmt.gpa.free(sub_real_path); |
| 713 | |
| 714 | if (fmt.seen.exists(sub_real_path)) return; |
| 715 | try fmt.seen.put(sub_real_path); |
| 716 | |
| 717 | if (is_dir) { |
| 718 | try fmtPathDir(fmt, full_path, check_mode, sub_real_path); |
| 719 | } else { |
| 720 | fmtPathFile(fmt, full_path, check_mode, sub_real_path) catch |err| { |
| 721 | std.debug.warn("unable to format '{}': {}\n", .{ full_path, err }); |
| 722 | fmt.any_error = true; |
| 723 | return; |
| 724 | }; |
| 725 | } |
| 726 | } |
| 727 | } |
| 728 | } |
| 699 | 729 | |
| 700 | | const source_code = source_file.readAllAlloc(fmt.gpa, stat.size, max_src_size) catch |err| switch (err) { |
| 701 | | error.IsDir => { |
| 702 | | var dir = try fs.cwd().openDir(file_path, .{ .iterate = true }); |
| 703 | | defer dir.close(); |
| 730 | fn fmtPathFile(fmt: *Fmt, file_path: []const u8, check_mode: bool, real_path: []const u8) FmtError!void { |
| 731 | const source_file = try fs.cwd().openFile(real_path, .{}); |
| 732 | defer source_file.close(); |
| 704 | 733 | |
| 705 | | var dir_it = dir.iterate(); |
| 734 | const stat = try source_file.stat(); |
| 706 | 735 | |
| 707 | | while (try dir_it.next()) |entry| { |
| 708 | | if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) { |
| 709 | | const full_path = try fs.path.join(fmt.gpa, &[_][]const u8{ file_path, entry.name }); |
| 710 | | try fmtPath(fmt, full_path, check_mode); |
| 711 | | } |
| 712 | | } |
| 713 | | return; |
| 714 | | }, |
| 715 | | else => { |
| 716 | | std.debug.warn("unable to read '{}': {}\n", .{ file_path, err }); |
| 717 | | fmt.any_error = true; |
| 718 | | return; |
| 719 | | }, |
| 736 | if (stat.kind == .Directory) |
| 737 | return error.IsDir; |
| 738 | |
| 739 | const source_code = source_file.readAllAlloc(fmt.gpa, stat.size, max_src_size) catch |err| switch (err) { |
| 740 | error.ConnectionResetByPeer => unreachable, |
| 741 | error.ConnectionTimedOut => unreachable, |
| 742 | else => |e| return e, |
| 720 | 743 | }; |
| 721 | 744 | defer fmt.gpa.free(source_code); |
| 722 | 745 | |
| 723 | | const tree = std.zig.parse(fmt.gpa, source_code) catch |err| { |
| 724 | | std.debug.warn("error parsing file '{}': {}\n", .{ file_path, err }); |
| 725 | | fmt.any_error = true; |
| 726 | | return; |
| 727 | | }; |
| 746 | const tree = try std.zig.parse(fmt.gpa, source_code); |
| 728 | 747 | defer tree.deinit(); |
| 729 | 748 | |
| 730 | 749 | for (tree.errors) |parse_error| { |