This is an automated email from the ASF dual-hosted git repository.

abeizn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 1f71ae6f fix(gitlab): modify makePipelinePlan
1f71ae6f is described below

commit 1f71ae6f000aa9b1dc41b124f1723f1d3db84afc
Author: Yingchu Chen <[email protected]>
AuthorDate: Thu Oct 13 19:03:18 2022 +0800

    fix(gitlab): modify makePipelinePlan
    
    relate to #3127
---
 plugins/github/api/blueprint.go      |   3 -
 plugins/gitlab/api/blueprint.go      | 258 +++++++++++++++++------------------
 plugins/gitlab/api/blueprint_test.go |  80 +++++++++--
 3 files changed, 192 insertions(+), 149 deletions(-)

diff --git a/plugins/github/api/blueprint.go b/plugins/github/api/blueprint.go
index e9dc5d1a..1cd7219b 100644
--- a/plugins/github/api/blueprint.go
+++ b/plugins/github/api/blueprint.go
@@ -163,9 +163,6 @@ func makePipelinePlan(subtaskMetas []core.SubTaskMeta, 
scope []*core.BlueprintSc
                        if j == len(plan) {
                                plan = append(plan, nil)
                        }
-                       if err != nil {
-                               return nil, err
-                       }
                        repo, err = memorizedGetApiRepo()
                        if err != nil {
                                return nil, err
diff --git a/plugins/gitlab/api/blueprint.go b/plugins/gitlab/api/blueprint.go
index 8f424127..5e22fb7c 100644
--- a/plugins/gitlab/api/blueprint.go
+++ b/plugins/gitlab/api/blueprint.go
@@ -38,178 +38,172 @@ import (
 
 func MakePipelinePlan(subtaskMetas []core.SubTaskMeta, connectionId uint64, 
scope []*core.BlueprintScopeV100) (core.PipelinePlan, errors.Error) {
        var err errors.Error
-       plan := make(core.PipelinePlan, len(scope))
-       for i, scopeElem := range scope {
-               plan, err = processScope(subtaskMetas, connectionId, scopeElem, 
i, plan, nil, nil)
-               if err != nil {
-                       return nil, err
-               }
-       }
-       return plan, nil
-}
-
-func processScope(subtaskMetas []core.SubTaskMeta, connectionId uint64, 
scopeElem *core.BlueprintScopeV100, i int, plan core.PipelinePlan, apiRepo 
*tasks.GitlabApiProject, connection *models.GitlabConnection) 
(core.PipelinePlan, errors.Error) {
-       var err errors.Error
-       // handle taskOptions and transformationRules, by dumping them to 
taskOptions
-       transformationRules := make(map[string]interface{})
-       if len(scopeElem.Transformation) > 0 {
-               err = errors.Convert(json.Unmarshal(scopeElem.Transformation, 
&transformationRules))
-               if err != nil {
-                       return nil, err
-               }
-       }
-       // refdiff
-       if refdiffRules, ok := transformationRules["refdiff"]; ok && 
refdiffRules != nil {
-               // add a new task to next stage
-               j := i + 1
-               if j == len(plan) {
-                       plan = append(plan, nil)
-               }
-               plan[j] = core.PipelineStage{
-                       {
-                               Plugin:  "refdiff",
-                               Options: refdiffRules.(map[string]interface{}),
-                       },
-               }
-               // remove it from github transformationRules
-               delete(transformationRules, "refdiff")
-       }
-       // construct task options for github
-       options := make(map[string]interface{})
-       err = errors.Convert(json.Unmarshal(scopeElem.Options, &options))
+       connection := new(models.GitlabConnection)
+       err = connectionHelper.FirstById(connection, connectionId)
        if err != nil {
                return nil, err
        }
-       options["connectionId"] = connectionId
-       options["transformationRules"] = transformationRules
-       // make sure task options is valid
-       op, err := tasks.DecodeAndValidateTaskOptions(options)
+       token := strings.Split(connection.Token, ",")[0]
+
+       apiClient, err := helper.NewApiClient(
+               context.TODO(),
+               connection.Endpoint,
+               map[string]string{
+                       "Authorization": fmt.Sprintf("Bearer %s", token),
+               },
+               10*time.Second,
+               connection.Proxy,
+               BasicRes,
+       )
        if err != nil {
                return nil, err
        }
-       // construct subtasks
-       subtasks, err := helper.MakePipelinePlanSubtasks(subtaskMetas, 
scopeElem.Entities)
+       plan, err := makePipelinePlan(subtaskMetas, scope, apiClient, 
connection)
        if err != nil {
                return nil, err
        }
-       stage := plan[i]
-       if stage == nil {
-               stage = core.PipelineStage{}
-       }
-       stage = append(stage, &core.PipelineTask{
-               Plugin:   "gitlab",
-               Subtasks: subtasks,
-               Options:  options,
-       })
-       // collect git data by gitextractor if CODE was requested
-       if utils.StringsContains(scopeElem.Entities, core.DOMAIN_TYPE_CODE) {
-               // here is the tricky part, we have to obtain the repo id 
beforehand
-               if connection == nil {
-                       connection = new(models.GitlabConnection)
-                       err = connectionHelper.FirstById(connection, 
connectionId)
+       return plan, nil
+}
+
+func makePipelinePlan(subtaskMetas []core.SubTaskMeta, scope 
[]*core.BlueprintScopeV100, apiClient helper.ApiClientGetter, connection 
*models.GitlabConnection) (core.PipelinePlan, errors.Error) {
+       var err errors.Error
+       var repo *tasks.GitlabApiProject
+       plan := make(core.PipelinePlan, len(scope))
+       for i, scopeElem := range scope {
+               // handle taskOptions and transformationRules, by dumping them 
to taskOptions
+               transformationRules := make(map[string]interface{})
+               if len(scopeElem.Transformation) > 0 {
+                       err = 
errors.Convert(json.Unmarshal(scopeElem.Transformation, &transformationRules))
                        if err != nil {
                                return nil, err
                        }
                }
-               token := strings.Split(connection.Token, ",")[0]
-               if apiRepo == nil {
-                       apiRepo = new(tasks.GitlabApiProject)
-                       err = getApiRepo(connection, token, op, apiRepo)
-                       if err != nil {
-                               return nil, err
+               // refdiff
+               if refdiffRules, ok := transformationRules["refdiff"]; ok && 
refdiffRules != nil {
+                       // add a new task to next stage
+                       j := i + 1
+                       if j == len(plan) {
+                               plan = append(plan, nil)
+                       }
+                       plan[j] = core.PipelineStage{
+                               {
+                                       Plugin:  "refdiff",
+                                       Options: 
refdiffRules.(map[string]interface{}),
+                               },
                        }
+                       // remove it from github transformationRules
+                       delete(transformationRules, "refdiff")
                }
-               cloneUrl, err := 
errors.Convert01(url.Parse(apiRepo.HttpUrlToRepo))
+               // construct task options for github
+               options := make(map[string]interface{})
+               err = errors.Convert(json.Unmarshal(scopeElem.Options, 
&options))
                if err != nil {
                        return nil, err
                }
-               cloneUrl.User = url.UserPassword("git", token)
-               stage = append(stage, &core.PipelineTask{
-                       Plugin: "gitextractor",
-                       Options: map[string]interface{}{
-                               "url":    cloneUrl.String(),
-                               "repoId": 
didgen.NewDomainIdGenerator(&models.GitlabProject{}).Generate(connectionId, 
apiRepo.GitlabId),
-                               "proxy":  connection.Proxy,
-                       },
-               })
-       }
-       // dora
-       if productionPattern, ok := transformationRules["productionPattern"]; 
ok && productionPattern != nil {
-               j := i + 1
-               // add a new task to next stage
-               if j == len(plan) {
-                       plan = append(plan, nil)
+               options["connectionId"] = connection.ID
+               options["transformationRules"] = transformationRules
+               // make sure task options is valid
+               op, err := tasks.DecodeAndValidateTaskOptions(options)
+               if err != nil {
+                       return nil, err
                }
-               if plan[j] != nil {
-                       j++
+
+               memorizedGetApiRepo := func() (*tasks.GitlabApiProject, 
errors.Error) {
+                       if repo == nil {
+                               repo, err = getApiRepo(op, apiClient)
+                       }
+                       return repo, err
                }
-               if j == len(plan) {
-                       plan = append(plan, nil)
+
+               // construct subtasks
+               subtasks, err := helper.MakePipelinePlanSubtasks(subtaskMetas, 
scopeElem.Entities)
+               if err != nil {
+                       return nil, err
                }
-               if apiRepo == nil {
-                       if connection == nil {
-                               connection = new(models.GitlabConnection)
-                               err = connectionHelper.FirstById(connection, 
connectionId)
-                               if err != nil {
-                                       return nil, err
-                               }
+               stage := plan[i]
+               if stage == nil {
+                       stage = core.PipelineStage{}
+               }
+               stage = append(stage, &core.PipelineTask{
+                       Plugin:   "gitlab",
+                       Subtasks: subtasks,
+                       Options:  options,
+               })
+               // collect git data by gitextractor if CODE was requested
+               if utils.StringsContains(scopeElem.Entities, 
core.DOMAIN_TYPE_CODE) {
+                       // here is the tricky part, we have to obtain the repo 
id beforehand
+                       repo, err = memorizedGetApiRepo()
+                       if err != nil {
+                               return nil, err
                        }
-                       token := strings.Split(connection.Token, ",")[0]
-                       apiRepo = new(tasks.GitlabApiProject)
-                       err = getApiRepo(connection, token, op, apiRepo)
+                       cloneUrl, err := 
errors.Convert01(url.Parse(repo.HttpUrlToRepo))
                        if err != nil {
                                return nil, err
                        }
+                       cloneUrl.User = url.UserPassword("git", 
connection.Token)
+                       stage = append(stage, &core.PipelineTask{
+                               Plugin: "gitextractor",
+                               Options: map[string]interface{}{
+                                       "url":    cloneUrl.String(),
+                                       "repoId": 
didgen.NewDomainIdGenerator(&models.GitlabProject{}).Generate(connection.ID, 
repo.GitlabId),
+                                       "proxy":  connection.Proxy,
+                               },
+                       })
                }
-               doraOption := make(map[string]interface{})
-               doraOption["repoId"] = 
didgen.NewDomainIdGenerator(&models.GitlabProject{}).Generate(connectionId, 
apiRepo.GitlabId)
-               doraOption["tasks"] = []string{"EnrichTaskEnv"}
-               doraRules := make(map[string]interface{})
-               doraRules["productionPattern"] = productionPattern
-               doraOption["transformationRules"] = doraRules
-               plan[j] = core.PipelineStage{
-                       {
-                               Plugin:   "dora",
-                               Subtasks: []string{"EnrichTaskEnv"},
-                               Options:  doraOption,
-                       },
+               // dora
+               if productionPattern, ok := 
transformationRules["productionPattern"]; ok && productionPattern != nil {
+                       j := i + 1
+                       // add a new task to next stage
+                       if j == len(plan) {
+                               plan = append(plan, nil)
+                       }
+                       if plan[j] != nil {
+                               j++
+                       }
+                       if j == len(plan) {
+                               plan = append(plan, nil)
+                       }
+                       repo, err = memorizedGetApiRepo()
+                       if err != nil {
+                               return nil, err
+                       }
+                       plan[j] = core.PipelineStage{
+                               {
+                                       Plugin:   "dora",
+                                       Subtasks: []string{"EnrichTaskEnv"},
+                                       Options: map[string]interface{}{
+                                               "repoId": 
didgen.NewDomainIdGenerator(&models.GitlabProject{}).Generate(connection.ID, 
repo.GitlabId),
+                                               "transformationRules": 
map[string]interface{}{
+                                                       "productionPattern": 
productionPattern,
+                                               },
+                                       },
+                               },
+                       }
+                       // remove it from github transformationRules
+                       delete(transformationRules, "productionPattern")
                }
-               // remove it from github transformationRules
-               delete(transformationRules, "productionPattern")
+               plan[i] = stage
        }
-       plan[i] = stage
        return plan, nil
 }
 
-func getApiRepo(connection *models.GitlabConnection, token string, op 
*tasks.GitlabOptions, apiRepo *tasks.GitlabApiProject) errors.Error {
-       apiClient, err := helper.NewApiClient(
-               context.TODO(),
-               connection.Endpoint,
-               map[string]string{
-                       "Authorization": fmt.Sprintf("Bearer %s", token),
-               },
-               10*time.Second,
-               connection.Proxy,
-               BasicRes,
-       )
-       if err != nil {
-               return err
-       }
+func getApiRepo(op *tasks.GitlabOptions, apiClient helper.ApiClientGetter) 
(*tasks.GitlabApiProject, errors.Error) {
+       apiRepo := &tasks.GitlabApiProject{}
        res, err := apiClient.Get(fmt.Sprintf("projects/%d", op.ProjectId), 
nil, nil)
        if err != nil {
-               return err
+               return nil, err
        }
-       //defer res.Body.Close()
+       defer res.Body.Close()
        if res.StatusCode != http.StatusOK {
-               return 
errors.HttpStatus(res.StatusCode).New(fmt.Sprintf("unexpected status code when 
requesting repo detail from %s", res.Request.URL.String()))
+               return nil, 
errors.HttpStatus(res.StatusCode).New(fmt.Sprintf("unexpected status code when 
requesting repo detail from %s", res.Request.URL.String()))
        }
        body, err := errors.Convert01(io.ReadAll(res.Body))
        if err != nil {
-               return err
+               return nil, err
        }
        err = errors.Convert(json.Unmarshal(body, apiRepo))
        if err != nil {
-               return err
+               return nil, err
        }
-       return nil
+       return apiRepo, nil
 }
diff --git a/plugins/gitlab/api/blueprint_test.go 
b/plugins/gitlab/api/blueprint_test.go
index 2afe9848..721a5e9a 100644
--- a/plugins/gitlab/api/blueprint_test.go
+++ b/plugins/gitlab/api/blueprint_test.go
@@ -18,6 +18,7 @@ limitations under the License.
 package api
 
 import (
+       "bytes"
        "encoding/json"
        "github.com/apache/incubator-devlake/mocks"
        "github.com/apache/incubator-devlake/models/common"
@@ -26,6 +27,9 @@ import (
        "github.com/apache/incubator-devlake/plugins/gitlab/tasks"
        "github.com/apache/incubator-devlake/plugins/helper"
        "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/mock"
+       "io"
+       "net/http"
        "testing"
 )
 
@@ -46,14 +50,26 @@ func TestProcessScope(t *testing.T) {
                        Token: "123",
                },
        }
+       mockApiCLient := mocks.NewApiClientGetter(t)
+       repo := &tasks.GitlabApiProject{
+               GitlabId:      12345,
+               HttpUrlToRepo: "*this is HttpUrlToRepo*",
+       }
+       js, err := json.Marshal(repo)
+       assert.Nil(t, err)
+       res := &http.Response{}
+       res.Body = io.NopCloser(bytes.NewBuffer(js))
+       res.StatusCode = http.StatusOK
+       mockApiCLient.On("Get", "projects/12345", mock.Anything, 
mock.Anything).Return(res, nil)
+
        mockMeta := mocks.NewPluginMeta(t)
        
mockMeta.On("RootPkgPath").Return("github.com/apache/incubator-devlake/plugins/gitlab")
-       err := core.RegisterPlugin("gitlab", mockMeta)
+       err = core.RegisterPlugin("gitlab", mockMeta)
        assert.Nil(t, err)
        bs := &core.BlueprintScopeV100{
                Entities: []string{"CODE"},
                Options: json.RawMessage(`{
-              "projectId": 123
+              "projectId": 12345
             }`),
                Transformation: json.RawMessage(`{
               "prType": "hey,man,wasup",
@@ -65,19 +81,55 @@ func TestProcessScope(t *testing.T) {
               "productionPattern": "xxxx"
             }`),
        }
-       apiRepo := &tasks.GitlabApiProject{
-               GitlabId:      123,
-               HttpUrlToRepo: "HttpUrlToRepo",
-       }
        scopes := make([]*core.BlueprintScopeV100, 0)
        scopes = append(scopes, bs)
-       plan := make(core.PipelinePlan, len(scopes))
-       for i, scopeElem := range scopes {
-               plan, err = processScope(nil, 1, scopeElem, i, plan, apiRepo, 
connection)
-               assert.Nil(t, err)
+       plan, err := makePipelinePlan(nil, scopes, mockApiCLient, connection)
+       assert.Nil(t, err)
+
+       expectPlan := core.PipelinePlan{
+               core.PipelineStage{
+                       {
+                               Plugin:   "gitlab",
+                               Subtasks: []string{},
+                               Options: map[string]interface{}{
+                                       "connectionId": uint64(1),
+                                       "projectId":    float64(12345),
+                                       "transformationRules": 
map[string]interface{}{
+                                               "prType": "hey,man,wasup",
+                                       },
+                               },
+                       },
+                       {
+                               Plugin: "gitextractor",
+                               Options: map[string]interface{}{
+                                       "proxy":  "",
+                                       "repoId": 
"gitlab:GitlabProject:1:12345",
+                                       "url":    
"//git:123@%2Athis%20is%20HttpUrlToRepo%2A",
+                               },
+                       },
+               },
+               core.PipelineStage{
+                       {
+                               Plugin: "refdiff",
+                               Options: map[string]interface{}{
+                                       "tagsLimit":   float64(10),
+                                       "tagsOrder":   "reverse semver",
+                                       "tagsPattern": "pattern",
+                               },
+                       },
+               },
+               core.PipelineStage{
+                       {
+                               Plugin:   "dora",
+                               Subtasks: []string{"EnrichTaskEnv"},
+                               Options: map[string]interface{}{
+                                       "repoId": 
"gitlab:GitlabProject:1:12345",
+                                       "transformationRules": 
map[string]interface{}{
+                                               "productionPattern": "xxxx",
+                                       },
+                               },
+                       },
+               },
        }
-       planJson, err1 := json.Marshal(plan)
-       assert.Nil(t, err1)
-       expectPlan := 
`[[{"plugin":"gitlab","subtasks":[],"options":{"connectionId":1,"projectId":123,"transformationRules":{"prType":"hey,man,wasup"}}},{"plugin":"gitextractor","subtasks":null,"options":{"proxy":"","repoId":"gitlab:GitlabProject:1:123","url":"//git:123@HttpUrlToRepo"}}],[{"plugin":"refdiff","subtasks":null,"options":{"tagsLimit":10,"tagsOrder":"reverse
 
semver","tagsPattern":"pattern"}}],[{"plugin":"dora","subtasks":["EnrichTaskEnv"],"options":{"repoId":"gitlab:GitlabProject:1:
 [...]
-       assert.Equal(t, expectPlan, string(planJson))
+       assert.Equal(t, expectPlan, plan)
 }

Reply via email to