replaced update-patches.py with update-patches.zig

This commit is contained in:
Chris Boesch 2023-04-25 21:35:18 +02:00
parent cffbbff8bd
commit 213d0712a5
2 changed files with 90 additions and 68 deletions

View file

@ -1,68 +0,0 @@
#!/usr/bin/env python
import os
import os.path
import subprocess
IGNORE = subprocess.DEVNULL
EXERCISES_PATH = "exercises"
ANSWERS_PATH = "answers"
PATCHES_PATH = "patches/patches"
# Heals all the exercises.
def heal():
maketree(ANSWERS_PATH)
with os.scandir(EXERCISES_PATH) as it:
for entry in it:
name = entry.name
original_path = entry.path
patch_path = os.path.join(PATCHES_PATH, patch_name(name))
output_path = os.path.join(ANSWERS_PATH, name)
patch(original_path, patch_path, output_path)
def main():
heal()
with os.scandir(EXERCISES_PATH) as it:
for entry in it:
name = entry.name
broken_path = entry.path
healed_path = os.path.join(ANSWERS_PATH, name)
patch_path = os.path.join(PATCHES_PATH, patch_name(name))
with open(patch_path, "w") as file:
term = subprocess.run(
["diff", broken_path, healed_path],
stdout=file,
text=True,
)
assert term.returncode == 1
def maketree(path):
return os.makedirs(path, exist_ok=True)
# Returns path with the patch extension.
def patch_name(path):
name, _ = os.path.splitext(path)
return name + ".patch"
# Applies patch to original, and write the file to output.
def patch(original, patch, output):
subprocess.run(
["patch", "-i", patch, "-o", output, original], stdout=IGNORE, check=True
)
main()

90
tools/update-patches.zig Normal file
View file

@ -0,0 +1,90 @@
const std = @import("std");
const print = std.debug.print;
const string = []const u8;
const cwd = std.fs.cwd();
const Dir = std.fs.Dir;
const Allocator = std.mem.Allocator;
const EXERCISES_PATH = "exercises";
const ANSWERS_PATH = "answers";
const PATCHES_PATH = "patches/patches";
// Heals all the exercises.
fn heal(alloc: Allocator) !void {
try cwd.makePath(ANSWERS_PATH);
const org_path = try cwd.realpathAlloc(alloc, EXERCISES_PATH);
const patch_path = try cwd.realpathAlloc(alloc, PATCHES_PATH);
const healed_path = try cwd.realpathAlloc(alloc, ANSWERS_PATH);
var idir = try cwd.openIterableDir(EXERCISES_PATH, Dir.OpenDirOptions{});
defer idir.close();
var it = idir.iterate();
while (try it.next()) |entry| {
// create filenames
const healed_file = try concat(alloc, &.{ healed_path, "/", entry.name });
const patch_file = try concat(alloc, &.{ patch_path, "/", try patch_name(alloc, entry.name) });
// patch the file
const result = try std.ChildProcess.exec(.{
.allocator = alloc,
.argv = &.{ "patch", "-i", patch_file, "-o", healed_file, entry.name },
.cwd = org_path,
});
print("{s}", .{result.stderr});
}
}
// Creates new patch files for every exercise
fn update(alloc: Allocator) !void {
const org_path = try cwd.realpathAlloc(alloc, EXERCISES_PATH);
const healed_path = try cwd.realpathAlloc(alloc, ANSWERS_PATH);
const patch_path = try cwd.realpathAlloc(alloc, PATCHES_PATH);
var idir = try cwd.openIterableDir(EXERCISES_PATH, Dir.OpenDirOptions{});
defer idir.close();
var it = idir.iterate();
while (try it.next()) |entry| {
// create diff
const org_file = try concat(alloc, &.{ org_path, "/", entry.name });
const healed_file = try concat(alloc, &.{ healed_path, "/", entry.name });
const result = try std.ChildProcess.exec(.{
.allocator = alloc,
.argv = &.{ "diff", org_file, healed_file },
});
std.debug.assert(result.term.Exited == 1);
// write diff to file
const patch_file = try concat(alloc, &.{ patch_path, "/", try patch_name(alloc, entry.name) });
var file = try std.fs.cwd().createFile(patch_file, .{ .read = false });
defer file.close();
try file.writer().print("{s}", .{result.stdout});
}
}
fn concat(alloc: Allocator, slices: []const string) !string {
const buf = try std.mem.concat(alloc, u8, slices);
return buf;
}
fn patch_name(alloc: Allocator, path: string) !string {
var filename = path;
const index = std.mem.lastIndexOfScalar(u8, path, '.') orelse return path;
if (index > 0) filename = path[0..index];
return try concat(alloc, &.{ filename, ".patch" });
}
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const alloc = arena.allocator();
try heal(alloc);
try update(alloc);
}