diff --git a/ExerciceChecker/src/app.ts b/ExerciceChecker/src/app.ts index 84168a52c86110ef280f8c58cd18875bb02806cc..abccdb23da378f896318247f630fd21bbfcb9335 100644 --- a/ExerciceChecker/src/app.ts +++ b/ExerciceChecker/src/app.ts @@ -4,29 +4,33 @@ const path = require('node:path'); require('dotenv').config({ path: path.join(__dirname, '../.env') }); require('./shared/helpers/TypeScriptExtensions'); // ATTENTION : This line MUST be the second of this file -import * as fs from 'fs'; -import chalk from 'chalk'; -import HttpManager from './managers/HttpManager'; -import DojoBackendManager from './managers/DojoBackendManager'; -import Config from './config/Config'; +import ExerciceCheckerError from './types/ExerciceCheckerError'; +import { exec, spawn } from 'child_process'; +import util from 'util'; +import * as fs from 'fs'; +import chalk from 'chalk'; +import HttpManager from './managers/HttpManager'; +import DojoBackendManager from './managers/DojoBackendManager'; +import Config from './config/Config'; (async () => { - HttpManager.registerAxiosInterceptor(); - + const execAsync = util.promisify(exec); - console.log(chalk.blue('Dojo Exercice Checker')); + HttpManager.registerAxiosInterceptor(); + console.log(chalk.bgBlue.black.bold('DOJO EXERCICE CHECKER')); /* Step 1 & 2: - Read the dojo enonce file from the enonce repository - Download immutables files (maybe throw or show an error if the files have been modified ?) */ + console.log(chalk.green('Checking the exercice\'s enonce and his immutables files')); const exerciceEnonce = await DojoBackendManager.getExerciceEnonce(); if ( !exerciceEnonce ) { console.error(chalk.red(`Error while getting the exercice's enonce`)); - process.exit(1); + process.exit(ExerciceCheckerError.EXERCICE_ENONCE_GET_ERROR); } exerciceEnonce.immutable.forEach(immutableFile => { @@ -36,10 +40,61 @@ import Config from './config/Config'; }); - // Step 3: Run docker-compose file - // Step 4: Wait the end of the execution of the result container + /* + Step 3 & 4: + - Run docker-compose file + - Wait until the end of the execution of the result container + */ + console.log(chalk.green('Run docker compose file')); + const changeDirectoryCommand = `cd "${ Config.filesFolder }"`; + const dockerComposeCommand = `docker compose --project-name ${ Config.dockerCompose.projectName } --progress plain`; + + const containerExitStatus = await new Promise<[ number, string ]>((resolve, reject) => { + let logs = '####################################################### Docker Compose & Main Container Logs #######################################################\n'; + + const dockerCompose = spawn(`${ dockerComposeCommand } run ${ exerciceEnonce.enonceFile.result.container }`, { + cwd : Config.filesFolder, + shell: true, + env : { + 'DOCKER_BUILDKIT' : '1', + 'BUILDKIT_PROGRESS': 'plain', ...process.env + } + }); + + dockerCompose.stdout.on('data', (data) => { + logs += data.toString(); + console.log(data.toString()); + }); + + dockerCompose.stderr.on('data', (data) => { + logs += data.toString(); + console.error(data.toString()); + }); + + dockerCompose.on('exit', (code) => { + logs += '####################################################### Other Services Logs #######################################################\n'; + resolve([ code ?? ExerciceCheckerError.DOCKER_COMPOSE_UP_ERROR, logs ]); + }); + }); + if ( containerExitStatus[0] === ExerciceCheckerError.DOCKER_COMPOSE_UP_ERROR ) { + console.error(chalk.red(`Error while running the docker-compose file`)); + process.exit(containerExitStatus[0]); + } + fs.writeFileSync(`${ Config.resultsFolder }/dockerComposeLogs.txt`, containerExitStatus[1]); + + try { + await execAsync(`${ changeDirectoryCommand };${ dockerComposeCommand } logs --timestamps >> ${ Config.resultsFolder }/dockerComposeLogs.txt`); + } catch ( error ) { + console.error(chalk.red(`Error while getting the docker-compose logs`)); + process.exit(ExerciceCheckerError.DOCKER_COMPOSE_LOGS_ERROR); + } + + // Step 5: Get the result from the volume // Step 6: Check content requirements and content size // Step 7: Upload and show the results + + // Step 8: Exit with container exit code + process.exit(containerExitStatus[0]); })();