diff --git a/README.md b/README.md index 121fa261..7e19daac 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Options for uuid: Global options: -h, --help Show this help message and exit --version Show this tool's version information and exit + -t, --track-dir Specify a track directory to use instead of the current directory -v, --verbosity The verbosity of output. Allowed values: q[uiet], n[ormal], d[etailed] ``` diff --git a/src/cli.nim b/src/cli.nim index ea3acb27..e9819fc0 100644 --- a/src/cli.nim +++ b/src/cli.nim @@ -35,11 +35,13 @@ type Conf* = object action*: Action + trackDir*: string verbosity*: Verbosity Opt = enum optHelp = "help" optVersion = "version" + optTrackDir = "trackDir" optVerbosity = "verbosity" optSyncExercise = "exercise" optSyncCheck = "check" @@ -110,6 +112,7 @@ func genHelpText: string = for opt in Opt: let paramName = case opt + of optTrackDir: "dir" of optVerbosity: "verbosity" of optSyncExercise: "slug" of optSyncMode: "mode" @@ -127,6 +130,7 @@ func genHelpText: string = const descriptions: array[Opt, string] = [ optHelp: "Show this help message and exit", optVersion: "Show this tool's version information and exit", + optTrackDir: "Specify a track directory to use instead of the current directory", optVerbosity: &"The verbosity of output. {allowedValues(Verbosity)}", optSyncExercise: "Only sync this exercise", optSyncCheck: "Terminates with a non-zero exit code if one or more tests " & @@ -213,9 +217,11 @@ func initAction*(actionKind: ActionKind, probSpecsDir = ""): Action = of actUuid: Action(kind: actionKind, num: 1) -func initConf*(action = initAction(actNil), verbosity = verNormal): Conf = +func initConf*(action = initAction(actNil), trackDir = getCurrentDir(), + verbosity = verNormal): Conf = result = Conf( action: action, + trackDir: trackDir, verbosity: verbosity, ) @@ -285,7 +291,7 @@ proc handleArgument(conf: var Conf; kind: CmdLineKind; key: string) = if conf.action.kind == actNil: let actionKind = parseActionKind(key) let action = initAction(actionKind) - conf = initConf(action, conf.verbosity) + conf = initConf(action, conf.trackDir, conf.verbosity) else: showError(&"invalid argument for command '{conf.action.kind}': '{key}'") @@ -310,6 +316,8 @@ proc handleOption(conf: var Conf; kind: CmdLineKind; key, val: string) = showHelp() of optVersion: showVersion() + of optTrackDir: + setGlobalOpt(trackDir, val) of optVerbosity: setGlobalOpt(verbosity, parseVal[Verbosity](kind, key, val)) else: diff --git a/src/sync/exercises.nim b/src/sync/exercises.nim index 2d1aad61..595f5cb8 100644 --- a/src/sync/exercises.nim +++ b/src/sync/exercises.nim @@ -75,8 +75,8 @@ proc status*(exercise: Exercise): ExerciseStatus = proc hasCanonicalData*(exercise: Exercise): bool = exercise.testCases.len > 0 -proc testsFile(exercise: Exercise): string = - getCurrentDir() / "exercises" / exercise.slug / ".meta" / "tests.toml" +proc testsFile(exercise: Exercise, trackDir: string): string = + trackDir / "exercises" / exercise.slug / ".meta" / "tests.toml" proc toToml(exercise: Exercise): string = result.add("[canonical-tests]\n") @@ -89,8 +89,8 @@ proc toToml(exercise: Exercise): string = result.add(&"\n# {testCase.description}") result.add(&"\n\"{testCase.uuid}\" = {isIncluded}\n") -proc writeTestsToml*(exercise: Exercise) = - let testsPath = testsFile(exercise) +proc writeTestsToml*(exercise: Exercise, trackDir: string) = + let testsPath = testsFile(exercise, trackDir) createDir(testsPath.parentDir()) let contents = toToml(exercise) diff --git a/src/sync/sync.nim b/src/sync/sync.nim index 7ba14ecf..7dbd2923 100644 --- a/src/sync/sync.nim +++ b/src/sync/sync.nim @@ -64,9 +64,10 @@ proc syncDecision(testCase: ExerciseTestCase, mode: Mode): SyncDecision = of modeChoose: chooseSyncDecision(testCase) -proc sync(exercise: Exercise, mode: Mode): Exercise = +proc sync(exercise: Exercise, conf: Conf): Exercise = result = exercise + let mode = conf.action.mode case mode of modeInclude: logNormal(&"[info] {exercise.slug}: included {exercise.tests.missing.len} missing test cases") @@ -100,13 +101,13 @@ proc sync(exercise: Exercise, mode: Mode): Exercise = result.tests = initExerciseTests(included, excluded, missing) - writeTestsToml(result) + writeTestsToml(result, conf.trackDir) -proc sync(exercises: seq[Exercise], mode: Mode): seq[Exercise] = +proc sync(exercises: seq[Exercise], conf: Conf): seq[Exercise] = for exercise in exercises: case exercise.status of exOutOfSync: - result.add(sync(exercise, mode)) + result.add(sync(exercise, conf)) of exInSync: logDetailed(&"[skip] {exercise.slug} is up-to-date") of exNoCanonicalData: @@ -116,7 +117,7 @@ proc sync*(conf: Conf) = logNormal("Syncing exercises...") let exercises = findExercises(conf) - let syncedExercises = sync(exercises, conf.action.mode) + let syncedExercises = sync(exercises, conf) if syncedExercises.anyIt(it.status == exOutOfSync): logNormal("[warn] some exercises are still missing test cases") diff --git a/src/sync/tracks.nim b/src/sync/tracks.nim index 77e90e95..76429769 100644 --- a/src/sync/tracks.nim +++ b/src/sync/tracks.nim @@ -24,9 +24,6 @@ type tests*: TrackExerciseTests repoExercise: TrackRepoExercise -proc newTrackRepo: TrackRepo = - result.dir = getCurrentDir() - proc configJsonFile(repo: TrackRepo): string = repo.dir / "config.json" @@ -83,5 +80,5 @@ proc findTrackExercises(repo: TrackRepo, conf: Conf): seq[TrackExercise] = result.add(newTrackExercise(repoExercise)) proc findTrackExercises*(conf: Conf): seq[TrackExercise] = - let trackRepo = newTrackRepo() + let trackRepo = TrackRepo(dir: conf.trackDir) trackRepo.findTrackExercises(conf)