You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by kl...@apache.org on 2022/08/29 08:18:26 UTC

[incubator-devlake] branch main updated: feat: add dora plugin by the simplest way (#2866)

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

klesh 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 d2a9bedd feat: add dora plugin by the simplest way (#2866)
d2a9bedd is described below

commit d2a9bedda525b08f257bcc743818dedfc56a6c4d
Author: likyh <l...@likyh.com>
AuthorDate: Mon Aug 29 16:18:22 2022 +0800

    feat: add dora plugin by the simplest way (#2866)
    
    Co-authored-by: linyh <ya...@meri.co>
---
 plugins/core/plugin_meta.go                        |  17 ++++
 plugins/dora/api/data.go                           |  63 ++++++++++++
 plugins/{core/plugin_meta.go => dora/api/init.go}  |  26 +++--
 plugins/{core/plugin_meta.go => dora/dora.go}      |  30 ++++--
 plugins/dora/impl/impl.go                          | 109 +++++++++++++++++++++
 .../migrationscripts/20220829_add_init_tables.go}  |  26 +++--
 .../models/migrationscripts/register.go}           |  14 +--
 plugins/dora/tasks/change_lead_time_convertor.go   |  59 +++++++++++
 .../plugin_meta.go => dora/tasks/task_data.go}     |  31 ++++--
 9 files changed, 345 insertions(+), 30 deletions(-)

diff --git a/plugins/core/plugin_meta.go b/plugins/core/plugin_meta.go
index 9bf2e68c..6bc05a53 100644
--- a/plugins/core/plugin_meta.go
+++ b/plugins/core/plugin_meta.go
@@ -23,3 +23,20 @@ type PluginMeta interface {
 	// PkgPath information lost when compiled as plugin(.so)
 	RootPkgPath() string
 }
+
+type GrafanaDashboard struct {
+	ID                   string
+	Title                string
+	Description          string
+	GrafanaDashboardJson string
+}
+
+// PluginDashboard return it's dashboard which should be display at grafana
+type PluginDashboard interface {
+	Dashboards() []GrafanaDashboard
+}
+
+// PluginIcon return it's icon (.svg text)
+type PluginIcon interface {
+	SvgIcon() string
+}
diff --git a/plugins/dora/api/data.go b/plugins/dora/api/data.go
new file mode 100644
index 00000000..18f72496
--- /dev/null
+++ b/plugins/dora/api/data.go
@@ -0,0 +1,63 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package api
+
+import (
+	"github.com/apache/incubator-devlake/plugins/core"
+	"net/http"
+)
+
+const RAW_DEPLOYMENTS_TABLE = `dora_deplyments`
+
+//TODO Please modify the folowing code to adapt to your plugin
+/*
+POST /plugins/dora/deployments
+{
+	TODO
+}
+*/
+func PostDeployments(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
+	// TODO
+	return &core.ApiResourceOutput{Body: nil, Status: http.StatusOK}, nil
+}
+
+const RAW_ISSUES_TABLE = `dora_issues`
+
+//TODO Please modify the folowing code to adapt to your plugin
+/*
+POST /plugins/dora/issues
+{
+	TODO
+}
+*/
+func PostIssues(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
+	// TODO
+	return &core.ApiResourceOutput{Body: nil, Status: http.StatusOK}, nil
+}
+
+//TODO Please modify the folowing code to adapt to your plugin
+/*
+POST /plugins/dora/issues/:id/close
+{
+	TODO
+}
+*/
+func CloseIssues(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
+	// TODO
+	return &core.ApiResourceOutput{Body: nil, Status: http.StatusOK}, nil
+}
diff --git a/plugins/core/plugin_meta.go b/plugins/dora/api/init.go
similarity index 58%
copy from plugins/core/plugin_meta.go
copy to plugins/dora/api/init.go
index 9bf2e68c..6774e148 100644
--- a/plugins/core/plugin_meta.go
+++ b/plugins/dora/api/init.go
@@ -15,11 +15,25 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package core
+package api
 
