You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by wa...@apache.org on 2023/03/14 13:43:32 UTC
[incubator-devlake] branch main updated: refactor(bitbucket): refactor scope (#4661)
This is an automated email from the ASF dual-hosted git repository.
warren 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 615a88f48 refactor(bitbucket): refactor scope (#4661)
615a88f48 is described below
commit 615a88f4865fb149666facde25fcac9ea8a6d78e
Author: Warren Chen <yi...@merico.dev>
AuthorDate: Tue Mar 14 21:43:26 2023 +0800
refactor(bitbucket): refactor scope (#4661)
---
backend/helpers/pluginhelper/api/scope_helper.go | 46 +-----
.../helpers/pluginhelper/api/scope_helper_test.go | 41 -----
backend/plugins/bamboo/api/init.go | 13 +-
backend/plugins/bamboo/api/remote.go | 5 +
backend/plugins/bamboo/api/scope.go | 171 ++-------------------
backend/plugins/bamboo/impl/impl.go | 2 +-
backend/plugins/bamboo/models/project.go | 4 +-
backend/plugins/bitbucket/api/init.go | 7 +
backend/plugins/bitbucket/api/remote.go | 5 +
backend/plugins/bitbucket/api/scope.go | 147 ++----------------
backend/plugins/bitbucket/impl/impl.go | 2 +-
backend/plugins/bitbucket/models/repo.go | 4 +-
backend/plugins/github/api/scope.go | 5 +-
backend/plugins/github/models/repo.go | 2 +-
backend/plugins/gitlab/api/scope.go | 13 +-
backend/plugins/gitlab/impl/impl.go | 2 +-
backend/plugins/gitlab/models/project.go | 2 +-
17 files changed, 78 insertions(+), 393 deletions(-)
diff --git a/backend/helpers/pluginhelper/api/scope_helper.go b/backend/helpers/pluginhelper/api/scope_helper.go
index 04244290e..b153dfe27 100644
--- a/backend/helpers/pluginhelper/api/scope_helper.go
+++ b/backend/helpers/pluginhelper/api/scope_helper.go
@@ -66,7 +66,7 @@ func NewScopeHelper[Conn any, Scope any, Tr any](
type ScopeRes[T any] struct {
Scope T `mapstructure:",squash"`
- TransformationRuleName string `json:"transformationRuleName,omitempty"`
+ TransformationRuleName string `mapstructure:"transformationRuleName,omitempty"`
}
type ScopeReq[T any] struct {
@@ -331,9 +331,9 @@ func VerifyScope(scope interface{}, vld *validator.Validate) errors.Error {
}
// Implement MarshalJSON method to flatten all fields
-func (sr ScopeRes[T]) MarshalJSON() ([]byte, error) {
- // Create an empty map to store flattened fields and values
- flatMap, err := flattenStruct(sr)
+func (sr *ScopeRes[T]) MarshalJSON() ([]byte, error) {
+ var flatMap map[string]interface{}
+ err := mapstructure.Decode(sr, &flatMap)
if err != nil {
return nil, err
}
@@ -345,41 +345,3 @@ func (sr ScopeRes[T]) MarshalJSON() ([]byte, error) {
return result, nil
}
-
-// A helper function to flatten nested structs
-func flattenStruct(s interface{}) (map[string]interface{}, error) {
- flatMap := make(map[string]interface{})
-
- // Use reflection to get all fields of the nested struct type
- fields := reflect.TypeOf(s).NumField()
-
- // Traverse all fields of the nested struct and add them to flatMap
- for i := 0; i < fields; i++ {
- field := reflect.TypeOf(s).Field(i)
- fieldValue := reflect.ValueOf(s).Field(i)
- if strings.Contains(field.Tag.Get("swaggerignore"), "true") {
- continue
- }
- if fieldValue.IsZero() && strings.Contains(field.Tag.Get("json"), "omitempty") {
- continue
- }
- // If the field is a nested struct, recursively flatten its fields
- if field.Type.Kind() == reflect.Struct && strings.Contains(field.Tag.Get("mapstructure"), "squash") {
- nestedFields, err := flattenStruct(fieldValue.Interface())
- if err != nil {
- return nil, err
- }
- for k, v := range nestedFields {
- flatMap[lowerCaseFirst(k)] = v
- }
- } else {
- // If the field is not a nested struct, add its name and value to flatMap
- flatMap[lowerCaseFirst(field.Name)] = fieldValue.Interface()
- }
- }
- return flatMap, nil
-}
-
-func lowerCaseFirst(name string) string {
- return strings.ToLower(string(name[0])) + name[1:]
-}
diff --git a/backend/helpers/pluginhelper/api/scope_helper_test.go b/backend/helpers/pluginhelper/api/scope_helper_test.go
index cc0657eea..c90afffa4 100644
--- a/backend/helpers/pluginhelper/api/scope_helper_test.go
+++ b/backend/helpers/pluginhelper/api/scope_helper_test.go
@@ -291,44 +291,3 @@ func TestScopeApiHelper_Put(t *testing.T) {
_, err := apiHelper.Put(input)
assert.NoError(t, err)
}
-
-func TestFlattenStruct(t *testing.T) {
- type InnerStruct struct {
- Foo int
- Bar string
- }
-
- type OuterStruct struct {
- Baz bool
- Qux float64
- Inner InnerStruct `mapstructure:",squash"`
- OtherProp string
- }
-
- input := OuterStruct{
- Baz: true,
- Qux: 3.14,
- Inner: InnerStruct{
- Foo: 42,
- Bar: "hello",
- },
- OtherProp: "world",
- }
-
- expectedOutput := map[string]interface{}{
- "baz": true,
- "qux": 3.14,
- "foo": 42,
- "bar": "hello",
- "otherProp": "world",
- }
-
- output, err := flattenStruct(input)
- if err != nil {
- t.Errorf("flattenStruct returned an error: %v", err)
- }
-
- if !reflect.DeepEqual(output, expectedOutput) {
- t.Errorf("flattenStruct returned incorrect output.\nExpected: %v\nActual: %v", expectedOutput, output)
- }
-}
diff --git a/backend/plugins/bamboo/api/init.go b/backend/plugins/bamboo/api/init.go
index cd019a36f..3044a56ba 100644
--- a/backend/plugins/bamboo/api/init.go
+++ b/backend/plugins/bamboo/api/init.go
@@ -19,19 +19,26 @@ package api
import (
"github.com/apache/incubator-devlake/core/context"
- helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+ "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+ "github.com/apache/incubator-devlake/plugins/github/models"
"github.com/go-playground/validator/v10"
)
var vld *validator.Validate
-var connectionHelper *helper.ConnectionApiHelper
+var connectionHelper *api.ConnectionApiHelper
+var scopeHelper *api.ScopeApiHelper[models.GithubConnection, models.GithubRepo, models.GithubTransformationRule]
var basicRes context.BasicRes
func Init(br context.BasicRes) {
basicRes = br
vld = validator.New()
- connectionHelper = helper.NewConnectionHelper(
+ connectionHelper = api.NewConnectionHelper(
basicRes,
vld,
)
+ scopeHelper = api.NewScopeHelper[models.GithubConnection, models.GithubRepo, models.GithubTransformationRule](
+ basicRes,
+ vld,
+ connectionHelper,
+ )
}
diff --git a/backend/plugins/bamboo/api/remote.go b/backend/plugins/bamboo/api/remote.go
index 250571390..91551001c 100644
--- a/backend/plugins/bamboo/api/remote.go
+++ b/backend/plugins/bamboo/api/remote.go
@@ -300,3 +300,8 @@ func GetQueryForSearchProject(search string, page int, perPage int) url.Values {
return query
}
+func extractParam(params map[string]string) (uint64, string) {
+ connectionId, _ := strconv.ParseUint(params["connectionId"], 10, 64)
+ projectKey := params["projectKey"]
+ return connectionId, projectKey
+}
diff --git a/backend/plugins/bamboo/api/scope.go b/backend/plugins/bamboo/api/scope.go
index 703f20a39..3b318da8f 100644
--- a/backend/plugins/bamboo/api/scope.go
+++ b/backend/plugins/bamboo/api/scope.go
@@ -18,26 +18,18 @@ limitations under the License.
package api
import (
- "context"
- "net/http"
- "strconv"
-
- "github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
"github.com/apache/incubator-devlake/plugins/bamboo/models"
- "github.com/mitchellh/mapstructure"
)
-type apiProject struct {
+type ScopeRes struct {
models.BambooProject
TransformationRuleName string `json:"transformationRuleName,omitempty"`
}
-type req struct {
- Data []*models.BambooProject `json:"data"`
-}
+type ScopeReq api.ScopeReq[models.BambooProject]
// PutScope create or update bamboo project
// @Summary create or update bamboo project
@@ -45,40 +37,13 @@ type req struct {
// @Tags plugins/bamboo
// @Accept application/json
// @Param connectionId path int false "connection ID"
-// @Param scope body req true "json"
+// @Param scope body ScopeReq true "json"
// @Success 200 {object} []models.BambooProject
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bamboo/connections/{connectionId}/scopes [PUT]
func PutScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- connectionId, _ := extractParam(input.Params)
-
- if connectionId == 0 {
- return nil, errors.BadInput.New("invalid connectionId")
- }
- var projects req
- err := errors.Convert(mapstructure.Decode(input.Body, &projects))
- if err != nil {
- return nil, errors.BadInput.Wrap(err, "decoding Bamboo project error")
- }
- keeper := make(map[string]struct{})
- for _, project := range projects.Data {
- if _, ok := keeper[project.ProjectKey]; ok {
- return nil, errors.BadInput.New("duplicated item")
- } else {
- keeper[project.ProjectKey] = struct{}{}
- }
- project.ConnectionId = connectionId
- err = verifyProject(project)
- if err != nil {
- return nil, err
- }
- }
- err = basicRes.GetDal().CreateOrUpdate(projects.Data)
- if err != nil {
- return nil, errors.Default.Wrap(err, "error on saving BambooProject")
- }
- return &plugin.ApiResourceOutput{Body: projects.Data, Status: http.StatusOK}, nil
+ return scopeHelper.Put(input)
}
// UpdateScope patch to bamboo project
@@ -87,35 +52,14 @@ func PutScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors
// @Tags plugins/bamboo
// @Accept application/json
// @Param connectionId path int false "connection ID"
-// @Param projectKey path int false "project ID"
+// @Param scopeId path int false "project ID"
// @Param scope body models.BambooProject true "json"
// @Success 200 {object} models.BambooProject
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
-// @Router /plugins/bamboo/connections/{connectionId}/scopes/{projectKey} [PATCH]
+// @Router /plugins/bamboo/connections/{connectionId}/scopes/{scopeId} [PATCH]
func UpdateScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- connectionId, projectKey := extractParam(input.Params)
- if connectionId == 0 || projectKey == "" {
- return nil, errors.BadInput.New("invalid path params")
- }
- var project models.BambooProject
- err := basicRes.GetDal().First(&project, dal.Where("connection_id = ? AND project_key = ?", connectionId, projectKey))
- if err != nil {
- return nil, errors.Default.Wrap(err, "getting BambooProject error")
- }
- err = api.DecodeMapStruct(input.Body, &project)
- if err != nil {
- return nil, errors.Default.Wrap(err, "patch bamboo project error")
- }
- err = verifyProject(&project)
- if err != nil {
- return nil, err
- }
- err = basicRes.GetDal().Update(project)
- if err != nil {
- return nil, errors.Default.Wrap(err, "error on saving BambooProject")
- }
- return &plugin.ApiResourceOutput{Body: project, Status: http.StatusOK}, nil
+ return scopeHelper.Update(input, "project_key")
}
// GetScopeList get Bamboo projects
@@ -123,43 +67,12 @@ func UpdateScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, err
// @Description get Bamboo projects
// @Tags plugins/bamboo
// @Param connectionId path int false "connection ID"
-// @Success 200 {object} []apiProject
+// @Success 200 {object} []ScopeRes
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bamboo/connections/{connectionId}/scopes/ [GET]
func GetScopeList(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- var projects []models.BambooProject
- connectionId, _ := extractParam(input.Params)
- if connectionId == 0 {
- return nil, errors.BadInput.New("invalid path params")
- }
- limit, offset := api.GetLimitOffset(input.Query, "pageSize", "page")
- err := basicRes.GetDal().All(&projects, dal.Where("connection_id = ?", connectionId), dal.Limit(limit), dal.Offset(offset))
- if err != nil {
- return nil, err
- }
- var ruleIds []uint64
- for _, proj := range projects {
- if proj.TransformationRuleId > 0 {
- ruleIds = append(ruleIds, proj.TransformationRuleId)
- }
- }
- var rules []models.BambooTransformationRule
- if len(ruleIds) > 0 {
- err = basicRes.GetDal().All(&rules, dal.Where("id IN (?)", ruleIds))
- if err != nil {
- return nil, err
- }
- }
- names := make(map[uint64]string)
- for _, rule := range rules {
- names[rule.ID] = rule.Name
- }
- var apiProjects []apiProject
- for _, proj := range projects {
- apiProjects = append(apiProjects, apiProject{proj, names[proj.TransformationRuleId]})
- }
- return &plugin.ApiResourceOutput{Body: apiProjects, Status: http.StatusOK}, nil
+ return scopeHelper.GetScopeList(input)
}
// GetScope get one Bamboo project
@@ -167,71 +80,13 @@ func GetScopeList(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, er
// @Description get one Bamboo project
// @Tags plugins/bamboo
// @Param connectionId path int false "connection ID"
-// @Param projectKey path int false "project ID"
+// @Param scopeId path int false "project ID"
// @Param pageSize query int false "page size, default 50"
// @Param page query int false "page size, default 1"
-// @Success 200 {object} apiProject
+// @Success 200 {object} ScopeRes
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
-// @Router /plugins/bamboo/connections/{connectionId}/scopes/{projectKey} [GET]
+// @Router /plugins/bamboo/connections/{connectionId}/scopes/{scopeId} [GET]
func GetScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- var project models.BambooProject
- connectionId, projectKey := extractParam(input.Params)
- if connectionId == 0 || projectKey == "" {
- return nil, errors.BadInput.New("invalid path params")
- }
- db := basicRes.GetDal()
- err := db.First(&project, dal.Where("connection_id = ? AND project_key = ?", connectionId, projectKey))
- if err != nil && db.IsErrorNotFound(err) {
- var scope models.BambooProject
- connection := &models.BambooConnection{}
- err = connectionHelper.First(connection, input.Params)
- if err != nil {
- return nil, err
- }
- apiClient, err := api.NewApiClientFromConnection(context.TODO(), basicRes, connection)
- if err != nil {
- return nil, err
- }
-
- apiProject, err := GetApiProject(projectKey, apiClient)
- if err != nil {
- return nil, err
- }
-
- scope.Convert(apiProject)
- scope.ConnectionId = connectionId
- err = db.CreateIfNotExist(&scope)
- if err != nil {
- return nil, err
- }
- return nil, errors.NotFound.New("record not found")
- } else if err != nil {
- return nil, err
- }
-
- var rule models.BambooTransformationRule
- if project.TransformationRuleId > 0 {
- err = basicRes.GetDal().First(&rule, dal.Where("id = ?", project.TransformationRuleId))
- if err != nil {
- return nil, err
- }
- }
- return &plugin.ApiResourceOutput{Body: apiProject{project, rule.Name}, Status: http.StatusOK}, nil
-}
-
-func extractParam(params map[string]string) (uint64, string) {
- connectionId, _ := strconv.ParseUint(params["connectionId"], 10, 64)
- projectKey := params["projectKey"]
- return connectionId, projectKey
-}
-
-func verifyProject(project *models.BambooProject) errors.Error {
- if project.ConnectionId == 0 {
- return errors.BadInput.New("invalid connectionId")
- }
- if project.ProjectKey == "" {
- return errors.BadInput.New("invalid projectKey")
- }
- return nil
+ return scopeHelper.GetScope(input, "project_key")
}
diff --git a/backend/plugins/bamboo/impl/impl.go b/backend/plugins/bamboo/impl/impl.go
index 50de2945b..f5612f6cd 100644
--- a/backend/plugins/bamboo/impl/impl.go
+++ b/backend/plugins/bamboo/impl/impl.go
@@ -213,7 +213,7 @@ func (p Bamboo) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
"connections/:connectionId/search-remote-scopes": {
"GET": api.SearchRemoteScopes,
},
- "connections/:connectionId/scopes/:projectKey": {
+ "connections/:connectionId/scopes/:scopeId": {
"GET": api.GetScope,
"PATCH": api.UpdateScope,
},
diff --git a/backend/plugins/bamboo/models/project.go b/backend/plugins/bamboo/models/project.go
index 89e7caa4b..279b996e3 100644
--- a/backend/plugins/bamboo/models/project.go
+++ b/backend/plugins/bamboo/models/project.go
@@ -24,8 +24,8 @@ import (
)
type BambooProject struct {
- ConnectionId uint64 `json:"connectionId" mapstructure:"connectionId" gorm:"primaryKey"`
- ProjectKey string `json:"projectKey" gorm:"primaryKey;type:varchar(256)"`
+ ConnectionId uint64 `json:"connectionId" mapstructure:"connectionId" validate:"required" gorm:"primaryKey"`
+ ProjectKey string `json:"projectKey" gorm:"primaryKey;type:varchar(256)" validate:"required"`
TransformationRuleId uint64 `json:"transformationRuleId,omitempty" mapstructure:"transformationRuleId"`
Name string `json:"name" gorm:"index;type:varchar(256)"`
Description string `json:"description"`
diff --git a/backend/plugins/bitbucket/api/init.go b/backend/plugins/bitbucket/api/init.go
index d92c2b334..a91525bd4 100644
--- a/backend/plugins/bitbucket/api/init.go
+++ b/backend/plugins/bitbucket/api/init.go
@@ -20,11 +20,13 @@ package api
import (
"github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+ "github.com/apache/incubator-devlake/plugins/bitbucket/models"
"github.com/go-playground/validator/v10"
)
var vld *validator.Validate
var connectionHelper *api.ConnectionApiHelper
+var scopeHelper *api.ScopeApiHelper[models.BitbucketConnection, models.BitbucketRepo, models.BitbucketTransformationRule]
var basicRes context.BasicRes
func Init(br context.BasicRes) {
@@ -34,4 +36,9 @@ func Init(br context.BasicRes) {
basicRes,
vld,
)
+ scopeHelper = api.NewScopeHelper[models.BitbucketConnection, models.BitbucketRepo, models.BitbucketTransformationRule](
+ basicRes,
+ vld,
+ connectionHelper,
+ )
}
diff --git a/backend/plugins/bitbucket/api/remote.go b/backend/plugins/bitbucket/api/remote.go
index 9fc116842..49f85b8a7 100644
--- a/backend/plugins/bitbucket/api/remote.go
+++ b/backend/plugins/bitbucket/api/remote.go
@@ -361,3 +361,8 @@ func GetQueryFromPageData(pageData *PageData) (url.Values, errors.Error) {
query.Set("pagelen", fmt.Sprintf("%v", pageData.PerPage))
return query, nil
}
+func extractParam(params map[string]string) (uint64, string) {
+ connectionId, _ := strconv.ParseUint(params["connectionId"], 10, 64)
+ fullName := strings.TrimLeft(params["repoId"], "/")
+ return connectionId, fullName
+}
diff --git a/backend/plugins/bitbucket/api/scope.go b/backend/plugins/bitbucket/api/scope.go
index e9053e56c..496def2e9 100644
--- a/backend/plugins/bitbucket/api/scope.go
+++ b/backend/plugins/bitbucket/api/scope.go
@@ -18,25 +18,18 @@ limitations under the License.
package api
import (
- "github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
"github.com/apache/incubator-devlake/plugins/bitbucket/models"
- "github.com/mitchellh/mapstructure"
- "net/http"
- "strconv"
- "strings"
)
-type apiRepo struct {
+type ScopeRes struct {
models.BitbucketRepo
TransformationRuleName string `json:"transformationRuleName,omitempty"`
}
-type req struct {
- Data []*models.BitbucketRepo `json:"data"`
-}
+type ScopeReq api.ScopeReq[models.BitbucketRepo]
// PutScope create or update repo
// @Summary create or update repo
@@ -44,39 +37,13 @@ type req struct {
// @Tags plugins/bitbucket
// @Accept application/json
// @Param connectionId path int true "connection ID"
-// @Param scope body req true "json"
+// @Param scope body ScopeReq true "json"
// @Success 200 {object} []models.BitbucketRepo
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId}/scopes [PUT]
func PutScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- connectionId, _ := extractParam(input.Params)
- if connectionId == 0 {
- return nil, errors.BadInput.New("invalid connectionId")
- }
- var repos req
- err := errors.Convert(mapstructure.Decode(input.Body, &repos))
- if err != nil {
- return nil, errors.BadInput.Wrap(err, "decoding repo error")
- }
- keeper := make(map[string]struct{})
- for _, repo := range repos.Data {
- if _, ok := keeper[repo.BitbucketId]; ok {
- return nil, errors.BadInput.New("duplicated item")
- } else {
- keeper[repo.BitbucketId] = struct{}{}
- }
- repo.ConnectionId = connectionId
- err = verifyRepo(repo)
- if err != nil {
- return nil, err
- }
- }
- err = basicRes.GetDal().CreateOrUpdate(repos.Data)
- if err != nil {
- return nil, errors.Default.Wrap(err, "error on saving BitbucketRepo")
- }
- return &plugin.ApiResourceOutput{Body: repos.Data, Status: http.StatusOK}, nil
+ return scopeHelper.Put(input)
}
// UpdateScope patch to repo
@@ -85,35 +52,14 @@ func PutScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors
// @Tags plugins/bitbucket
// @Accept application/json
// @Param connectionId path int true "connection ID"
-// @Param repoId path string true "repo ID"
+// @Param scopeId path string true "repo ID"
// @Param scope body models.BitbucketRepo true "json"
// @Success 200 {object} models.BitbucketRepo
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
-// @Router /plugins/bitbucket/connections/{connectionId}/scopes/{repoId} [PATCH]
+// @Router /plugins/bitbucket/connections/{connectionId}/scopes/{scopeId} [PATCH]
func UpdateScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- connectionId, repoId := extractParam(input.Params)
- if connectionId == 0 || repoId == "" {
- return nil, errors.BadInput.New("invalid connectionId or repoId")
- }
- var repo models.BitbucketRepo
- err := basicRes.GetDal().First(&repo, dal.Where("connection_id = ? AND bitbucket_id = ?", connectionId, repoId))
- if err != nil {
- return nil, errors.Default.Wrap(err, "getting Repo error")
- }
- err = api.DecodeMapStruct(input.Body, &repo)
- if err != nil {
- return nil, errors.Default.Wrap(err, "patch repo error")
- }
- err = verifyRepo(&repo)
- if err != nil {
- return nil, err
- }
- err = basicRes.GetDal().Update(repo)
- if err != nil {
- return nil, errors.Default.Wrap(err, "error on saving BitbucketRepo")
- }
- return &plugin.ApiResourceOutput{Body: repo, Status: http.StatusOK}, nil
+ return scopeHelper.Update(input, "bitbucket_id")
}
// GetScopeList get repos
@@ -123,43 +69,12 @@ func UpdateScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, err
// @Param connectionId path int true "connection ID"
// @Param pageSize query int false "page size, default 50"
// @Param page query int false "page size, default 1"
-// @Success 200 {object} []apiRepo
+// @Success 200 {object} []ScopeRes
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId}/scopes/ [GET]
func GetScopeList(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- var repos []models.BitbucketRepo
- connectionId, _ := extractParam(input.Params)
- if connectionId == 0 {
- return nil, errors.BadInput.New("invalid path params")
- }
- limit, offset := api.GetLimitOffset(input.Query, "pageSize", "page")
- err := basicRes.GetDal().All(&repos, dal.Where("connection_id = ?", connectionId), dal.Limit(limit), dal.Offset(offset))
- if err != nil {
- return nil, err
- }
- var ruleIds []uint64
- for _, repo := range repos {
- if repo.TransformationRuleId > 0 {
- ruleIds = append(ruleIds, repo.TransformationRuleId)
- }
- }
- var rules []models.BitbucketTransformationRule
- if len(ruleIds) > 0 {
- err = basicRes.GetDal().All(&rules, dal.Where("id IN (?)", ruleIds))
- if err != nil {
- return nil, err
- }
- }
- names := make(map[uint64]string)
- for _, rule := range rules {
- names[rule.ID] = rule.Name
- }
- var apiRepos []apiRepo
- for _, repo := range repos {
- apiRepos = append(apiRepos, apiRepo{repo, names[repo.TransformationRuleId]})
- }
- return &plugin.ApiResourceOutput{Body: apiRepos, Status: http.StatusOK}, nil
+ return scopeHelper.GetScopeList(input)
}
// GetScope get one repo
@@ -167,47 +82,11 @@ func GetScopeList(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, er
// @Description get one repo
// @Tags plugins/bitbucket
// @Param connectionId path int true "connection ID"
-// @Param repoId path string true "repo ID"
-// @Success 200 {object} apiRepo
+// @Param scopeId path string true "repo ID"
+// @Success 200 {object} ScopeRes
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
-// @Router /plugins/bitbucket/connections/{connectionId}/scopes/{repoId} [GET]
+// @Router /plugins/bitbucket/connections/{connectionId}/scopes/{scopeId} [GET]
func GetScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- var repo models.BitbucketRepo
- connectionId, repoId := extractParam(input.Params)
- if connectionId == 0 || repoId == "" {
- return nil, errors.BadInput.New("invalid connectionId or repoId")
- }
- db := basicRes.GetDal()
- err := db.First(&repo, dal.Where("connection_id = ? AND bitbucket_id = ?", connectionId, repoId))
- if db.IsErrorNotFound(err) {
- return nil, errors.NotFound.New("record not found")
- }
- if err != nil {
- return nil, err
- }
- var rule models.BitbucketTransformationRule
- if repo.TransformationRuleId > 0 {
- err = basicRes.GetDal().First(&rule, dal.Where("id = ?", repo.TransformationRuleId))
- if err != nil {
- return nil, err
- }
- }
- return &plugin.ApiResourceOutput{Body: apiRepo{repo, rule.Name}, Status: http.StatusOK}, nil
-}
-
-func extractParam(params map[string]string) (uint64, string) {
- connectionId, _ := strconv.ParseUint(params["connectionId"], 10, 64)
- fullName := strings.TrimLeft(params["repoId"], "/")
- return connectionId, fullName
-}
-
-func verifyRepo(repo *models.BitbucketRepo) errors.Error {
- if repo.ConnectionId == 0 {
- return errors.BadInput.New("invalid connectionId")
- }
- if repo.BitbucketId == `` {
- return errors.BadInput.New("invalid bitbucket ID or full name")
- }
- return nil
+ return scopeHelper.GetScope(input, "bitbucket_id")
}
diff --git a/backend/plugins/bitbucket/impl/impl.go b/backend/plugins/bitbucket/impl/impl.go
index 927667108..50b2d19ca 100644
--- a/backend/plugins/bitbucket/impl/impl.go
+++ b/backend/plugins/bitbucket/impl/impl.go
@@ -193,7 +193,7 @@ func (p Bitbucket) ApiResources() map[string]map[string]plugin.ApiResourceHandle
"DELETE": api.DeleteConnection,
"GET": api.GetConnection,
},
- "connections/:connectionId/scopes/*repoId": {
+ "connections/:connectionId/scopes/*scopeId": {
"GET": api.GetScope,
"PATCH": api.UpdateScope,
},
diff --git a/backend/plugins/bitbucket/models/repo.go b/backend/plugins/bitbucket/models/repo.go
index 249651a7b..417ebe064 100644
--- a/backend/plugins/bitbucket/models/repo.go
+++ b/backend/plugins/bitbucket/models/repo.go
@@ -23,8 +23,8 @@ import (
)
type BitbucketRepo struct {
- ConnectionId uint64 `json:"connectionId" gorm:"primaryKey" mapstructure:"connectionId,omitempty"`
- BitbucketId string `json:"bitbucketId" gorm:"primaryKey;type:varchar(255)" mapstructure:"bitbucketId"`
+ ConnectionId uint64 `json:"connectionId" gorm:"primaryKey" validate:"required" mapstructure:"connectionId,omitempty"`
+ BitbucketId string `json:"bitbucketId" gorm:"primaryKey;type:varchar(255)" validate:"required" mapstructure:"bitbucketId"`
Name string `json:"name" gorm:"type:varchar(255)" mapstructure:"name,omitempty"`
HTMLUrl string `json:"HTMLUrl" gorm:"type:varchar(255)" mapstructure:"HTMLUrl,omitempty"`
Description string `json:"description" mapstructure:"description,omitempty"`
diff --git a/backend/plugins/github/api/scope.go b/backend/plugins/github/api/scope.go
index d9ba2499a..1225e9edd 100644
--- a/backend/plugins/github/api/scope.go
+++ b/backend/plugins/github/api/scope.go
@@ -20,6 +20,7 @@ package api
import (
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
+ "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
"github.com/apache/incubator-devlake/plugins/github/models"
)
@@ -28,13 +29,15 @@ type ScopeRes struct {
TransformationRuleName string `json:"transformationRuleName,omitempty"`
}
+type ScopeReq api.ScopeReq[models.GithubRepo]
+
// PutScope create or update github repo
// @Summary create or update github repo
// @Description Create or update github repo
// @Tags plugins/github
// @Accept application/json
// @Param connectionId path int true "connection ID"
-// @Param scope body req true "json"
+// @Param scope body ScopeReq true "json"
// @Success 200 {object} []models.GithubRepo
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
diff --git a/backend/plugins/github/models/repo.go b/backend/plugins/github/models/repo.go
index 045437180..9eda5e118 100644
--- a/backend/plugins/github/models/repo.go
+++ b/backend/plugins/github/models/repo.go
@@ -36,7 +36,7 @@ type GithubRepo struct {
CloneUrl string `json:"cloneUrl" gorm:"type:varchar(255)" mapstructure:"cloneUrl,omitempty"`
CreatedDate *time.Time `json:"createdDate" mapstructure:"-"`
UpdatedDate *time.Time `json:"updatedDate" mapstructure:"-"`
- common.NoPKModel `json:"-" mapstructure:",squash"`
+ common.NoPKModel `json:"-" mapstructure:"-"`
}
func (GithubRepo) TableName() string {
diff --git a/backend/plugins/gitlab/api/scope.go b/backend/plugins/gitlab/api/scope.go
index 9f3da5b67..a40ccf6f0 100644
--- a/backend/plugins/gitlab/api/scope.go
+++ b/backend/plugins/gitlab/api/scope.go
@@ -20,6 +20,7 @@ package api
import (
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
+ "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
"github.com/apache/incubator-devlake/plugins/gitlab/models"
)
@@ -28,13 +29,15 @@ type ScopeRes struct {
TransformationRuleName string `json:"transformationRuleName,omitempty"`
}
+type ScopeReq api.ScopeReq[models.GitlabProject]
+
// PutScope create or update gitlab project
// @Summary create or update gitlab project
// @Description Create or update gitlab project
// @Tags plugins/gitlab
// @Accept application/json
// @Param connectionId path int false "connection ID"
-// @Param scope body req true "json"
+// @Param scope body ScopeReq true "json"
// @Success 200 {object} []models.GitlabProject
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
@@ -49,12 +52,12 @@ func PutScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors
// @Tags plugins/gitlab
// @Accept application/json
// @Param connectionId path int false "connection ID"
-// @Param projectId path int false "project ID"
+// @Param scopeId path int false "project ID"
// @Param scope body models.GitlabProject true "json"
// @Success 200 {object} models.GitlabProject
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
-// @Router /plugins/gitlab/connections/{connectionId}/scopes/{projectId} [PATCH]
+// @Router /plugins/gitlab/connections/{connectionId}/scopes/{scopeId} [PATCH]
func UpdateScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
return scopeHelper.Update(input, "gitlab_id")
}
@@ -77,13 +80,13 @@ func GetScopeList(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, er
// @Description get one Gitlab project
// @Tags plugins/gitlab
// @Param connectionId path int false "connection ID"
-// @Param projectId path int false "project ID"
+// @Param scopeId path int false "project ID"
// @Param pageSize query int false "page size, default 50"
// @Param page query int false "page size, default 1"
// @Success 200 {object} ScopeRes
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
-// @Router /plugins/gitlab/connections/{connectionId}/scopes/{projectId} [GET]
+// @Router /plugins/gitlab/connections/{connectionId}/scopes/{scopeId} [GET]
func GetScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
return scopeHelper.GetScope(input, "gitlab_id")
}
diff --git a/backend/plugins/gitlab/impl/impl.go b/backend/plugins/gitlab/impl/impl.go
index a5949aa49..99c2dd968 100644
--- a/backend/plugins/gitlab/impl/impl.go
+++ b/backend/plugins/gitlab/impl/impl.go
@@ -246,7 +246,7 @@ func (p Gitlab) ApiResources() map[string]map[string]plugin.ApiResourceHandler {
"DELETE": api.DeleteConnection,
"GET": api.GetConnection,
},
- "connections/:connectionId/scopes/:projectId": {
+ "connections/:connectionId/scopes/:scopeId": {
"GET": api.GetScope,
"PATCH": api.UpdateScope,
},
diff --git a/backend/plugins/gitlab/models/project.go b/backend/plugins/gitlab/models/project.go
index 91db090ff..41c6855f5 100644
--- a/backend/plugins/gitlab/models/project.go
+++ b/backend/plugins/gitlab/models/project.go
@@ -42,7 +42,7 @@ type GitlabProject struct {
CreatedDate time.Time `json:"createdDate" mapstructure:"-"`
UpdatedDate *time.Time `json:"updatedDate" mapstructure:"-"`
- common.NoPKModel `json:"-" mapstructure:",squash"`
+ common.NoPKModel `json:"-" mapstructure:"-"`
}
func (GitlabProject) TableName() string {