159 lines
4.5 KiB
Go
159 lines
4.5 KiB
Go
package main
|
||
|
||
import (
|
||
"context"
|
||
"flag"
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
"strings"
|
||
|
||
"scout/pkg/client"
|
||
)
|
||
|
||
func main() {
|
||
if len(os.Args) < 2 {
|
||
printUsage()
|
||
os.Exit(2)
|
||
}
|
||
switch os.Args[1] {
|
||
case "check":
|
||
checkCommand(os.Args[2:])
|
||
case "download":
|
||
downloadCommand(os.Args[2:])
|
||
case "upload":
|
||
uploadCommand(os.Args[2:])
|
||
case "watch":
|
||
watchCommand(os.Args[2:])
|
||
default:
|
||
printUsage()
|
||
os.Exit(2)
|
||
}
|
||
}
|
||
|
||
func checkCommand(args []string) {
|
||
flags := flag.NewFlagSet("check", flag.ExitOnError)
|
||
server := flags.String("server", "http://localhost:8080", "服务端地址")
|
||
name := flags.String("package", "", "包名")
|
||
current := flags.String("current", "", "当前版本")
|
||
flags.Parse(args)
|
||
requirePackage(*name)
|
||
api := newClient(*server, "")
|
||
latest, available, err := api.CheckUpdate(context.Background(), *name, *current)
|
||
if err != nil {
|
||
fatal("检查更新失败: %v", err)
|
||
}
|
||
if available {
|
||
fmt.Printf("发现更新:%s %s -> %s\n", latest.Name, *current, latest.Version)
|
||
return
|
||
}
|
||
fmt.Printf("当前已是最新版本:%s\n", latest.Version)
|
||
}
|
||
|
||
func downloadCommand(args []string) {
|
||
flags := flag.NewFlagSet("download", flag.ExitOnError)
|
||
server := flags.String("server", "http://localhost:8080", "服务端地址")
|
||
name := flags.String("package", "", "包名")
|
||
version := flags.String("version", "", "版本;为空时下载最新版本")
|
||
output := flags.String("output", "", "保存路径")
|
||
flags.Parse(args)
|
||
requirePackage(*name)
|
||
if *output == "" {
|
||
resolvedVersion := *version
|
||
if resolvedVersion == "" {
|
||
resolvedVersion = "latest"
|
||
}
|
||
*output = filepath.Join(".", fmt.Sprintf("%s-%s.pkg", *name, resolvedVersion))
|
||
}
|
||
api := newClient(*server, "")
|
||
item, err := api.Download(context.Background(), *name, *version, *output)
|
||
if err != nil {
|
||
fatal("下载失败: %v", err)
|
||
}
|
||
fmt.Printf("下载完成:%s\n版本:%s\nSHA-256:%s\n", *output, item.Version, item.SHA256)
|
||
}
|
||
|
||
func uploadCommand(args []string) {
|
||
flags := flag.NewFlagSet("upload", flag.ExitOnError)
|
||
server := flags.String("server", "http://localhost:8080", "服务端地址")
|
||
token := flags.String("token", "", "开发者令牌")
|
||
name := flags.String("package", "", "包名")
|
||
version := flags.String("version", "", "版本")
|
||
filePath := flags.String("file", "", "包文件路径")
|
||
description := flags.String("description", "", "包描述")
|
||
platform := flags.String("platform", "", "运行平台")
|
||
architecture := flags.String("architecture", "", "运行架构")
|
||
flags.Parse(args)
|
||
requirePackage(*name)
|
||
if *version == "" || *filePath == "" {
|
||
fatal("必须指定 --version 和 --file")
|
||
}
|
||
file, err := os.Open(*filePath)
|
||
if err != nil {
|
||
fatal("打开包文件失败: %v", err)
|
||
}
|
||
defer file.Close()
|
||
api := newClient(*server, *token)
|
||
item, err := api.Upload(context.Background(), client.UploadRequest{
|
||
Name: *name,
|
||
Version: *version,
|
||
Description: *description,
|
||
Platform: *platform,
|
||
Architecture: *architecture,
|
||
FileName: filepath.Base(*filePath),
|
||
File: file,
|
||
})
|
||
if err != nil {
|
||
fatal("上传失败: %v", err)
|
||
}
|
||
fmt.Printf("上传成功:%s %s\nSHA-256:%s\n", item.Name, item.Version, item.SHA256)
|
||
}
|
||
|
||
func watchCommand(args []string) {
|
||
flags := flag.NewFlagSet("watch", flag.ExitOnError)
|
||
server := flags.String("server", "http://localhost:8080", "服务端地址")
|
||
packages := flags.String("packages", "", "要监听的包名,多个包用逗号分隔")
|
||
flags.Parse(args)
|
||
api := newClient(*server, "")
|
||
updates, err := api.WatchUpdates(context.Background(), splitPackages(*packages)...)
|
||
if err != nil {
|
||
fatal("连接更新通知失败: %v", err)
|
||
}
|
||
fmt.Println("已连接更新通知,等待新包……")
|
||
for update := range updates {
|
||
fmt.Printf("收到更新:%s %s\n", update.Package.Name, update.Package.Version)
|
||
}
|
||
}
|
||
|
||
func newClient(server, token string) *client.Client {
|
||
api, err := client.New(server, client.WithDeveloperToken(token))
|
||
if err != nil {
|
||
fatal("创建客户端失败: %v", err)
|
||
}
|
||
return api
|
||
}
|
||
|
||
func splitPackages(value string) []string {
|
||
if strings.TrimSpace(value) == "" {
|
||
return nil
|
||
}
|
||
return strings.Split(value, ",")
|
||
}
|
||
|
||
func requirePackage(name string) {
|
||
if strings.TrimSpace(name) == "" {
|
||
fatal("必须指定 --package")
|
||
}
|
||
}
|
||
|
||
func fatal(format string, args ...any) {
|
||
fmt.Printf("错误:"+format+"\n", args...)
|
||
os.Exit(1)
|
||
}
|
||
|
||
func printUsage() {
|
||
fmt.Println("Scout 轻量化包管理客户端")
|
||
fmt.Println("用法:scout-client <check|download|upload|watch> [参数]")
|
||
fmt.Println("upload 用于开发者上传,check、download、watch 用于客户端更新流程")
|
||
}
|