From b95c6a3de43121c061457039a4c926d5d34f2737 Mon Sep 17 00:00:00 2001 From: jsteuer <jan.steuer.htw@gmail.com> Date: Mon, 16 Dec 2019 13:28:22 +0100 Subject: [PATCH] better docs, helpers namespace --- README.md | 288 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 216 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index ecec13f..d7f97fd 100644 --- a/README.md +++ b/README.md @@ -1,117 +1,259 @@ - + # MathCoach IDE API In diesem Paket ([Das Gitblit Repository findet sich hier](https://newton.htwsaar.de/gitblit/summary/mathcoach!mathcoach-ide-api.git)) -ist die öffentliche Schnittstelle zur MathCoach Entwicklungsumgebung (IDE) -definiert. Mithilfe dieser Schnittstelle können externe Werkzeuge (z.B. Editoren) erstellt werden. -Für den Anwender stehen diese Werkzeuge dann komfortabel - in die IDE integriert - zur Verfügung. +ist die öffentliche Schnittstelle zur MathCoach Entwicklungsumgebung (IDE) definiert. Mithilfe +dieser Schnittstelle können externe Werkzeuge (z.B. Editoren) erstellt werden. Ziel ist, dass +diese Werkzeuge für den Anwender komfortable - in die IDE integriert -zur Verfügung gestellt werden +können. Darüber hinaus werden als Ergänzung einige Hilfsfunktionen zum Bau von Werkzeugen angeboten.  +*Beispielhafte Anwendung: Eine Datei wird angelegt und einem Demo-Editor geöffnet. Dieser +generiert eine Groovy-Aufgabe* + + + +## Idee +Grundlegende Idee ist, dass ein externes Werkzeug nahtlos in die MathCoach IDE integriert werden +kann. Bestimmte Dateien werden anhand ihrer Dateiendung mit dem Werkzeug verknüpft, sodass der +Benutzer das passende Werkzeug durch einen einfache Klick im Dateie-Explorer starten kann. Diese +Datei wird im folgenden Kontext-Datei genannt und soll dazu dienen das interene Datenmodell (also +alle Informationen, die der Benutzer im Editor angibt) zu speichern. Das gespeicherte Datenmodell kann +zu einem späteren Zeitpunkt wieder geladen werden. Weiterhin kann das Werkzeug aus dem internen +Datenmodell eine MathCoach-Aufgabe (Groovy-Datei) generieren. Weitere Funktionalitäten - beispielsweise +das Starten der generierten Aufgabe in der Aufgaben-Vorschau der IDE - sind ebenfalls für den +Werkzeugentwickler verfügbar. + +Das Realisieren von Werkzeugen auf diese Art und Weise hat zahlreiche Vorteile: +- Werkzeuge werden einheitliche und benutzerfreundlich zur Verfügung gestellt +- Grundlegende Funktionalitäten (Anlegen von Dateien, Navigieren im Dateisystem) werden bereits + durch die IDE bereitgestellt. So können Werkzeug-Entwickler ihren Fokus auf das Werkzeug legen. +- Die IDE kann gefährliche Situationen (z.B. das Überschreiben von Dateien) abfangen + und den Benutzer entscheiden lassen, wie fortgefahren werden soll. + + + +## Entwicklung externer Werkzeuge + +Externe Werkzeuge laufen ausschließlich im Webbrowser des Benutzers - es muss also +auf `HTML`, `JavaScript` und `CSS` gesetzt werden. Außerdem muss das Werkzeug unter +der Domain des jeweiligen MathCoach-Servers erreichbar sein. Zur Entwicklungszeit legt man das Werkzeug +dazu im www-Verzeichnis ab. Die von der IDE bereitgestellte `ide-lib.js` Bibliothek +muss eingebunden werden. + + <script src="/mathcoach/ui/ide/ide-lib.js"/> + +Dabei darf der MathCoach-Server **nicht** fest in die URL eincodiert werden. Andernfalls +kann es zu Problemen kommen, wenn das Werkzeug auf unterschiedlichen Server bereitgestellt +wird. Bei korrekter Verwendung steht die IDE API nun durch die globale Varialbe `MC` zur +Verfügung - [Dokumentation der IDE API](./interfaces/mathcoach.api.html). + +> **Hinweis**: Es steht **ausschließlich** die API, welche über die globale Variable `MC` +> definiert ist, zur Verfügung! Hilfsfunktionen wie `Helpers.enableOfflineUsageIfNecessary()` +> sind grundsätzlich nicht verfügbar und müssen vom Werkzeugentwickler eingebunden +> werden - siehe "Hilfunktionen für Werkzeug-Entwickler" weiter unten. + +> **Hinweis**: Erst, wenn das Werkzeug in die IDE integriert und aus dieser heraus +> gestartet wurde, kann die IDE API verwendet werden! Soll das Werkzeug auch ohne die +> IDE nutzbar sein (z.B. zum Testen), muss dies bei der Implementierung berücksichtigt +> werden. Konnte die `ide-lib.js` nicht eingebunden werden (weil das Werkzeug ohne IDE +> gestartet wurde - darum darf auch kein Server fest eincodiert werden), steht die +> globale Variable `MC` nicht zur Verfügung (`typeof MC === "undefined"`). Hier kann das +> Werkezug eine Fallunterscheidung treffen und beispielsweise eine eigene Implementierung +> über die globale Variable `MC` bereitstellen. Siehe auch `Helpers.enableOfflineUsageIfNecessary()` +> weiter unten. + + + +### Empfohlenes Vorgehen +Damit externe Werkzeuge ein einheitliches Verhalten aufweisen, sollte wie folgt vorgegangen werden. + +Als erstes muss sichergestellt werden, dass die MathCoach IDE API auch verfügbar ist. Dies ist +beispielsweise nicht der Fall, wenn das Werkzeug ohne die IDE gestartet wurde oder die IDE (aus +welchen Gründen auch immer) nicht einsatzbereit ist. + + if(typeof MC === "undefined"){ + // Hinweis: Hier kann die IDE API nachgebildet werden, + // sodass das Werkzeug auch "Offline" funktioniert. + // Also: MC = { isReady: async () => true, ...} + throw new Error("IDE Lib nicht eingebunden"); // TODO: show error to user + } + const isReady = await MC.isReady(); + if(!isReady){ + throw new Error("Die MathCoach-API ist nicht einsatzbereit."); // TODO: show error to user + } + ... + +Von nun an kann die IDE API vollständig genutzt werden. Zunächst sollte die Kontext-Datei (die +Datei, mit der das Werkzeug gestartet wurde) geladen werden. + +Ist der Inhalt der Kontext-Datei leer, wurde die Datei neu angelegt und zum ersten mal geöffnet. +Nun soll das Werkzeug: +- Sich initialisieren. Es ist sinnvoll, dass das Werkzeug mit einem beispielhaften + Datenmodell inititalisiert wird. +- Das interne Datenmodell in die Kontext-Datei schreiben +- Die zugehörige Aufgabe generieren. Siehe auch `contextFileToExerciseFile` weiter unten. + +Andernfalls kann das zuvor gespeichertes Datenmodell aus der Kontext-Datei in den +Editor geladen werden. Anschließend sollte die generierten Aufgaben in der Vorschau gestartet werden, sodass der +Benutzer besser abschätzen kann, wie sich Änderungen im Werkzeug auf die Aufgabe auswirken. + + + let contextFile = await MC.ide.getContextFile(); // Datei, mit der der Editor gestartet wurde + let contextFileContent = await MC.ide.fs.readFile(contextFile); + let contextFileIsEmpty = contextFileContent === ""; + + let exerciseFile = contextFileToExerciseFile(contextFile); + + if(contextFileIsEmpty){ + // TODO: Datenmodell anlegen (Idealerweise mit beispielhaften Inhalt) + // TODO: Datenmodell in Kontext-Datei schreiben, z.B. mit JSON.stringify(...) + let dataModelAsString = JSON.stringify({/* TODO */}); + await MC.ide.fs.writeFile(contextFile, dataModelAsString); + // TODO: Aufgabe generieren + let generatedExerciseCode = "startup { print('Hallo Welt!') }"; + await MC.ide.fs.writeFile(exerciseFile, generatedExerciseCode); + }else{ + // TODO: Datenmodell laden, z.B. mit JSON.parse(contextFileContent) + // TODO: (Aufgabe neu generieren) + // TODO: init application based on your data model + } + + // Aufgabe anzeigen + await MC.ide.navigator.navigateToExercise(exerciseFile); + +Jedes Werkzeug sollte über eine "Speichern"-Funktion verfügen, mit der der Benutzer: +- Das interne Datenmodell in die Kontext-Datei speichert (sodass es später wieder geladen werden kann) +- Die zugehörige Aufgabe wird generiert und die Vorschau zu dieser navigiert + + + +### Hilfsunktionen für Werkzeug-Entwickler + +[Dokumentation der Hilfsfunktionen](./modules/helpers.html) + +Dieses Paket beinhaltet zusätzlich Hilfsfunktionen für Werkzeug-Entwickler. Diese sind aktuell +in `TypeScript` implementiert und können bei Bedarf auch zukünftig als ES6-JavaScript +bereitgestellt werden. Zum Einbinden der Funktionen wird demzufolge ein Build-System +vorausgesetzt. Keine der Hilfsfunktionen wird durch die `ide-lib.js` ausgeliefert! + +Beispielsweise werden diese wie folgt eingebunden und genutzt: + + import { Helpers } from "@mathcoach/ide-api"; + Helpers.enableOfflineUsageIfNecessary() -## Entwicklung externer Werkzeuge +> **Hinweis**: Hilfunktionen ohne Build-System bereitzustellen gestaltet sich schwierig und +> bringt große Nachteile mit sich: +> - Als reine JavaScript-Datei - platziert auf einem Server - ist die die +> Offline-Fähigkeit (siehe `Helpers.enableOfflineUsageIfNecessary()`) von Werkzeugen nicht +> gewährleistet. +> - Werden Dateien oder Code-Ausschnitte von Hand kopiert, muss der Werkzeug-Entwickler sich +> um das Aktualisieren kümmern. +> +> Ein möglicher Kompromiss wäre die Hilsfunktionen als reine JavaScript-Datei (ES5 oder ES6) +> bereitzustellen und eine Kopie mit dem Werkezug auszuliefern. Der aktuelle Ansatz bettet +> Hilfsfunktionen durch den Build-Prozess in das Werkzeug ein. -- Externe Werkzeuge müssen unter der Domain von MathCoach erreichbar sein. Zur Entwicklungszeit legt - man das Werkzeug dazu im www-Verzeichnis ab. -- Die von der IDE bereitgestellte Bibliothek muss eingebunden werden - - <script src="/mathcoach/ui/ide/ide-lib.js"/> - -- Von nun an steht die hier definierte API durch die globale Variable `MC` zur Verfügung. -- **Hinweis**: Erst, wenn das Werkzeug in die IDE integriert und aus dieser heraus - gestartet wurde, kann die API verwendet werden! (Hinweis: durch nachbilden der API kann - eine Nutzung ohne IDE ermöglicht werden, siehe `enableOfflineUsageIfNecessary`) ### Beispiele -Im Verzeichnis `./examples/` finden sich Beispiele für externe Werkzeuge. +Im Verzeichnis `./examples/` finden sich Beispiele für externe Werkzeuge. -### Hilfunktionen für Werkzeug-Entwickler -Dieses Paket beinhaltet zusätzlich Hilfsfunktionen für Werkzeug-Entwickler. Beispielsweise kann -ein Werkzeug ohne IDE-Anbindung genutzt werden, indem die API nachgebildet wird - aktuell auf -Basis des LocalStorage des Browsers. - - import { enableOfflineUsageIfNecessary } from "@mathcoach/ide-api"; - let offline: boolean = enableOfflineUsageIfNecessary(); - - -### Kleinere Werkzeuge -Für kleiner Werkzeuge bietet es sich an im WWW-Verzeichnis zu entwickeln (z.B. +### Entwicklung kleinerer Werkzeuge +Für kleiner Werkzeuge bietet es sich an im www-Verzeichnis zu entwickeln (z.B. `myTool/tool.html` und `myTool/tool.js`). Die MathCoach-IDE stellt Autovervollständigung beim -Editieren der `tool.js`-Datei zur Verfügung. Da es sich um eine JavaScript-Datei handelt, -ist keine Typsicherheit gegeben. Das Werkzeug muss lokal in die IDE integriert werden, siehe +Editieren der `tool.js`-Datei zur Verfügung. Da es sich um eine JavaScript-Datei handelt, +ist keine Typsicherheit gegeben. Das Werkzeug muss lokal in die IDE integriert werden, siehe weiter unten.  -### Größere Werkzeuge -Für größere Werkzeuge sollte ein Build-System wie [webpack](https://webpack.js.org/) -oder [PARCEL](https://parceljs.org/) in Kombination mit -[TypeScript](https://www.typescriptlang.org/) verwendet werden. Das Werkzeug muss nach dem -Build-Prozess in das WWW-Verzeichnis kopiert und ebenfalls lokal in die IDE integriert werden, siehe -weiter unten. +### Entwicklung größerer Werkzeuge +Für größere Werkzeuge sollten etablierte Entwicklungswerkzeuge verwendet werden, beispielsweise: +- [npm](https://nodejs.org/en/) um externe Bibliotheken (u.A. dieses Paket) einzubinden +- [webpack](https://webpack.js.org/) oder [Parcel](https://parceljs.org/) als Build-System um den Quellcode des Werkzeuges zu "bündeln" +- [TypeScript](https://www.typescriptlang.org/) zum typsischeren Programmieren (und/oder Dateien zu ES6 oder ES5 konformen JavaScript umzuformen) +- [Git](https://git-scm.com/) zur Versionierung des Quellcodes +- [Visual Studio Code](https://code.visualstudio.com/) als Entwicklungsumgebung +- Unit Tests + +Das "gebündelte" Werkzeug muss nach dem Build-Prozess in das WWW-Verzeichnis kopiert und ebenfalls +lokal in die IDE integriert werden, siehe weiter unten. -Die MathCoach-API kann auch als npm-Package eingebunden werden, sodass eine typsichere -und komfortable Entwicklung (z.B. mit Visual Studio Code) möglich ist. Hierzu muss +#### MathCoach-API als npm-Package einbinden + +Die MathCoach-API kann auch als npm-Package eingebunden werden, sodass eine typsichere +und komfortable Entwicklung (z.B. mit Visual Studio Code) möglich ist. Außerdem wird es +möglich die angebotenen [Hilfsfunktionen](./modules/helpers.html) zu einzubinden. Hierzu muss die `package.json` des Werkzeug-Projektes wie folgt ergänzt werden: { ... "devDependencies": { - "@mathcoach/ide-api": "git+https://newton.htwsaar.de/gitblit/r/mathcoach/mathcoach-ide-api.git#1.1.0" + "@mathcoach/ide-api": "git+https://newton.htwsaar.de/gitblit/r/mathcoach/mathcoach-ide-api.git#1.2.0" }, ... } + -Bei Verwendung einer Entwicklungsumgebung wie Visual Studio Code kann die Typdefinition der -API auch für JavaScript eingebunden werden. Hierfür ist ggf. ein spezielles Kommentar am Anfang -der Datei notwendig (Pfad falls nötig anpassen): +Wie man der Git-Repo URL ansieht, werden Git-Tags verwendet um eine Versionierung +[(Semantic Versioning)](https://semver.org/lang/de/) der API zu erreichen. Lässt man die Versionierung weg, +wird die aktuellste Version verwendet. (Siehe Gitblit um verfügbare Versionen einzusehen) + + + + +#### Typdefinition auch ohne Build-System nutzen +Beim Arbeiten mit Visual Studio Code kann man auch ohne Einsatz weiterer Entwicklungswerkzeuge +und Build-Systeme von der Typdefinition der IDE API profitieren. Hierzu muss ein spezielles Kommentar +an den Anfang der JavaScript-Datei platziert werden (Pfad anpassen!): /// <reference path="../node_modules/@mathcoach/ide-api/mathcoach-api.d.ts"/> -Wie man der Git-Repo URL ansieht, werden Git-Tags verwendet um eine -Versionierung [(Semantic Versioning)](https://semver.org/lang/de/) -der API zu erreichen. Lässt man die Versionierung weg, wird die -aktuellste Version verwendet. (Siehe Gitblit um verfügbare Versionen -einzusehen) +Dies sorgt dafür, dass Visual Studio Code Autovervollständigung samt Dokumentation der +IDE API anbieten kann. Nachteilig ist, dass die `mathcoach-api.d.ts` dazu heruntergeladen +werden muss. - -Zertifikat von Newton hinzufügen, damit npm auf das Repository zugreifen kann. +#### Zertifikat-Problem beheben +Falls es Probleme mit dem HTW Zertifikat gibt, muss das Zertifikat von Newton ggf. von +Hand hinzugefügt werden. Nur so kann npm auf das Git-Repository zugreifen und den +Inhalt automatisch herunterladen. cd /usr/local/share/ca-certificates/ sudo mkdir newton.htwsaar.de - + sudo cp path/to/newton.htwsaar.de.crt /usr/local/share/ca-certificates/newton.htwsaar.de/ - - sudo chown 755 /usr/local/share/ca-certificates/newton.htwsaar.de + + sudo chown 755 /usr/local/share/ca-certificates/newton.htwsaar.de sudo chown 644 /usr/local/share/ca-certificates/newton.htwsaar.de/newton.htwsaar.de.crt sudo update-ca-certificates - + ## Werkzeuge in die IDE integrieren Damit die IDE das Werkzeug integrieren kann, muss eine Werkzeug-Deklaration registriert werden. Zur -Entwicklungszeit kann der Werkzeug-Entwickler dies lokal vornehmen. Anschließend können verknüpfte -Dateien mit dem Werkzeug geöffnet werden und erstellt werden (siehe Kontext-Menüs im IDE-Explorer). -Eine Freischaltung des Werkzeugs für alle Autoren erfolgt durch einen Administrator. +Entwicklungszeit kann der Werkzeug-Entwickler dies lokal vornehmen. Anschließend können verknüpfte +Dateien mit dem Werkzeug geöffnet werden und erstellt werden (siehe Kontext-Menüs im IDE-Explorer). +Eine Freischaltung des Werkzeugs für alle Autoren erfolgt durch einen Administrator. -### Lokal (Nur für den Entwickler des Werkzeugs) -In der IDE muss eine Werkzeug-Deklaration angelegt werden, dazu muss die Datei `ide-settings.json` editiert werden: +### Lokal (Nur für den Entwickler des Werkzeugs) +In der IDE muss eine Werkzeug-Deklaration angelegt werden, dazu muss die Datei `ide-settings.json` editiert werden: { ... - "editor.external.declarations": [ + "editor.external.declarations": [ { - "displayName": "Dummy", - "entry": "/mathcoach/www/YOURNAME/tool.html", - "description": "...", - "developer": "...", - "extension": "ext" + "displayName": "Dummy", + "entry": "/mathcoach/www/YOURNAME/tool.html", + "description": "...", + "developer": "...", + "extension": "fib.json" } ... - ], + ], ... - } + } | Schlüssel | Beschreibung | Beispiel | |---------------|---|---| @@ -124,30 +266,32 @@ ### Global (Für alle Autoren) -- Das Werkzeug samt Werkzeug-Deklaration muss als `.zip`-Datei an einen Administrator übergeben werden +- Das Werkzeug samt Werkzeug-Deklaration muss an einen Administrator übergeben werden - Der Administrator schaltet das Werkzeug nach einer kurzen Prüfung (Keine Konflikte mit anderen Dateierweiterung, usw) frei. Beim nächsten Release von MathCoach ist das Werkzeug dann für alle Autoren verfügbar. - - + + ## Infos zu diesem Repository . ├── CHANGELOG.md // Dokumentation von Änderungen der API ├── examples // Beispiele - │ ├── ... + │ ├── ... + │ └── ... + ├── media // Grafiken │ └── ... ├── src // Hilfsfunktionen für Werkzeugentwickler │ ├── index.ts // Einstiegspunkt │ └── ... - ├── mathcoach-api.d.ts // Definition der API - ├── package.json + ├── mathcoach-api.d.ts // Typ-Definition der API + ├── package.json ├── package-lock.json ├── README.md └── tsconfig.json - + ### Dokumentation erzeugen -- Gitblit v1.10.0-SNAPSHOT