You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by zh...@apache.org on 2025/01/16 03:59:10 UTC

(dubbo-kubernetes) branch master updated: [dubboctl] add repo and template logic (#544)

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

zhongxjian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-kubernetes.git


The following commit(s) were added to refs/heads/master by this push:
     new 4c813e28 [dubboctl] add repo and template logic (#544)
4c813e28 is described below

commit 4c813e28b38220cc32e0ecc5d58d8cbbf6fd6531
Author: Jian Zhong <11...@qq.com>
AuthorDate: Thu Jan 16 11:59:05 2025 +0800

    [dubboctl] add repo and template logic (#544)
---
 dubboctl/common/.gitignore                         |   5 -
 .../pkg/{filesystem/filesystem.go => fs/fs.go}     |   2 +-
 dubboctl/pkg/sdk/client.go                         |   5 +-
 dubboctl/pkg/sdk/repositories.go                   |  62 +++++++++++
 dubboctl/pkg/sdk/repository.go                     | 113 ++++++++++++++++++++-
 dubboctl/pkg/sdk/template.go                       |   6 +-
 6 files changed, 180 insertions(+), 13 deletions(-)

diff --git a/dubboctl/common/.gitignore b/dubboctl/common/.gitignore
deleted file mode 100644
index fbffce1f..00000000
--- a/dubboctl/common/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-
-# Applications use the .dubbo directory for local runtime data which should
-# generally not be tracked in source control. To instruct the system to track
-# .dubbo in source control, comment the following line (prefix it with '# ').
-/.dubbo
diff --git a/dubboctl/pkg/filesystem/filesystem.go b/dubboctl/pkg/fs/fs.go
similarity index 99%
rename from dubboctl/pkg/filesystem/filesystem.go
rename to dubboctl/pkg/fs/fs.go
index 38172059..908d8572 100644
--- a/dubboctl/pkg/filesystem/filesystem.go
+++ b/dubboctl/pkg/fs/fs.go
@@ -1,4 +1,4 @@
-package filesystem
+package fs
 
 import (
 	"archive/zip"
diff --git a/dubboctl/pkg/sdk/client.go b/dubboctl/pkg/sdk/client.go
index 41905b0d..602f1875 100644
--- a/dubboctl/pkg/sdk/client.go
+++ b/dubboctl/pkg/sdk/client.go
@@ -15,8 +15,9 @@ import (
 )
 
 type Client struct {
-	templates    *Templates
-	repositories *Repositories
+	templates        *Templates
+	repositories     *Repositories
+	repositoriesPath string
 }
 
 type Option func(client *Client)
diff --git a/dubboctl/pkg/sdk/repositories.go b/dubboctl/pkg/sdk/repositories.go
index 21ed11d3..d30c4f01 100644
--- a/dubboctl/pkg/sdk/repositories.go
+++ b/dubboctl/pkg/sdk/repositories.go
@@ -18,20 +18,82 @@
 package sdk
 
 import (
+	"errors"
 	"fmt"
+	"os"
+	"path/filepath"
+	"strings"
 )
 
 type Repositories struct {
 	client *Client
+	path   string
 }
 
 func newRepositories(client *Client) *Repositories {
 	return &Repositories{
 		client: client,
+		path:   client.repositoriesPath,
 	}
 }
 
+func (r *Repositories) All() (repos []Repository, err error) {
+	var repo Repository
+
+	if repo, err = NewRepository("", ""); err != nil {
+		return
+	}
+	repos = append(repos, repo)
+
+	if r.path == "" {
+		return
+	}
+
+	if _, err = os.Stat(r.path); os.IsNotExist(err) {
+		return repos, nil
+	}
+
+	ff, err := os.ReadDir(r.path)
+	if err != nil {
+		return
+	}
+	for _, f := range ff {
+		if !f.IsDir() || strings.HasPrefix(f.Name(), ".") {
+			continue
+		}
+		var abspath string
+		abspath, err = filepath.Abs(r.path)
+		if err != nil {
+			return
+		}
+		if repo, err = NewRepository("", "file://"+filepath.ToSlash(abspath)+"/"+f.Name()); err != nil {
+			return
+		}
+		repos = append(repos, repo)
+	}
+	return
+}
+
 func (r *Repositories) Get(name string) (repo Repository, err error) {
+	all, err := r.All()
+	if err != nil {
+		return
+	}
+	if len(all) == 0 { // should not be possible because embedded always exists.
+		err = errors.New("internal error: no repositories loaded")
+		return
+	}
+
+	if name == DefaultRepositoryName {
+		repo = all[0]
+		return
+	}
 
+	for _, v := range all {
+		if v.Name == name {
+			repo = v
+			return
+		}
+	}
 	return repo, fmt.Errorf("repository not found")
 }
diff --git a/dubboctl/pkg/sdk/repository.go b/dubboctl/pkg/sdk/repository.go
index fdfb56d5..bce0c195 100644
--- a/dubboctl/pkg/sdk/repository.go
+++ b/dubboctl/pkg/sdk/repository.go
@@ -2,13 +2,122 @@ package sdk
 
 import (
 	"fmt"
-	"github.com/apache/dubbo-kubernetes/dubboctl/pkg/filesystem"
+	"github.com/apache/dubbo-kubernetes/dubboctl/pkg/fs"
+	"net/url"
+	"os"
+	"path"
+	"strings"
 )
 
 type Repository struct {
 	Name     string
 	Runtimes []Runtime
-	fs       filesystem.Filesystem
+	fs       fs.Filesystem
+}
+
+type repositoryConfig struct {
+	DefaultName   string `yaml:"name,omitempty"`
+	TemplatesPath string `yaml:"templates,omitempty"`
+}
+
+func NewRepository(name, uri string) (r Repository, err error) {
+	r = Repository{}
+	repoConfig := repositoryConfig{}
+	if repoConfig.TemplatesPath != "" {
+		if err = checkDir(r.fs, repoConfig.TemplatesPath); err != nil {
+			err = fmt.Errorf("templates path '%v' does not exist in repo '%v'. %v",
+				repoConfig.TemplatesPath, r.Name, err)
+			return
+		}
+	} else {
+		repoConfig.TemplatesPath = "."
+	}
+
+	r.Name, err = repositoryDefaultName(repoConfig.DefaultName, uri)
+	if err != nil {
+		return
+	}
+	if name != "" {
+		r.Name = name
+	}
+	r.Runtimes, err = repositoryRuntimes(nil, r.Name, repoConfig)
+	return
+}
+
+func repositoryDefaultName(name, uri string) (string, error) {
+	if name != "" {
+		return name, nil
+	}
+	if uri != "" {
+		parsed, err := url.Parse(uri)
+		if err != nil {
+			return "", err
+		}
+		ss := strings.Split(parsed.Path, "/")
+		if len(ss) > 0 {
+			return strings.TrimSuffix(ss[len(ss)-1], ".git"), nil
+		}
+	}
+	return DefaultRepositoryName, nil
+}
+
+func repositoryRuntimes(fs fs.Filesystem, repoName string, repoConfig repositoryConfig) (runtimes []Runtime, err error) {
+	runtimes = []Runtime{}
+
+	fis, err := fs.ReadDir(repoConfig.TemplatesPath)
+	if err != nil {
+		return
+	}
+	for _, fi := range fis {
+		if !fi.IsDir() || strings.HasPrefix(fi.Name(), ".") {
+			continue
+		}
+		runtime := Runtime{
+			Name: fi.Name(),
+		}
+
+		runtime.Templates, err = runtimeTemplates(fs, repoConfig.TemplatesPath, repoName, runtime.Name)
+		if err != nil {
+			return
+		}
+		runtimes = append(runtimes, runtime)
+	}
+	return
+}
+
+func runtimeTemplates(fs fs.Filesystem, templatesPath, repoName, runtimeName string) (templates []Template, err error) {
+	runtimePath := path.Join(templatesPath, runtimeName)
+	if err = checkDir(fs, runtimePath); err != nil {
+		err = fmt.Errorf("runtime path '%v' not found. %v", runtimePath, err)
+		return
+	}
+
+	fis, err := fs.ReadDir(runtimePath)
+	if err != nil {
+		return
+	}
+	for _, fi := range fis {
+		if !fi.IsDir() || strings.HasPrefix(fi.Name(), ".") {
+			continue
+		}
+		t := template{
+			name:    fi.Name(),
+			runtime: runtimeName,
+		}
+
+		templates = append(templates, t)
+	}
+	return
+}
+
+func checkDir(fs fs.Filesystem, path string) error {
+	fi, err := fs.Stat(path)
+	if err != nil && os.IsNotExist(err) {
+		err = fmt.Errorf("path '%v` not found", path)
+	} else if err == nil && !fi.IsDir() {
+		err = fmt.Errorf("path '%v' is not a directory", path)
+	}
+	return err
 }
 
 type Runtime struct {
diff --git a/dubboctl/pkg/sdk/template.go b/dubboctl/pkg/sdk/template.go
index f312496b..0013e53c 100644
--- a/dubboctl/pkg/sdk/template.go
+++ b/dubboctl/pkg/sdk/template.go
@@ -2,7 +2,7 @@ package sdk
 
 import (
 	"context"
-	"github.com/apache/dubbo-kubernetes/dubboctl/pkg/filesystem"
+	"github.com/apache/dubbo-kubernetes/dubboctl/pkg/fs"
 	"github.com/apache/dubbo-kubernetes/dubboctl/pkg/sdk/dubbo"
 	"path"
 )
@@ -10,7 +10,7 @@ import (
 type template struct {
 	name    string
 	runtime string
-	fs      filesystem.Filesystem
+	fs      fs.Filesystem
 }
 
 type Template interface {
@@ -25,7 +25,7 @@ func (t template) Write(ctx context.Context, f *dubbo.DubboConfig) error {
 		return f == "manifest.yaml"
 	}
 
-	return filesystem.CopyFromFS(".", f.Root, filesystem.NewMaskingFS(mask, t.fs))
+	return fs.CopyFromFS(".", f.Root, fs.NewMaskingFS(mask, t.fs))
 }
 
 func (t template) Name() string {