Skip to content

Commit 59e2898

Browse files
committed
build: restore the exercise chain
The new parallel build support in Zig broke the exercise chain, so that each esercise check is no longer strictly serialized. 1. Add the Dexno option, in order to isolate the chain starting from a named exercise from the normal chain, thus simplify the code. The current code have an additional issue: it added 4 x n steps, making reading the help message or the list of steps very hard. Add only the `install`, `uninstall`, `zigling`, `test` and `start` steps. The last three steps match the old steps `n`, `n_test` and `n_start`. The default step is zigling (note the singular form). The `install` step override the builtin install step, showing a custom description and matches the old `n_install` step. The uninstall step was added for consistency, so that the description is consistent. Setup a new chain starting at `zig build -Dexno=n start` so that it is stricly serialized. The behavior should be the same as the old one. 2. Handle the code for all the exercises separately. Add only the `ziglings step`, making it the default step, in addition to the install and uninstall steps. Setup a new chain starting at the first exercise, to that it is strictly serialized. The behavior should be the same as the old one. The current code has a know issue: the messages from the ZiglingStep and the ones from the compiler compilation progress are interleaved, but each message is written atomically, due to the use of `std.debug.getStderrMutex()`. Update the README.md file. Closes ratfactor#202
1 parent 75a1600 commit 59e2898

File tree

2 files changed

+67
-32
lines changed

2 files changed

+67
-32
lines changed

