From 5d194c9d288ce18dcfbadd77d3c26d906f4d7694 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <michael@minelli.me>
Date: Fri, 13 Oct 2023 14:13:10 +0200
Subject: [PATCH] Add assignment check command

---
 .../commander/assignment/AssignmentCommand.ts |  2 +
 .../subcommands/AssignmentCheckCommand.ts     | 96 +++++++++++++++++++
 2 files changed, 98 insertions(+)
 create mode 100644 NodeApp/src/commander/assignment/subcommands/AssignmentCheckCommand.ts

diff --git a/NodeApp/src/commander/assignment/AssignmentCommand.ts b/NodeApp/src/commander/assignment/AssignmentCommand.ts
index 3363dd7..d78a64a 100644
--- a/NodeApp/src/commander/assignment/AssignmentCommand.ts
+++ b/NodeApp/src/commander/assignment/AssignmentCommand.ts
@@ -2,6 +2,7 @@ import CommanderCommand           from '../CommanderCommand';
 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 0000000..d46efaa
--- /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
-- 
GitLab