diff --git a/NodeApp/.env.vault b/NodeApp/.env.vault index d23514b1f82b73507230f27e5d9b2f1fbaec3e90..08c024706a6acbd81885bf354454c5ddc6d6c4ea 100644 --- a/NodeApp/.env.vault +++ b/NodeApp/.env.vault @@ -4,8 +4,8 @@ #/--------------------------------------------------/ # development -DOTENV_VAULT_DEVELOPMENT="NTrhViMVBn/ekwfQ6v08+59FZipjGK0nZ7HJ7eUW1x4BrUG/hQlj3oRMddzPWa8DE8e++W/SCLWWdP6kEOj0xreTQyDymi1d/95TswRdGrmST9iYBTiW7SBoCW0jUCkXkCVcFj/81cButo52OP7BJoAyosc0R6qtt6mO+zxMSyA51tVERgis9TMHTkqH42Fa+2w0ggcYuu3fdbKLUSYoJMLeM08MttiGHy+5bPnS6fCpSuZzNpt9tgMz+K4uAkKjsRAk2BF8xrW3stG4CcWlejhHPllMh0hCF1tISrN2pTmAqS2J/MbIouohr7+LA/9Jqm/oaFUs1lybhMjT45DE7BjqOQWPKEhXx+8faWujOs2v5cV9X3W8uGvQlI4tluXxdvj/wJvPh8BoI7SLpZ0+6xSTl99TorE5bg5n1yuXRLcfZ3HuCqvgXAUAF8l955H9Bjgssoufe4BZroNkt1HWSgEIPMpJGMmzP27rpAfV9ROwQl6aMtCVFiC/0FvxgW4P8N/UgGAS4xCgWqURZ/3wFsko+RBG2gJ3FYEj+PnoRJoR7zhjKZhywLfNESshDmOsIUPYpMQEgKl7CEaRVFy+GSjnHosDeIZu7JqDJnU+URRQf1SzJqByjOyfVViI4Dqzhtm3lzT77xW5jJUurO+uhYGD8jDAKkwtSJV/RHLyz3p56No1YW2buIZhRTVcfmRsHYfTdZNFBY+lzR4DWe9HXbJ48apMN83grqlsFzyT9wfxMwzJAeR2Ah+QQyRTar3y0gckJWesdXprTGJbNZDmSCzMK1p6lvWtfnIgN0KJfQDU/OuoUogaiYJdJQ8cUDyTEARZtfQLV7+gMpf2BU66EGB8LhTmd1vqRusyYV1P7O8pfDjyt8j5uvpi4fCeIFpFcOdUANq6NrXnhvsFIc9gKk20Ky8Ar0QYtFXvo3K2dXcWbhj8sUN61rNHTC5JgWL8N8mf5kVmeIPZv/E5JfcFSPACVw==" +DOTENV_VAULT_DEVELOPMENT="FvCrekiDgv/1bvov01DTRTEdipq7tduoYf/cAjX3+slE4zZSVG5S7AuQ2bXf4gzSHrfxjsx2kTl5ild1l+pSQGiDrLqdj0EigMleCya/xRiEDuVBeGRLZLJfWS/AGYi31/sNxtCT2FBcYoEZ+6KF0pq7jyMNTwaFFoSZgTBd+kk3GG1iF36pxt+lGHyeI6TOQQtFFgyoVzxLLZeBQp0V2OJAltVvXnCHzgKyY4zyHb5teyNVEKa2HOf5UivnWJqk89HSD8c+ijvS8Jq8JRu7nzI81JJQwGmU3MNUyRkt+jVJxv0H67YU5Cw18Fqa3NEb8K9mDeHJImwfU2HGhv8WZzqWEXKC/so1hjO6qWOHxwWPqko5YYNPOQw0vPwEzXZPcY/OSH70gHYqkJl3zOA1GwdHY1jBmwdPWOu6GSekxPED8gDrtW6x0TsvdSfLGRODDTIXJVCKM3xkkkV7oU+4hO743HwrVQxvyWrLQucPFSMQVEe+XA0kUddNGcgj9A3VfpWJwm2NycQXqYWuOEX0Q3qyLVi75KvZsPr8vBR3EcZfWtYGfC/2a8rl+kAZ9w8wpBoca6F8nnFkh7deB+/fV5uMRSDiEHI+aJufDFcOXq4J+uljQRDlCo8trrRkcqkYLJWg/ctvDWBG7A6ODgWLk31ycCryj/w297UsE7mew84uA5eCFQIbO3PT9MIKMy0hK3pFkoQq3KhL9S9/dl8VtvvyfNu1zfPyNl6ckiBJz0zG7zIV5sxGUcSdClUBluaQBxdU1kA2kkoAYrPTX56XaC9ZLx9VvbloWRAJxMwxnQV6w1vxWxRgtV3tzlZBK2JyWtEu+cykbnLJM4cfhP/7bysZqnidOuwv7cZy33plIFqzXxOiujCxpShI3IoALnx+nRo/vS4QvLJwU9Lh5QsSuKzHXoheobCpqgZM2aflNPmFdUPAgCqXJ5caEjRSdqlGf/lFE84qrwl3XB8rU4Emn1jIK7SwlcNbk4fVq6BccOIzS0tZzB4EPZNg6YYO8jfRNVhr2On8WOAwtVH9Jikvq2ffD88GQMZu+d/YDLwAmgg4eIjQscNHPvERyjlhyKE5" # production -DOTENV_VAULT_PRODUCTION="QyizJk0k4H0ebjOx03rGPVAL8XM2oRjdO6CXvCXATMvwgdLGGV7k4FKc5vWea7G7JL21KuHRAjdzq/DRhke5N1x5RECcKenMOBvClya6B4tj+UB3mixDkU5uTqAbcdvA64WGbQB3Ubh1ZVIgSLyK3ZUotbrKJkFplLWEuXfOtiRtc1o5MJVDYwy3aIxl2F0xUseSM7TYvH/HRwYwnddSojwaZ2UMQTM6ne4KifQSY6/VFlkaHen+9z8tjs9TLcRrxZK63WhN4OTDC3E1c6dRH9JIyAc6a1LE2L1CaGUvyCU3ipNkocLG+p/kJitJRK75PSbx2zfhceahC6PFkU5rdKpBLU06T8fyVNz2t4WemBT4qvVl7O7CbSN3WaL5talyrVVQEib4P3vg7O+c3tz+A6ZZltHSryROtiV4lD7cievfUPirzBlhkdn+g4qa2Z3v5p7/gMQ5fOEwFpOMDylXE+z7k9P+2KJWzFrQgEXHvBtiGQ79FIB2F+NjBLh4LeqyUjJFJCT/D2glDfRc+yJiiZhpOAx/7NYRQRjP26cgH9/IlLQXzzot362IjvomLKEjws9x2AlKXWy78xvIQPEnb4MCEuL2HJlRHll6aAKUeHpSyMfIqTJhTVkNmlChYXtbxuYvAwyEFVMLCtgbsyzCJmaHV9XQUzgreinKVJAV206xanLmS9mYd2jk6HopaUIDBLEN5HswOMAkVHkJKX65D8eQzEk0E9ymmnA6rui0mLz6gVRFuKmMZKpYcMZMiTk3oeFc/ZXTrj1iXHAJdeIs3bwdPTy/vejWMjeLxbH7HbKyYccQ4aG7N5oyiN+7SjuTJ0Y/eNzBIb2VXB6Zq//2lLHhs7+dfQZa" +DOTENV_VAULT_PRODUCTION="XJI0mhrbeefm0pw+Ii2qnr8DLtnxVYRAt+jdzIudrQmrepJBuj7ujWT3+e4Fydw5zgqQeSZHLolSNV/hCh97cNmTd4+vEipb6pfoEPlTDoiv869kcOW9oJ2St5RcWK4ZtTTlJNXqD9AWp5ST+Ox83SUsGjZpqTdz7pN9YnnlnoWaCDxnWxPI25CqKfwI66ALvbZ3/GYplT8nWC9cVll9UnwgpFF8ol+AXO57cccLz1dzEjGI4bODbrjhxO9ZkgNbVYHpemY10hV7BeVsSR5wwuxXI8B0cG4jhlXX6Uf/GnGSJ++4LsIraA7FnNmtBpxIXnsImU6G4j3ILJvtnjhl6aIL39zenlZep7ZeTQAtQPhHUmS/tF9xPBqFSUTghE+ZrLOHnqvoXl1/n4ynPCz20VzJtQ4MaoxaO4qOoktyMXU9c1YpqyG7qfLD3N2z6DK3jnIz8RhAhYimKpRb9QuH8gbKHu4BsQlNrl1VQz78sFo9XxtrrxLIOQgMNoANtqROfiVQdcpl4MdK/H3iPpPI/H2esovjjuL+h42tDLbjPq7H2ghjHzckK14ZwO20zyStK9hRY5fAfeO61v6n5EOrsFsjbO/6tIuyG0JQniUnDFWtyxFq78i8F/hom6UbJunHvyV69uSfqdST61vAU/yFtgBZ0WosTUQB7aBJ5nkRRfliZhYu/UCAJ/nJDtjnKgv0kbl0KmTMDTa3HeOfDpK6Yd53IrvPxgfaTkALB0yfAm6W9vGdV4675aLBIJ8A7PjdLz+Ydw6QmDWUROe+XGXGDKlQe2YGBdjT9fO9qEf7Hiv68xizdh3XYdkbr6cj8YDDI84ZpswoUjhVnzEb5erg1OIgHFAYtVV9jdmI8N+c426QcyEOXXSQI1/AM0rDKitdftZZahiaCRKtHDs1Zfnn+LulOKaJP7abgYlPYFkj7LpDVUaPZqo34uMbWatoltQpUbGIYGc=" diff --git a/NodeApp/package-lock.json b/NodeApp/package-lock.json index c31f89fb2c84722aebd72bd9a722586039995f03..38eccb9553557d7eef62152401c803a1503e3983 100644 --- a/NodeApp/package-lock.json +++ b/NodeApp/package-lock.json @@ -16,6 +16,7 @@ "chalk": "^4.1.2", "commander": "^11.0.0", "dotenv": "^16.3.1", + "dotenv-expand": "^10.0.0", "fs-extra": "^11.1.1", "http-status-codes": "^2.2.0", "inquirer": "^8.2.5", @@ -23,7 +24,8 @@ "jsonwebtoken": "^8.5.1", "ora": "^5.4.1", "tar-stream": "^3.1.6", - "winston": "^3.10.0" + "winston": "^3.10.0", + "yaml": "^2.3.2" }, "bin": { "dojo": "dist/app.js" @@ -1354,6 +1356,14 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "engines": { + "node": ">=12" + } + }, "node_modules/dotenv-vault": { "version": "1.25.0", "resolved": "https://registry.npmjs.org/dotenv-vault/-/dotenv-vault-1.25.0.tgz", @@ -3655,6 +3665,14 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yaml": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", + "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/NodeApp/package.json b/NodeApp/package.json index 1c30e7d57bdb595024027ea9f22eef18b1433268..b4f8edfe6b9748cec7c7440185ce460496da54cd 100644 --- a/NodeApp/package.json +++ b/NodeApp/package.json @@ -39,6 +39,7 @@ "chalk" : "^4.1.2", "commander" : "^11.0.0", "dotenv" : "^16.3.1", + "dotenv-expand" : "^10.0.0", "fs-extra" : "^11.1.1", "http-status-codes": "^2.2.0", "inquirer" : "^8.2.5", @@ -46,7 +47,8 @@ "jsonwebtoken" : "^8.5.1", "ora" : "^5.4.1", "tar-stream" : "^3.1.6", - "winston" : "^3.10.0" + "winston" : "^3.10.0", + "yaml" : "^2.3.2" }, "devDependencies": { "@types/fs-extra" : "^11.0.1", diff --git a/NodeApp/src/app.ts b/NodeApp/src/app.ts index ea7d4ef9a1c6eb8f15517b3df0a0bb2cf56a6dbd..634f276293e465b7a1e2fd599d502d6aeb371586 100644 --- a/NodeApp/src/app.ts +++ b/NodeApp/src/app.ts @@ -1,10 +1,11 @@ // Read from the .env file // ATTENTION : This lines MUST be the first of this file (except for the path import) const path = require('node:path'); -require('dotenv').config({ - path : path.join(__dirname, '../.env'), - DOTENV_KEY: 'dotenv://:key_fc323d8e0a02349342f1c6a119bb38495958ce3a43a87d19a3f674b7e2896dcb@dotenv.local/vault/.env.vault?environment=development' - }); +const myEnv = require('dotenv').config({ + path : path.join(__dirname, '../.env'), + DOTENV_KEY: 'dotenv://:key_fc323d8e0a02349342f1c6a119bb38495958ce3a43a87d19a3f674b7e2896dcb@dotenv.local/vault/.env.vault?environment=development' + }); +require('dotenv-expand').expand(myEnv); require('./shared/helpers/TypeScriptExtensions'); // ATTENTION : This line MUST be the second of this file diff --git a/NodeApp/src/commander/assignment/AssignmentCommand.ts b/NodeApp/src/commander/assignment/AssignmentCommand.ts index c629ddc14f3ed6785ac5a4b5c7a9fe05b82ef23b..d78a64aa54d0920f49377a029e7de78806b338d1 100644 --- a/NodeApp/src/commander/assignment/AssignmentCommand.ts +++ b/NodeApp/src/commander/assignment/AssignmentCommand.ts @@ -1,7 +1,8 @@ import CommanderCommand from '../CommanderCommand'; -import AssignmentCreateCommand from './AssignmentCreateCommand'; -import AssignmentPublishCommand from './AssignmentPublishCommand'; -import AssignmentUnpublishCommand from './AssignmentUnpublishCommand'; +import AssignmentCreateCommand from './subcommands/AssignmentCreateCommand'; +import AssignmentPublishCommand from './subcommands/AssignmentPublishCommand'; +import AssignmentUnpublishCommand from './subcommands/AssignmentUnpublishCommand'; +import AssignmentCheckCommand from './subcommands/AssignmentCheckCommand'; class AssignmentCommand extends CommanderCommand { @@ -14,6 +15,7 @@ class AssignmentCommand extends CommanderCommand { protected defineSubCommands() { AssignmentCreateCommand.registerOnCommand(this.command); + AssignmentCheckCommand.registerOnCommand(this.command); AssignmentPublishCommand.registerOnCommand(this.command); AssignmentUnpublishCommand.registerOnCommand(this.command); } diff --git a/NodeApp/src/commander/assignment/subcommands/AssignmentCheckCommand.ts b/NodeApp/src/commander/assignment/subcommands/AssignmentCheckCommand.ts new file mode 100644 index 0000000000000000000000000000000000000000..d46efaa66632054313f3bf246b419c280841287e --- /dev/null +++ b/NodeApp/src/commander/assignment/subcommands/AssignmentCheckCommand.ts @@ -0,0 +1,96 @@ +import CommanderCommand from '../../CommanderCommand'; +import Config from '../../../config/Config'; +import ora from 'ora'; +import util from 'util'; +import { exec } from 'child_process'; +import chalk from 'chalk'; +import AssignmentValidator from '../../../sharedByClients/helpers/Dojo/AssignmentValidator'; +import ClientsSharedAssignmentHelper from '../../../sharedByClients/helpers/Dojo/ClientsSharedAssignmentHelper'; + + +const execAsync = util.promisify(exec); + + +class AssignmentCheckCommand extends CommanderCommand { + protected commandName: string = 'check'; + + protected defineCommand() { + this.command + .description('locally run a check of an assignment') + .option('-p, --path <value>', 'assignment path', Config.folders.defaultLocalExercise) + .option('-v, --verbose', 'verbose mode (display docker compose logs in live)') + .action(this.commandAction.bind(this)); + } + + protected async commandAction(options: { path: string, verbose: boolean }): Promise<void> { + const localExercisePath: string = options.path ?? Config.folders.defaultLocalExercise; + + const assignmentValidator = new AssignmentValidator(localExercisePath); + + try { + await new Promise<void>((resolve, reject) => { + let spinner: ora.Ora; + + if ( options.verbose ) { + assignmentValidator.events.on('logs', (log: string, _error: boolean, displayable: boolean) => { + if ( displayable ) { + console.log(log); + } + }); + } + + assignmentValidator.events.on('step', (name: string, message: string) => { + console.log(chalk.cyan(message)); + }); + + assignmentValidator.events.on('subStep', (name: string, message: string) => { + spinner = ora({ + text : message, + indent: 4 + }).start(); + + if ( options.verbose && name == 'COMPOSE_RUN' ) { + spinner.info(); + } + }); + + assignmentValidator.events.on('endSubStep', (stepName: string, message: string, error: boolean) => { + if ( error ) { + if ( options.verbose && stepName == 'COMPOSE_RUN' ) { + ora({ + text : message, + indent: 4 + }).start().fail(); + } else { + spinner.fail(message); + } + } else { + if ( options.verbose && stepName == 'COMPOSE_RUN' ) { + ora({ + text : message, + indent: 4 + }).start().succeed(); + } else { + spinner.succeed(message); + } + } + }); + + assignmentValidator.events.on('finished', (success: boolean, exitCode: number) => { + success ? resolve() : reject(); + }); + + assignmentValidator.run(true); + }); + } catch ( error ) { } + + ClientsSharedAssignmentHelper.displayExecutionResults(assignmentValidator, `The assignment is ready to be pushed.`, { + INFO : chalk.bold, + SUCCESS: chalk.green, + FAILURE: chalk.red + }); + } +} + + +export default new AssignmentCheckCommand(); \ No newline at end of file diff --git a/NodeApp/src/commander/assignment/AssignmentCreateCommand.ts b/NodeApp/src/commander/assignment/subcommands/AssignmentCreateCommand.ts similarity index 85% rename from NodeApp/src/commander/assignment/AssignmentCreateCommand.ts rename to NodeApp/src/commander/assignment/subcommands/AssignmentCreateCommand.ts index c2b384afaf2f8c41e52c0cf836d537912df28ed1..0b28a1c7ff9302c5b0416043e8bc3421cbbfb96b 100644 --- a/NodeApp/src/commander/assignment/AssignmentCreateCommand.ts +++ b/NodeApp/src/commander/assignment/subcommands/AssignmentCreateCommand.ts @@ -1,12 +1,12 @@ -import CommanderCommand from '../CommanderCommand'; +import CommanderCommand from '../../CommanderCommand'; import chalk from 'chalk'; import ora from 'ora'; -import GitlabManager from '../../managers/GitlabManager'; -import GitlabUser from '../../shared/types/Gitlab/GitlabUser'; -import DojoBackendManager from '../../managers/DojoBackendManager'; -import Toolbox from '../../shared/helpers/Toolbox'; -import AccessesHelper from '../../helpers/AccessesHelper'; -import Assignment from '../../sharedByClients/models/Assignment'; +import GitlabManager from '../../../managers/GitlabManager'; +import GitlabUser from '../../../shared/types/Gitlab/GitlabUser'; +import DojoBackendManager from '../../../managers/DojoBackendManager'; +import Toolbox from '../../../shared/helpers/Toolbox'; +import AccessesHelper from '../../../helpers/AccessesHelper'; +import Assignment from '../../../sharedByClients/models/Assignment'; class AssignmentCreateCommand extends CommanderCommand { @@ -68,8 +68,7 @@ class AssignmentCreateCommand extends CommanderCommand { const oraInfo = (message: string) => { ora({ - text : message, - indent: 4 + text: message, indent: 4 }).start().info(); }; diff --git a/NodeApp/src/commander/assignment/AssignmentPublishCommand.ts b/NodeApp/src/commander/assignment/subcommands/AssignmentPublishCommand.ts similarity index 100% rename from NodeApp/src/commander/assignment/AssignmentPublishCommand.ts rename to NodeApp/src/commander/assignment/subcommands/AssignmentPublishCommand.ts diff --git a/NodeApp/src/commander/assignment/AssignmentPublishUnpublishCommandBase.ts b/NodeApp/src/commander/assignment/subcommands/AssignmentPublishUnpublishCommandBase.ts similarity index 69% rename from NodeApp/src/commander/assignment/AssignmentPublishUnpublishCommandBase.ts rename to NodeApp/src/commander/assignment/subcommands/AssignmentPublishUnpublishCommandBase.ts index b5df0c9b02e54abd46fbc438e7005e868f17a551..41593c08b1ac4967b10ebdd62d953016af74e907 100644 --- a/NodeApp/src/commander/assignment/AssignmentPublishUnpublishCommandBase.ts +++ b/NodeApp/src/commander/assignment/subcommands/AssignmentPublishUnpublishCommandBase.ts @@ -1,10 +1,11 @@ -import CommanderCommand from '../CommanderCommand'; -import inquirer from 'inquirer'; -import chalk from 'chalk'; -import SessionManager from '../../managers/SessionManager'; -import ora from 'ora'; -import DojoBackendManager from '../../managers/DojoBackendManager'; -import Assignment from '../../sharedByClients/models/Assignment'; +import CommanderCommand from '../../CommanderCommand'; +import inquirer from 'inquirer'; +import chalk from 'chalk'; +import SessionManager from '../../../managers/SessionManager'; +import ora from 'ora'; +import DojoBackendManager from '../../../managers/DojoBackendManager'; +import Assignment from '../../../sharedByClients/models/Assignment'; +import SharedAssignmentHelper from '../../../shared/helpers/Dojo/SharedAssignmentHelper'; abstract class AssignmentPublishUnpublishCommandBase extends CommanderCommand { @@ -56,15 +57,28 @@ abstract class AssignmentPublishUnpublishCommandBase extends CommanderCommand { } assignmentGetSpinner.succeed(`The assignment exists`); + const assignmentCheckAccessSpinner: ora.Ora = ora({ text : 'Checking accesses', indent: 8 }).start(); - if ( !assignment.staff ) { + if ( !assignment.staff.some(staff => staff.gitlabId === SessionManager.profile?.gitlabId) ) { assignmentCheckAccessSpinner.fail(`You are not in the staff of this assignment`); return; } assignmentCheckAccessSpinner.succeed(`You are in the staff of this assignment`); + + + const assignmentIsPublishable: ora.Ora = ora({ + text : 'Checking if the assignment is publishable', + indent: 8 + }).start(); + const isPublishable = await SharedAssignmentHelper.isPublishable(assignment.gitlabId); + if ( !isPublishable.isPublishable ) { + assignmentIsPublishable.fail(`The assignment is not publishable: ${ isPublishable.status?.message }`); + return; + } + assignmentIsPublishable.succeed(`The assignment is publishable`); } { diff --git a/NodeApp/src/commander/assignment/AssignmentUnpublishCommand.ts b/NodeApp/src/commander/assignment/subcommands/AssignmentUnpublishCommand.ts similarity index 100% rename from NodeApp/src/commander/assignment/AssignmentUnpublishCommand.ts rename to NodeApp/src/commander/assignment/subcommands/AssignmentUnpublishCommand.ts diff --git a/NodeApp/src/commander/exercise/ExerciseCommand.ts b/NodeApp/src/commander/exercise/ExerciseCommand.ts index ef2c3f263f3bf1bdd287016d4d194b41ab44888d..bc122a864f7cc7fd9b32c00879b4427cdaae67e6 100644 --- a/NodeApp/src/commander/exercise/ExerciseCommand.ts +++ b/NodeApp/src/commander/exercise/ExerciseCommand.ts @@ -1,6 +1,6 @@ import CommanderCommand from '../CommanderCommand'; -import ExerciseCreateCommand from './ExerciseCreateCommand'; -import ExerciseRunCommand from './ExerciseRunCommand'; +import ExerciseCreateCommand from './subcommands/ExerciseCreateCommand'; +import ExerciseRunCommand from './subcommands/ExerciseRunCommand'; class ExerciseCommand extends CommanderCommand { diff --git a/NodeApp/src/commander/exercise/ExerciseCreateCommand.ts b/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts similarity index 79% rename from NodeApp/src/commander/exercise/ExerciseCreateCommand.ts rename to NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts index 9116ff3a4c5cf8356ab05f57fd171b6eae15702b..bb51c2e6ece83361bd4fa5bd011b8d2e5731f97b 100644 --- a/NodeApp/src/commander/exercise/ExerciseCreateCommand.ts +++ b/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts @@ -1,12 +1,12 @@ -import CommanderCommand from '../CommanderCommand'; +import CommanderCommand from '../../CommanderCommand'; import chalk from 'chalk'; -import GitlabManager from '../../managers/GitlabManager'; -import GitlabUser from '../../shared/types/Gitlab/GitlabUser'; +import GitlabManager from '../../../managers/GitlabManager'; +import GitlabUser from '../../../shared/types/Gitlab/GitlabUser'; import ora from 'ora'; -import DojoBackendManager from '../../managers/DojoBackendManager'; -import AccessesHelper from '../../helpers/AccessesHelper'; -import Assignment from '../../sharedByClients/models/Assignment'; -import Exercise from '../../sharedByClients/models/Exercise'; +import DojoBackendManager from '../../../managers/DojoBackendManager'; +import AccessesHelper from '../../../helpers/AccessesHelper'; +import Assignment from '../../../sharedByClients/models/Assignment'; +import Exercise from '../../../sharedByClients/models/Exercise'; class ExerciseCreateCommand extends CommanderCommand { @@ -40,8 +40,7 @@ class ExerciseCreateCommand extends CommanderCommand { ora('Checking assignment:').start().info(); const assignmentGetSpinner: ora.Ora = ora({ - text : 'Checking if assignment exists', - indent: 4 + text: 'Checking if assignment exists', indent: 4 }).start(); assignment = await DojoBackendManager.getAssignment(options.assignment); if ( !assignment ) { @@ -51,8 +50,7 @@ class ExerciseCreateCommand extends CommanderCommand { assignmentGetSpinner.succeed(`Assignment "${ options.assignment }" exists`); const assignmentPublishedSpinner: ora.Ora = ora({ - text : 'Checking if assignment is published', - indent: 4 + text: 'Checking if assignment is published', indent: 4 }).start(); if ( !assignment.published ) { assignmentPublishedSpinner.fail(`Assignment "${ assignment.name }" isn't published`); @@ -70,8 +68,7 @@ class ExerciseCreateCommand extends CommanderCommand { const oraInfo = (message: string) => { ora({ - text : message, - indent: 4 + text: message, indent: 4 }).start().info(); }; diff --git a/NodeApp/src/commander/exercise/ExerciseRunCommand.ts b/NodeApp/src/commander/exercise/subcommands/ExerciseRunCommand.ts similarity index 78% rename from NodeApp/src/commander/exercise/ExerciseRunCommand.ts rename to NodeApp/src/commander/exercise/subcommands/ExerciseRunCommand.ts index 4fb7ea8dbf61e3992f5b96297b7b5b7ee1599f70..bac1eb1db39cf5f36fe539855803420d0f872f52 100644 --- a/NodeApp/src/commander/exercise/ExerciseRunCommand.ts +++ b/NodeApp/src/commander/exercise/subcommands/ExerciseRunCommand.ts @@ -1,5 +1,5 @@ -import CommanderCommand from '../CommanderCommand'; -import Config from '../../config/Config'; +import CommanderCommand from '../../CommanderCommand'; +import Config from '../../../config/Config'; import fs from 'node:fs'; import ora from 'ora'; import util from 'util'; @@ -7,13 +7,13 @@ 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'; +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); @@ -42,8 +42,7 @@ class ExerciseRunCommand extends CommanderCommand { private displayExecutionLogs() { ora({ - text : `${ chalk.magenta('Execution logs folder:') } ${ this.folderResultsVolume }`, - indent: 0 + text: `${ chalk.magenta('Execution logs folder:') } ${ this.folderResultsVolume }`, indent: 0 }).start().info(); } @@ -56,7 +55,7 @@ class ExerciseRunCommand extends CommanderCommand { let haveResultsVolume: boolean; - // Step 1: Check requirements (if it's an exercise folder and if Docker deamon is running) + // Step 1: Check requirements (if it's an exercise folder and if Docker daemon is running) { console.log(chalk.cyan('Please wait while we are checking and creating dependencies...')); @@ -67,15 +66,13 @@ class ExerciseRunCommand extends CommanderCommand { ora({ - text : `Checking exercise content:`, - indent: 4 + text: `Checking exercise content:`, indent: 4 }).start().info(); // Exercise folder { const spinner: ora.Ora = ora({ - text : `Checking exercise folder`, - indent: 8 + text: `Checking exercise folder`, indent: 8 }).start(); const files = fs.readdirSync(options.path); @@ -92,13 +89,12 @@ class ExerciseRunCommand extends CommanderCommand { // dojo_assignment.json validity { const spinner: ora.Ora = ora({ - text : `Checking ${ Config.assignment.filename } file`, - indent: 8 + text: `Checking ${ ClientsSharedConfig.assignment.filename } file`, indent: 8 }).start(); - const validationResults = SharedAssignmentHelper.validateDescriptionFile(`${ options.path }/${ Config.assignment.filename }`); + const validationResults = SharedAssignmentHelper.validateDescriptionFile(path.join(options.path, ClientsSharedConfig.assignment.filename)); if ( !validationResults.isValid ) { - spinner.fail(`The ${ Config.assignment.filename } file is invalid: ${ JSON.stringify(validationResults.errors) }`); + spinner.fail(`The ${ ClientsSharedConfig.assignment.filename } file is invalid: ${ JSON.stringify(validationResults.errors) }`); return; } else { assignmentFile = validationResults.results!; @@ -106,24 +102,23 @@ class ExerciseRunCommand extends CommanderCommand { haveResultsVolume = assignmentFile.result.volume !== undefined; - spinner.succeed(`The ${ Config.assignment.filename } file is valid`); + spinner.succeed(`The ${ ClientsSharedConfig.assignment.filename } file is valid`); } - // Docker deamon + // Docker daemon { const spinner: ora.Ora = ora({ - text : `Checking Docker deamon`, - indent: 4 + text: `Checking Docker daemon`, indent: 4 }).start(); try { await execAsync(`cd "${ Config.folders.defaultLocalExercise }";docker ps`); } catch ( error ) { - spinner.fail(`The Docker deamon is not running`); + spinner.fail(`The Docker daemon is not running`); return; } - spinner.succeed(`The Docker deamon is running`); + spinner.succeed(`The Docker daemon is running`); } } @@ -157,8 +152,7 @@ class ExerciseRunCommand extends CommanderCommand { exerciseDockerCompose.events.on('step', (name: string, message: string) => { spinner = ora({ - text : message, - indent: 4 + text: message, indent: 4 }).start(); if ( options.verbose && name == 'COMPOSE_RUN' ) { @@ -170,8 +164,7 @@ class ExerciseRunCommand extends CommanderCommand { if ( error ) { if ( options.verbose && stepName == 'COMPOSE_RUN' ) { ora({ - text : message, - indent: 4 + text: message, indent: 4 }).start().fail(); } else { spinner.fail(message); @@ -179,8 +172,7 @@ class ExerciseRunCommand extends CommanderCommand { } else { if ( options.verbose && stepName == 'COMPOSE_RUN' ) { ora({ - text : message, - indent: 4 + text: message, indent: 4 }).start().succeed(); } else { spinner.succeed(message); @@ -218,8 +210,7 @@ class ExerciseRunCommand extends CommanderCommand { exerciseResultsValidation.events.on('step', (name: string, message: string) => { spinner = ora({ - text : message, - indent: 4 + text: message, indent: 4 }).start(); }); @@ -251,9 +242,7 @@ class ExerciseRunCommand extends CommanderCommand { // Step 4: Display results + Volume location { ClientsSharedExerciseHelper.displayExecutionResults(exerciseResultsValidation.exerciseResults!, exerciseDockerCompose.exitCode, { - INFO : chalk.bold, - SUCCESS: chalk.green, - FAILURE: chalk.red + INFO: chalk.bold, SUCCESS: chalk.green, FAILURE: chalk.red }, `\n\n${ chalk.bold('Execution results folder') } : ${ this.folderResultsVolume }`); } } diff --git a/NodeApp/src/commander/session/SessionCommand.ts b/NodeApp/src/commander/session/SessionCommand.ts index c7089d6b0441979a93133f0cab4a30ee3bad306e..8ec16854a4bc15f6cdfb8534f57c28c2bef128c8 100644 --- a/NodeApp/src/commander/session/SessionCommand.ts +++ b/NodeApp/src/commander/session/SessionCommand.ts @@ -1,7 +1,7 @@ import CommanderCommand from '../CommanderCommand'; -import SessionTestCommand from './SessionTestCommand'; -import SessionAppCommand from './App/SessionAppCommand'; -import SessionGitlabCommand from './Gitlab/SessionGitlabCommand'; +import SessionTestCommand from './subcommands/SessionTestCommand'; +import SessionAppCommand from './subcommands/SessionAppCommand'; +import SessionGitlabCommand from './subcommands/SessionGitlabCommand'; class SessionCommand extends CommanderCommand { diff --git a/NodeApp/src/commander/session/App/SessionAppCommand.ts b/NodeApp/src/commander/session/subcommands/SessionAppCommand.ts similarity index 78% rename from NodeApp/src/commander/session/App/SessionAppCommand.ts rename to NodeApp/src/commander/session/subcommands/SessionAppCommand.ts index d0c943b10a8f3a38fe93fd245c0c533582bffd8e..f8d179efead33b4652c0a994d8aed4cdc9e28e81 100644 --- a/NodeApp/src/commander/session/App/SessionAppCommand.ts +++ b/NodeApp/src/commander/session/subcommands/SessionAppCommand.ts @@ -1,6 +1,6 @@ import CommanderCommand from '../../CommanderCommand'; -import SessionAppLoginCommand from './SessionAppLoginCommand'; -import SessionAppLogoutCommand from './SessionAppLogoutCommand'; +import SessionAppLoginCommand from './application/SessionAppLoginCommand'; +import SessionAppLogoutCommand from './application/SessionAppLogoutCommand'; class SessionAppCommand extends CommanderCommand { diff --git a/NodeApp/src/commander/session/Gitlab/SessionGitlabCommand.ts b/NodeApp/src/commander/session/subcommands/SessionGitlabCommand.ts similarity index 78% rename from NodeApp/src/commander/session/Gitlab/SessionGitlabCommand.ts rename to NodeApp/src/commander/session/subcommands/SessionGitlabCommand.ts index 3662faa1e86d0d7f0d78ac71de71c4c4c02254ca..e80ceb264f1d16f458b1f4cb770dc82dd93da817 100644 --- a/NodeApp/src/commander/session/Gitlab/SessionGitlabCommand.ts +++ b/NodeApp/src/commander/session/subcommands/SessionGitlabCommand.ts @@ -1,6 +1,6 @@ import CommanderCommand from '../../CommanderCommand'; -import SessionGitlabLoginCommand from './SessionGitlabLoginCommand'; -import SessionGitlabLogoutCommand from './SessionGitlabLogoutCommand'; +import SessionGitlabLoginCommand from './gitlab/SessionGitlabLoginCommand'; +import SessionGitlabLogoutCommand from './gitlab/SessionGitlabLogoutCommand'; class SessionGitlabCommand extends CommanderCommand { diff --git a/NodeApp/src/commander/session/SessionTestCommand.ts b/NodeApp/src/commander/session/subcommands/SessionTestCommand.ts similarity index 72% rename from NodeApp/src/commander/session/SessionTestCommand.ts rename to NodeApp/src/commander/session/subcommands/SessionTestCommand.ts index d0ab1b62051f3e7a6555081957851cde1461cc7f..57c1bf00b1ea126c17fddea14714d06effdbea40 100644 --- a/NodeApp/src/commander/session/SessionTestCommand.ts +++ b/NodeApp/src/commander/session/subcommands/SessionTestCommand.ts @@ -1,6 +1,6 @@ -import CommanderCommand from '../CommanderCommand'; -import SessionManager from '../../managers/SessionManager'; -import GitlabManager from '../../managers/GitlabManager'; +import CommanderCommand from '../../CommanderCommand'; +import SessionManager from '../../../managers/SessionManager'; +import GitlabManager from '../../../managers/GitlabManager'; class SessionTestCommand extends CommanderCommand { diff --git a/NodeApp/src/commander/session/App/SessionAppLoginCommand.ts b/NodeApp/src/commander/session/subcommands/application/SessionAppLoginCommand.ts similarity index 71% rename from NodeApp/src/commander/session/App/SessionAppLoginCommand.ts rename to NodeApp/src/commander/session/subcommands/application/SessionAppLoginCommand.ts index 58bc031c2c4b389ae024cf41479abb2241119eb1..88deb2e8b9a40cdc8d399393a81257ff327e4992 100644 --- a/NodeApp/src/commander/session/App/SessionAppLoginCommand.ts +++ b/NodeApp/src/commander/session/subcommands/application/SessionAppLoginCommand.ts @@ -1,7 +1,7 @@ import chalk from 'chalk'; -import CommanderCommand from '../../CommanderCommand'; +import CommanderCommand from '../../../CommanderCommand'; import inquirer from 'inquirer'; -import SessionManager from '../../../managers/SessionManager'; +import SessionManager from '../../../../managers/SessionManager'; class SessionAppLoginCommand extends CommanderCommand { @@ -18,10 +18,7 @@ class SessionAppLoginCommand extends CommanderCommand { protected async commandAction(options: { user: string, password: string }): Promise<void> { if ( !options.password ) { options.password = (await inquirer.prompt({ - type : 'password', - name : 'password', - message: 'Please enter your password', - mask : '' + type: 'password', name: 'password', message: 'Please enter your password', mask: '' })).password; } diff --git a/NodeApp/src/commander/session/App/SessionAppLogoutCommand.ts b/NodeApp/src/commander/session/subcommands/application/SessionAppLogoutCommand.ts similarity index 72% rename from NodeApp/src/commander/session/App/SessionAppLogoutCommand.ts rename to NodeApp/src/commander/session/subcommands/application/SessionAppLogoutCommand.ts index 650440d8396647ecfc4d634b4eda32347c2473b6..7d051a31a7ebf761ef5fd119b0fb1bdd4b8aa6d6 100644 --- a/NodeApp/src/commander/session/App/SessionAppLogoutCommand.ts +++ b/NodeApp/src/commander/session/subcommands/application/SessionAppLogoutCommand.ts @@ -1,6 +1,6 @@ -import CommanderCommand from '../../CommanderCommand'; +import CommanderCommand from '../../../CommanderCommand'; import inquirer from 'inquirer'; -import SessionManager from '../../../managers/SessionManager'; +import SessionManager from '../../../../managers/SessionManager'; import ora from 'ora'; @@ -17,10 +17,7 @@ class SessionAppLogoutCommand extends CommanderCommand { protected async commandAction(options: any): Promise<void> { if ( !options.force ) { const confirm: boolean = (await inquirer.prompt({ - name : 'confirm', - message: 'Are you sure?', - type : 'confirm', - default: false + name: 'confirm', message: 'Are you sure?', type: 'confirm', default: false })).confirm; if ( !confirm ) { diff --git a/NodeApp/src/commander/session/Gitlab/SessionGitlabLoginCommand.ts b/NodeApp/src/commander/session/subcommands/gitlab/SessionGitlabLoginCommand.ts similarity index 67% rename from NodeApp/src/commander/session/Gitlab/SessionGitlabLoginCommand.ts rename to NodeApp/src/commander/session/subcommands/gitlab/SessionGitlabLoginCommand.ts index e76525eca30b430a63c93b200e795bf5be606c98..fae91b6cf934f21e1c40a64f878c9a526b6f8241 100644 --- a/NodeApp/src/commander/session/Gitlab/SessionGitlabLoginCommand.ts +++ b/NodeApp/src/commander/session/subcommands/gitlab/SessionGitlabLoginCommand.ts @@ -1,6 +1,6 @@ import chalk from 'chalk'; -import CommanderCommand from '../../CommanderCommand'; -import GitlabManager from '../../../managers/GitlabManager'; +import CommanderCommand from '../../../CommanderCommand'; +import GitlabManager from '../../../../managers/GitlabManager'; import inquirer from 'inquirer'; @@ -17,10 +17,7 @@ class SessionGitlabLoginCommand extends CommanderCommand { protected async commandAction(options: { token: string }): Promise<void> { if ( !options.token ) { options.token = (await inquirer.prompt({ - type : 'password', - name : 'token', - message: 'Please enter your gitlab token', - mask : '' + type: 'password', name: 'token', message: 'Please enter your gitlab token', mask: '' })).token; } diff --git a/NodeApp/src/commander/session/Gitlab/SessionGitlabLogoutCommand.ts b/NodeApp/src/commander/session/subcommands/gitlab/SessionGitlabLogoutCommand.ts similarity index 72% rename from NodeApp/src/commander/session/Gitlab/SessionGitlabLogoutCommand.ts rename to NodeApp/src/commander/session/subcommands/gitlab/SessionGitlabLogoutCommand.ts index 6b86883c7f4021362d6b0ca785d95cd7101e2a29..4d43d379fbbc185cb571cf1039460e1c620965dc 100644 --- a/NodeApp/src/commander/session/Gitlab/SessionGitlabLogoutCommand.ts +++ b/NodeApp/src/commander/session/subcommands/gitlab/SessionGitlabLogoutCommand.ts @@ -1,7 +1,7 @@ -import CommanderCommand from '../../CommanderCommand'; +import CommanderCommand from '../../../CommanderCommand'; import inquirer from 'inquirer'; import ora from 'ora'; -import GitlabManager from '../../../managers/GitlabManager'; +import GitlabManager from '../../../../managers/GitlabManager'; class SessionGitlabLogoutCommand extends CommanderCommand { @@ -17,10 +17,7 @@ class SessionGitlabLogoutCommand extends CommanderCommand { protected async commandAction(options: any): Promise<void> { if ( !options.force ) { const confirm: boolean = (await inquirer.prompt({ - name : 'confirm', - message: 'Are you sure?', - type : 'confirm', - default: false + name: 'confirm', message: 'Are you sure?', type: 'confirm', default: false })).confirm; if ( !confirm ) { diff --git a/NodeApp/src/config/Config.ts b/NodeApp/src/config/Config.ts index 51193829e79c0be8760b24b6a6c9bbf120137936..d1935ab6335da38804364d3065639f65f1629882 100644 --- a/NodeApp/src/config/Config.ts +++ b/NodeApp/src/config/Config.ts @@ -14,10 +14,6 @@ class Config { defaultLocalExercise: string }; - public assignment: { - filename: string - }; - public readonly exercise: { neededFiles: Array<string> }; @@ -36,10 +32,6 @@ class Config { defaultLocalExercise: process.env.LOCAL_EXERCISE_DEFAULT_FOLDER || './' }; - this.assignment = { - filename: process.env.ASSIGNMENT_FILENAME || '' - }; - this.exercise = { neededFiles: JSON.parse(process.env.EXERCISE_NEEDED_FILES || '[]') }; diff --git a/NodeApp/src/managers/GitlabManager.ts b/NodeApp/src/managers/GitlabManager.ts index 89561033e3a1e790f55e61a7a190a9d26db5efc0..92ce994a5027dfbac721c413d1625c44621f32b7 100644 --- a/NodeApp/src/managers/GitlabManager.ts +++ b/NodeApp/src/managers/GitlabManager.ts @@ -1,17 +1,17 @@ -import LocalConfig from '../config/LocalConfig'; -import LocalConfigKeys from '../types/LocalConfigKeys'; -import axios from 'axios'; -import ora from 'ora'; -import GitlabUser from '../shared/types/Gitlab/GitlabUser'; -import GitlabRoute from '../shared/types/Gitlab/GitlabRoute'; -import ClientsSharedConfig from '../sharedByClients/config/ClientsSharedConfig'; +import LocalConfig from '../config/LocalConfig'; +import LocalConfigKeys from '../types/LocalConfigKeys'; +import axios from 'axios'; +import ora from 'ora'; +import GitlabUser from '../shared/types/Gitlab/GitlabUser'; +import GitlabRoute from '../shared/types/Gitlab/GitlabRoute'; +import SharedConfig from '../shared/config/SharedConfig'; class GitlabManager { private _token: string | null = null; private getApiUrl(route: GitlabRoute): string { - return `${ ClientsSharedConfig.gitlab.apiURL }${ route }`; + return `${ SharedConfig.gitlab.apiURL }${ route }`; } get isLogged(): boolean { diff --git a/NodeApp/src/managers/HttpManager.ts b/NodeApp/src/managers/HttpManager.ts index b95922e2293eadc197a7ac2c5e3d50df66ac974e..5b8ea67c2a7d802a599ecb304bc04056737219dc 100644 --- a/NodeApp/src/managers/HttpManager.ts +++ b/NodeApp/src/managers/HttpManager.ts @@ -9,6 +9,7 @@ import DojoBackendResponse from '../shared/types/Dojo/DojoBackendResp import DojoStatusCode from '../shared/types/Dojo/DojoStatusCode'; import boxen from 'boxen'; import Config from '../config/Config'; +import SharedConfig from '../shared/config/SharedConfig'; class HttpManager { @@ -41,7 +42,7 @@ class HttpManager { config.headers['client-version'] = version; } - if ( GitlabManager.isLogged && config.url && config.url.indexOf(ClientsSharedConfig.gitlab.apiURL) !== -1 ) { + if ( GitlabManager.isLogged && config.url && config.url.indexOf(SharedConfig.gitlab.apiURL) !== -1 ) { config.headers['PRIVATE-TOKEN'] = GitlabManager.token; } diff --git a/NodeApp/src/shared b/NodeApp/src/shared index 8424367748a6fc47f8da10b85e7663f3f7d07620..efe1bf313f57d1826faf935c183d37a0835f8c2d 160000 --- a/NodeApp/src/shared +++ b/NodeApp/src/shared @@ -1 +1 @@ -Subproject commit 8424367748a6fc47f8da10b85e7663f3f7d07620 +Subproject commit efe1bf313f57d1826faf935c183d37a0835f8c2d diff --git a/NodeApp/src/sharedByClients b/NodeApp/src/sharedByClients index 97ba763f9517880ecfa6245c172a0e330ebdd11a..d9379b055a4626e4b35cf4cc4a7429040a4aeaf7 160000 --- a/NodeApp/src/sharedByClients +++ b/NodeApp/src/sharedByClients @@ -1 +1 @@ -Subproject commit 97ba763f9517880ecfa6245c172a0e330ebdd11a +Subproject commit d9379b055a4626e4b35cf4cc4a7429040a4aeaf7