sylixos-uploader/cmd/upload.go

130 lines
3.8 KiB
Go

package cmd
import (
"net"
"os"
"path/filepath"
"sylixos-uploader/common"
"sylixos-uploader/detector"
"sylixos-uploader/log"
"sylixos-uploader/parser"
"sylixos-uploader/pusher"
"github.com/spf13/cobra"
)
var uplaodCmd = &cobra.Command{
Use: "upload",
Short: "upload SylixOS project",
Long: `upload SylixOS project to device`,
Run: func(cmd *cobra.Command, args []string) {
if ProjectPath == "" {
ProjectPath = "."
}
if UploadMethod != "ftp" {
log.DefaultLogger(log.LogLevelError, "Only support upload ftp now.")
return
}
prj := detector.NewSylixOSPrj(ProjectPath)
if !prj.IsSylixOSPrj() {
log.DefaultLogger(log.LogLevelError, "%s is Not a SylixOS project!", ProjectPath)
return
}
if !prj.HasUploadYml {
generateYamlFromRealEvo(ProjectPath, BasePrjPath, Device)
}
uploader := new(parser.UploadSetting)
err := uploader.LoadConfig(filepath.Join(ProjectPath, common.YamlFile))
if err != nil {
log.DefaultLogger(log.LogLevelError, "Error load %s: %v", filepath.Join(ProjectPath, common.YamlFile), err)
return
}
remoteIP := net.ParseIP(uploader.RemoteSettings.IP)
if remoteIP != nil {
log.DefaultLogger(log.LogLevelInfo, "Upload Device IP: %s", uploader.RemoteSettings.IP)
} else {
log.DefaultLogger(log.LogLevelWarn, "No Valid Device IP in YML, please set Device IP by --device")
return
}
if UploadMethod == "ftp" {
p := pusher.NewFtpPusher(uploader.RemoteSettings.IP)
err := p.Login(common.SylixOSUser, common.SylixOSPassword)
if err != nil {
log.DefaultLogger(log.LogLevelError, "Error login to %s: %v", uploader.RemoteSettings.IP, err)
return
} else {
log.DefaultLogger(log.LogLevelInfo, "Login Success: %s", uploader.RemoteSettings.IP)
}
defer p.Logout()
for _, UploadFile := range uploader.UploadPair {
absLocalFilePath, err := uploader.GetAbsLocalPath(UploadFile.LocalPath, "")
if err != nil {
log.DefaultLogger(log.LogLevelError, "Error getting absolute path for %s: %v", UploadFile.LocalPath, err)
return
}
err = p.Push(absLocalFilePath, UploadFile.RemotePath, log.DefaultLogger, log.DefaultClearLinesUp)
if err != nil {
log.DefaultLogger(log.LogLevelError, "Error uploading %s to %s: %v", UploadFile.LocalPath, UploadFile.RemotePath, err)
return
} else {
info, _ := os.Stat(absLocalFilePath)
if info.IsDir() {
// 统计文件和子文件夹数量
fileCount, dirCount := countFilesAndDirs(absLocalFilePath)
log.DefaultLogger(log.LogLevelInfo, "Upload Dir Success: %s, Files: %d, Subdirectories: %d", UploadFile.RemotePath, fileCount, dirCount)
} else {
log.DefaultLogger(log.LogLevelInfo, "Upload File Success: %s", UploadFile.RemotePath)
}
}
}
}
},
}
// countFilesAndDirs 递归统计文件和子文件夹数量
func countFilesAndDirs(dirPath string) (int, int) {
var fileCount, dirCount int
err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
// 忽略单个文件/文件夹的错误
log.DefaultLogger(log.LogLevelWarn, "Error accessing %s: %v", path, err)
return nil
}
if info.IsDir() {
dirCount++
} else {
fileCount++
}
return nil
})
if err != nil {
log.DefaultLogger(log.LogLevelError, "Error walking the directory %s: %v", dirPath, err)
}
// 返回文件数和子文件夹数
return fileCount, dirCount - 1 // 减去根目录本身
}
func init() {
RootCmd.AddCommand(uplaodCmd)
// Adding flags with long names
uplaodCmd.Flags().StringVar(&ProjectPath, "path", "", "Project path")
uplaodCmd.Flags().StringVar(&BasePrjPath, "base", "", "Base project path")
uplaodCmd.Flags().StringVar(&Device, "device", "", "Device")
uplaodCmd.Flags().StringVar(&UploadMethod, "method", "ftp", "Upload method now only support ftp")
}