package main import ( "fmt" "strings" "time" "github.com/spf13/cobra" "skillmgr/internal/config" "skillmgr/internal/repo" "skillmgr/internal/types" ) // validateGitURL 验证 Git URL 格式 func validateGitURL(url string) error { if url == "" { return fmt.Errorf("URL 不能为空") } // 支持 https://, http://, git@, git:// 协议 validPrefixes := []string{"https://", "http://", "git@", "git://"} for _, prefix := range validPrefixes { if strings.HasPrefix(url, prefix) { return nil } } return fmt.Errorf("无效的 Git URL 格式,必须以 https://, http://, git@ 或 git:// 开头") } var addCmd = &cobra.Command{ Use: "add ", Short: "添加源仓库", Long: `添加一个 git 仓库作为 skills/commands 的源。 示例: skillmgr add https://github.com/user/skills skillmgr add https://github.com/user/skills --name my-skills skillmgr add https://github.com/user/skills --branch main`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { url := args[0] // 验证 URL 格式 if err := validateGitURL(url); err != nil { return err } name, _ := cmd.Flags().GetString("name") branch, _ := cmd.Flags().GetString("branch") // 如果没有指定名称,从 URL 生成 if name == "" { name = repo.URLToPathName(url) } if branch == "" { branch = "main" // 默认分支 } // Clone 仓库 fmt.Printf("正在克隆仓库 %s...\n", url) repoPath, err := repo.CloneOrPull(url, branch) if err != nil { return fmt.Errorf("克隆仓库失败: %w", err) } // 保存到配置 repository := types.Repository{ Name: name, URL: url, Branch: branch, AddedAt: time.Now(), } if err := config.AddRepository(repository); err != nil { return err } fmt.Printf("✓ 仓库 '%s' 添加成功\n", name) fmt.Printf(" 缓存路径: %s\n", repoPath) return nil }, } func init() { addCmd.Flags().String("name", "", "仓库别名") addCmd.Flags().String("branch", "main", "克隆的分支") rootCmd.AddCommand(addCmd) }