import CommanderCommand from '../../CommanderCommand'; 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 * as Gitlab from '@gitbeaker/rest'; import TextStyle from '../../../types/TextStyle'; import GitlabManager from '../../../managers/GitlabManager'; type CommandOptions = { assignment: string, members_id?: Array<number>, members_username?: Array<string>, clone?: string | boolean } class ExerciseCreateCommand extends CommanderCommand { protected commandName: string = 'create'; private members!: Array<Gitlab.UserSchema> | undefined; private assignment!: Assignment | undefined; private exercise!: Exercise; protected defineCommand() { this.command .description('create a new exercise from an assignment') .requiredOption('-a, --assignment <value>', 'assignment source (Dojo assignment ID, Dojo assignment name or Gitlab assignment URL)') .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)') .action(this.commandAction.bind(this)); } private async dataRetrieval(options: CommandOptions) { console.log(TextStyle.BLOCK('Please wait while we verify and retrieve data...')); if ( !await AccessesHelper.checkStudent() ) { throw new Error(); } this.members = await GitlabManager.fetchMembers(options); if ( !this.members ) { throw new Error(); } ora('Checking assignment:').start().info(); const assignmentGetSpinner: ora.Ora = ora({ text : 'Checking if assignment exists', indent: 4 }).start(); this.assignment = await DojoBackendManager.getAssignment(options.assignment); if ( !this.assignment ) { assignmentGetSpinner.fail(`Assignment "${ options.assignment }" doesn't exists`); throw new Error(); } assignmentGetSpinner.succeed(`Assignment "${ options.assignment }" exists`); const assignmentPublishedSpinner: ora.Ora = ora({ text : 'Checking if assignment is published', indent: 4 }).start(); if ( !this.assignment.published ) { assignmentPublishedSpinner.fail(`Assignment "${ this.assignment.name }" isn't published`); throw new Error(); } assignmentPublishedSpinner.succeed(`Assignment "${ this.assignment.name }" is published`); } private async createExercise() { console.log(TextStyle.BLOCK('Please wait while we are creating the exercise (approximately 10 seconds)...')); this.exercise = await DojoBackendManager.createExercise(this.assignment!.name, this.members!); const oraInfo = (message: string) => { ora({ text : message, indent: 4 }).start().info(); }; oraInfo(`${ TextStyle.LIST_ITEM_NAME('Id:') } ${ this.exercise.id }`); oraInfo(`${ TextStyle.LIST_ITEM_NAME('Name:') } ${ this.exercise.name }`); oraInfo(`${ TextStyle.LIST_ITEM_NAME('Web URL:') } ${ this.exercise.gitlabCreationInfo.web_url }`); oraInfo(`${ TextStyle.LIST_ITEM_NAME('HTTP Repo:') } ${ this.exercise.gitlabCreationInfo.http_url_to_repo }`); oraInfo(`${ TextStyle.LIST_ITEM_NAME('SSH Repo:') } ${ this.exercise.gitlabCreationInfo.ssh_url_to_repo }`); } private async cloneRepository(options: CommandOptions) { if ( options.clone ) { console.log(TextStyle.BLOCK('Please wait while we are cloning the repository...')); await GitlabManager.cloneRepository(options.clone, this.exercise.gitlabCreationInfo.ssh_url_to_repo, `DojoExercise_${ this.exercise.assignmentName }`, true, 0); } } protected async commandAction(options: CommandOptions): Promise<void> { try { await this.dataRetrieval(options); await this.createExercise(); await this.cloneRepository(options); } catch ( e ) { /* Do nothing */ } } } export default new ExerciseCreateCommand();