From dd1de8405e50b7e26b70b5676ee303ac71c56dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <michael@minelli.me> Date: Thu, 10 Aug 2023 01:01:37 +0200 Subject: [PATCH] Add icon and styles provided by types (remove code duplicates) --- ExerciceChecker/src/app.ts | 63 +++++++++++++--------------- ExerciceChecker/src/config/Config.ts | 4 ++ ExerciceChecker/src/types/Icon.ts | 9 ++++ ExerciceChecker/src/types/Styles.ts | 13 ++++++ 4 files changed, 55 insertions(+), 34 deletions(-) create mode 100644 ExerciceChecker/src/types/Icon.ts create mode 100644 ExerciceChecker/src/types/Styles.ts diff --git a/ExerciceChecker/src/app.ts b/ExerciceChecker/src/app.ts index 8a3695a..afc0cb6 100644 --- a/ExerciceChecker/src/app.ts +++ b/ExerciceChecker/src/app.ts @@ -4,6 +4,8 @@ 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 Styles from './types/Styles'; +import Icon from './types/Icon'; import boxen from 'boxen'; import RecursiveFilesStats from './shared/helpers/recursiveFilesStats/RecursiveFilesStats'; import Toolbox from './shared/helpers/Toolbox'; @@ -12,7 +14,6 @@ import ExerciceCheckerError from './types/ExerciceCheckerError'; import { exec, spawn } from 'child_process'; import util from 'util'; import fs from 'fs-extra'; -import chalk from 'chalk'; import HttpManager from './managers/HttpManager'; import DojoBackendManager from './managers/DojoBackendManager'; import Config from './config/Config'; @@ -24,22 +25,17 @@ import ArchiveHelper from './shared/helpers/ArchiveHelper'; HttpManager.registerAxiosInterceptor(); - const chalkInfo: chalk.Chalk = chalk.blue; - const chalkError: chalk.Chalk = chalk.red; - const chalkSuccess: chalk.Chalk = chalk.green; - const chalkFailure: chalk.Chalk = chalk.red; - - console.log(chalk.bgBlue.black.bold('DOJO EXERCICE CHECKER')); + console.log(Styles.APP_NAME(Config.appName)); /* - Step 1 & 2: + //////////////////////////////////////////////////////////////////////////////////////////////////////////// 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(chalkInfo(`- Checking the exercice's enonce and his immutable files`)); + console.log(Styles.INFO(`${ Icon.INFO }️ Checking the exercice's enonce and his immutable files`)); const exerciceEnonce = await DojoBackendManager.getExerciceEnonce(); if ( !exerciceEnonce ) { - console.error(chalkError(`X Error while getting the exercice's enonce`)); + console.error(Styles.ERROR(`${ Icon.ERROR } Error while getting the exercice's enonce`)); process.exit(ExerciceCheckerError.EXERCICE_ENONCE_GET_ERROR); } @@ -51,12 +47,12 @@ import ArchiveHelper from './shared/helpers/ArchiveHelper'; /* - Step 3 & 4 & 5: + //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 3 & 4 & 5: - Get override of docker-compose file (for override the volume by a bind mount to the results folder shared between dind and the host) - Run docker-compose file - Get logs from linked services */ - console.log(chalkInfo('- Run docker compose file')); + console.log(Styles.INFO(`${ Icon.INFO } Run docker compose file`)); const dockerComposeOverride = fs.readFileSync(path.join(__dirname, '../assets/docker-compose-override.yml'), 'utf8').replace('{{VOLUME_NAME}}', exerciceEnonce.enonceFile.result.volume).replace('{{MOUNT_PATH}}', Config.folders.resultsExercice); fs.writeFileSync(`${ Config.folders.project }/docker-compose-override.yml`, dockerComposeOverride); @@ -92,34 +88,34 @@ import ArchiveHelper from './shared/helpers/ArchiveHelper'; }); const containerExitCode = containerExitStatus[0]; if ( containerExitCode === ExerciceCheckerError.DOCKER_COMPOSE_UP_ERROR ) { - console.error(chalkError(`X Error while running the docker compose file`)); + console.error(Styles.ERROR(`${ Icon.ERROR } Error while running the docker compose file`)); process.exit(containerExitCode); } fs.writeFileSync(`${ Config.folders.resultsDojo }/dockerComposeLogs.txt`, containerExitStatus[1]); - console.log(chalkInfo('- Acquire logs of linked services')); + console.log(Styles.INFO(`${ Icon.INFO } Acquire logs of linked services`)); try { await execAsync(`${ changeDirectoryCommand };${ dockerComposeCommand } logs --timestamps >> ${ Config.folders.resultsDojo }/dockerComposeLogs.txt`); } catch ( error ) { - console.error(chalkError(`X Error while getting the linked services logs`)); + console.error(Styles.ERROR(`${ Icon.ERROR } Error while getting the linked services logs`)); process.exit(ExerciceCheckerError.DOCKER_COMPOSE_LOGS_ERROR); } - // Step 6: Check content requirements and content size - console.log(chalkInfo('- Validating results folder size')); + //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 6: Check content requirements and content size + console.log(Styles.INFO(`${ Icon.INFO } Validating results folder size`)); const resultsFolderSize = await Toolbox.fs.getTotalSize(Config.folders.resultsExercice); if ( resultsFolderSize > Config.resultsFolderMaxSizeInBytes ) { - console.error(chalkError(`X Results folder size is too big (bigger than ${ Config.resultsFolderMaxSizeInBytes / 1000000 })`)); + console.error(Styles.ERROR(`${ Icon.ERROR } Results folder size is too big (bigger than ${ Config.resultsFolderMaxSizeInBytes / 1000000 })`)); process.exit(ExerciceCheckerError.EXERCICE_RESULTS_FOLDER_TOO_BIG); } - console.log(chalkInfo('- Checking results file')); + console.log(Styles.INFO(`${ Icon.INFO } Checking results file`)); const resultsFileOriginPath = path.join(Config.folders.resultsExercice, Config.filenames.results); const resultsFilePath = path.join(Config.folders.resultsDojo, Config.filenames.results); if ( !fs.existsSync(resultsFileOriginPath) ) { - console.error(chalkError(`X Results file not found.`)); + console.error(Styles.ERROR(`${ Icon.ERROR } Results file not found.`)); process.exit(ExerciceCheckerError.EXERCICE_RESULTS_FILE_NOT_FOUND); } @@ -128,15 +124,15 @@ import ArchiveHelper from './shared/helpers/ArchiveHelper'; const validationResults = ExerciceHelper.validateResultFile(resultsFilePath); if ( !validationResults.isValid ) { - console.error(chalkError(`X Results file is not valid. Here are the errors :`)); - console.error(chalkError(JSON.stringify(validationResults.errors))); + console.error(Styles.ERROR(`${ Icon.ERROR } Results file is not valid. Here are the errors :`)); + console.error(Styles.ERROR(JSON.stringify(validationResults.errors))); process.exit(ExerciceCheckerError.EXERCICE_RESULTS_FILE_SCHEMA_NOT_VALID); } - // Step 7: Upload and show the results + //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 7: Upload and show the results try { - console.log(chalkInfo(`- Uploading results to the dojo server`)); + console.log(Styles.INFO(`${ Icon.INFO } Uploading results to the dojo server`)); const commit: any = {}; Toolbox.getKeysWithPrefix(process.env, 'CI_COMMIT_').forEach(key => { commit[Toolbox.snakeToCamel(key.replace('CI_COMMIT_', ''))] = process.env[key]; @@ -149,22 +145,22 @@ import ArchiveHelper from './shared/helpers/ArchiveHelper'; await DojoBackendManager.sendResults(containerExitCode, commit, validationResults.results!, files, await ArchiveHelper.getBase64(Config.folders.resultsVolume)); } catch ( error ) { - console.error(chalkError(`X Error while uploading the results`)); + console.error(Styles.ERROR(`${ Icon.ERROR } Error while uploading the results`)); console.error(JSON.stringify(error)); process.exit(ExerciceCheckerError.UPLOAD); } - // Step 8: Exit with container exit code - const finalLogGlobalResult = `${ chalkInfo('Global result') } : ${ validationResults.results!.success ? chalkSuccess('✅ Success') : chalkFailure('❌ Failure') }`; + //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 8: Exit with container exit code + const finalLogGlobalResult = `${ Styles.INFO('Global result') } : ${ validationResults.results!.success ? Styles.SUCCESS(`${ Icon.SUCCESS } Success`) : Styles.FAILURE(`${ Icon.FAILURE } Failure`) }`; - const finalLogExecutionExitCode = `${ chalkInfo('Execution exit code') } : ${ (containerExitCode == 0 ? chalkSuccess : chalkError)(containerExitCode) }`; + const finalLogExecutionExitCode = `${ Styles.INFO('Execution exit code') } : ${ (containerExitCode == 0 ? Styles.SUCCESS : Styles.ERROR)(containerExitCode) }`; - const finalLogResultNumbers = validationResults.results!.successfulTests || validationResults.results!.failedTests ? `\n\n${ chalkSuccess('Tests passed') } : ${ validationResults.results!.successfulTests ?? '--' }\n${ chalkError('Tests failed') } : ${ validationResults.results!.failedTests ?? '--' }` : ''; + const finalLogResultNumbers = validationResults.results!.successfulTests || validationResults.results!.failedTests ? `\n\n${ Styles.SUCCESS('Tests passed') } : ${ validationResults.results!.successfulTests ?? '--' }\n${ Styles.ERROR('Tests failed') } : ${ validationResults.results!.failedTests ?? '--' }` : ''; - const finalLogSuccessResultDetails = (validationResults.results!.successfulTestsList ?? []).map(testName => `- ✅ ${ testName }`).join('\n'); - const finalLogFailedResultDetails = (validationResults.results!.failedTestsList ?? []).map(testName => `- ❌ ${ testName }`).join('\n'); - const finalLogResultDetails = validationResults.results!.successfulTestsList || validationResults.results!.failedTestsList ? `\n\n${ chalkInfo('Tests') } :${ finalLogSuccessResultDetails != '' ? '\n' + finalLogSuccessResultDetails : '' }${ finalLogFailedResultDetails != '' ? '\n' + finalLogFailedResultDetails : '' }` : ''; + const finalLogSuccessResultDetails = (validationResults.results!.successfulTestsList ?? []).map(testName => `- ${ Icon.SUCCESS } ${ testName }`).join('\n'); + const finalLogFailedResultDetails = (validationResults.results!.failedTestsList ?? []).map(testName => `- ${ Icon.FAILURE } ${ testName }`).join('\n'); + const finalLogResultDetails = validationResults.results!.successfulTestsList || validationResults.results!.failedTestsList ? `\n\n${ Styles.INFO('Tests') } :${ finalLogSuccessResultDetails != '' ? '\n' + finalLogSuccessResultDetails : '' }${ finalLogFailedResultDetails != '' ? '\n' + finalLogFailedResultDetails : '' }` : ''; console.log(boxen(`${ finalLogGlobalResult }\n\n${ finalLogExecutionExitCode }${ finalLogResultNumbers }${ finalLogResultDetails }`, { title : 'Results', @@ -177,5 +173,4 @@ import ArchiveHelper from './shared/helpers/ArchiveHelper'; })); process.exit(containerExitCode); -})(); - +})(); \ No newline at end of file diff --git a/ExerciceChecker/src/config/Config.ts b/ExerciceChecker/src/config/Config.ts index 2b47064..6782c14 100644 --- a/ExerciceChecker/src/config/Config.ts +++ b/ExerciceChecker/src/config/Config.ts @@ -3,6 +3,8 @@ import path from 'path'; class Config { + public readonly appName: string; + public readonly resultsFolderMaxSizeInBytes: number; public readonly folders: { @@ -22,6 +24,8 @@ class Config { }; constructor() { + this.appName = process.env.APP_NAME || ''; + this.resultsFolderMaxSizeInBytes = Number(process.env.RESULTS_FOLDER_MAX_SIZE_IN_BYTES || 0); this.folders = { diff --git a/ExerciceChecker/src/types/Icon.ts b/ExerciceChecker/src/types/Icon.ts new file mode 100644 index 0000000..9d5a0ec --- /dev/null +++ b/ExerciceChecker/src/types/Icon.ts @@ -0,0 +1,9 @@ +enum Icon { + INFO = 'ℹ️', + ERROR = '⛔️', + SUCCESS = '✅', + FAILURE = '❌' +} + + +export default Icon; \ No newline at end of file diff --git a/ExerciceChecker/src/types/Styles.ts b/ExerciceChecker/src/types/Styles.ts new file mode 100644 index 0000000..64f6bdd --- /dev/null +++ b/ExerciceChecker/src/types/Styles.ts @@ -0,0 +1,13 @@ +import chalk from 'chalk'; + + +class Styles { + public readonly APP_NAME = chalk.bgBlue.black.bold; + public readonly INFO = chalk.blue; + public readonly ERROR = chalk.red; + public readonly SUCCESS = chalk.green; + public readonly FAILURE = chalk.red; +} + + +export default new Styles(); \ No newline at end of file -- GitLab