## GodoOS App Store Development Tutorial ### Quick Start 1. Download the [mysql5.7 zip package](https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.44-winx64.zip), and extract it to the `.godoos/run/windows/` directory under the user directory, naming the folder `mysql5.7`. 2. Copy the `mysql5.7` from this program's `docs/demo/mysql5.7` to the `.godoos/run/windows/mysql5.7` directory under the user directory. 3. Open the app store, add an app, select development mode, input `mysql5.7` as the local path, and click OK. ### Development Requirements 1. Basic HTML development skills. 2. Familiarity with the executable file startup process, then configure the JSON file according to the following flow. ### How to Add an Application 1. Create an application folder under the `.godoos/run/windows/` directory in the user directory. 2. An application requires two configuration files; create the `install.json` and `store.json` files at the root of the application directory. The configuration file formats are as follows: - `install.json` [Sample](./demo/mysql5.7/install.json) ```json { "name": "", // string, Name of the application. "url": "", // string, Download URL of the application or adapter package. "pkg": "", // string, Official download URL of the application. Can be empty. "webUrl":"", // string, If set, the application will be displayed on the desktop. "isDev": true, // boolean, Whether it is a development environment. If set to true, data will not be downloaded. "version": "1.0.0", // string, Version of the application. "icon": "", // string, Icon of the application, accessible network address. "hasStart": true, // boolean, Indicates whether startup and shutdown are shown. "hasRestart": true, // boolean, Whether a restart is needed. "setting": true // boolean, Whether settings are needed. Only shown when the application is stopped. } ``` - Note: If a web application does not require a backend process, store.json does not need to be configured. The structure of install.json is: ```json type InstallInfo struct { Name string `json:"name"` // Name of the application. Important, must match the directory name of the application. URL string `json:"url"` // Download URL of the application or adapter package. Pkg string `json:"pkg"` // Official download URL of the application. WebUrl string `json:"webUrl"` // Web address of the application. IsDev bool `json:"isDev"` // Flag indicating whether it is a developer version. Version string `json:"version"` // Version number of the application. Desc string `json:"desc"` // Description information of the application. Icon string `json:"icon"` // Path to the application icon. HasStart bool `json:"hasStart"` // Flag indicating whether startup and shutdown are shown. HasRestart bool `json:"hasRestart"` // Flag indicating whether a restart is needed after installation. Setting bool `json:"setting"` // Flag indicating whether configuration is needed. Dependencies []Item `json:"dependencies"` // Dependencies. History []InstallHastory `json:"history"`// History } type InstallHastory struct { Version string `json:"version"` URL string `json:"url"` Pkg string `json:"pkg"` // Official download URL of the application. } ``` - store.json [Sample](./demo/mysql5.7/store.json) ```json { "setting": { "binPath": "{exePath}/bin/mysqld.exe", // string, Important, must be set. Path to the startup program. "confPath": "{exePath}/my.ini", // string, Can be empty. Path to the configuration file. "progressName": "mysqld.exe", // string, Process name. Not required if single-threaded. "isOn": true // boolean, Whether to start the daemon process. }, "config": { // object, Configuration file. Any configuration inside can be filled out, used in conjunction with commands. Can be set via HTTP. }, "commands": {}, // object, List of commands. Available for invocation by `installCmds` inside `install`, also callable through external HTTP requests. "install": { // object, Installation configuration. "installEnvs": [], // object[], Environment variables. "installCmds": [] // object[], Startup commands. Can invoke commands from the command list set `commands`. }, "start": { "startEnvs": [], "beforeCmds": [], // List of commands to execute before startup. Can invoke commands from the command list set `commands`. "startCmds": [ // object[], Pure parameter command set. Will start `setting.binPath`, cannot invoke commands from the `commands` list. "--defaults-file={exePath}/my.ini" ], "AfterCmds": [] // List of commands to execute after startup. Can invoke commands from the command list set `commands`. } } ``` - Note: The core replacement parameter is `{exePath}`, which is the execution directory of the program. Other `{parameters}` correspond to the config in `store.json`. The structure for `store.json` is as follows: ```json type StoreInfo struct { Setting Setting `json:"setting"` // Configuration information for the application store. Config map[string]any `json:"config"` // Mapping of application configuration information. Commands map[string][]Cmd `json:"commands"` // Collection of application commands. Install InstallStruct `json:"install"` // Information for installing the application. Start StartStruct `json:"start"` // Information for starting the application. } ``` The structure for Setting is: ```json // Contains critical setting information such as the binary file path and configuration file path of the application. type Setting struct { BinPath string `json:"binPath"` // Path to the application's binary file. ConfPath string `json:"confPath"` // Path to the application's configuration file. ProgressName string `json:"progressName"` // Name of the process. IsOn bool `json:"isOn"` // Indicates if the daemon process is running. } ``` The structure for Cmd is: ```json type Cmd struct { Name string `json:"name"` // Name of the command. FilePath string `json:"filePath,omitempty"` // Path to the command file. Content string `json:"content,omitempty"` // Content of the command. BinPath string `json:"binPath,omitempty"` // Path to the binary file for executing the command. TplPath string `json:"tplPath,omitempty"` // Template path for the command. Cmds []string `json:"cmds,omitempty"` // List of subcommands to be executed. Waiting int `json:"waiting"` // Waiting time. Kill bool `json:"kill"` // Flag indicating whether to terminate previous commands. If the process name is set in `content`, priority is given to killing the process by name. Envs []Item `json:"envs"` // Environment variables during command execution. } ``` The structure for Install is: ```json // `InstallStruct` describes environment variables and command lists during the installation process. type InstallStruct struct { InstallEnvs []Item `json:"installEnvs"` // Environment variables required during installation. InstallCmds []string `json:"installCmds"` // List of commands to execute during installation. } type StartStruct struct { StartEnvs []Item `json:"startEnvs"` // Environment variables required during startup. BeforeCmds []string `json:"beforeCmds"` // List of commands to execute before startup. Commands can be invoked from the `commands` list. StartCmds []string `json:"startCmds"` // List of commands to execute during startup. AfterCmds []string `json:"afterCmds"` // List of commands to execute after startup. Commands can be invoked from the `commands` list. } // `Item` is a generic key-value pair structure used to represent configuration items or environment variables, etc. type Item struct { Name string `json:"name"` // Name of the configuration item. Value any `json:"value"` // Value of the configuration item. } ``` 3. To add an application in the app store, select local addition and input the name of the application directory (no need to fill in the entire directory). ### Explanation of the Configuration File `store.json` 1. install can invoke commands from the commands list. 2. Commands in the commands list can also invoke their own commands. 3. All commands can be chained together. ### How to Set Configuration 1. Create a static directory under the application directory and create an index.html file. Set setting to true in install.json. Frontend configuration example [Sample](./demo/mysql5.7/static/index.html) ```js const postData = { dataDir: dataDir, // Corresponds to the config configuration item in store.json logDir: logDir, // Corresponds to the config configuration item in store.json port: port, // Corresponds to the config configuration item in store.json name: "mysql5.7", // Application name cmdKey: "setting" // Command key, name of cmds }; const comp = await fetch('http://localhost:56780/store/setting', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(postData) }); ``` - It is crucial to set name and cmdKey correctly; name is the application name, and cmdKey corresponds to the key in the commands object in store.json. An object can configure a series of commands, which can refer to the structure of Cmd, sample: ```json "commands": { "initData": [ { "name": "exec", "binPath": "{exePath}/bin/mysqld.exe", "cmds": [ "--defaults-file={exePath}/my.ini", "--initialize" ], "waiting": 1 //Waiting seconds }, { "name": "exec", "binPath": "{exePath}/bin/mysqld.exe", "cmds": [ "--defaults-file={exePath}/my.ini", "--init-file={exePath}/password.txt" ], "waiting": 3, "content": "mysqld.exe", "kill": true }, { "name": "start" } ], "setting": [ { "name": "changeFile", "tplPath": "{exePath}/my.ini.tpl", "filePath": "{exePath}/my.ini" }, { "name": "initData" } ], } ``` - In the above sample, setting invokes the initData command again. - The fixed address for POST is http://localhost:56780/store/setting - The principle works by sending configuration information to the store service through an http request to the /store/setting interface. Then, the store service will automatically update the configuration information and start the application based on the configuration information. ### Explanation of the static Directory 1. `index.html` is the homepage of the application. 2. When install is executed, files under the static directory are automatically copied to the .godoos/static/ application directory. 3. If store.json sets icon and the file exists in the static directory, the application icon is that file. Otherwise, it is the icon in install.json. ### Description of Built-in Applications - The system encapsulates some functions for handling process control and file operations. Below are detailed descriptions of each function: 1. `start` Start the application. 2. `stop` Stop the application. 3. `restart` Restart the application. 4. `exec` Execute a command. Must set binPath and cmds. 5. `writeFile` Write to a file. Must set filePath and content. Based on config, replaces {parameters} in content. 6. `changeFile` Modify a file. Must set filePath and tplPath. Based on config, performs replacements in the template file. 7. `deleteFile` Delete a file. 8. `unzip` Unzip a file. Must set filePath and content. content is the extraction directory. 9. `zip` Compress a file. Must set filePath and content. filePath is the folder to be compressed, and content is the name of the compressed file. 10. `mkdir` Create a directory. Must set FilePath, which is the path of the directory to be created. 11. `startApp` Start another application. content is the name of the application. 12. `stopApp` Stop another application. content is the name of the application. ### Advanced Operations 1. Download [mysql8.0](https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.39-winx64.zip) 2. Refer to the mysql8.0 directory under demo and attempt to create your own installation package.