aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManlio Perillo <[email protected]>2023-04-16 12:23:10 +0200
committerManlio Perillo <[email protected]>2023-04-18 18:16:19 +0200
commit6b17a188936d489e2777e541c84112b2609532d5 (patch)
tree99303fde89f0b921f44705433b7fc1a39d0b6fef
parentb59bef29b9c74270539e2f775d2f0394ec435f2d (diff)
downloadziglings-6b17a188936d489e2777e541c84112b2609532d5.tar.xz
ziglings-6b17a188936d489e2777e541c84112b2609532d5.zip
Ensure the exercises use the canonical format
Add the check-exercises.py tool in the new tools directory. It is used to check that the exercises are correctly formatted, printing on stderr the invalid ones and the diff in the unified format. Update the exercises that don't use the canonical zig fmt format. Update some patches that cause the generated zig file to be incorrectly formatted.
-rw-r--r--exercises/058_quiz7.zig28
-rw-r--r--exercises/059_integers.zig6
-rw-r--r--exercises/069_comptime4.zig2
-rw-r--r--exercises/075_quiz8.zig4
-rw-r--r--exercises/083_anonymous_lists.zig4
-rw-r--r--exercises/092_interfaces.zig2
-rw-r--r--patches/patches/024_errors4.patch2
-rw-r--r--patches/patches/059_integers.patch8
-rw-r--r--patches/patches/083_anonymous_lists.patch4
-rwxr-xr-xtools/check-exercises.py97
10 files changed, 127 insertions, 30 deletions
diff --git a/exercises/058_quiz7.zig b/exercises/058_quiz7.zig
index 3069710..1ceac5a 100644
--- a/exercises/058_quiz7.zig
+++ b/exercises/058_quiz7.zig
@@ -107,7 +107,7 @@ const Path = struct {
const a_paths = [_]Path{
Path{
.from = &a, // from: Archer's Point
- .to = &b, // to: Bridge
+ .to = &b, // to: Bridge
.dist = 2,
},
};
@@ -115,12 +115,12 @@ const a_paths = [_]Path{
const b_paths = [_]Path{
Path{
.from = &b, // from: Bridge
- .to = &a, // to: Archer's Point
+ .to = &a, // to: Archer's Point
.dist = 2,
},
Path{
.from = &b, // from: Bridge
- .to = &d, // to: Dogwood Grove
+ .to = &d, // to: Dogwood Grove
.dist = 1,
},
};
@@ -128,12 +128,12 @@ const b_paths = [_]Path{
const c_paths = [_]Path{
Path{
.from = &c, // from: Cottage
- .to = &d, // to: Dogwood Grove
+ .to = &d, // to: Dogwood Grove
.dist = 3,
},
Path{
.from = &c, // from: Cottage
- .to = &e, // to: East Pond
+ .to = &e, // to: East Pond
.dist = 2,
},
};
@@ -141,17 +141,17 @@ const c_paths = [_]Path{
const d_paths = [_]Path{
Path{
.from = &d, // from: Dogwood Grove
- .to = &b, // to: Bridge
+ .to = &b, // to: Bridge
.dist = 1,
},
Path{
.from = &d, // from: Dogwood Grove
- .to = &c, // to: Cottage
+ .to = &c, // to: Cottage
.dist = 3,
},
Path{
.from = &d, // from: Dogwood Grove
- .to = &f, // to: Fox Pond
+ .to = &f, // to: Fox Pond
.dist = 7,
},
};
@@ -159,20 +159,20 @@ const d_paths = [_]Path{
const e_paths = [_]Path{
Path{
.from = &e, // from: East Pond
- .to = &c, // to: Cottage
+ .to = &c, // to: Cottage
.dist = 2,
},
Path{
.from = &e, // from: East Pond
- .to = &f, // to: Fox Pond
- .dist = 1, // (one-way down a short waterfall!)
+ .to = &f, // to: Fox Pond
+ .dist = 1, // (one-way down a short waterfall!)
},
};
const f_paths = [_]Path{
Path{
.from = &f, // from: Fox Pond
- .to = &d, // to: Dogwood Grove
+ .to = &d, // to: Dogwood Grove
.dist = 7,
},
};
@@ -355,8 +355,8 @@ pub fn main() void {
// Here's where the hermit decides where he would like to go. Once
// you get the program working, try some different Places on the
// map!
- const start = &a; // Archer's Point
- const destination = &f; // Fox Pond
+ const start = &a; // Archer's Point
+ const destination = &f; // Fox Pond
// Store each Path array as a slice in each Place. As mentioned
// above, we needed to delay making these references to avoid
diff --git a/exercises/059_integers.zig b/exercises/059_integers.zig
index 5a6295d..a497efa 100644
--- a/exercises/059_integers.zig
+++ b/exercises/059_integers.zig
@@ -18,10 +18,10 @@
const print = @import("std").debug.print;
pub fn main() void {
- var zig = [_]u8 {
- 0o131, // octal
+ var zig = [_]u8{
+ 0o131, // octal
0b1101000, // binary
- 0x66, // hex
+ 0x66, // hex
};
print("{s} is cool.\n", .{zig});
diff --git a/exercises/069_comptime4.zig b/exercises/069_comptime4.zig
index 004a42c..f4c8bbb 100644
--- a/exercises/069_comptime4.zig
+++ b/exercises/069_comptime4.zig
@@ -16,7 +16,7 @@ const print = @import("std").debug.print;
pub fn main() void {
// Here we declare arrays of three different types and sizes
// at compile time from a function call. Neat!
- const s1 = makeSequence(u8, 3); // creates a [3]u8
+ const s1 = makeSequence(u8, 3); // creates a [3]u8
const s2 = makeSequence(u32, 5); // creates a [5]u32
const s3 = makeSequence(i64, 7); // creates a [7]i64
diff --git a/exercises/075_quiz8.zig b/exercises/075_quiz8.zig
index c2dbc1a..d54864c 100644
--- a/exercises/075_quiz8.zig
+++ b/exercises/075_quiz8.zig
@@ -151,8 +151,8 @@ const HermitsNotebook = struct {
};
pub fn main() void {
- const start = &a; // Archer's Point
- const destination = &f; // Fox Pond
+ const start = &a; // Archer's Point
+ const destination = &f; // Fox Pond
// We could either have this:
//
diff --git a/exercises/083_anonymous_lists.zig b/exercises/083_anonymous_lists.zig
index 838d40e..daaeaff 100644
--- a/exercises/083_anonymous_lists.zig
+++ b/exercises/083_anonymous_lists.zig
@@ -18,8 +18,8 @@ pub fn main() void {
//
// Don't change this part:
//
- // = .{'h', 'e', 'l', 'l', 'o'};
+ // = .{ 'h', 'e', 'l', 'l', 'o' };
//
- const hello = .{'h', 'e', 'l', 'l', 'o'};
+ const hello = .{ 'h', 'e', 'l', 'l', 'o' };
print("I say {s}!\n", .{hello});
}
diff --git a/exercises/092_interfaces.zig b/exercises/092_interfaces.zig
index 43f1119..5ac5768 100644
--- a/exercises/092_interfaces.zig
+++ b/exercises/092_interfaces.zig
@@ -99,7 +99,7 @@ pub fn main() !void {
var my_insects = [_]Insect{
Insect{ .ant = Ant{ .still_alive = true } },
Insect{ .bee = Bee{ .flowers_visited = 17 } },
- Insect{ .grasshopper = Grasshopper{ .distance_hopped = 32 }, },
+ Insect{ .grasshopper = Grasshopper{ .distance_hopped = 32 } },
};
std.debug.print("Daily Insect Report:\n", .{});
diff --git a/patches/patches/024_errors4.patch b/patches/patches/024_errors4.patch
index 5996a99..48e0821 100644
--- a/patches/patches/024_errors4.patch
+++ b/patches/patches/024_errors4.patch
@@ -5,6 +5,6 @@
> if (err == MyNumberError.TooSmall) {
> return 10;
> }
->
+>
> return err;
> };
diff --git a/patches/patches/059_integers.patch b/patches/patches/059_integers.patch
index 50a89a0..7075ebe 100644
--- a/patches/patches/059_integers.patch
+++ b/patches/patches/059_integers.patch
@@ -1,8 +1,8 @@
22,24c22,24
-< 0o131, // octal
+< 0o131, // octal
< 0b1101000, // binary
-< 0x66, // hex
+< 0x66, // hex
---
-> 0o132, // octal
+> 0o132, // octal
> 0b1101001, // binary
-> 0x67, // hex
+> 0x67, // hex
diff --git a/patches/patches/083_anonymous_lists.patch b/patches/patches/083_anonymous_lists.patch
index b981909..94b594b 100644
--- a/patches/patches/083_anonymous_lists.patch
+++ b/patches/patches/083_anonymous_lists.patch
@@ -1,4 +1,4 @@
23c23
-< const hello = .{'h', 'e', 'l', 'l', 'o'};
+< const hello = .{ 'h', 'e', 'l', 'l', 'o' };
---
-> const hello: [5]u8 = .{'h', 'e', 'l', 'l', 'o'};
+> const hello: [5]u8 = .{ 'h', 'e', 'l', 'l', 'o' };
diff --git a/tools/check-exercises.py b/tools/check-exercises.py
new file mode 100755
index 0000000..fa0b5cb
--- /dev/null
+++ b/tools/check-exercises.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+
+import difflib
+import io
+import os
+import os.path
+import subprocess
+import sys
+
+
+IGNORE = subprocess.DEVNULL
+PIPE = subprocess.PIPE
+
+EXERCISES_PATH = "exercises"
+HEALED_PATH = "patches/healed"
+PATCHES_PATH = "patches/patches"
+
+
+# Heals all the exercises.
+def heal():
+ maketree(HEALED_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(HEALED_PATH, name)
+
+ patch(original_path, patch_path, output_path)
+
+
+# Yields all the healed exercises that are not correctly formatted.
+def check_healed():
+ term = subprocess.run(
+ ["zig", "fmt", "--check", HEALED_PATH], stdout=PIPE, text=True
+ )
+ if term.stdout == "" and term.returncode != 0:
+ term.check_returncode()
+
+ stream = io.StringIO(term.stdout)
+ for line in stream:
+ yield line.strip()
+
+
+def main():
+ heal()
+
+ # Show the unified diff between the original example and the correctly
+ # formatted one.
+ for i, original in enumerate(check_healed()):
+ if i > 0:
+ print()
+
+ name = os.path.basename(original)
+ print(f"checking exercise {name}...\n")
+
+ from_file = open(original)
+ to_file = zig_fmt_file(original)
+
+ diff = difflib.unified_diff(
+ from_file.readlines(), to_file.readlines(), name, name + "-fmt"
+ )
+ sys.stderr.writelines(diff)
+
+
+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
+ )
+
+
+# Formats the Zig file at path, and returns the possibly reformatted file as a
+# file object.
+def zig_fmt_file(path):
+ with open(path) as stdin:
+ term = subprocess.run(
+ ["zig", "fmt", "--stdin"], stdin=stdin, stdout=PIPE, check=True, text=True
+ )
+
+ return io.StringIO(term.stdout)
+
+
+main()