From fd88865b409b7ec26cb8d683c3c661c691330511 Mon Sep 17 00:00:00 2001 From: Trevor Burton-McCreadie Date: Fri, 7 Jul 2023 11:12:03 +0100 Subject: [PATCH] Install logic to core (#233) * refactored build to ensure core has dependencies available * moved CmtcCommand into core * moved arg parsers * refactored some of the package/helper methods * refactored SetCurrentCourse and Install commands, also cmtc tests moved to core * scalaformattin' --- build.sbt | 7 +- .../com/lunatech/cmt/client/Domain.scala | 15 ---- .../com/lunatech/cmt/client/Helpers.scala | 49 ------------ .../lunatech/cmt/client/cli/ArgParsers.scala | 77 +----------------- .../cmt/client/command/GotoExercise.scala | 12 ++- .../client/command/GotoFirstExercise.scala | 6 +- .../cmt/client/command/ListExercises.scala | 7 +- .../cmt/client/command/ListSavedStates.scala | 4 +- .../cmt/client/command/NextExercise.scala | 9 ++- .../lunatech/cmt/client/command/Package.scala | 7 -- .../cmt/client/command/PreviousExercise.scala | 8 +- .../cmt/client/command/PullSolution.scala | 6 +- .../cmt/client/command/PullTemplate.scala | 8 +- .../cmt/client/command/RestoreState.scala | 6 +- .../cmt/client/command/SaveState.scala | 7 +- .../cli/GotoExerciseArgumentsSpec.scala | 6 +- .../cmt/client/cli/InstallArgumentsSpec.scala | 4 +- .../main/scala/com/lunatech/cmt/Domain.scala | 19 +++++ .../main/scala/com/lunatech/cmt/Helpers.scala | 46 +++++++++++ .../lunatech/cmt/client/Configuration.scala | 22 ++---- .../lunatech/cmt/client/cli/CmtcCommand.scala | 4 +- .../cmt/client/command/Executable.scala | 0 .../lunatech/cmt/client/command/Install.scala | 29 ++++--- .../cmt/client/command/SetCurrentCourse.scala | 8 +- .../lunatech/cmt/core/cli/ArgParsers.scala | 78 +++++++++++++++++++ .../lunatech/cmt/core/command/Package.scala | 16 ++++ .../cmt/client/ConfigurationSpec.scala | 9 +-- .../cmt/client/command/InstallSpec.scala | 0 .../client/command/SetCurrentCourseSpec.scala | 6 +- .../lunatech/cmt/support/TestSupport.scala | 3 +- project/Build.scala | 4 +- project/Dependencies.scala | 4 +- 32 files changed, 252 insertions(+), 234 deletions(-) delete mode 100644 cmtc/src/main/scala/com/lunatech/cmt/client/Helpers.scala create mode 100644 core/src/main/scala/com/lunatech/cmt/Domain.scala rename {cmtc => core}/src/main/scala/com/lunatech/cmt/client/Configuration.scala (96%) rename {cmtc => core}/src/main/scala/com/lunatech/cmt/client/cli/CmtcCommand.scala (100%) rename {cmtc => core}/src/main/scala/com/lunatech/cmt/client/command/Executable.scala (100%) rename {cmtc => core}/src/main/scala/com/lunatech/cmt/client/command/Install.scala (94%) rename {cmtc => core}/src/main/scala/com/lunatech/cmt/client/command/SetCurrentCourse.scala (87%) create mode 100644 core/src/main/scala/com/lunatech/cmt/core/cli/ArgParsers.scala create mode 100644 core/src/main/scala/com/lunatech/cmt/core/command/Package.scala rename {cmtc => core}/src/test/scala/com/lunatech/cmt/client/ConfigurationSpec.scala (97%) rename {cmtc => core}/src/test/scala/com/lunatech/cmt/client/command/InstallSpec.scala (100%) rename {cmtc => core}/src/test/scala/com/lunatech/cmt/client/command/SetCurrentCourseSpec.scala (98%) diff --git a/build.sbt b/build.sbt index d7df506b..392483a0 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,9 @@ lazy val `course-management-tools` = .settings(commonSettings: _*) .settings(publish / skip := true) -lazy val core = project.in(file("core")).settings(commonSettings: _*) +lazy val core = project.in(file("core")) + .settings(commonSettings: _*) + .settings(libraryDependencies ++= Dependencies.coreDependencies) lazy val cmta = project .in(file("cmta")) @@ -28,8 +30,9 @@ lazy val cmtc = project .settings(buildInfoKeys := buildKeysWithName("Course Management Tools (Client)")) lazy val `functional-tests` = project.in(file("functional-tests")) - .dependsOn(cmta, cmtc) + .dependsOn(cmta, cmtc, core) .settings(commonSettings: _*) + .settings(libraryDependencies ++= Dependencies.functionalTestDependencies) .settings(publish / skip := true) lazy val docs = project diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/Domain.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/Domain.scala index 80bbbf04..e13f2c25 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/Domain.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/Domain.scala @@ -12,30 +12,15 @@ package com.lunatech.cmt.client * * See the License for the specific language governing permissions and limitations under the License. */ - -import sbt.io.syntax.{File, file} - object Domain: final case class ExerciseId(value: String) object ExerciseId: val default: ExerciseId = ExerciseId("") - final case class StudentifiedRepo(value: File) final case class ForceMoveToExercise(forceMove: Boolean) - object StudentifiedRepo: - val default: StudentifiedRepo = StudentifiedRepo(file(".").getAbsoluteFile.getParentFile) final case class TemplatePath(value: String) object TemplatePath: val default: TemplatePath = TemplatePath("") - sealed trait InstallationSource - object InstallationSource: - final case class LocalDirectory(value: File) extends InstallationSource - final case class ZipFile(value: File) extends InstallationSource - final case class GithubProject(organisation: String, project: String) extends InstallationSource { - val displayName = s"$organisation/$project" - } - end InstallationSource - end Domain diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/Helpers.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/Helpers.scala deleted file mode 100644 index 50a0f8dd..00000000 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/Helpers.scala +++ /dev/null @@ -1,49 +0,0 @@ -package com.lunatech.cmt.client - -import com.lunatech.cmt.client.command.{getCurrentExerciseId, starCurrentExercise} -import com.lunatech.cmt.{CMTcConfig, CmtError, FailedToValidateArgument, toConsoleGreen} -import sbt.io.syntax.* -extension (f: File) - // Gets the parent folder of this folder but return this - // folder if it's a root folder - def getParentOrSelf: File = - val pf = f.getParentFile() - if (pf == null) f else pf - -private val cmtSignature1 = ".cmt/.cmt-config" -private val cmtSignature2 = ".cmt/.bookmark" - -private def isStudentifiedRepo(folder: File): Boolean = - (folder / cmtSignature1).exists && (folder / cmtSignature2).exists - -/** @param Path - * to either the root of a studentified repo or any subfolder in such repo - * @return - * The root folder of the studentified repo or an error message in case the passed-in fodler wasn't pointing to a - * studentified repo. - */ -def findStudentRepoRoot(path: File): Either[CmtError, File] = - lazy val error = FailedToValidateArgument.because("s", s"$path is not a CMT student project") - @scala.annotation.tailrec - def findStudentRepoRootRecurse(path: File): Option[File] = - if (path.isDirectory() && isStudentifiedRepo(path)) Some(path) - else - val pf = path.getParentOrSelf - if (path == pf) - None - else - findStudentRepoRootRecurse(pf) - - if (path.isDirectory()) - findStudentRepoRootRecurse(path).toRight(error) - else - Left(error) - -def listExercises(config: CMTcConfig): String = - val currentExerciseId = getCurrentExerciseId(config.bookmarkFile) - - config.exercises.zipWithIndex - .map { case (exName, index) => - toConsoleGreen(f"${index + 1}%3d. ${starCurrentExercise(currentExerciseId, exName)} $exName") - } - .mkString("\n") diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/cli/ArgParsers.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/cli/ArgParsers.scala index fce80f93..373b57e3 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/cli/ArgParsers.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/cli/ArgParsers.scala @@ -1,35 +1,11 @@ package com.lunatech.cmt.client.cli -import caseapp.core.Error -import caseapp.core.Error.Other import caseapp.core.argparser.{ArgParser, FlagArgParser, SimpleArgParser} -import com.lunatech.cmt.client.Domain.{ - ExerciseId, - ForceMoveToExercise, - InstallationSource, - StudentifiedRepo, - TemplatePath -} -import sbt.io.syntax.{File, file} -import cats.syntax.apply.* +import com.lunatech.cmt.client.Domain.{ExerciseId, ForceMoveToExercise, TemplatePath} import cats.syntax.either.* -import com.lunatech.cmt.client.Domain.InstallationSource.{GithubProject, LocalDirectory, ZipFile} -import com.lunatech.cmt.core.validation.FileValidations.* object ArgParsers { - private val fileArgParser: ArgParser[File] = - SimpleArgParser.from[File]("file")(file(_).asRight) - - given studentifiedRepoArgParser: ArgParser[StudentifiedRepo] = - fileArgParser.xmapError[StudentifiedRepo]( - _.value, - file => - (file.validateExists, file.validateIsDirectory) - .mapN((_, _) => StudentifiedRepo(file)) - .leftMap(_.flatten) - .toEither) - given forceMoveToExerciseArgParser: ArgParser[ForceMoveToExercise] = FlagArgParser.boolean.xmap[ForceMoveToExercise](_.forceMove, ForceMoveToExercise(_)) @@ -38,55 +14,4 @@ object ArgParsers { given templatePathArgParser: ArgParser[TemplatePath] = SimpleArgParser.from[TemplatePath]("template path")(TemplatePath(_).asRight) - - given installationSourceArgParser: ArgParser[InstallationSource] = { - - val githubProjectRegex = "([A-Za-z0-9-_]*)\\/([A-Za-z0-9-_]*)".r - - def toString(installationSource: InstallationSource): String = - installationSource match { - case LocalDirectory(value) => value.getAbsolutePath() - case ZipFile(value) => value.getAbsolutePath() - case GithubProject(organisation, project) => s"$organisation/$project" - } - - def fromString(str: String): Either[Error, InstallationSource] = { - val maybeFile = file(str) - val maybeGithub = str match { - case githubProjectRegex(organisation, project) => Some(GithubProject(organisation, project)) - case _ => None - } - - // is it a file? does it exist? - // yes - // - is it a directory? - // yes - // - it's a LocalDirectory - // no - // - does it end in '.zip'? - // yes - // - it's a ZipFile - // no - // - error - can't install from a file - // no - // - is it of the form a/b - // yes - // - it's a GithubProject - // no - // - error - i don't know what to do - (maybeFile.exists(), maybeFile.isDirectory, str.endsWith(".zip"), maybeGithub) match { - case (true, true, _, _) => LocalDirectory(maybeFile).asRight - case (true, false, true, _) => ZipFile(maybeFile).asRight - case (true, false, false, _) => - Other( - s"'$str' is a file but not a zip file - i'm afraid I don't know how to install a course from this file").asLeft - case (false, _, _, Some(githubProject)) => githubProject.asRight - case (_, _, _, _) => - Other( - s"'$str' is not a local directory or zip file and it doesn't appear to be a Github project either. I'm afraid I don't know how to deal with this.").asLeft - } - } - - SimpleArgParser.string.xmapError[InstallationSource](toString, fromString) - } } diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/GotoExercise.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/GotoExercise.scala index 7f26705b..68e7ec02 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/GotoExercise.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/GotoExercise.scala @@ -10,18 +10,16 @@ import com.lunatech.cmt.{ toExecuteCommandErrorMessage } import com.lunatech.cmt.Helpers.{exerciseFileHasBeenModified, getFilesToCopyAndDelete, pullTestCode} +import com.lunatech.cmt.Domain.StudentifiedRepo import com.lunatech.cmt.client.Configuration -import com.lunatech.cmt.client.Domain.{ExerciseId, ForceMoveToExercise, StudentifiedRepo} -import com.lunatech.cmt.client.command.getCurrentExerciseId +import com.lunatech.cmt.client.Domain.{ExerciseId, ForceMoveToExercise} import com.lunatech.cmt.core.validation.Validatable import sbt.io.syntax.* -import com.lunatech.cmt.client.cli.ArgParsers.{ - exerciseIdArgParser, - forceMoveToExerciseArgParser, - studentifiedRepoArgParser -} +import com.lunatech.cmt.client.cli.ArgParsers.{exerciseIdArgParser, forceMoveToExerciseArgParser} +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser import com.lunatech.cmt.client.cli.CmtcCommand import com.lunatech.cmt.core.cli.enforceTrailingArgumentCount +import com.lunatech.cmt.core.command.Package.getCurrentExerciseId object GotoExercise: diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/GotoFirstExercise.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/GotoFirstExercise.scala index faa39824..e9722bd5 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/GotoFirstExercise.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/GotoFirstExercise.scala @@ -3,9 +3,11 @@ package com.lunatech.cmt.client.command import caseapp.{AppName, CommandName, ExtraName, HelpMessage, RemainingArgs} import com.lunatech.cmt.client.Configuration import com.lunatech.cmt.{CMTcConfig, CmtError, printResult} -import com.lunatech.cmt.client.Domain.{ExerciseId, ForceMoveToExercise, StudentifiedRepo} +import com.lunatech.cmt.client.Domain.{ExerciseId, ForceMoveToExercise} +import com.lunatech.cmt.Domain.StudentifiedRepo import com.lunatech.cmt.core.validation.Validatable -import com.lunatech.cmt.client.cli.ArgParsers.{forceMoveToExerciseArgParser, studentifiedRepoArgParser} +import com.lunatech.cmt.client.cli.ArgParsers.forceMoveToExerciseArgParser +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser import com.lunatech.cmt.client.cli.CmtcCommand import com.lunatech.cmt.core.cli.enforceNoTrailingArguments diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/ListExercises.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/ListExercises.scala index 753f2e7b..d16f8ab9 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/ListExercises.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/ListExercises.scala @@ -1,13 +1,14 @@ package com.lunatech.cmt.client.command import caseapp.{AppName, CommandName, ExtraName, HelpMessage, RemainingArgs} -import com.lunatech.cmt.client.{Configuration, listExercises} -import com.lunatech.cmt.client.Domain.StudentifiedRepo +import com.lunatech.cmt.client.Configuration +import com.lunatech.cmt.Domain.StudentifiedRepo import com.lunatech.cmt.{CMTcConfig, CmtError, printResult} import com.lunatech.cmt.client.cli.CmtcCommand import com.lunatech.cmt.core.validation.Validatable import com.lunatech.cmt.core.cli.enforceNoTrailingArguments -import com.lunatech.cmt.client.cli.ArgParsers.studentifiedRepoArgParser +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser +import com.lunatech.cmt.Helpers.listExercises object ListExercises: diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/ListSavedStates.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/ListSavedStates.scala index 6e54b96c..b1fdb836 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/ListSavedStates.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/ListSavedStates.scala @@ -2,13 +2,13 @@ package com.lunatech.cmt.client.command import caseapp.{AppName, CommandName, ExtraName, HelpMessage, RemainingArgs} import com.lunatech.cmt.client.Configuration -import com.lunatech.cmt.client.Domain.StudentifiedRepo +import com.lunatech.cmt.Domain.StudentifiedRepo import com.lunatech.cmt.client.cli.CmtcCommand import com.lunatech.cmt.{CMTcConfig, CmtError, printResult, toConsoleGreen, toConsoleYellow} import com.lunatech.cmt.core.validation.Validatable import sbt.io.IO as sbtio import com.lunatech.cmt.core.cli.enforceNoTrailingArguments -import com.lunatech.cmt.client.cli.ArgParsers.studentifiedRepoArgParser +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser object ListSavedStates: diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/NextExercise.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/NextExercise.scala index 9248ccf4..52ac9140 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/NextExercise.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/NextExercise.scala @@ -10,14 +10,16 @@ import com.lunatech.cmt.{ toExecuteCommandErrorMessage } import com.lunatech.cmt.Helpers.{exerciseFileHasBeenModified, getFilesToCopyAndDelete, pullTestCode} +import com.lunatech.cmt.Domain.StudentifiedRepo import com.lunatech.cmt.client.Configuration -import com.lunatech.cmt.client.Domain.{ForceMoveToExercise, StudentifiedRepo} -import com.lunatech.cmt.client.command.getCurrentExerciseId +import com.lunatech.cmt.client.Domain.ForceMoveToExercise import com.lunatech.cmt.core.validation.Validatable import sbt.io.syntax.* -import com.lunatech.cmt.client.cli.ArgParsers.{forceMoveToExerciseArgParser, studentifiedRepoArgParser} +import com.lunatech.cmt.client.cli.ArgParsers.forceMoveToExerciseArgParser +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser import com.lunatech.cmt.client.cli.CmtcCommand import com.lunatech.cmt.core.cli.enforceNoTrailingArguments +import com.lunatech.cmt.core.command.Package.getCurrentExerciseId object NextExercise: @@ -39,7 +41,6 @@ object NextExercise: extension (options: NextExercise.Options) def execute(configuration: Configuration): Either[CmtError, String] = { - import com.lunatech.cmt.client.Domain.ForceMoveToExercise val cMTcConfig = new CMTcConfig(options.studentifiedRepo.getOrElse(configuration.currentCourse.value).value) val currentExerciseId = getCurrentExerciseId(cMTcConfig.bookmarkFile) diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/Package.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/Package.scala index 8b3c6494..f950985d 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/Package.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/Package.scala @@ -4,7 +4,6 @@ import com.lunatech.cmt.{CMTcConfig, Helpers} import com.lunatech.cmt.Helpers.writeStudentifiedCMTBookmark import sbt.io.syntax.* import sbt.io.IO as sbtio -import java.nio.charset.StandardCharsets final case class ExerciseFiles(filesAbsolute: Seq[File], filesRelative: Seq[File]) private final case class PathARO(absolutePath: File, maybeRelativePath: Option[File]) @@ -34,9 +33,6 @@ def deleteCurrentState(studentifiedRepo: File)(config: CMTcConfig): Unit = val ExerciseFiles(filesToBeDeleted, _) = getCurrentExerciseStateExceptDontTouch(studentifiedRepo)(config) sbtio.deleteFilesEmptyDirs(filesToBeDeleted) -def getCurrentExerciseId(bookmarkFile: File): String = - sbtio.readLines(bookmarkFile, StandardCharsets.UTF_8).head - def copyTestCodeAndReadMeFiles(solution: File, prevOrNextExercise: String)(config: CMTcConfig): Unit = val (pathsToCopy, _) = @@ -61,6 +57,3 @@ def copyTestCodeAndReadMeFiles(solution: File, prevOrNextExercise: String)(confi } sbtio.copyFile(solution / file, config.activeExerciseFolder / file) writeStudentifiedCMTBookmark(config.bookmarkFile, prevOrNextExercise) - -def starCurrentExercise(currentExercise: String, exercise: String): String = - if (currentExercise == exercise) " * " else " " diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/PreviousExercise.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/PreviousExercise.scala index f804199d..72fcf9b6 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/PreviousExercise.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/PreviousExercise.scala @@ -11,13 +11,15 @@ import com.lunatech.cmt.{ } import com.lunatech.cmt.Helpers.{exerciseFileHasBeenModified, getFilesToCopyAndDelete, pullTestCode} import com.lunatech.cmt.client.Configuration -import com.lunatech.cmt.client.Domain.{ForceMoveToExercise, StudentifiedRepo} -import com.lunatech.cmt.client.command.getCurrentExerciseId +import com.lunatech.cmt.Domain.StudentifiedRepo +import com.lunatech.cmt.client.Domain.ForceMoveToExercise import com.lunatech.cmt.core.validation.Validatable import sbt.io.syntax.* -import com.lunatech.cmt.client.cli.ArgParsers.{forceMoveToExerciseArgParser, studentifiedRepoArgParser} +import com.lunatech.cmt.client.cli.ArgParsers.forceMoveToExerciseArgParser +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser import com.lunatech.cmt.client.cli.CmtcCommand import com.lunatech.cmt.core.cli.enforceNoTrailingArguments +import com.lunatech.cmt.core.command.Package.getCurrentExerciseId object PreviousExercise: diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/PullSolution.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/PullSolution.scala index e0d532cb..fdfaae59 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/PullSolution.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/PullSolution.scala @@ -4,14 +4,14 @@ import caseapp.{AppName, CommandName, ExtraName, HelpMessage, RemainingArgs} import com.lunatech.cmt.{CMTcConfig, CmtError, printResult, toConsoleGreen, toConsoleYellow} import com.lunatech.cmt.Helpers.{adaptToNixSeparatorChar, exerciseFileHasBeenModified, withZipFile} import com.lunatech.cmt.client.Configuration -import com.lunatech.cmt.client.Domain.StudentifiedRepo -import com.lunatech.cmt.client.command.getCurrentExerciseId +import com.lunatech.cmt.Domain.StudentifiedRepo import com.lunatech.cmt.client.cli.CmtcCommand import com.lunatech.cmt.core.validation.Validatable import sbt.io.IO as sbtio import sbt.io.syntax.* import com.lunatech.cmt.core.cli.enforceNoTrailingArguments -import com.lunatech.cmt.client.cli.ArgParsers.studentifiedRepoArgParser +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser +import com.lunatech.cmt.core.command.Package.getCurrentExerciseId object PullSolution: diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/PullTemplate.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/PullTemplate.scala index f55784fa..58f95a3d 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/PullTemplate.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/PullTemplate.scala @@ -11,15 +11,17 @@ import com.lunatech.cmt.{ } import com.lunatech.cmt.Helpers.withZipFile import com.lunatech.cmt.client.Configuration -import com.lunatech.cmt.client.Domain.{StudentifiedRepo, TemplatePath} -import com.lunatech.cmt.client.command.getCurrentExerciseId +import com.lunatech.cmt.Domain.StudentifiedRepo +import com.lunatech.cmt.client.Domain.TemplatePath import com.lunatech.cmt.core.validation.Validatable import sbt.io.CopyOptions import sbt.io.IO as sbtio import sbt.io.syntax.* -import com.lunatech.cmt.client.cli.ArgParsers.{templatePathArgParser, studentifiedRepoArgParser} +import com.lunatech.cmt.client.cli.ArgParsers.templatePathArgParser +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser import com.lunatech.cmt.client.cli.CmtcCommand import com.lunatech.cmt.core.cli.enforceTrailingArgumentCount +import com.lunatech.cmt.core.command.Package.getCurrentExerciseId object PullTemplate: diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/RestoreState.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/RestoreState.scala index 959e8155..c0504f3f 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/RestoreState.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/RestoreState.scala @@ -1,8 +1,10 @@ package com.lunatech.cmt.client.command -import com.lunatech.cmt.client.Domain.{ExerciseId, StudentifiedRepo} +import com.lunatech.cmt.Domain.StudentifiedRepo +import com.lunatech.cmt.client.Domain.ExerciseId import caseapp.{AppName, CommandName, ExtraName, HelpMessage, RemainingArgs} -import com.lunatech.cmt.client.cli.ArgParsers.{exerciseIdArgParser, studentifiedRepoArgParser} +import com.lunatech.cmt.client.cli.ArgParsers.exerciseIdArgParser +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser import com.lunatech.cmt.client.command.deleteCurrentState import com.lunatech.cmt.core.validation.Validatable import com.lunatech.cmt.* diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/SaveState.scala b/cmtc/src/main/scala/com/lunatech/cmt/client/command/SaveState.scala index ce784276..a72d6444 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/SaveState.scala +++ b/cmtc/src/main/scala/com/lunatech/cmt/client/command/SaveState.scala @@ -2,16 +2,17 @@ package com.lunatech.cmt.client.command import caseapp.{AppName, CommandName, ExtraName, HelpMessage, RemainingArgs} import com.lunatech.cmt.Helpers.zipAndDeleteOriginal -import com.lunatech.cmt.client.command.{getCurrentExerciseId, getCurrentExerciseStateExceptDontTouch} +import com.lunatech.cmt.client.command.getCurrentExerciseStateExceptDontTouch import com.lunatech.cmt.core.validation.Validatable import com.lunatech.cmt.* import com.lunatech.cmt.client.Configuration -import com.lunatech.cmt.client.Domain.StudentifiedRepo +import Domain.StudentifiedRepo import com.lunatech.cmt.client.cli.CmtcCommand import sbt.io.IO as sbtio import sbt.io.syntax.* import com.lunatech.cmt.core.cli.enforceNoTrailingArguments -import com.lunatech.cmt.client.cli.ArgParsers.studentifiedRepoArgParser +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser +import com.lunatech.cmt.core.command.Package.getCurrentExerciseId object SaveState: diff --git a/cmtc/src/test/scala/com/lunatech/cmt/client/cli/GotoExerciseArgumentsSpec.scala b/cmtc/src/test/scala/com/lunatech/cmt/client/cli/GotoExerciseArgumentsSpec.scala index 0bfd791b..f0e10984 100644 --- a/cmtc/src/test/scala/com/lunatech/cmt/client/cli/GotoExerciseArgumentsSpec.scala +++ b/cmtc/src/test/scala/com/lunatech/cmt/client/cli/GotoExerciseArgumentsSpec.scala @@ -14,11 +14,13 @@ package com.lunatech.cmt.client.cli */ import caseapp.Parser -import com.lunatech.cmt.client.Domain.{ExerciseId, ForceMoveToExercise, StudentifiedRepo} +import com.lunatech.cmt.Domain.StudentifiedRepo +import com.lunatech.cmt.client.Domain.{ExerciseId, ForceMoveToExercise} +import com.lunatech.cmt.client.cli.ArgParsers.given import com.lunatech.cmt.client.command.GotoExercise +import com.lunatech.cmt.core.cli.ArgParsers.given import com.lunatech.cmt.support.TestDirectories import sbt.io.syntax.File -import com.lunatech.cmt.client.cli.ArgParsers.given final class GotoExerciseArgumentsSpec extends CommandLineArgumentsSpec[GotoExercise.Options] with TestDirectories { diff --git a/cmtc/src/test/scala/com/lunatech/cmt/client/cli/InstallArgumentsSpec.scala b/cmtc/src/test/scala/com/lunatech/cmt/client/cli/InstallArgumentsSpec.scala index 2a7eaf3b..fa34850d 100644 --- a/cmtc/src/test/scala/com/lunatech/cmt/client/cli/InstallArgumentsSpec.scala +++ b/cmtc/src/test/scala/com/lunatech/cmt/client/cli/InstallArgumentsSpec.scala @@ -1,11 +1,11 @@ package com.lunatech.cmt.client.cli import caseapp.Parser -import com.lunatech.cmt.client.Domain.InstallationSource.{GithubProject, LocalDirectory, ZipFile} +import com.lunatech.cmt.Domain.InstallationSource.{GithubProject, LocalDirectory, ZipFile} import com.lunatech.cmt.client.command.Install import com.lunatech.cmt.support.TestDirectories import sbt.io.syntax.{File, file} -import com.lunatech.cmt.client.cli.ArgParsers.given +import com.lunatech.cmt.core.cli.ArgParsers.given final class InstallArgumentsSpec extends CommandLineArgumentsSpec[Install.Options] with TestDirectories { diff --git a/core/src/main/scala/com/lunatech/cmt/Domain.scala b/core/src/main/scala/com/lunatech/cmt/Domain.scala new file mode 100644 index 00000000..9516ac77 --- /dev/null +++ b/core/src/main/scala/com/lunatech/cmt/Domain.scala @@ -0,0 +1,19 @@ +package com.lunatech.cmt + +import sbt.io.syntax.{File, file} + +object Domain { + + final case class StudentifiedRepo(value: File) + object StudentifiedRepo: + val default: StudentifiedRepo = StudentifiedRepo(file(".").getAbsoluteFile.getParentFile) + + sealed trait InstallationSource + object InstallationSource: + final case class LocalDirectory(value: File) extends InstallationSource + final case class ZipFile(value: File) extends InstallationSource + final case class GithubProject(organisation: String, project: String) extends InstallationSource { + val displayName = s"$organisation/$project" + } + end InstallationSource +} diff --git a/core/src/main/scala/com/lunatech/cmt/Helpers.scala b/core/src/main/scala/com/lunatech/cmt/Helpers.scala index 426bffbc..c4a0b955 100644 --- a/core/src/main/scala/com/lunatech/cmt/Helpers.scala +++ b/core/src/main/scala/com/lunatech/cmt/Helpers.scala @@ -15,6 +15,7 @@ package com.lunatech.cmt import com.lunatech.cmt.ProcessDSL.ProcessCmd import com.lunatech.cmt.core.GeneratorInfo +import com.lunatech.cmt.core.command.Package.* import com.typesafe.config.{ConfigFactory, ConfigRenderOptions} import sbt.io.IO as sbtio import sbt.io.syntax.* @@ -459,4 +460,49 @@ object Helpers: dumpStringToFile(metadataConfig, studentifiedRootFolder / cmtaConfig.codeSizeAndChecksums) end writeCodeMetadata + extension (f: File) + // Gets the parent folder of this folder but return this + // folder if it's a root folder + def getParentOrSelf: File = + val pf = f.getParentFile() + if (pf == null) f else pf + + private val cmtSignature1 = ".cmt/.cmt-config" + private val cmtSignature2 = ".cmt/.bookmark" + + private def isStudentifiedRepo(folder: File): Boolean = + (folder / cmtSignature1).exists && (folder / cmtSignature2).exists + + /** @param Path + * to either the root of a studentified repo or any subfolder in such repo + * @return + * The root folder of the studentified repo or an error message in case the passed-in fodler wasn't pointing to a + * studentified repo. + */ + def findStudentRepoRoot(path: File): Either[CmtError, File] = + lazy val error = FailedToValidateArgument.because("s", s"$path is not a CMT student project") + @scala.annotation.tailrec + def findStudentRepoRootRecurse(path: File): Option[File] = + if (path.isDirectory() && isStudentifiedRepo(path)) Some(path) + else + val pf = path.getParentOrSelf + if (path == pf) + None + else + findStudentRepoRootRecurse(pf) + + if (path.isDirectory()) + findStudentRepoRootRecurse(path).toRight(error) + else + Left(error) + + def listExercises(config: CMTcConfig): String = + val currentExerciseId = getCurrentExerciseId(config.bookmarkFile) + + config.exercises.zipWithIndex + .map { case (exName, index) => + toConsoleGreen(f"${index + 1}%3d. ${starCurrentExercise(currentExerciseId, exName)} $exName") + } + .mkString("\n") + end Helpers diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/Configuration.scala b/core/src/main/scala/com/lunatech/cmt/client/Configuration.scala similarity index 96% rename from cmtc/src/main/scala/com/lunatech/cmt/client/Configuration.scala rename to core/src/main/scala/com/lunatech/cmt/client/Configuration.scala index da331853..32f45264 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/Configuration.scala +++ b/core/src/main/scala/com/lunatech/cmt/client/Configuration.scala @@ -1,28 +1,18 @@ package com.lunatech.cmt.client -import com.lunatech.cmt.client.Configuration.{ - CmtHome, - CoursesDirectoryToken, - CurrentCourseToken, - DefaultGithubApiToken, - GithubApiToken, - GithubApiTokenToken, - globalConfigFile, - writeGlobalConfig -} +import com.lunatech.cmt.Helpers.{adaptToNixSeparatorChar, adaptToOSSeparatorChar} +import com.lunatech.cmt.client.Configuration.* +import com.lunatech.cmt.Domain.StudentifiedRepo import com.lunatech.cmt.{CmtError, FailedToWriteGlobalConfiguration, printMessage} -import com.lunatech.cmt.client.Domain.StudentifiedRepo import com.typesafe.config.{Config, ConfigFactory} +import dev.dirs.ProjectDirectories import sbt.io.IO.* import sbt.io.syntax.* -import com.lunatech.cmt.Helpers.{adaptToNixSeparatorChar, adaptToOSSeparatorChar} - -import scala.jdk.CollectionConverters.* -import scala.util.{Failure, Success, Try} -import dev.dirs.ProjectDirectories import java.nio.charset.StandardCharsets import java.util.Base64 +import scala.jdk.CollectionConverters.* +import scala.util.{Failure, Success, Try} final case class Configuration( homeDirectory: CmtHome, diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/cli/CmtcCommand.scala b/core/src/main/scala/com/lunatech/cmt/client/cli/CmtcCommand.scala similarity index 100% rename from cmtc/src/main/scala/com/lunatech/cmt/client/cli/CmtcCommand.scala rename to core/src/main/scala/com/lunatech/cmt/client/cli/CmtcCommand.scala index a9b55510..749a8b56 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/cli/CmtcCommand.scala +++ b/core/src/main/scala/com/lunatech/cmt/client/cli/CmtcCommand.scala @@ -2,10 +2,10 @@ package com.lunatech.cmt.client.cli import caseapp.core.help.Help import caseapp.core.parser.Parser -import com.lunatech.cmt.printErrorAndExit +import cats.syntax.either.* import com.lunatech.cmt.client.Configuration import com.lunatech.cmt.core.cli.CmtCommand -import cats.syntax.either.* +import com.lunatech.cmt.printErrorAndExit abstract class CmtcCommand[T](using parser: Parser[T], help: Help[T]) extends CmtCommand[T] { diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/Executable.scala b/core/src/main/scala/com/lunatech/cmt/client/command/Executable.scala similarity index 100% rename from cmtc/src/main/scala/com/lunatech/cmt/client/command/Executable.scala rename to core/src/main/scala/com/lunatech/cmt/client/command/Executable.scala diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/Install.scala b/core/src/main/scala/com/lunatech/cmt/client/command/Install.scala similarity index 94% rename from cmtc/src/main/scala/com/lunatech/cmt/client/command/Install.scala rename to core/src/main/scala/com/lunatech/cmt/client/command/Install.scala index c18ee59b..a7fc10a6 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/Install.scala +++ b/core/src/main/scala/com/lunatech/cmt/client/command/Install.scala @@ -1,31 +1,30 @@ package com.lunatech.cmt.client.command -import GithubSupport.* -import caseapp.{AppName, CommandName, ExtraName, HelpMessage, RemainingArgs} +import caseapp.* import cats.effect.IO import cats.effect.unsafe.implicits.global import cats.syntax.either.* -import com.lunatech.cmt.client.{Configuration} -import com.lunatech.cmt.client.Domain.{InstallationSource, StudentifiedRepo} -import com.lunatech.cmt.{CmtError, GenericError, printMessage, printResult, toExecuteCommandErrorMessage} +import com.lunatech.cmt.* +import com.lunatech.cmt.Domain.InstallationSource.{GithubProject, LocalDirectory, ZipFile} +import com.lunatech.cmt.Domain.{InstallationSource, StudentifiedRepo} +import com.lunatech.cmt.client.Configuration import com.lunatech.cmt.client.cli.CmtcCommand -import com.lunatech.cmt.core.validation.Validatable -import com.lunatech.cmt.client.Domain.InstallationSource.{GithubProject, LocalDirectory, ZipFile} -import com.lunatech.cmt.client.cli.ArgParsers.installationSourceArgParser +import com.lunatech.cmt.client.command.GithubSupport.* +import com.lunatech.cmt.core.cli.ArgParsers.installationSourceArgParser import com.lunatech.cmt.core.cli.enforceNoTrailingArguments -import com.lunatech.cmt.client.command.GithubSupport.Asset -import org.http4s.* -import org.http4s.circe.* +import com.lunatech.cmt.core.validation.Validatable import github4s.Github import github4s.domain.Release import io.circe.* +import org.http4s.* +import org.http4s.circe.* +import org.http4s.client.{Client, JavaNetClientBuilder} +import sbt.io.IO as sbtio +import sbt.io.syntax.* + import java.io.File import java.net.URL import java.time.ZonedDateTime -import sbt.io.syntax.* -import sbt.io.IO as sbtio -import org.http4s.client.Client -import org.http4s.client.JavaNetClientBuilder import scala.concurrent.Await import scala.concurrent.duration.* import scala.sys.process.* diff --git a/cmtc/src/main/scala/com/lunatech/cmt/client/command/SetCurrentCourse.scala b/core/src/main/scala/com/lunatech/cmt/client/command/SetCurrentCourse.scala similarity index 87% rename from cmtc/src/main/scala/com/lunatech/cmt/client/command/SetCurrentCourse.scala rename to core/src/main/scala/com/lunatech/cmt/client/command/SetCurrentCourse.scala index c9bfb9cd..c8fe5f9b 100644 --- a/cmtc/src/main/scala/com/lunatech/cmt/client/command/SetCurrentCourse.scala +++ b/core/src/main/scala/com/lunatech/cmt/client/command/SetCurrentCourse.scala @@ -1,10 +1,12 @@ package com.lunatech.cmt.client.command import caseapp.{AppName, CommandName, ExtraName, HelpMessage, RemainingArgs} -import com.lunatech.cmt.client.Domain.StudentifiedRepo -import com.lunatech.cmt.client.cli.ArgParsers.studentifiedRepoArgParser +import com.lunatech.cmt.Domain.StudentifiedRepo +import com.lunatech.cmt.Helpers.findStudentRepoRoot +import com.lunatech.cmt.core.cli.ArgParsers.studentifiedRepoArgParser import com.lunatech.cmt.client.cli.CmtcCommand -import com.lunatech.cmt.client.{Configuration, CurrentCourse, findStudentRepoRoot, listExercises} +import com.lunatech.cmt.client.{Configuration, CurrentCourse} +import com.lunatech.cmt.Helpers.listExercises import com.lunatech.cmt.core.cli.enforceNoTrailingArguments import com.lunatech.cmt.core.validation.Validatable import com.lunatech.cmt.{CMTcConfig, CmtError, printResult} diff --git a/core/src/main/scala/com/lunatech/cmt/core/cli/ArgParsers.scala b/core/src/main/scala/com/lunatech/cmt/core/cli/ArgParsers.scala new file mode 100644 index 00000000..51d8ef27 --- /dev/null +++ b/core/src/main/scala/com/lunatech/cmt/core/cli/ArgParsers.scala @@ -0,0 +1,78 @@ +package com.lunatech.cmt.core.cli + +import caseapp.core.Error +import caseapp.core.Error.Other +import caseapp.core.argparser.{ArgParser, SimpleArgParser} +import cats.syntax.apply.* +import cats.syntax.either.* +import com.lunatech.cmt.Domain.{InstallationSource, StudentifiedRepo} +import com.lunatech.cmt.Domain.InstallationSource.{GithubProject, LocalDirectory, ZipFile} +import com.lunatech.cmt.core.validation.FileValidations.* +import sbt.io.syntax.{File, file} + +object ArgParsers: + + val fileArgParser: ArgParser[File] = + SimpleArgParser.from[File]("file")(file(_).asRight) + + given studentifiedRepoArgParser: ArgParser[StudentifiedRepo] = + fileArgParser.xmapError[StudentifiedRepo]( + _.value, + file => + (file.validateExists, file.validateIsDirectory) + .mapN((_, _) => StudentifiedRepo(file)) + .leftMap(_.flatten) + .toEither) + + given installationSourceArgParser: ArgParser[InstallationSource] = { + + val githubProjectRegex = "([A-Za-z0-9-_]*)\\/([A-Za-z0-9-_]*)".r + + def toString(installationSource: InstallationSource): String = + installationSource match { + case LocalDirectory(value) => value.getAbsolutePath() + case ZipFile(value) => value.getAbsolutePath() + case GithubProject(organisation, project) => s"$organisation/$project" + } + + def fromString(str: String): Either[Error, InstallationSource] = { + val maybeFile = file(str) + val maybeGithub = str match { + case githubProjectRegex(organisation, project) => Some(GithubProject(organisation, project)) + case _ => None + } + + // is it a file? does it exist? + // yes + // - is it a directory? + // yes + // - it's a LocalDirectory + // no + // - does it end in '.zip'? + // yes + // - it's a ZipFile + // no + // - error - can't install from a file + // no + // - is it of the form a/b + // yes + // - it's a GithubProject + // no + // - error - i don't know what to do + (maybeFile.exists(), maybeFile.isDirectory, str.endsWith(".zip"), maybeGithub) match { + case (true, true, _, _) => LocalDirectory(maybeFile).asRight + case (true, false, true, _) => ZipFile(maybeFile).asRight + case (true, false, false, _) => + Other( + s"'$str' is a file but not a zip file - i'm afraid I don't know how to install a course from this file").asLeft + case (false, _, _, Some(githubProject)) => githubProject.asRight + case (_, _, _, _) => + Other( + s"'$str' is not a local directory or zip file and it doesn't appear to be a Github project either. I'm afraid I don't know how to deal with this.").asLeft + } + } + + SimpleArgParser.string.xmapError[InstallationSource](toString, fromString) + } + +end ArgParsers diff --git a/core/src/main/scala/com/lunatech/cmt/core/command/Package.scala b/core/src/main/scala/com/lunatech/cmt/core/command/Package.scala new file mode 100644 index 00000000..5bfbd815 --- /dev/null +++ b/core/src/main/scala/com/lunatech/cmt/core/command/Package.scala @@ -0,0 +1,16 @@ +package com.lunatech.cmt.core.command + +import sbt.io.syntax.File +import sbt.io.IO as sbtio + +import java.nio.charset.StandardCharsets + +object Package: + + def getCurrentExerciseId(bookmarkFile: File): String = + sbtio.readLines(bookmarkFile, StandardCharsets.UTF_8).head + + def starCurrentExercise(currentExercise: String, exercise: String): String = + if (currentExercise == exercise) " * " else " " + +end Package diff --git a/cmtc/src/test/scala/com/lunatech/cmt/client/ConfigurationSpec.scala b/core/src/test/scala/com/lunatech/cmt/client/ConfigurationSpec.scala similarity index 97% rename from cmtc/src/test/scala/com/lunatech/cmt/client/ConfigurationSpec.scala rename to core/src/test/scala/com/lunatech/cmt/client/ConfigurationSpec.scala index 71024f45..c7dc0331 100644 --- a/cmtc/src/test/scala/com/lunatech/cmt/client/ConfigurationSpec.scala +++ b/core/src/test/scala/com/lunatech/cmt/client/ConfigurationSpec.scala @@ -1,18 +1,17 @@ package com.lunatech.cmt.client +import com.lunatech.cmt.Domain.StudentifiedRepo import com.lunatech.cmt.client.Configuration.{CmtHome, GithubApiToken} -import com.lunatech.cmt.client.Domain.StudentifiedRepo +import com.lunatech.cmt.support.EitherSupport +import dev.dirs.ProjectDirectories import org.scalatest.BeforeAndAfterEach import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike -import com.lunatech.cmt.support.EitherSupport import sbt.io.IO as sbtio import sbt.io.syntax.* -import scala.compiletime.uninitialized -import dev.dirs.ProjectDirectories - import java.nio.charset.StandardCharsets +import scala.compiletime.uninitialized final class ConfigurationSpec extends AnyWordSpecLike with Matchers with BeforeAndAfterEach with EitherSupport { diff --git a/cmtc/src/test/scala/com/lunatech/cmt/client/command/InstallSpec.scala b/core/src/test/scala/com/lunatech/cmt/client/command/InstallSpec.scala similarity index 100% rename from cmtc/src/test/scala/com/lunatech/cmt/client/command/InstallSpec.scala rename to core/src/test/scala/com/lunatech/cmt/client/command/InstallSpec.scala diff --git a/cmtc/src/test/scala/com/lunatech/cmt/client/command/SetCurrentCourseSpec.scala b/core/src/test/scala/com/lunatech/cmt/client/command/SetCurrentCourseSpec.scala similarity index 98% rename from cmtc/src/test/scala/com/lunatech/cmt/client/command/SetCurrentCourseSpec.scala rename to core/src/test/scala/com/lunatech/cmt/client/command/SetCurrentCourseSpec.scala index 8cb9b54c..9a735b46 100644 --- a/cmtc/src/test/scala/com/lunatech/cmt/client/command/SetCurrentCourseSpec.scala +++ b/core/src/test/scala/com/lunatech/cmt/client/command/SetCurrentCourseSpec.scala @@ -1,14 +1,14 @@ package com.lunatech.cmt.client.command -import com.lunatech.cmt.client.Domain.StudentifiedRepo +import com.lunatech.cmt.Domain.StudentifiedRepo +import com.lunatech.cmt.Helpers.dumpStringToFile import com.lunatech.cmt.client.{Configuration, CurrentCourse} +import com.lunatech.cmt.support.EitherSupport import org.scalatest.BeforeAndAfterEach import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike -import com.lunatech.cmt.support.EitherSupport import sbt.io.IO as sbtio import sbt.io.syntax.* -import com.lunatech.cmt.Helpers.dumpStringToFile import java.nio.charset.StandardCharsets import scala.compiletime.uninitialized diff --git a/functional-tests/src/test/scala/com/lunatech/cmt/support/TestSupport.scala b/functional-tests/src/test/scala/com/lunatech/cmt/support/TestSupport.scala index 85d256b7..213b1a25 100644 --- a/functional-tests/src/test/scala/com/lunatech/cmt/support/TestSupport.scala +++ b/functional-tests/src/test/scala/com/lunatech/cmt/support/TestSupport.scala @@ -17,9 +17,10 @@ import com.lunatech.cmt.Helpers.* import com.lunatech.cmt.admin.Domain.MainRepository import com.lunatech.cmt.admin.cli.SharedOptions import com.lunatech.cmt.admin.command +import com.lunatech.cmt.Domain.StudentifiedRepo import com.lunatech.cmt.client.{Configuration, CoursesDirectory, CurrentCourse} import com.lunatech.cmt.client.Configuration.{CmtHome, GithubApiToken} -import com.lunatech.cmt.client.Domain.{ExerciseId, ForceMoveToExercise, StudentifiedRepo, TemplatePath} +import com.lunatech.cmt.client.Domain.{ExerciseId, ForceMoveToExercise, TemplatePath} import com.lunatech.cmt.client.command.{ GotoExercise, GotoFirstExercise, diff --git a/project/Build.scala b/project/Build.scala index ce378d35..4c38f1b9 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -27,9 +27,7 @@ object Build { scalacOptions ++= CompileOptions.compileOptions, buildInfoPackage := "com.lunatech.cmt.version", Test / parallelExecution := false, - Test / logBuffered := false, - // ThisBuild / parallelExecution := false, - libraryDependencies ++= Dependencies.cmtDependencies) + Test / logBuffered := false) lazy val commonBuildInfoKeys = Seq[BuildInfoKey](version, scalaVersion, sbtVersion) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8af4bccf..2fed390b 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -40,6 +40,8 @@ object Dependencies { import Library._ + lazy val coreDependencies = (http4s ++ List(sbtio, typesafeConfig, scalaTest, scalaCheck, commonsCodec, caseapp, cats, devDirs, circe, github4s)).map(_.withSources()) lazy val cmtDependencies = List(sbtio, typesafeConfig, scalaTest, scalaCheck, commonsCodec, caseapp, cats).map(_.withSources()) - lazy val cmtcDependencies = (http4s ++ List(devDirs, circe, github4s)).map(_.withSources()) + lazy val cmtcDependencies = (http4s ++ List(devDirs, circe, github4s, scalaTest, scalaCheck)).map(_.withSources()) + lazy val functionalTestDependencies = List(scalaTest, scalaCheck).map(_.withSources()) }