From c28f29099245c315b553907e33569dc8aa397808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <git@minelli.swiss> Date: Thu, 27 Feb 2025 15:13:58 +0100 Subject: [PATCH] ExerciseCreation => Add prompt when exercises already exist --- NodeApp/.idea/vcs.xml | 1 + .../subcommands/ExerciseCreateCommand.ts | 107 ++++++++++++++---- 2 files changed, 86 insertions(+), 22 deletions(-) diff --git a/NodeApp/.idea/vcs.xml b/NodeApp/.idea/vcs.xml index d86e73b..5e5bcd0 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 a942775..16b70b7 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(); + } } } } -- GitLab