From de700cfdefebb9f724e2e2b9db88bfcb864fbb67 Mon Sep 17 00:00:00 2001 From: icechen Date: Tue, 28 Dec 2021 20:42:51 +0800 Subject: [PATCH] update --- config_handler/config_handler.go | 80 +++++++++++++++++++++++++++ config_handler/destination_config.go | 27 +++++++++ config_handler/real_config.go | 46 ++++++++++++++++ config_handler/util.go | 21 +++++++ git/git.go | 82 ++++++++++++++++++++++++++++ go.mod | 3 + go.sum | 30 ++++++++++ go_coverter/go_coverter.go | 40 -------------- go_handler/go_handler.go | 20 +++++++ main.go | 5 +- 10 files changed, 312 insertions(+), 42 deletions(-) create mode 100644 config_handler/config_handler.go create mode 100644 config_handler/destination_config.go create mode 100644 config_handler/real_config.go create mode 100644 config_handler/util.go create mode 100644 git/git.go delete mode 100644 go_coverter/go_coverter.go create mode 100644 go_handler/go_handler.go diff --git a/config_handler/config_handler.go b/config_handler/config_handler.go new file mode 100644 index 0000000..7af6e2e --- /dev/null +++ b/config_handler/config_handler.go @@ -0,0 +1,80 @@ +package config_handler + +import ( + "context" + "encoding/json" + "strings" + + "git.icechen.cn/pkg/drone_plugin/git" + + "github.com/drone/drone-go/drone" + "github.com/drone/drone-go/plugin/config" + "github.com/sirupsen/logrus" +) + +// New returns a new conversion plugin. +func New() config.Plugin { + return &plugin{} +} + +type plugin struct{} + +func (p *plugin) Find(ctx context.Context, req *config.Request) (*drone.Config, error) { + resp, err := json.Marshal(req) + if err != nil { + logrus.Error(err) + return nil, err + } + logrus.Infof("%s", string(resp)) + + // 1. 获取原始配置文件信息 + cfg, err := getRealConfig(getGitClient(req)) + if err != nil { + logrus.Error(err) + return nil, err + } + + // 2. 非 monorepo 的直接返回 + if cfg.Type != TypeMonorepo { + // 返回 nil 按照 204 处理 + return nil, nil + } + + // 3. 获取提交文件树 + modifiedFileList, err := getGitClient(req).GetCommitModifiedFileList() + if err != nil { + logrus.Error(err) + return nil, err + } + + // 4. 根据文件树以及原始配置文件的信息,组装需要构建的服务的ci信息 + // 4.1 api + modifiedApiList := getModifiedApi(cfg.Api, modifiedFileList) + + _ = modifiedApiList + // 4.2 service + + // 5. 组装所有ci信息并输出 + return nil, nil +} + +func getGitClient(req *config.Request) git.Client { + return git.New(req.Repo.Namespace, req.Repo.Name, req.Build.After, req.Repo.Config) +} + +func getModifiedApi(api []Api, modifiedFileList []string) []Api { + ret := make([]Api, 0) + tempIndex := NewSet() + for i, a := range api { + for _, file := range modifiedFileList { + if strings.HasSuffix(file, a.Root) { + tempIndex.Add(i) + } + } + } + + for _, i := range tempIndex.ToSlice() { + ret = append(ret, api[i]) + } + return ret +} diff --git a/config_handler/destination_config.go b/config_handler/destination_config.go new file mode 100644 index 0000000..e763fd7 --- /dev/null +++ b/config_handler/destination_config.go @@ -0,0 +1,27 @@ +package config_handler + +import "git.icechen.cn/pkg/drone_plugin/go_handler" + +type ApiHandler interface { + ToDestinationConfig() (string, error) +} + +func (al ApiList) toDestinationConfig() (string, error) { + return "", nil +} + +func (a Api) toDestinationConfig() (string, error) { + var handler ApiHandler + switch a.Type { + case go_handler.TypeGolang: + handler = go_handler.GoApiHandler{} + } + + return handler.ToDestinationConfig() +} + +func (sl ServiceList) toDestinationConfig() { +} + +func (s Service) toDestinationConfig() { +} diff --git a/config_handler/real_config.go b/config_handler/real_config.go new file mode 100644 index 0000000..e17f51e --- /dev/null +++ b/config_handler/real_config.go @@ -0,0 +1,46 @@ +package config_handler + +import ( + "git.icechen.cn/pkg/drone_plugin/git" + "gopkg.in/yaml.v3" +) + +const TypeMonorepo = "monorepo" // 单库类型 + +type Config struct { + Kind string `json:"kind" yaml:"kind"` + Type string `json:"type" yaml:"type"` + Name string `json:"name" yaml:"name"` + Api ApiList `json:"api" yaml:"api"` + Service ServiceList `json:"service" yaml:"service"` +} + +type ( + ApiList []Api + Api struct { + Name string `json:"name" yaml:"name"` + Root string `json:"root" yaml:"root"` + Type string `json:"type" yaml:"type"` + } +) + +type ( + ServiceList []Service + Service struct { + Name string `json:"name" yaml:"name"` + Root string `json:"root" yaml:"root"` + Type string `json:"type" yaml:"type"` + } +) + +// getRealConfig 获取原始配置文件内容 +func getRealConfig(client git.Client) (Config, error) { + var c Config + realConfigContent, err := client.GetRealConfig() + if err != nil { + return c, err + } + + err = yaml.Unmarshal([]byte(realConfigContent), &c) + return c, err +} diff --git a/config_handler/util.go b/config_handler/util.go new file mode 100644 index 0000000..9a5d126 --- /dev/null +++ b/config_handler/util.go @@ -0,0 +1,21 @@ +package config_handler + +type Set map[int]struct{} + +func NewSet() Set { + return make(Set) +} + +func (s *Set) Add(data ...int) { + for _, d := range data { + (*s)[d] = struct{}{} + } +} + +func (s Set) ToSlice() []int { + ret := make([]int, 0, len(s)) + for k := range s { + ret = append(ret, k) + } + return ret +} diff --git a/git/git.go b/git/git.go new file mode 100644 index 0000000..a957f7b --- /dev/null +++ b/git/git.go @@ -0,0 +1,82 @@ +package git + +import ( + "encoding/base64" + "errors" + "net/http" + + "code.gitea.io/sdk/gitea" +) + +var cli *gitea.Client + +func init() { + var err error + cli, err = gitea.NewClient("https://git.icechen.cn/", gitea.SetToken("4322b0d361004db5dcea1741417f9e014a0f428f")) + if err != nil { + panic(err) + } +} + +// DefaultRealConfigFilePath 默认原始配置文件路径 +const DefaultRealConfigFilePath = ".drone.yml" + +// Client git 客户端 +type Client struct { + namespace string + repo string + ref string + realConfigPath string +} + +// New 创建 git 客户端 +func New(namespace string, repo string, ref string, configPath string) Client { + return Client{ + namespace: namespace, + repo: repo, + ref: ref, + realConfigPath: configPath, + } +} + +// GetFileContent 获取文件内容 +func (c Client) GetFileContent(filepath string) (string, error) { + ret, resp, err := cli.GetContents(c.namespace, c.repo, c.ref, filepath) + if err != nil { + return "", err + } + if resp.StatusCode != http.StatusOK { + return "", errors.New("gitea fail") + } + + fileContent, err := base64.StdEncoding.DecodeString(*ret.Content) + if err != nil { + return "", err + } + return string(fileContent), nil +} + +// GetRealConfig 获取原始配置文件 +func (c Client) GetRealConfig() (string, error) { + filePath := DefaultRealConfigFilePath + if c.realConfigPath == "" { + filePath = c.realConfigPath + } + return c.GetFileContent(filePath) +} + +func (c Client) GetCommitModifiedFileList() ([]string, error) { + commit, resp, err := cli.GetSingleCommit(c.namespace, c.repo, c.ref) + if err != nil { + return nil, err + } + if resp.StatusCode != http.StatusOK { + return nil, errors.New("gitea fail") + } + + modifiedFileList := make([]string, len(commit.Files)) + for i, file := range commit.Files { + modifiedFileList[i] = file.Filename + } + return modifiedFileList, nil +} diff --git a/go.mod b/go.mod index 04cab85..74b424b 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,9 @@ require ( ) require ( + code.gitea.io/sdk/gitea v0.15.0 // indirect github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e // indirect + github.com/hashicorp/go-version v1.3.0 // indirect golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index c2d34a9..d37ae62 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,45 @@ +code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= +code.gitea.io/sdk/gitea v0.15.0 h1:tsNhxDM/2N1Ohv1Xq5UWrht/esg0WmtRj4wsHVHriTg= +code.gitea.io/sdk/gitea v0.15.0/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA= github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e h1:rl2Aq4ZODqTDkeSqQBy+fzpZPamacO1Srp8zq7jf2Sc= github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/drone/drone-go v1.7.1 h1:ZX+3Rs8YHUSUQ5mkuMLmm1zr1ttiiE2YGNxF3AnyDKw= github.com/drone/drone-go v1.7.1/go.mod h1:fxCf9jAnXDZV1yDr0ckTuWd1intvcQwfJmTRpTZ1mXg= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= +github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go_coverter/go_coverter.go b/go_coverter/go_coverter.go deleted file mode 100644 index f460082..0000000 --- a/go_coverter/go_coverter.go +++ /dev/null @@ -1,40 +0,0 @@ -package go_coverter - -import ( - "context" - "encoding/json" - - "github.com/sirupsen/logrus" - - "github.com/drone/drone-go/plugin/config" - - "github.com/drone/drone-go/drone" -) - -const defaultPipeline = ` -kind: pipeline -name: default -steps: -- name: build - image: golang - commands: - - go build - - go test -v -` - -// New returns a new conversion plugin. -func New() config.Plugin { - return &plugin{} -} - -type plugin struct{} - -func (p *plugin) Find(ctx context.Context, req *config.Request) (*drone.Config, error) { - resp, err := json.Marshal(req) - if err != nil { - logrus.Error(err) - return nil, err - } - logrus.Infof("%s", string(resp)) - return nil, nil -} diff --git a/go_handler/go_handler.go b/go_handler/go_handler.go new file mode 100644 index 0000000..36a9506 --- /dev/null +++ b/go_handler/go_handler.go @@ -0,0 +1,20 @@ +package go_handler + +const TypeGolang = "golang" + +const defaultPipeline = ` +kind: pipeline +name: default +steps: +- name: build + image: golang + commands: + - go build + - go test -v +` + +type GoApiHandler struct{} + +func (GoApiHandler) ToDestinationConfig() (string, error) { + return "", nil +} diff --git a/main.go b/main.go index 79da67c..c109cfc 100644 --- a/main.go +++ b/main.go @@ -3,11 +3,12 @@ package main import ( "net/http" + "git.icechen.cn/pkg/drone_plugin/config_handler" + "github.com/drone/drone-go/plugin/config" "github.com/sirupsen/logrus" - "git.icechen.cn/pkg/drone_plugin/go_coverter" "github.com/kelseyhightower/envconfig" ) @@ -36,7 +37,7 @@ func main() { } handler := config.Handler( - go_coverter.New(), + config_handler.New(), spec.Secret, logrus.StandardLogger(), )