feature. See also
. The project being documented here (as the example) is the Zig library itself.
WriteFile.operate
fn operate(
maker: *Maker,
step_index: Configuration.Step.Index,
open_dir_cache: []const Io.Dir,
root_path: std.Build.Cache.Path,
progress_node: std.Progress.Node,
) !void
File
Code
fn operate(
maker: *Maker,
step_index: Configuration.Step.Index,
open_dir_cache: []const Io.Dir,
root_path: std.Build.Cache.Path,
progress_node: std.Progress.Node,
) !void {
const graph = maker.graph;
const gpa = maker.gpa;
const arena = maker.graph.arena;
const io = graph.io;
const step = maker.stepByIndex(step_index);
const conf = &maker.scanned_config.configuration;
const conf_step = step_index.ptr(conf);
const conf_wf = conf_step.extended.get(conf.extra).write_file;
const root_directory: std.Build.Cache.Directory = .{
.handle = root_path.root_dir.handle.createDirPathOpen(io, root_path.sub_path, .{}) catch |err|
return step.fail(maker, "failed creating path {f}: {t}", .{ root_path, err }),
.path = try root_path.toString(arena),
};
defer root_directory.handle.close(io);
for (conf_wf.embeds.slice) |*embed| {
const dest_path: Path = .{
.root_dir = root_directory,
.sub_path = embed.sub_path.slice(conf),
};
if (Io.Dir.path.dirname(dest_path.sub_path)) |dirname| {
const dirname_path: Path = .{
.root_dir = root_directory,
.sub_path = dirname,
};
dirname_path.root_dir.handle.createDirPath(io, dirname_path.sub_path) catch |err|
return step.fail(maker, "failed creating path {f}: {t}", .{ dirname_path, err });
}
dest_path.root_dir.handle.writeFile(io, .{
.sub_path = dest_path.sub_path,
.data = embed.contents.slice(conf),
}) catch |err| return step.fail(maker, "failed writing contents to file {f}: {t}", .{ dest_path, err });
progress_node.completeOne();
}
for (conf_wf.copies.slice) |*copy| {
const dest_path: Path = .{
.root_dir = root_directory,
.sub_path = copy.sub_path.slice(conf),
};
// more common case where the directory does not exist.
if (Io.Dir.path.dirname(dest_path.sub_path)) |dirname| {
const dirname_path: Path = .{
.root_dir = root_directory,
.sub_path = dirname,
};
dirname_path.root_dir.handle.createDirPath(io, dirname_path.sub_path) catch |err|
return step.fail(maker, "failed creating path {f}: {t}", .{ dirname_path, err });
}
const source_path = try maker.resolveLazyPathIndex(arena, copy.src_file, step_index);
Io.Dir.copyFile(
source_path.root_dir.handle,
source_path.sub_path,
dest_path.root_dir.handle,
dest_path.sub_path,
io,
.{},
) catch |err| return step.fail(maker, "failed copying file from {f} to {f}: {t}", .{
source_path, dest_path, err,
});
progress_node.completeOne();
}
for (conf_wf.directories.slice, open_dir_cache) |conf_dir, already_open_dir| {
const exclude_extensions = conf_dir.exclude_extensions.slice(conf) orelse &.{};
const include_extensions = conf_dir.include_extensions.slice(conf);
const src_dir_path = try maker.resolveLazyPathIndex(arena, conf_dir.src_path, step_index);
const dest_dir_path: Path = .{
.root_dir = root_directory,
.sub_path = conf_dir.sub_path.slice(conf),
};
if (dest_dir_path.sub_path.len != 0) {
dest_dir_path.root_dir.handle.createDirPath(io, dest_dir_path.sub_path) catch |err|
return step.fail(maker, "failed creating path {f}: {t}", .{ dest_dir_path, err });
}
var it = try already_open_dir.walk(gpa);
defer it.deinit();
while (it.next(io) catch |err| switch (err) {
error.Canceled, error.OutOfMemory => |e| return e,
else => |e| return step.fail(maker, "failed iterating dir {f}: {t}", .{ src_dir_path, e }),
}) |entry| {
if (!pathIncluded(conf, exclude_extensions, include_extensions, entry.path)) continue;
const src_entry_path = try src_dir_path.join(arena, entry.path);
const dest_path = try dest_dir_path.join(arena, entry.path);
switch (entry.kind) {
.directory => dest_path.root_dir.handle.createDirPath(io, dest_path.sub_path) catch |err| {
return step.fail(maker, "failed creating path {f}: {t}", .{ dest_path, err });
},
.file => {
Io.Dir.copyFile(
src_entry_path.root_dir.handle,
src_entry_path.sub_path,
dest_path.root_dir.handle,
dest_path.sub_path,
io,
.{ .make_path = true },
) catch |err| return step.fail(maker, "failed copying file from {f} to {f}: {t}", .{
src_entry_path, dest_path, err,
});
progress_node.completeOne();
},
else => continue,
}
}
}
}