提交 ab986b8a 编写于 作者: 徐晓伟's avatar 徐晓伟

导出所有(混合命令,多接口命令)

1. git 仓库
2. wiki 仓库
上级 5df651bb
......@@ -198,6 +198,7 @@ COMMANDS:
project, projects, p 项目 API,中文文档:https://docs.gitlab.cn/jh/api/projects.html
mix-delete, mix-rm 删除(混合命令,多接口命令)
mix-archive 归档(混合命令,多接口命令)
mix-export 导出(混合命令,多接口命令)
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
......@@ -534,6 +535,34 @@ COPYRIGHT:
--help, -h show help
```
- 导出(混合命令,多接口命令)
```shell
$ go run main.go mix-export --help
NAME:
gitlab-go mix-export - 导出(混合命令,多接口命令)
USAGE:
gitlab-go mix-export command [command options] [arguments...]
COMMANDS:
all, a 导出所有(混合命令,多接口命令)
已包含:
1. git 仓库
2. wiki 仓库
help, h Shows a list of commands or help for one command
OPTIONS:
--base-url value 实例地址,例如:https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token
--username value 用户名
--owned 当前用户明确拥有的项目。 (default: false)
--export-folder value 导出文件夹
--skip-project-path value [ --skip-project-path value ] 跳过项目路径
--skip-project-wiki-path value [ --skip-project-wiki-path value ] 跳过项目wiki路径
--help, -h show help
```
### test
```shell
......
package constant
const (
Token = "token"
BaseUrl = "base-url"
BaseUrlDefault = "https://gitlab.com/api/v4"
Id = "id"
JobIdRange = "job-id-range"
IIdRange = "iid-range"
Repository = "repository"
TagName = "tag-name"
JobId = "job-id"
ArtifactsName = "artifacts-name"
Sort = "sort"
SortDefault = "desc"
Page = "page"
PerPage = "per-page"
PrintJson = "print-json"
PrintJsonDefault = false
PrintTime = "print-time"
PrintTimeDefault = false
Scope = "scope"
IssueId = "issue-id"
IssueIdRange = "issue-id-range"
Recursion = "recursion"
Owned = "owned"
Username = "username"
Token = "token"
BaseUrl = "base-url"
BaseUrlDefault = "https://gitlab.com/api/v4"
Id = "id"
JobIdRange = "job-id-range"
IIdRange = "iid-range"
Repository = "repository"
TagName = "tag-name"
JobId = "job-id"
ArtifactsName = "artifacts-name"
Sort = "sort"
SortDefault = "desc"
Page = "page"
PerPage = "per-page"
PrintJson = "print-json"
PrintJsonDefault = false
PrintTime = "print-time"
PrintTimeDefault = false
Scope = "scope"
IssueId = "issue-id"
IssueIdRange = "issue-id-range"
Recursion = "recursion"
Owned = "owned"
ExportFolder = "export-folder"
SkipProjectPath = "skip-project-path"
SkipProjectWikiPath = "skip-project-wiki-path"
)
......@@ -49,6 +49,14 @@ func BaseUrl() cli.Flag {
}
}
func Username(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.Username,
Usage: "用户名",
Required: required,
}
}
func Token(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.Token,
......@@ -195,3 +203,25 @@ func IssueIdRange(required bool) cli.Flag {
Required: required,
}
}
func ExportFolder(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.ExportFolder,
Usage: "导出文件夹",
Required: required,
}
}
func SkipProjectPath() cli.Flag {
return &cli.StringSliceFlag{
Name: constant.SkipProjectPath,
Usage: "跳过项目路径",
}
}
func SkipProjectWikiPath() cli.Flag {
return &cli.StringSliceFlag{
Name: constant.SkipProjectWikiPath,
Usage: "跳过项目wiki路径",
}
}
package groups
import (
"github.com/xanzy/go-gitlab"
"log"
)
// ListGroups 列出群组 https://docs.gitlab.cn/jh/api/groups.html#%E5%88%97%E5%87%BA%E7%BE%A4%E7%BB%84
func ListGroups(token string, baseUrl string, page int, perPage int) ([]*gitlab.Group, error) {
var results []*gitlab.Group
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return nil, err
}
opt := &gitlab.ListGroupsOptions{
ListOptions: gitlab.ListOptions{
Page: page,
PerPage: perPage,
},
}
groups, response, err := gitClient.Groups.ListGroups(opt)
if err != nil {
return nil, err
}
log.Printf("ListGroups Page %d, PerPage: %d, Response StatusCode: %d\n", page, perPage, response.Response.StatusCode)
results = append(results, groups...)
if len(groups) != 0 {
groups, err = ListGroups(token, baseUrl, page+1, perPage)
if err != nil {
return nil, err
}
results = append(results, groups...)
}
return results, nil
}
......@@ -78,6 +78,7 @@ func main() {
projects.Projects(),
mix.Delete(),
mix.Archive(),
mix.Export(),
},
}
......
package mix
import (
"errors"
"github.com/urfave/cli/v2"
"github.com/xanzy/go-gitlab"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"github.com/xuxiaowei-com-cn/gitlab-go/projects"
"log"
"net/url"
"os"
"os/exec"
"path/filepath"
"strings"
)
func ExportAll() *cli.Command {
return &cli.Command{
Name: "all",
Aliases: []string{"a"},
Usage: "导出所有(混合命令,多接口命令)\n" +
"已包含:\n" +
"1. git 仓库\n" +
"2. wiki 仓库",
Flags: append(flag.CommonTokenRequired(), flag.Username(true), flag.Owned(true),
flag.ExportFolder(true), flag.SkipProjectPath(), flag.SkipProjectWikiPath()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var username = context.String(constant.Username)
var owned = context.Bool(constant.Owned)
var exportFolder = context.String(constant.ExportFolder)
var skipProjectPaths = context.StringSlice(constant.SkipProjectPath)
var skipProjectWikiPaths = context.StringSlice(constant.SkipProjectWikiPath)
baseURL, err := url.Parse(baseUrl)
if err != nil {
return err
}
host := baseURL.Host
for index, skipProjectPath := range skipProjectPaths {
skipProjectPath = strings.TrimPrefix(skipProjectPath, "/")
skipProjectPath = strings.TrimSuffix(skipProjectPath, "/")
skipProjectPaths[index] = skipProjectPath
}
for index, skipProjectWikiPath := range skipProjectWikiPaths {
skipProjectWikiPath = strings.TrimPrefix(skipProjectWikiPath, "/")
skipProjectWikiPath = strings.TrimSuffix(skipProjectWikiPath, "/")
skipProjectWikiPaths[index] = skipProjectWikiPath
}
projectList, err := projects.ListProjects(&owned, token, baseUrl, 1, 100)
if err != nil {
return err
}
for index, project := range projectList {
log.Printf("Project Index: %d, WebURL: %s", index, project.WebURL)
err = Repository(exportFolder, host, username, token, project, skipProjectPaths)
if err != nil {
return err
}
err = Wiki(exportFolder, host, username, token, project, skipProjectWikiPaths)
if err != nil {
return err
}
}
log.Printf("导出完成")
return nil
},
}
}
func Repository(exportFolder string, host string, username string, token string, project *gitlab.Project, skipProjectPaths []string) error {
c := contains(skipProjectPaths, project.PathWithNamespace)
if c {
log.Printf("跳过:%s", project.PathWithNamespace)
return nil
}
gitPath := filepath.Join(exportFolder, "repository", host, project.PathWithNamespace)
err := os.MkdirAll(gitPath, os.ModePerm)
if err != nil {
return err
}
HTTPURLToRepo := project.HTTPURLToRepo
repoUrl, err := url.Parse(HTTPURLToRepo)
if err != nil {
return err
}
userinfo := url.UserPassword(username, token)
repoUrl.User = userinfo
cmd := exec.Command("git", "clone", repoUrl.String(), gitPath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
return err
}
err = GitRemoteSetUrl(gitPath, HTTPURLToRepo)
if err != nil {
return err
}
return nil
}
func Wiki(exportFolder string, host string, username string, token string, project *gitlab.Project, skipProjectWikiPaths []string) error {
c := contains(skipProjectWikiPaths, project.PathWithNamespace)
if c {
log.Printf("跳过:%s", project.PathWithNamespace)
return nil
}
wikiPath := filepath.Join(exportFolder, "wiki", host, project.PathWithNamespace+".wiki")
err := os.MkdirAll(wikiPath, os.ModePerm)
if err != nil {
return err
}
var HTTPURLToRepo string
if strings.HasSuffix(project.HTTPURLToRepo, ".git") {
HTTPURLToRepo = strings.TrimSuffix(project.HTTPURLToRepo, ".git") + ".wiki.git"
} else {
return errors.New("仓库地址异常: " + project.HTTPURLToRepo)
}
repoUrl, err := url.Parse(HTTPURLToRepo)
if err != nil {
return err
}
userinfo := url.UserPassword(username, token)
repoUrl.User = userinfo
cmd := exec.Command("git", "clone", repoUrl.String(), wikiPath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
return err
}
err = GitRemoteSetUrl(wikiPath, HTTPURLToRepo)
if err != nil {
return err
}
return nil
}
func GitRemoteSetUrl(gitPath string, remoteUrl string) error {
cmd := exec.Command("git", "remote", "set-url", "origin", remoteUrl)
cmd.Dir = gitPath
err := cmd.Run()
if err != nil {
return err
}
return nil
}
func contains(arr []string, target string) bool {
for _, str := range arr {
if str == target {
return true
}
}
return false
}
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
// Export 导出
func Export() *cli.Command {
return &cli.Command{
Name: "mix-export",
Usage: "导出(混合命令,多接口命令)",
Flags: append(flag.Common(), flag.Username(false), flag.Owned(false),
flag.ExportFolder(false), flag.SkipProjectPath(), flag.SkipProjectWikiPath()),
Subcommands: []*cli.Command{
ExportAll(),
},
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册