diff --git a/NodeApp/.idea/vcs.xml b/NodeApp/.idea/vcs.xml index d86e73b516141a07b5ba1f16f6f315749512bedc..5e5bcd02ce8b098302940ffa22bb6d19b8d8986f 100644 --- a/NodeApp/.idea/vcs.xml +++ b/NodeApp/.idea/vcs.xml @@ -2,6 +2,7 @@ <project version="4"> <component name="VcsDirectoryMappings"> <mapping directory="$PROJECT_DIR$/.." vcs="Git" /> + <mapping directory="$PROJECT_DIR$/DojoExercise_Technique_de compilation - TP" vcs="Git" /> <mapping directory="$PROJECT_DIR$/src/shared" vcs="Git" /> <mapping directory="$PROJECT_DIR$/src/sharedByClients" vcs="Git" /> </component> diff --git a/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts b/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts index a94277533e02a8528ee69e4951f7a827a1a86f2a..16b70b79064d215c89e112b89c9b14c5e00ceeed 100644 --- a/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts +++ b/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts @@ -1,16 +1,18 @@ -import CommanderCommand from '../../CommanderCommand.js'; -import ora from 'ora'; -import DojoBackendManager from '../../../managers/DojoBackendManager.js'; -import AccessesHelper from '../../../helpers/AccessesHelper.js'; -import Assignment from '../../../sharedByClients/models/Assignment.js'; -import Exercise from '../../../sharedByClients/models/Exercise.js'; -import * as Gitlab from '@gitbeaker/rest'; -import TextStyle from '../../../types/TextStyle.js'; -import inquirer from 'inquirer'; -import Config from '../../../config/Config'; +import CommanderCommand from '../../CommanderCommand.js'; +import ora from 'ora'; +import DojoBackendManager from '../../../managers/DojoBackendManager.js'; +import AccessesHelper from '../../../helpers/AccessesHelper.js'; +import Assignment from '../../../sharedByClients/models/Assignment.js'; +import Exercise from '../../../sharedByClients/models/Exercise.js'; +import * as Gitlab from '@gitbeaker/rest'; +import TextStyle from '../../../types/TextStyle.js'; +import inquirer from 'inquirer'; +import Config from '../../../config/Config'; +import ClientsSharedConfig from '../../../sharedByClients/config/ClientsSharedConfig'; +import { Option } from 'commander'; -type CommandOptions = { assignment: string, members_id?: Array<number>, members_username?: Array<string>, clone?: string | boolean } +type CommandOptions = { assignment: string, members_id?: Array<number>, members_username?: Array<string>, clone?: string | boolean, force?: boolean }; class ExerciseCreateCommand extends CommanderCommand { @@ -27,6 +29,7 @@ class ExerciseCreateCommand extends CommanderCommand { .option('-i, --members_id <ids...>', 'list of gitlab members ids (group\'s student) to add to the repository') .option('-u, --members_username <usernames...>', 'list of gitlab members username (group\'s student) to add to the repository') .option('-c, --clone [string]', 'automatically clone the repository (SSH required) in the specified directory (this will create a subdirectory with the assignment name)') + .addOption(new Option('-f, --force', 'don\'t ask for choice if there are already exercises for this assignment and try to create a new one anyway')) .action(this.commandAction.bind(this)); } @@ -70,25 +73,85 @@ class ExerciseCreateCommand extends CommanderCommand { }).start().info(); }; - oraInfo(TextStyle.WARNING(`You already created ${ this.assignment.myExercises.length } exercises for this assignment:`), 4); + oraInfo(TextStyle.WARNING(`You already created ${ this.assignment.myExercises.length } exercise${ this.assignment.myExercises.length > 1 ? 's' : '' } for this assignment${ this.assignment.myExercises.length >= ClientsSharedConfig.exercise.maxPerAssignment ? ' (which is the limit)' : '' }:`), 4); + + type CreationChoice = { delete: string | false, deleteAll: boolean, create: boolean }; + const presets: Array<{ name: string, value: CreationChoice } | inquirer.Separator> = []; for ( const exercise of this.assignment.myExercises ) { oraInfo(`${ TextStyle.LIST_ITEM_NAME('Exercice Id:') } ${ exercise.id }`, 8); + oraInfo(`${ TextStyle.LIST_ITEM_NAME('Name:') } ${ exercise.name }`); oraInfo(`${ TextStyle.LIST_ITEM_NAME('Creation date:') } ${ exercise.gitlabCreationInfo.created_at }`); oraInfo(`${ TextStyle.LIST_ITEM_NAME('Repository:') } ${ exercise.gitlabCreationInfo.web_url }`); oraInfo(`${ TextStyle.LIST_ITEM_NAME('Members:') } ${ exercise.members?.map(member => member.gitlabUsername).join(', ') ?? 'There is only you' }`); - } - const confirm: boolean = (await inquirer.prompt({ - name : 'confirm', - prefix : ' ', - message: `${ TextStyle.QUESTION('?') } You already created ${ this.assignment.myExercises.length } exercises for this assignment (see above). Are you sure you want to create a new one?`, - type : 'confirm', - default: false - })).confirm; + presets.push({ + name : `Delete "${ exercise.name }" and create a new one.`, + value: { + delete : exercise.id, + deleteAll: false, + create : true + } + }); + } - if ( !confirm ) { - throw new Error(); + if ( !options.force ) { + presets.push(new inquirer.Separator()); + + if ( this.assignment.myExercises.length > 1 ) { + presets.push({ + name : `Delete all existing exercises for this assignment and create a new one.`, + value: { + delete : false, + deleteAll: true, + create : true + } + }, new inquirer.Separator()); + } + + if ( this.assignment.myExercises.length < ClientsSharedConfig.exercise.maxPerAssignment ) { + presets.push({ + name : `Create a new one`, + value: { + delete : false, + deleteAll: false, + create : true + } + }, new inquirer.Separator()); + } + + presets.push({ + name : `Cancel`, + value: { + delete : false, + deleteAll: false, + create : false + } + }); + + const creationChoice: CreationChoice = (await inquirer.prompt({ + name : 'creationChoice', + message : `You already created ${ this.assignment.myExercises.length } exercise${ this.assignment.myExercises.length > 1 ? 's' : '' }${ this.assignment.myExercises.length >= ClientsSharedConfig.exercise.maxPerAssignment ? ' (which is the limit)' : '' } for this assignment (see above). What do you want to do?`, + type : 'list', + pageSize: 1000, + choices : presets + })).creationChoice; + + if ( creationChoice.delete || creationChoice.deleteAll ) { + console.log(TextStyle.BLOCK(`Please wait while we are deleting the exercise${ creationChoice.deleteAll ? 's' : '' }...`)); + + if ( creationChoice.delete ) { + await DojoBackendManager.deleteExercise(creationChoice.delete); + } else if ( creationChoice.deleteAll ) { + for ( const exercise of this.assignment.myExercises ) { + await DojoBackendManager.deleteExercise(exercise.id); + } + } + } + + if ( !creationChoice.create ) { + throw new Error(); + } } } } diff --git a/NodeApp/src/sharedByClients b/NodeApp/src/sharedByClients index e549c7f03955a2ac295a8b8486f921154af751ee..530fe7459023f7fa11b14a9edf7a99629304cf8b 160000 --- a/NodeApp/src/sharedByClients +++ b/NodeApp/src/sharedByClients @@ -1 +1 @@ -Subproject commit e549c7f03955a2ac295a8b8486f921154af751ee +Subproject commit 530fe7459023f7fa11b14a9edf7a99629304cf8b