diff --git a/NodeApp/src/commander/exercise/ExerciseRunCommand.ts b/NodeApp/src/commander/exercise/ExerciseRunCommand.ts index b5eec3e44c8bd667145564999c9e184b49a6df2f..4fb7ea8dbf61e3992f5b96297b7b5b7ee1599f70 100644 --- a/NodeApp/src/commander/exercise/ExerciseRunCommand.ts +++ b/NodeApp/src/commander/exercise/ExerciseRunCommand.ts @@ -1,19 +1,19 @@ -import CommanderCommand from '../CommanderCommand'; -import Config from '../../config/Config'; -import fs from 'node:fs'; -import ora from 'ora'; -import util from 'util'; -import { exec } from 'child_process'; -import chalk from 'chalk'; -import * as os from 'os'; -import path from 'path'; -import ClientsSharedConfig from '../../sharedByClients/config/ClientsSharedConfig'; -import AssignmentFile from '../../shared/types/Dojo/AssignmentFile'; -import ExerciseDockerCompose from '../../sharedByClients/helpers/Dojo/ExerciseDockerCompose'; -import ExerciseResultsValidation from '../../sharedByClients/helpers/Dojo/ExerciseResultsValidation'; -import SharedAssignmentHelper from '../../shared/helpers/Dojo/SharedAssignmentHelper'; -import ExerciseCheckerError from '../../shared/types/Dojo/ExerciseCheckerError'; -import ClientsSharedExerciseHelper from '../../sharedByClients/helpers/Dojo/ClientsSharedExerciseHelper'; +import CommanderCommand from '../CommanderCommand'; +import Config from '../../config/Config'; +import fs from 'node:fs'; +import ora from 'ora'; +import util from 'util'; +import { exec } from 'child_process'; +import chalk from 'chalk'; +import * as os from 'os'; +import path from 'path'; +import ClientsSharedConfig from '../../sharedByClients/config/ClientsSharedConfig'; +import AssignmentFile from '../../shared/types/Dojo/AssignmentFile'; +import ExerciseDockerCompose from '../../sharedByClients/helpers/Dojo/ExerciseDockerCompose'; +import SharedAssignmentHelper from '../../shared/helpers/Dojo/SharedAssignmentHelper'; +import ExerciseCheckerError from '../../shared/types/Dojo/ExerciseCheckerError'; +import ClientsSharedExerciseHelper from '../../sharedByClients/helpers/Dojo/ClientsSharedExerciseHelper'; +import ExerciseResultsSanitizerAndValidator from '../../sharedByClients/helpers/Dojo/ExerciseResultsSanitizerAndValidator'; const execAsync = util.promisify(exec); @@ -36,7 +36,7 @@ class ExerciseRunCommand extends CommanderCommand { this.command .description('locally run an exercise') .option('-p, --path <value>', 'exercise path', Config.folders.defaultLocalExercise) - .option('-v, --verbose', 'exercise path', Config.folders.defaultLocalExercise) + .option('-v, --verbose', 'verbose mode (display docker compose logs in live)') .action(this.commandAction.bind(this)); } @@ -48,11 +48,13 @@ class ExerciseRunCommand extends CommanderCommand { } protected async commandAction(options: { path: string, verbose: boolean }): Promise<void> { - const localExercisePath = options.path ?? Config.folders.defaultLocalExercise; + const localExercisePath: string = options.path ?? Config.folders.defaultLocalExercise; let assignmentFile: AssignmentFile; let exerciseDockerCompose: ExerciseDockerCompose; - let exerciseResultsValidation: ExerciseResultsValidation; + let exerciseResultsValidation: ExerciseResultsSanitizerAndValidator; + + let haveResultsVolume: boolean; // Step 1: Check requirements (if it's an exercise folder and if Docker deamon is running) { @@ -102,6 +104,8 @@ class ExerciseRunCommand extends CommanderCommand { assignmentFile = validationResults.results!; } + haveResultsVolume = assignmentFile.result.volume !== undefined; + spinner.succeed(`The ${ Config.assignment.filename } file is valid`); } @@ -128,12 +132,16 @@ class ExerciseRunCommand extends CommanderCommand { { console.log(chalk.cyan('Please wait while we are running the exercise...')); + let composeFileOverride: string[] = []; const composeOverridePath: string = path.join(localExercisePath, 'docker-compose-override.yml'); + if ( haveResultsVolume ) { + const composeOverride = fs.readFileSync(path.join(__dirname, '../../../assets/docker-compose-override.yml'), 'utf8').replace('{{VOLUME_NAME}}', assignmentFile.result.volume!).replace('{{MOUNT_PATH}}', this.folderResultsExercise); + fs.writeFileSync(composeOverridePath, composeOverride); - const composeOverride = fs.readFileSync(path.join(__dirname, '../../../assets/docker-compose-override.yml'), 'utf8').replace('{{VOLUME_NAME}}', assignmentFile.result.volume).replace('{{MOUNT_PATH}}', this.folderResultsExercise); - fs.writeFileSync(composeOverridePath, composeOverride); + composeFileOverride = [ composeOverridePath ]; + } - exerciseDockerCompose = new ExerciseDockerCompose(this.projectName, assignmentFile, localExercisePath, [ composeOverridePath ]); + exerciseDockerCompose = new ExerciseDockerCompose(this.projectName, assignmentFile, localExercisePath, composeFileOverride); try { await new Promise<void>((resolve, reject) => { @@ -152,13 +160,31 @@ class ExerciseRunCommand extends CommanderCommand { text : message, indent: 4 }).start(); + + if ( options.verbose && name == 'COMPOSE_RUN' ) { + spinner.info(); + } }); exerciseDockerCompose.events.on('endStep', (stepName: string, message: string, error: boolean) => { if ( error ) { - spinner.fail(message); + if ( options.verbose && stepName == 'COMPOSE_RUN' ) { + ora({ + text : message, + indent: 4 + }).start().fail(); + } else { + spinner.fail(message); + } } else { - spinner.succeed(message); + if ( options.verbose && stepName == 'COMPOSE_RUN' ) { + ora({ + text : message, + indent: 4 + }).start().succeed(); + } else { + spinner.succeed(message); + } } }); @@ -170,7 +196,7 @@ class ExerciseRunCommand extends CommanderCommand { }); } catch ( error ) { } - fs.rmSync(composeOverridePath); + fs.rmSync(composeOverridePath, { force: true }); fs.writeFileSync(this.fileComposeLogs, exerciseDockerCompose.allLogs); if ( !exerciseDockerCompose.success ) { @@ -184,7 +210,7 @@ class ExerciseRunCommand extends CommanderCommand { { console.log(chalk.cyan('Please wait while we are checking the results...')); - exerciseResultsValidation = new ExerciseResultsValidation(this.folderResultsDojo, this.folderResultsExercise); + exerciseResultsValidation = new ExerciseResultsSanitizerAndValidator(this.folderResultsDojo, this.folderResultsExercise, exerciseDockerCompose.exitCode); try { await new Promise<void>((resolve, reject) => { diff --git a/NodeApp/src/shared b/NodeApp/src/shared index 8d7e3ca0cca10e874ac48e19e47da8a1491ccba7..8bdbef31376a8284bd8a5139588b43a57cf74a4b 160000 --- a/NodeApp/src/shared +++ b/NodeApp/src/shared @@ -1 +1 @@ -Subproject commit 8d7e3ca0cca10e874ac48e19e47da8a1491ccba7 +Subproject commit 8bdbef31376a8284bd8a5139588b43a57cf74a4b diff --git a/NodeApp/src/sharedByClients b/NodeApp/src/sharedByClients index 4ff3846e9415a6122b0b966be089eec3f0117f4f..97ba763f9517880ecfa6245c172a0e330ebdd11a 160000 --- a/NodeApp/src/sharedByClients +++ b/NodeApp/src/sharedByClients @@ -1 +1 @@ -Subproject commit 4ff3846e9415a6122b0b966be089eec3f0117f4f +Subproject commit 97ba763f9517880ecfa6245c172a0e330ebdd11a