From 2acf58495e95d8495d682bc164a2a0aa4b1d5f6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <michael@minelli.me>
Date: Sat, 13 Jan 2024 02:08:17 +0100
Subject: [PATCH] Commander => Add alert and informations about dev version and
 new versions

---
 NodeApp/src/commander/CommanderApp.ts | 51 ++++++++++++++++++++++++++-
 NodeApp/src/config/Config.ts          |  9 +++--
 NodeApp/src/managers/HttpManager.ts   | 11 ++++++
 3 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/NodeApp/src/commander/CommanderApp.ts b/NodeApp/src/commander/CommanderApp.ts
index 91ba8fe..5ea55d5 100644
--- a/NodeApp/src/commander/CommanderApp.ts
+++ b/NodeApp/src/commander/CommanderApp.ts
@@ -3,6 +3,12 @@ import SessionCommand      from './session/SessionCommand';
 import ClientsSharedConfig from '../sharedByClients/config/ClientsSharedConfig';
 import AssignmentCommand   from './assignment/AssignmentCommand';
 import ExerciseCommand     from './exercise/ExerciseCommand';
+import SharedConfig        from '../shared/config/SharedConfig';
+import boxen               from 'boxen';
+import { stateConfigFile } from '../config/ConfigFiles';
+import semver              from 'semver/preload';
+import { version }         from '../config/Version';
+import Config              from '../config/Config';
 
 
 class CommanderApp {
@@ -19,7 +25,12 @@ class CommanderApp {
                            sortOptions      : true,
                            sortSubcommands  : true
                        })
-        .option('-H, --host <string>', 'override the Dojo API endpoint', ClientsSharedConfig.apiURL);
+        .option('-H, --host <string>', 'override the Dojo API endpoint', ClientsSharedConfig.apiURL)
+        .hook('preAction', () => {
+            this.warnDevelopmentVersion();
+        }).hook('postAction', () => {
+            this.informNewVersion();
+        });
 
         this.program.on('option:host', () => {
             ClientsSharedConfig.apiURL = this.program.opts().host;
@@ -30,6 +41,44 @@ class CommanderApp {
         this.program.parse();
     }
 
+    private warnDevelopmentVersion() {
+        if ( !SharedConfig.production ) {
+            console.log(boxen(`This is a development (unstable) version of the DojoCLI.
+If you want to use the stable version, please install the package from the following url: 
+https://gitedu.hesge.ch/dojo_project/projects/ui/dojocli/-/releases/latest`, {
+                title         : 'Warning',
+                titleAlignment: 'center',
+                borderColor   : 'red',
+                borderStyle   : 'bold',
+                margin        : 1,
+                padding       : 1,
+                textAlignment : 'left'
+            }));
+        }
+    }
+
+    private informNewVersion() {
+        if ( SharedConfig.production ) {
+            const latestDojoCliVersion = stateConfigFile.getParam('latestDojoCliVersion') as string | null || '0.0.0';
+            const latestDojoCliVersionNotification = stateConfigFile.getParam('latestDojoCliVersionNotification') as number | null || 0;
+            if ( semver.lt(version, latestDojoCliVersion) ) {
+                if ( (new Date()).getTime() - latestDojoCliVersionNotification >= Config.versionUpdateInformationPeriodHours * 60 * 60 * 1000 ) {
+                    console.log(boxen(`The ${ latestDojoCliVersion } version of the DojoCLI is available: 
+https://gitedu.hesge.ch/dojo_project/projects/ui/dojocli/-/releases/latest`, {
+                        title         : 'Information',
+                        titleAlignment: 'center',
+                        borderColor   : 'blue',
+                        borderStyle   : 'bold',
+                        margin        : 1,
+                        padding       : 1,
+                        textAlignment : 'left'
+                    }));
+                    stateConfigFile.setParam('latestDojoCliVersionNotification', (new Date()).getTime());
+                }
+            }
+        }
+    }
+
     private registerCommands() {
         SessionCommand.registerOnCommand(this.program);
         AssignmentCommand.registerOnCommand(this.program);
diff --git a/NodeApp/src/config/Config.ts b/NodeApp/src/config/Config.ts
index 15b13e0..b0d2df8 100644
--- a/NodeApp/src/config/Config.ts
+++ b/NodeApp/src/config/Config.ts
@@ -3,9 +3,11 @@ import getAppDataPath from 'appdata-path';
 
 class Config {
     public readonly localConfig: {
-        folder: string; sessionFile: string;
+        folder: string; sessionFile: string; stateFile: string;
     };
 
+    public readonly versionUpdateInformationPeriodHours: number;
+
     public readonly gitlab: {
         cliReleasePage: string
     };
@@ -31,9 +33,12 @@ class Config {
     constructor() {
         this.localConfig = {
             folder     : getAppDataPath('DojoCLI'),
-            sessionFile: process.env.LOCAL_CONFIG_FILE_SESSION || ''
+            sessionFile: process.env.LOCAL_CONFIG_FILE_SESSION || '',
+            stateFile  : process.env.LOCAL_CONFIG_STATE || ''
         };
 
+        this.versionUpdateInformationPeriodHours = Number(process.env.VERSION_UPDATE_INFORMATION_PERIOD_HOURS || 24);
+
         this.gitlab = {
             cliReleasePage: process.env.GITLAB_CLI_RELEASE_PAGE || ''
         };
diff --git a/NodeApp/src/managers/HttpManager.ts b/NodeApp/src/managers/HttpManager.ts
index a0f5438..436a901 100644
--- a/NodeApp/src/managers/HttpManager.ts
+++ b/NodeApp/src/managers/HttpManager.ts
@@ -9,6 +9,7 @@ import DojoStatusCode                             from '../shared/types/Dojo/Doj
 import boxen                                      from 'boxen';
 import Config                                     from '../config/Config';
 import SharedConfig                               from '../shared/config/SharedConfig';
+import { stateConfigFile }                        from '../config/ConfigFiles';
 
 
 class HttpManager {
@@ -68,6 +69,16 @@ class HttpManager {
                 SessionManager.apiToken = response.data.sessionToken;
             }
 
+            if ( response.headers['dojocli-latest-version'] ) {
+                const latestDojoCliVersion = response.headers['dojocli-latest-version'];
+                const storedLatestDojoCliVersion = stateConfigFile.getParam('latestDojoCliVersion') as string | null || '0.0.0';
+
+                if ( latestDojoCliVersion !== storedLatestDojoCliVersion ) {
+                    stateConfigFile.setParam('latestDojoCliVersion', latestDojoCliVersion);
+                    stateConfigFile.setParam('latestDojoCliVersionNotification', 0);
+                }
+            }
+
             return response;
         }, async (error) => {
             if ( error.response ) {
-- 
GitLab