README.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,11 @@ $ git clone https://github.com/ratfactor/ziglings
5050
$ cd ziglings
5151
```
5252

53-
Then run `zig build 1` and follow the instructions to begin!
53+
Then run `zig build` and follow the instructions to begin!
5454

5555
```bash
56-
$ zig build 1
56+
$ zig build
5757
```
58-
## :warning: Attention
59-
Due to Zig's new build system, exercises can currently only be run manually with their number!
60-
61-
```bash
62-
$ zig build xy
63-
```
64-
We hope to be able to offer this again soon in the automatic way.
6558

6659
## A Note About Versions
6760

build.zig

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ const Exercise = struct {
5151
while (self.main_file[start_index] == '0') start_index += 1;
5252
return self.main_file[start_index..end_index.?];
5353
}
54+
55+
/// Returns the exercise key as an integer.
56+
pub fn number(self: Exercise) usize {
57+
return std.fmt.parseInt(usize, self.key(), 10) catch unreachable;
58+
}
5459
};
5560

5661
const exercises = [_]Exercise{
@@ -534,17 +539,21 @@ pub fn build(b: *Build) !void {
534539
\\
535540
;
536541

537-
const header_step = PrintStep.create(b, logo, std.io.getStdErr());
542+
const use_healed = b.option(bool, "healed", "Run exercises from patches/healed") orelse false;
543+
const exno: ?usize = b.option(usize, "n", "Select exercise");
538544

539-
const verify_all = b.step("ziglings", "Check all ziglings");
540-
verify_all.dependOn(&header_step.step);
541-
b.default_step = verify_all;
545+
const header_step = PrintStep.create(b, logo, std.io.getStdErr());
542546

543-
var prev_chain_verify = verify_all;
547+
if (exno) |i| {
548+
const ex = blk: {
549+
for (exercises) |ex| {
550+
if (ex.number() == i) break :blk ex;
551+
}
544552

545-
const use_healed = b.option(bool, "healed", "Run exercises from patches/healed") orelse false;
553+
print("unknown exercise number: {}\n", .{i});
554+
std.os.exit(1);
555+
};
546556

547-
for (exercises) |ex| {
548557
const base_name = ex.baseName();
549558
const file_path = std.fs.path.join(b.allocator, &[_][]const u8{
550559
if (use_healed) "patches/healed" else "exercises", ex.main_file,
@@ -553,31 +562,64 @@ pub fn build(b: *Build) !void {
553562
const build_step = b.addExecutable(.{ .name = base_name, .root_source_file = .{ .path = file_path } });
554563
build_step.install();
555564

565+
const run_step = build_step.run();
566+
567+
const test_step = b.step("test", b.fmt("Run {s} without checking output", .{ex.main_file}));
568+
test_step.dependOn(&run_step.step);
569+
570+
const install_step = b.step("install", b.fmt("Install {s} to prefix path", .{ex.main_file}));
571+
install_step.dependOn(b.getInstallStep());
572+
573+
const uninstall_step = b.step("uninstall", b.fmt("Uninstall {s} from prefix path", .{ex.main_file}));
574+
uninstall_step.dependOn(b.getUninstallStep());
575+
556576
const verify_step = ZiglingStep.create(b, ex, use_healed);
557577

558-
const key = ex.key();
578+
const zigling_step = b.step("zigling", b.fmt("Check the solution of {s}", .{ex.main_file}));
579+
zigling_step.dependOn(&verify_step.step);
580+
b.default_step = zigling_step;
559581

560-
const named_test = b.step(b.fmt("{s}_test", .{key}), b.fmt("Run {s} without checking output", .{ex.main_file}));
561-
const run_step = build_step.run();
562-
named_test.dependOn(&run_step.step);
582+
const start_step = b.step("start", b.fmt("Check all solutions starting at {s}", .{ex.main_file}));
563583

564-
const named_install = b.step(b.fmt("{s}_install", .{key}), b.fmt("Copy {s} to prefix path", .{ex.main_file}));
565-
named_install.dependOn(&build_step.install_step.?.step);
584+
var prev_step = verify_step;
585+
for (exercises) |exn| {
586+
const n = exn.number();
587+
if (n > i) {
588+
const verify_stepn = ZiglingStep.create(b, exn, use_healed);
589+
verify_stepn.step.dependOn(&prev_step.step);
566590

567-
const named_verify = b.step(key, b.fmt("Check {s} only", .{ex.main_file}));
568-
named_verify.dependOn(&verify_step.step);
591+
prev_step = verify_stepn;
592+
}
593+
}
594+
start_step.dependOn(&prev_step.step);
595+
596+
return;
597+
}
598+
599+
const ziglings_step = b.step("ziglings", "Check all ziglings");
600+
ziglings_step.dependOn(&header_step.step);
601+
b.default_step = ziglings_step;
602+
603+
var prev_step: *Step = undefined;
604+
for (exercises, 0..) |ex, i| {
605+
const base_name = ex.baseName();
606+
const file_path = std.fs.path.join(b.allocator, &[_][]const u8{
607+
if (use_healed) "patches/healed" else "exercises", ex.main_file,
608+
}) catch unreachable;
569609

570-
const chain_verify = b.allocator.create(Step) catch unreachable;
571-
chain_verify.* = Step.init(Step.Options{ .id = .custom, .name = b.fmt("chain {s}", .{key}), .owner = b });
572-
chain_verify.dependOn(&verify_step.step);
610+
const build_step = b.addExecutable(.{ .name = base_name, .root_source_file = .{ .path = file_path } });
611+
build_step.install();
573612

574-
const named_chain = b.step(b.fmt("{s}_start", .{key}), b.fmt("Check all solutions starting at {s}", .{ex.main_file}));
575-
named_chain.dependOn(&header_step.step);
576-
named_chain.dependOn(chain_verify);
613+
const verify_stepn = ZiglingStep.create(b, ex, use_healed);
614+
if (i == 0) {
615+
prev_step = &verify_stepn.step;
616+
} else {
617+
verify_stepn.step.dependOn(prev_step);
577618

578-
prev_chain_verify.dependOn(chain_verify);
579-
prev_chain_verify = chain_verify;
619+
prev_step = &verify_stepn.step;
620+
}
580621
}
622+
ziglings_step.dependOn(prev_step);
581623
}
582624

583625
var use_color_escapes = false;

0 commit comments

Comments
 (0)