From d0655588655a4ad121c97df1cb3a28a5c82798f9 Mon Sep 17 00:00:00 2001 From: zhengkunwang223 <31820853+zhengkunwang223@users.noreply.github.com> Date: Thu, 18 May 2023 19:06:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E5=BA=94=E7=94=A8=E9=BB=98=E8=AE=A4=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=8C=87=E4=BB=A4=20(#1076)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/server/app/app_config.go | 14 ++++ cmd/server/app/app_config.yml | 13 ++++ cmd/server/app/app_param.yml | 10 +++ cmd/server/app/logo.png | Bin 0 -> 6787 bytes cmd/server/cmd/app.go | 122 ++++++++++++++++++++++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 cmd/server/app/app_config.go create mode 100644 cmd/server/app/app_config.yml create mode 100644 cmd/server/app/app_param.yml create mode 100644 cmd/server/app/logo.png create mode 100644 cmd/server/cmd/app.go diff --git a/cmd/server/app/app_config.go b/cmd/server/app/app_config.go new file mode 100644 index 000000000..d4d155998 --- /dev/null +++ b/cmd/server/app/app_config.go @@ -0,0 +1,14 @@ +package app + +import ( + _ "embed" +) + +//go:embed app_config.yml +var Config []byte + +//go:embed logo.png +var Logo []byte + +//go:embed app_param.yml +var Param []byte diff --git a/cmd/server/app/app_config.yml b/cmd/server/app/app_config.yml new file mode 100644 index 000000000..3a2ec0827 --- /dev/null +++ b/cmd/server/app/app_config.yml @@ -0,0 +1,13 @@ +additionalProperties: + key: #应用的 key ,仅限英文,用于在 Linux 创建文件夹 + name: #应用名称 + tags: + - Tool #应用标签,可以有多个,请参照下方的标签列表 + shortDescZh: #应用中文描述,不要超过30个字 + shortDescEn: #应用英文描述 + type: tool #应用类型,区别于应用分类,只能有一个,请参照下方的类型列表 + crossVersionUpdate: #是否可以跨大版本升级 + limit: #应用安装数量限制,0 代表无限制 + website: #官网地址 + github: #github 地址 + document: #文档地址 \ No newline at end of file diff --git a/cmd/server/app/app_param.yml b/cmd/server/app/app_param.yml new file mode 100644 index 000000000..426fa78c6 --- /dev/null +++ b/cmd/server/app/app_param.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 8080 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/cmd/server/app/logo.png b/cmd/server/app/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ffc2c831b5838c7cb3ec600d9d99a7686341b053 GIT binary patch literal 6787 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 0 { + appKey = args[0] + if len(args) > 1 { + appVersion = args[1] + } + } + if appKey == "" { + fmt.Println("应用的 key 缺失,使用 -k 指定") + return nil + } + if appVersion == "" { + fmt.Println("应用版本缺失,使用 -v 指定") + return nil + } + fileOp := files.NewFileOp() + appKeyPath := fmt.Sprintf("./%s", appKey) + if err := createFolder(fileOp, appKeyPath); err != nil { + return err + } + configYamlPath := fmt.Sprintf("%s/data.yml", appKeyPath) + if err := createFile(fileOp, configYamlPath); err != nil { + return err + } + if err := writeFile(fileOp, configYamlPath, bytes.NewReader(app.Config)); err != nil { + return err + } + readMePath := fmt.Sprintf("%s/README.md", appKeyPath) + if err := createFile(fileOp, readMePath); err != nil { + return err + } + logoPath := fmt.Sprintf("%s/logo.png", appKeyPath) + if err := createFile(fileOp, logoPath); err != nil { + return err + } + if err := writeFile(fileOp, logoPath, bytes.NewReader(app.Logo)); err != nil { + return err + } + versionPath := fmt.Sprintf("%s/%s", appKeyPath, appVersion) + if fileOp.Stat(versionPath) { + return errors.New("版本已存在!") + } + if err := createFolder(fileOp, versionPath); err != nil { + return err + } + versionParamPath := fmt.Sprintf("%s/%s", versionPath, "data.yml") + if err := createFile(fileOp, versionParamPath); err != nil { + return err + } + if err := writeFile(fileOp, versionParamPath, bytes.NewReader(app.Param)); err != nil { + return err + } + dockerComposeYamlPath := fmt.Sprintf("%s/%s", versionPath, "docker-compose.yml") + if err := createFile(fileOp, dockerComposeYamlPath); err != nil { + return err + } + fmt.Println("创建成功!") + return nil + }, +} + +func createFile(fileOp files.FileOp, filePath string) error { + if fileOp.Stat(filePath) { + return nil + } + if err := fileOp.CreateFile(filePath); err != nil { + fmt.Printf("文件 %s 创建失败 %v", filePath, err) + return err + } + return nil +} + +func createFolder(fileOp files.FileOp, dirPath string) error { + if fileOp.Stat(dirPath) { + return nil + } + if err := fileOp.CreateDir(dirPath, 0755); err != nil { + fmt.Printf("文件夹 %s 创建失败 %v", dirPath, err) + return err + } + return nil +} + +func writeFile(fileOp files.FileOp, filePath string, in io.Reader) error { + if err := fileOp.WriteFile(filePath, in, 0755); err != nil { + fmt.Printf("文件 %s 写入失败 %v", filePath, err) + return err + } + return nil +}