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/20 13:47:01 UTC

(dubbo-kubernetes) branch master updated: [dubboctl] Refinement of repo command logic (#556)

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 00818dea [dubboctl] Refinement of repo command logic (#556)
00818dea is described below

commit 00818dea936c9511f68e9708a2a34ecaf233388b
Author: Jian Zhong <11...@qq.com>
AuthorDate: Mon Jan 20 21:46:57 2025 +0800

    [dubboctl] Refinement of repo command logic (#556)
---
 dubboctl/cmd/repo.go             | 93 ++++++++++++++++++++++++++++++++--------
 dubboctl/pkg/sdk/repositories.go | 33 ++++++++++++++
 dubboctl/pkg/sdk/repository.go   | 59 +++++++++++++++++++++++++
 dubboctl/pkg/util/path.go        | 36 ++++++++++++++++
 4 files changed, 202 insertions(+), 19 deletions(-)

diff --git a/dubboctl/cmd/repo.go b/dubboctl/cmd/repo.go
index 47a03ecc..73d4b5c9 100644
--- a/dubboctl/cmd/repo.go
+++ b/dubboctl/cmd/repo.go
@@ -1,16 +1,16 @@
 package cmd
 
 import (
+	"fmt"
 	"github.com/apache/dubbo-kubernetes/dubboctl/pkg/cli"
+	"github.com/apache/dubbo-kubernetes/dubboctl/pkg/util"
 	"github.com/apache/dubbo-kubernetes/operator/cmd/cluster"
 	"github.com/spf13/cobra"
 )
 
-type repoArgs struct {
-}
+type repoArgs struct{}
 
-func addRepoFlags(cmd *cobra.Command, rArgs *repoArgs) {
-}
+func addRepoFlags(cmd *cobra.Command, rArgs *repoArgs) {}
 
 func RepoCmd(_ cli.Context, cmd *cobra.Command, clientFactory ClientFactory) *cobra.Command {
 	rootArgs := &cluster.RootArgs{}
@@ -31,9 +31,6 @@ func RepoCmd(_ cli.Context, cmd *cobra.Command, clientFactory ClientFactory) *co
   # Remove an existing template library.
   dubboctl repo remove [name]
 `,
-		RunE: func(cmd *cobra.Command, args []string) error {
-			return runRepo(cmd, args, clientFactory)
-		},
 	}
 	cluster.AddFlags(rc, rootArgs)
 	addRepoFlags(rc, rArgs)
@@ -43,13 +40,11 @@ func RepoCmd(_ cli.Context, cmd *cobra.Command, clientFactory ClientFactory) *co
 	return rc
 }
 
-func runRepo(cmd *cobra.Command, args []string, clientFactory ClientFactory) error {
-	return nil
-}
-
 func addCmd(cmd *cobra.Command, clientFactory ClientFactory) *cobra.Command {
 	ac := &cobra.Command{
-		Use: "add",
+		Use:   "add [name] [URL]",
+		Short: "Add a new template library.",
+		Long:  "The add subcommand is used to add a new template library.",
 		RunE: func(cmd *cobra.Command, args []string) error {
 			return runAdd(cmd, args, clientFactory)
 		},
@@ -57,13 +52,42 @@ func addCmd(cmd *cobra.Command, clientFactory ClientFactory) *cobra.Command {
 	return ac
 }
 
-func runAdd(_ *cobra.Command, args []string, clientFactory ClientFactory) error {
-	return nil
+func runAdd(_ *cobra.Command, args []string, clientFactory ClientFactory) (err error) {
+	if err = util.CreatePath(); err != nil {
+		return
+	}
+	client, done := clientFactory()
+	defer done()
+
+	if len(args) != 2 {
+		return fmt.Errorf("Usage: dubboctl repo add [name] [URL]")
+	}
+
+	p := struct {
+		name string
+		url  string
+	}{}
+	if len(args) > 0 {
+		p.name = args[0]
+	}
+	if len(args) > 1 {
+		p.url = args[1]
+	}
+
+	var n string
+	if n, err = client.Repositories().Add(p.name, p.url); err != nil {
+		return
+	}
+
+	fmt.Printf("%s Repositories added.\n", n)
+	return
 }
 
 func listCmd(cmd *cobra.Command, clientFactory ClientFactory) *cobra.Command {
 	lc := &cobra.Command{
 		Use:     "list",
+		Short:   "View the list of template library.",
+		Long:    "The list subcommand is used to view the repositories that have been added.",
 		Aliases: []string{"ls"},
 		RunE: func(cmd *cobra.Command, args []string) error {
 			return runList(cmd, args, clientFactory)
@@ -72,13 +96,27 @@ func listCmd(cmd *cobra.Command, clientFactory ClientFactory) *cobra.Command {
 	return lc
 }
 
-func runList(_ *cobra.Command, args []string, clientFactory ClientFactory) error {
-	return nil
+func runList(_ *cobra.Command, args []string, clientFactory ClientFactory) (err error) {
+	client, done := clientFactory()
+	defer done()
+
+	list, err := client.Repositories().All()
+	if err != nil {
+		return
+	}
+
+	for _, l := range list {
+		fmt.Println(l.Name + "\t" + l.URL())
+	}
+	return
 }
 
 func removeCmd(cmd *cobra.Command, clientFactory ClientFactory) *cobra.Command {
 	rc := &cobra.Command{
-		Use: "remove",
+		Use:     "remove [name]",
+		Short:   "Remove an existing template library.",
+		Long:    "The delete subcommand is used to delete a template from an existing repository.",
+		Aliases: []string{"delete"},
 		RunE: func(cmd *cobra.Command, args []string) error {
 			return runRemove(cmd, args, clientFactory)
 		},
@@ -86,6 +124,23 @@ func removeCmd(cmd *cobra.Command, clientFactory ClientFactory) *cobra.Command {
 	return rc
 }
 
-func runRemove(_ *cobra.Command, args []string, clientFactory ClientFactory) error {
-	return nil
+func runRemove(_ *cobra.Command, args []string, clientFactory ClientFactory) (err error) {
+	client, done := clientFactory()
+	defer done()
+
+	p := struct {
+		name string
+		sure bool
+	}{}
+	if len(args) > 0 {
+		p.name = args[0]
+	}
+	p.sure = true
+
+	if err = client.Repositories().Remove(p.name); err != nil {
+		return
+	}
+
+	fmt.Printf("%s Repositories removed", p.name)
+	return
 }
diff --git a/dubboctl/pkg/sdk/repositories.go b/dubboctl/pkg/sdk/repositories.go
index 28c8a56e..182953fe 100644
--- a/dubboctl/pkg/sdk/repositories.go
+++ b/dubboctl/pkg/sdk/repositories.go
@@ -57,6 +57,39 @@ func (r *Repositories) All() (repos []Repository, err error) {
 	return
 }
 
+func (r *Repositories) Add(name, url string) (string, error) {
+	if r.path == "" {
+		return "", fmt.Errorf("repository %v not added.", name)
+	}
+
+	repo, err := NewRepository(name, url)
+	if err != nil {
+		return "", fmt.Errorf("failed to create new repository: %w", err)
+	}
+
+	dest := filepath.Join(r.path, repo.Name)
+	if _, err := os.Stat(dest); !os.IsNotExist(err) {
+		return "", fmt.Errorf("repository '%v' already exists", repo.Name)
+	}
+
+	err = repo.Write(dest)
+	if err != nil {
+		return "", fmt.Errorf("failed to write repository: %w", err)
+	}
+	return repo.Name, nil
+}
+
+func (r *Repositories) Remove(name string) error {
+	if r.path == "" {
+		return fmt.Errorf("repository %v not removed.", name)
+	}
+	if name == "" {
+		return errors.New("name is required")
+	}
+	path := filepath.Join(r.path, name)
+	return os.RemoveAll(path)
+}
+
 func (r *Repositories) Get(name string) (repo Repository, err error) {
 	all, err := r.All()
 	if err != nil {
diff --git a/dubboctl/pkg/sdk/repository.go b/dubboctl/pkg/sdk/repository.go
index 4fb322f1..d93b6e23 100644
--- a/dubboctl/pkg/sdk/repository.go
+++ b/dubboctl/pkg/sdk/repository.go
@@ -1,6 +1,7 @@
 package sdk
 
 import (
+	"errors"
 	"fmt"
 	"github.com/apache/dubbo-kubernetes/dubboctl/pkg/util"
 	"github.com/go-git/go-billy/v5/memfs"
@@ -162,6 +163,64 @@ func (r *Repository) Runtime(name string) (runtime Runtime, err error) {
 	return Runtime{}, fmt.Errorf("language runtime not found")
 }
 
+func (r *Repository) Write(dest string) (err error) {
+	if r.fs == nil {
+		return errors.New("the write operation is not supported on this repo")
+	}
+	fs := r.fs
+
+	if _, ok := r.fs.(util.BillyFilesystem); ok {
+		var (
+			tempDir string
+			clone   *git.Repository
+			wt      *git.Worktree
+		)
+		if tempDir, err = os.MkdirTemp("", "dubbo"); err != nil {
+			return
+		}
+		if clone, err = git.PlainClone(tempDir, false,
+			getGitCloneOptions(r.uri)); err != nil {
+			return fmt.Errorf("failed to plain clone repository: %w", err)
+		}
+		if wt, err = clone.Worktree(); err != nil {
+			return fmt.Errorf("failed to get worktree: %w", err)
+		}
+		fs = util.NewBillyFilesystem(wt.Filesystem)
+	}
+	return util.CopyFromFS(".", dest, fs)
+}
+
+func (r *Repository) URL() string {
+	uri := r.uri
+
+	if uri == "" {
+		return ""
+	}
+
+	if strings.HasPrefix(uri, "file://") {
+		uri = filepath.FromSlash(r.uri[7:])
+	}
+
+	repo, err := git.PlainOpen(uri)
+	if err != nil {
+		return ""
+	}
+
+	c, err := repo.Config()
+	if err != nil {
+		return ""
+	}
+
+	ref, _ := repo.Head()
+	if _, ok := c.Remotes["origin"]; ok {
+		urls := c.Remotes["origin"].URLs
+		if len(urls) > 0 {
+			return urls[0] + "#" + ref.Name().Short()
+		}
+	}
+	return ""
+}
+
 func filesystemFromURI(uri string) (fs util.Filesystem, err error) {
 	if uri == "" {
 		return EmbeddedTemplatesFS, nil
diff --git a/dubboctl/pkg/util/path.go b/dubboctl/pkg/util/path.go
new file mode 100644
index 00000000..328c00ab
--- /dev/null
+++ b/dubboctl/pkg/util/path.go
@@ -0,0 +1,36 @@
+package util
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+)
+
+const (
+	Repositories = "repositories"
+)
+
+func Dir() (path string) {
+	if home, err := os.UserHomeDir(); err == nil {
+		path = filepath.Join(home, ".config", "dubbo")
+	}
+	return
+}
+
+func CreatePath() (err error) {
+	if err = os.MkdirAll(Dir(), os.ModePerm); err != nil {
+		return fmt.Errorf("error creating global config path: %v", err)
+	}
+	if err = os.MkdirAll(RepositoriesPath(), os.ModePerm); err != nil {
+		return fmt.Errorf("error creating global config repositories path: %v", err)
+	}
+	return
+}
+
+func RepositoriesPath() string {
+	path := filepath.Join(Dir(), Repositories)
+	if e := os.Getenv("DUBBO_REPOSITORIES_PATH"); e != "" {
+		path = e
+	}
+	return path
+}