| ... | ... | @@ -544,31 +544,15 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi |
| 544 | 544 | const file_name = stripComponents(file.name, options.strip_components); |
| 545 | 545 | if (file_name.len == 0) return error.BadFileName; |
| 546 | 546 | |
| 547 | | const fs_file = dir.createFile(file_name, .{ .exclusive = true }) catch |err| switch (err) { |
| 548 | | error.FileNotFound => again: { |
| 549 | | const code = code: { |
| 550 | | if (std.fs.path.dirname(file_name)) |dir_name| { |
| 551 | | dir.makePath(dir_name) catch |code| break :code code; |
| 552 | | break :again dir.createFile(file_name, .{ .exclusive = true }) catch |code| { |
| 553 | | break :code code; |
| 554 | | }; |
| 555 | | } |
| 556 | | break :code err; |
| 557 | | }; |
| 558 | | const d = options.diagnostics orelse return error.UnableToCreateFile; |
| 559 | | try d.errors.append(d.allocator, .{ .unable_to_create_file = .{ |
| 560 | | .code = code, |
| 561 | | .file_name = try d.allocator.dupe(u8, file_name), |
| 562 | | } }); |
| 563 | | break :again null; |
| 564 | | }, |
| 565 | | else => |e| return e, |
| 566 | | }; |
| 567 | | defer if (fs_file) |f| f.close(); |
| 568 | | |
| 569 | | if (fs_file) |f| { |
| 570 | | try file.write(f); |
| 571 | | } else { |
| 547 | if (createDirAndFile(dir, file_name)) |fs_file| { |
| 548 | defer fs_file.close(); |
| 549 | try file.write(fs_file); |
| 550 | } else |err| { |
| 551 | const d = options.diagnostics orelse return err; |
| 552 | try d.errors.append(d.allocator, .{ .unable_to_create_file = .{ |
| 553 | .code = err, |
| 554 | .file_name = try d.allocator.dupe(u8, file_name), |
| 555 | } }); |
| 572 | 556 | try file.skip(); |
| 573 | 557 | } |
| 574 | 558 | }, |
| ... | ... | @@ -579,21 +563,10 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi |
| 579 | 563 | // The data inside the symbolic link. |
| 580 | 564 | const link_name = file.link_name; |
| 581 | 565 | |
| 582 | | dir.symLink(link_name, file_name, .{}) catch |err| again: { |
| 583 | | const code = code: { |
| 584 | | if (err == error.FileNotFound) { |
| 585 | | if (std.fs.path.dirname(file_name)) |dir_name| { |
| 586 | | dir.makePath(dir_name) catch |code| break :code code; |
| 587 | | break :again dir.symLink(link_name, file_name, .{}) catch |code| { |
| 588 | | break :code code; |
| 589 | | }; |
| 590 | | } |
| 591 | | } |
| 592 | | break :code err; |
| 593 | | }; |
| 594 | | const d = options.diagnostics orelse return error.UnableToCreateSymLink; |
| 566 | createDirAndSymlink(dir, link_name, file_name) catch |err| { |
| 567 | const d = options.diagnostics orelse return err; |
| 595 | 568 | try d.errors.append(d.allocator, .{ .unable_to_create_sym_link = .{ |
| 596 | | .code = code, |
| 569 | .code = err, |
| 597 | 570 | .file_name = try d.allocator.dupe(u8, file_name), |
| 598 | 571 | .link_name = try d.allocator.dupe(u8, link_name), |
| 599 | 572 | } }); |
| ... | ... | @@ -604,6 +577,30 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi |
| 604 | 577 | } |
| 605 | 578 | } |
| 606 | 579 | |
| 580 | fn createDirAndFile(dir: std.fs.Dir, file_name: []const u8) !std.fs.File { |
| 581 | const fs_file = dir.createFile(file_name, .{ .exclusive = true }) catch |err| { |
| 582 | if (err == error.FileNotFound) { |
| 583 | if (std.fs.path.dirname(file_name)) |dir_name| { |
| 584 | try dir.makePath(dir_name); |
| 585 | return try dir.createFile(file_name, .{ .exclusive = true }); |
| 586 | } |
| 587 | } |
| 588 | return err; |
| 589 | }; |
| 590 | return fs_file; |
| 591 | } |
| 592 | |
| 593 | fn createDirAndSymlink(dir: std.fs.Dir, link_name: []const u8, file_name: []const u8) !void { |
| 594 | dir.symLink(link_name, file_name, .{}) catch |err| { |
| 595 | if (err == error.FileNotFound) { |
| 596 | if (std.fs.path.dirname(file_name)) |dir_name| { |
| 597 | try dir.makePath(dir_name); |
| 598 | try dir.symLink(link_name, file_name, .{}); |
| 599 | } |
| 600 | } |
| 601 | }; |
| 602 | } |
| 603 | |
| 607 | 604 | fn stripComponents(path: []const u8, count: u32) []const u8 { |
| 608 | 605 | var i: usize = 0; |
| 609 | 606 | var c = count; |