diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..99c5450 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,20 @@ +kind: pipeline +type: docker +name: default + +steps: + - name: build + pull: if-not-exists + image: xiaoqidun/goenv + commands: + - CGO_ENABLED=0 go build -o gocos -trimpath -ldflags '-s -w' gocos.go + - name: docker + pull: if-not-exists + image: plugins/docker + settings: + repo: xiaoqidun/gocos + username: + from_secret: docker_username + password: + from_secret: docker_password + dockerfile: Dockerfile diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..77c6356 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +.vscode/ +.devcontainer/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4938242 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +# 基础镜像 +FROM alpine + +# 作者信息 +LABEL MAINTAINER="xiaoqidun@gmail.com" + +# 复制程序 +COPY gocos /bin/gocos + +# 启动命令 +ENTRYPOINT /bin/gocos diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e45f824 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/xiaoqidun/gocos + +go 1.16 + +require github.com/tencentyun/cos-go-sdk-v5 v0.7.15 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6aa200e --- /dev/null +++ b/go.sum @@ -0,0 +1,13 @@ +github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= +github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tencentyun/cos-go-sdk-v5 v0.7.15 h1:+uKDylojhKkGhBzb8B7J/nIoEl6afGYiJubkVWEctxA= +github.com/tencentyun/cos-go-sdk-v5 v0.7.15/go.mod h1:wQBO5HdAkLjj2q6XQiIfDSP8DXDNrppDRw2Kp/1BODA= diff --git a/gocos.go b/gocos.go new file mode 100644 index 0000000..214c0af --- /dev/null +++ b/gocos.go @@ -0,0 +1,113 @@ +package main + +import ( + "context" + "github.com/tencentyun/cos-go-sdk-v5" + "io/fs" + "log" + "net/http" + "net/url" + "os" + "path/filepath" + "strings" +) + +const ( + CodeErr = 1 + SecretID = "secret_id" + SecretKey = "secret_key" + BucketURL = "bucket_url" + Source = "source" + Target = "target" + StripPrefix = "strip_prefix" + PathSeparator = "/" +) + +func GetConfig(key string) string { + key = "PLUGIN_" + strings.ToUpper(key) + return os.Getenv(key) +} + +func VarIsEmpty(a ...interface{}) bool { + for _, v := range a { + switch v := v.(type) { + case string: + if "" == v { + return true + } + case []byte: + if 0 == len(v) { + return true + } + case []string: + if 0 == len(v) { + return true + } + } + } + return false +} + +func main() { + var ( + err error + secretID = GetConfig(SecretID) + secretKey = GetConfig(SecretKey) + bucketURL = GetConfig(BucketURL) + source = GetConfig(Source) + target = GetConfig(Target) + stripPrefix = GetConfig(StripPrefix) + ) + if !VarIsEmpty(secretID, secretKey, bucketURL, source, target) { + os.Exit(CodeErr) + return + } + sourceFiles := make([]string, 0, 0) + if err = filepath.WalkDir(source, func(path string, d fs.DirEntry, err error) error { + if !d.IsDir() { + sourceFiles = append(sourceFiles, path) + } + return nil + }); err != nil { + os.Exit(CodeErr) + return + } + sourceLen := len(sourceFiles) + if sourceLen == 0 { + return + } + if !strings.HasSuffix(target, PathSeparator) { + target += PathSeparator + } + u, err := url.Parse(bucketURL) + if err != nil { + os.Exit(CodeErr) + return + } + cosClient := cos.NewClient( + &cos.BaseURL{ + BucketURL: u, + }, + &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: secretID, + SecretKey: secretKey, + }, + }) + for i := 0; i < sourceLen; i++ { + local := sourceFiles[i] + remote := strings.TrimPrefix(local, stripPrefix) + if strings.HasPrefix(remote, PathSeparator) { + remote = strings.TrimPrefix(remote, PathSeparator) + } + remote = target + remote + if _, err = cosClient.Object.PutFromFile(context.Background(), remote, local, &cos.ObjectPutOptions{ + ACLHeaderOptions: &cos.ACLHeaderOptions{}, + ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{}, + }); err != nil { + os.Exit(CodeErr) + return + } + log.Printf("source:%s target:%s\r\n", local, remote) + } +}