-// Minimal features a plugin should comply, should be implemented by all plugins
-type PluginMeta interface {
-	Description() string
-	// PkgPath information lost when compiled as plugin(.so)
-	RootPkgPath() string
+import (
+	"github.com/apache/incubator-devlake/plugins/core"
+	"github.com/apache/incubator-devlake/plugins/helper"
+	"github.com/go-playground/validator/v10"
+	"github.com/spf13/viper"
+	"gorm.io/gorm"
+)
+
+var vld *validator.Validate
+var connectionHelper *helper.ConnectionApiHelper
+var basicRes core.BasicRes
+
+func Init(config *viper.Viper, logger core.Logger, database *gorm.DB) {
+	basicRes = helper.NewDefaultBasicRes(config, logger, database)
+	vld = validator.New()
+	connectionHelper = helper.NewConnectionHelper(
+		basicRes,
+		vld,
+	)
 }
diff --git a/plugins/core/plugin_meta.go b/plugins/dora/dora.go
similarity index 52%
copy from plugins/core/plugin_meta.go
copy to plugins/dora/dora.go
index 9bf2e68c..64f53e78 100644
--- a/plugins/core/plugin_meta.go
+++ b/plugins/dora/dora.go
@@ -15,11 +15,29 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package core
+package main
 
-// Minimal features a plugin should comply, should be implemented by all plugins
-type PluginMeta interface {
-	Description() string
-	// PkgPath information lost when compiled as plugin(.so)
-	RootPkgPath() string
+import (
+	"github.com/apache/incubator-devlake/plugins/Dora/impl"
+	"github.com/apache/incubator-devlake/runner"
+	"github.com/spf13/cobra"
+)
+
+// Export a variable named PluginEntry for Framework to search and load
+var PluginEntry impl.Dora //nolint
+
+// standalone mode for debugging
+func main() {
+	cmd := &cobra.Command{Use: "dora"}
+
+	// TODO add your cmd flag if necessary
+	// yourFlag := cmd.Flags().IntP("yourFlag", "y", 8, "TODO add description here")
+	// _ = cmd.MarkFlagRequired("yourFlag")
+
+	cmd.Run = func(cmd *cobra.Command, args []string) {
+		runner.DirectRun(cmd, args, PluginEntry, map[string]interface{}{
+			// TODO add more custom params here
+		})
+	}
+	runner.RunCmd(cmd)
 }
diff --git a/plugins/dora/impl/impl.go b/plugins/dora/impl/impl.go
new file mode 100644
index 00000000..e0fb04f8
--- /dev/null
+++ b/plugins/dora/impl/impl.go
@@ -0,0 +1,109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package impl
+
+import (
+	"fmt"
+	"github.com/apache/incubator-devlake/migration"
+	"github.com/apache/incubator-devlake/plugins/core"
+	"github.com/apache/incubator-devlake/plugins/dora/api"
+	"github.com/apache/incubator-devlake/plugins/dora/models/migrationscripts"
+	"github.com/apache/incubator-devlake/plugins/dora/tasks"
+	"github.com/spf13/viper"
+	"gorm.io/gorm"
+)
+
+// make sure interface is implemented
+var _ core.PluginMeta = (*Dora)(nil)
+var _ core.PluginInit = (*Dora)(nil)
+var _ core.PluginTask = (*Dora)(nil)
+var _ core.PluginApi = (*Dora)(nil)
+var _ core.CloseablePluginTask = (*Dora)(nil)
+
+type Dora struct{}
+
+func (plugin Dora) Description() string {
+	return "collect some Dora data"
+}
+
+func (plugin Dora) Dashboards() []core.GrafanaDashboard {
+	return nil
+}
+
+func (plugin Dora) SvgIcon() string {
+	// FIXME replace it with correct icon
+	return `<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8C0 12.42 3.58 16 8 16C12.42 16 16 12.42 16 8C16 3.58 12.42 0 8 0ZM9 13H7V11H9V13ZM10.93 6.48C10.79 6.8 10.58 7.12 10.31 7.45L9.25 8.83C9.13 8.98 9.01 9.12 8.97 9.25C8.93 9.38 8.88 9.55 8.88 9.77V10H7.12V8.88C7.12 8.88 7.17 8.37 7.33 8.17L8.4 6.73C8.62 6.47 8.75 6.24 8.84 6.05C8.93 5.86 8.96 5.67 8.96 5.47C8.96 5.17 8.86 4.92 8.68 4.72C8.5 4.53 8.24 4.44 7.92 4.44C7.59 4.44 7.33 4.54 7.14 4.73C6.95 4.92 6.81 5.19 6.74  [...]
+</svg>`
+}
+
+func (plugin Dora) Init(config *viper.Viper, logger core.Logger, db *gorm.DB) error {
+	api.Init(config, logger, db)
+	return nil
+}
+
+func (plugin Dora) SubTaskMetas() []core.SubTaskMeta {
+	// TODO add your sub task here
+	return []core.SubTaskMeta{
+		//tasks.ConvertChangeLeadTimeMeta,
+	}
+}
+
+func (plugin Dora) PrepareTaskData(taskCtx core.TaskContext, options map[string]interface{}) (interface{}, error) {
+	op, err := tasks.DecodeAndValidateTaskOptions(options)
+	if err != nil {
+		return nil, err
+	}
+
+	return &tasks.DoraTaskData{
+		Options: op,
+	}, nil
+}
+
+// PkgPath information lost when compiled as plugin(.so)
+func (plugin Dora) RootPkgPath() string {
+	return "github.com/apache/incubator-devlake/plugins/dora"
+}
+
+func (plugin Dora) MigrationScripts() []migration.Script {
+	return migrationscripts.All()
+}
+
+func (plugin Dora) ApiResources() map[string]map[string]core.ApiResourceHandler {
+	return map[string]map[string]core.ApiResourceHandler{
+		"deployments": {
+			"POST": api.PostDeployments,
+		},
+		"issues": {
+			"POST": api.PostIssues,
+		},
+		"issues/:id/close": {
+			"POST": api.CloseIssues,
+		},
+	}
+}
+
+func (plugin Dora) Close(taskCtx core.TaskContext) error {
+	data, ok := taskCtx.GetData().(*tasks.DoraTaskData)
+	if !ok {
+		return fmt.Errorf("GetData failed when try to close %+v", taskCtx)
+	}
+	// TODO
+	println(data)
+	return nil
+}
diff --git a/plugins/core/plugin_meta.go b/plugins/dora/models/migrationscripts/20220829_add_init_tables.go
similarity index 67%
copy from plugins/core/plugin_meta.go
copy to plugins/dora/models/migrationscripts/20220829_add_init_tables.go
index 9bf2e68c..93a35f9e 100644
--- a/plugins/core/plugin_meta.go
+++ b/plugins/dora/models/migrationscripts/20220829_add_init_tables.go
@@ -15,11 +15,25 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package core
+package migrationscripts
 
-// Minimal features a plugin should comply, should be implemented by all plugins
-type PluginMeta interface {
-	Description() string
-	// PkgPath information lost when compiled as plugin(.so)
-	RootPkgPath() string
+import (
+	"context"
+	"gorm.io/gorm"
+)
+
+type addInitTables struct {}
+
+func (u *addInitTables) Up(ctx context.Context, db *gorm.DB) error {
+	return db.Migrator().AutoMigrate(
+		// TODO add you models
+	)
+}
+
+func (*addInitTables) Version() uint64 {
+	return 20220829000001
+}
+
+func (*addInitTables) Name() string {
+	return "dora init schemas"
 }
diff --git a/plugins/core/plugin_meta.go b/plugins/dora/models/migrationscripts/register.go
similarity index 77%
copy from plugins/core/plugin_meta.go
copy to plugins/dora/models/migrationscripts/register.go
index 9bf2e68c..92e20c01 100644
--- a/plugins/core/plugin_meta.go
+++ b/plugins/dora/models/migrationscripts/register.go
@@ -15,11 +15,13 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package core
+package migrationscripts
 
-// Minimal features a plugin should comply, should be implemented by all plugins
-type PluginMeta interface {
-	Description() string
-	// PkgPath information lost when compiled as plugin(.so)
-	RootPkgPath() string
+import "github.com/apache/incubator-devlake/migration"
+
+// All return all the migration scripts
+func All() []migration.Script {
+	return []migration.Script{
+		new(addInitTables),
+	}
 }
diff --git a/plugins/dora/tasks/change_lead_time_convertor.go b/plugins/dora/tasks/change_lead_time_convertor.go
new file mode 100644
index 00000000..4f7f3cdc
--- /dev/null
+++ b/plugins/dora/tasks/change_lead_time_convertor.go
@@ -0,0 +1,59 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package tasks
+
+import (
+	"github.com/apache/incubator-devlake/plugins/core"
+	"github.com/apache/incubator-devlake/plugins/dora/api"
+	"github.com/apache/incubator-devlake/plugins/helper"
+)
+
+var ConvertChangeLeadTimeMeta = core.SubTaskMeta{
+	Name:             "ConvertChangeLeadTime",
+	EntryPoint:       ConvertChangeLeadTime,
+	EnabledByDefault: true,
+	Description:      "TODO",
+	DomainTypes:      []string{core.DOMAIN_TYPE_CICD},
+}
+
+func ConvertChangeLeadTime(taskCtx core.SubTaskContext) error {
+	//db := taskCtx.GetDal()
+	//data := taskCtx.GetData().(*DoraTaskData)
+
+	converter, err := helper.NewDataConverter(helper.DataConverterArgs{
+		RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
+			Ctx:    taskCtx,
+			Params: DoraApiParams{
+				// TODO
+			},
+			Table: api.RAW_ISSUES_TABLE,
+		},
+		//InputRowType: reflect.TypeOf(githubModels.GithubJob{}),
+		//Input:        cursor,
+		Convert: func(inputRow interface{}) ([]interface{}, error) {
+			// TODO
+
+			return []interface{}{}, nil
+		},
+	})
+	if err != nil {
+		return err
+	}
+
+	return converter.Execute()
+}
diff --git a/plugins/core/plugin_meta.go b/plugins/dora/tasks/task_data.go
similarity index 63%
copy from plugins/core/plugin_meta.go
copy to plugins/dora/tasks/task_data.go
index 9bf2e68c..6ef125a2 100644
--- a/plugins/core/plugin_meta.go
+++ b/plugins/dora/tasks/task_data.go
@@ -15,11 +15,30 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package core
+package tasks
 
-// Minimal features a plugin should comply, should be implemented by all plugins
-type PluginMeta interface {
-	Description() string
-	// PkgPath information lost when compiled as plugin(.so)
-	RootPkgPath() string
+import (
+	"github.com/mitchellh/mapstructure"
+)
+
+type DoraApiParams struct {
+}
+
+type DoraOptions struct {
+	Tasks []string `json:"tasks,omitempty"`
+	Since string
+}
+
+type DoraTaskData struct {
+	Options *DoraOptions
+}
+
+func DecodeAndValidateTaskOptions(options map[string]interface{}) (*DoraOptions, error) {
+	var op DoraOptions
+	err := mapstructure.Decode(options, &op)
+	if err != nil {
+		return nil, err
+	}
+
+	return &op, nil
 }