From 3f4193ffa171f0da3246b1ae8a84682709de9e15 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Fri, 17 Jun 2022 12:12:14 +0200 Subject: [PATCH] sync(tests): improve error for invalid TOML (#614) A manually edited `tests.toml` file might contain invalid TOML. For example: [2ee1d9af-1c43-416c-b41b-cefd7d4d2b2a] description = encode yes where `encode yes` is invalid [1] because it is unquoted. Before this commit, `configlet sync` would not handle the TOML parsing exception: $ cd /tmp $ git clone --quiet https://github.com/exercism/common-lisp $ cd common-lisp $ git checkout f521b1fb0f04ffc2d5baa6cf0bba37c231cc1bd7 $ bin/fetch-configlet $ bin/configlet sync --tests Updating cached 'problem-specifications' data... Checking exercises... parsetoml.nim(908) parseValue Error: unhandled exception: /tmp/common-lisp/exercises/practice/affine-cipher/.meta/tests.toml(6:16) unexpected character "e" [TomlError] With this commit, configlet still exits immediately, but handles the exception: $ configlet sync --tests Updating cached 'problem-specifications' data... Checking exercises... Error: A 'tests.toml' file contains invalid TOML: /tmp/common-lisp/exercises/practice/affine-cipher/.meta/tests.toml(6:16) unexpected character "e" The expected 'tests.toml' format is documented in https://exercism.org/docs/building/configlet/sync#h-tests Note that `configlet lint` does not yet lint `tests.toml` files, and so invalid TOML does not yet cause `configlet lint` to indicate an error. [1] https://toml.io/en/v1.0.0#string Fixes: #613 --- src/sync/tracks.nim | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/sync/tracks.nim b/src/sync/tracks.nim index b5b288f5..cd8f49a4 100644 --- a/src/sync/tracks.nim +++ b/src/sync/tracks.nim @@ -1,4 +1,4 @@ -import std/[algorithm, json, os, sets] +import std/[algorithm, json, os, sets, strformat, strutils] import pkg/parsetoml import ".."/cli @@ -65,7 +65,21 @@ proc init(T: typedesc[PracticeExerciseTests], testsPath: string): T = ## included and excluded test case UUIDs. result = PracticeExerciseTests.init() if fileExists(testsPath): - let tests = parsetoml.parseFile(testsPath) + let tests = + try: + parsetoml.parseFile(testsPath) + except TomlError: # Note that `TomlError` inherits from `Defect`. + stderr.writeLine fmt""" + + Error: A 'tests.toml' file contains invalid TOML: + {getCurrentExceptionMsg()} + + The expected 'tests.toml' format is documented in + https://exercism.org/docs/building/configlet/sync#h-tests""".unindent() + quit 1 + except CatchableError: + stderr.writeLine "Error: " & getCurrentExceptionMsg() + quit 1 for uuid, val in tests.getTable(): if val.hasKey("include"):