Skip to content

Commit fea7bcc

Browse files
lint: allow overlap of files.example and files.exemplar values
This commit allows the values in the `files.example` and `files.exemplar` keys in the `config.json` to overlap, whilst still disallowing the other keys' values to overlap.
1 parent 70f1252 commit fea7bcc

2 files changed

Lines changed: 36 additions & 6 deletions

File tree

src/lint/track_config.nim

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,16 @@ type
293293

294294
Concepts* = seq[Concept]
295295

296+
FilePatterns* = object
297+
solution*: seq[string]
298+
test*: seq[string]
299+
example*: seq[string]
300+
exemplar*: seq[string]
301+
editor*: seq[string]
302+
296303
TrackConfig* = object
304+
slug*: string
305+
files*: FilePatterns
297306
exercises*: Exercises
298307
concepts*: Concepts
299308

@@ -655,6 +664,32 @@ proc checkExerciseSlugsAndForegone(exercises: Exercises; b: var bool;
655664
"but there is an implemented exercise with that slug"
656665
b.setFalseAndPrint(msg, path)
657666

667+
proc checkFilePatternsOverlap(filePatterns: FilePatterns; trackSlug: string,
668+
b: var bool; path: Path) =
669+
const uniqueFilePatternCombinations = [
670+
("solution", "test"),
671+
("solution", "example"),
672+
("solution", "exemplar"),
673+
("solution", "editor"),
674+
("test", "example"),
675+
("test", "exemplar"),
676+
("test", "editor"),
677+
("editor", "example"),
678+
("editor", "exemplar"),
679+
]
680+
681+
var seenFilePatterns = initTable[string, HashSet[string]](250)
682+
for key, patterns in filePatterns.fieldPairs:
683+
seenFilePatterns[key] = patterns.toHashSet
684+
685+
for (key1, key2) in uniqueFilePatternCombinations:
686+
let duplicatePatterns = seenFilePatterns[key1] * seenFilePatterns[key2]
687+
for duplicatePattern in duplicatePatterns:
688+
let msg =
689+
&"The values in the `files.{key1}` and `files.{key2}` keys must not overlap, " &
690+
&"but the {q duplicatePattern} value appears in both"
691+
b.setFalseAndPrint(msg, path)
692+
658693
proc satisfiesSecondPass(trackConfigContents: string; path: Path): bool =
659694
## Returns `true` if `trackConfigContents` satisfies some checks.
660695
##
@@ -684,6 +719,7 @@ proc satisfiesSecondPass(trackConfigContents: string; path: Path): bool =
684719
checkExercisesPCP(conceptExercises, result, path)
685720
checkExercisesPCP(practiceExercises, result, path)
686721
checkExerciseSlugsAndForegone(exercises, result, path)
722+
checkFilePatternsOverlap(trackConfig.files, trackConfig.slug, result, path)
687723

688724
proc getExerciseSlugs(data: JsonNode; k: string): HashSet[string] =
689725
result = initHashSet[string]()

src/lint/validators.nim

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ func list(a: SomeSet[string]; prefix = ""; suffix = ""): string =
229229
result.add ", and "
230230

231231
var seenUuids = initHashSet[string](250)
232-
var seenFilePatterns = initHashSet[string](250)
233232

234233
proc isString*(data: JsonNode; key: string; path: Path; context: string;
235234
isRequired = true; allowed = emptySetOfStrings;
@@ -282,11 +281,6 @@ proc isString*(data: JsonNode; key: string; path: Path; context: string;
282281
"lowercased version 4 UUID"
283282
result.setFalseAndPrint(msg, path, annotation = errorAnnotation)
284283
elif checkIsFilesPattern:
285-
if seenFilePatterns.containsOrIncl(s):
286-
let msg =
287-
&"A {format(context, key)} value is {q s}, which is not a unique " &
288-
"`files` entry"
289-
result.setFalseAndPrint(msg, path, annotation = errorAnnotation)
290284
if isFilesPattern(s):
291285
if "%{" in s and "}" notin s:
292286
let msg =

0 commit comments

Comments
 (0)