mirror of
https://github.com/beego/bee.git
synced 2025-06-12 10:00:41 +00:00
beego pro init
This commit is contained in:
231
internal/pkg/git/repository.go
Normal file
231
internal/pkg/git/repository.go
Normal file
@ -0,0 +1,231 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/beego/bee/internal/pkg/command"
|
||||
"github.com/beego/bee/internal/pkg/utils"
|
||||
beeLogger "github.com/beego/bee/logger"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 获取某项目代码库的标签列表
|
||||
func GetTags(repoPath string, limit int) ([]string, error) {
|
||||
repo, err := OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = repo.Pull()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list, err := repo.GetTags()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(list) > limit {
|
||||
list = list[0:limit]
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// clone repo
|
||||
func CloneRepo(url string, dst string) (err error) {
|
||||
if utils.IsExist(dst) {
|
||||
return errors.New("dst is not empty, dst is " + dst)
|
||||
}
|
||||
if !utils.Mkdir(dst) {
|
||||
err = errors.New("make dir error, dst is " + dst)
|
||||
return
|
||||
}
|
||||
|
||||
beeLogger.Log.Info("start git clone from " + url + ", to dst at " + dst)
|
||||
_, stderr, err := command.ExecCmd("git", "clone", url, dst)
|
||||
|
||||
if err != nil {
|
||||
beeLogger.Log.Error("error git clone from " + url + ", to dst at " + dst)
|
||||
return concatenateError(err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloneORPullRepo
|
||||
func CloneORPullRepo(url string, dst string) error {
|
||||
if !utils.IsDir(dst) {
|
||||
return CloneRepo(url, dst)
|
||||
} else {
|
||||
//projectName, err := getGitProjectName(url)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
//fmt.Println("dst------>", dst)
|
||||
//projectDir := dst + "/" + projectName
|
||||
utils.Mkdir(dst)
|
||||
|
||||
repo, err := OpenRepository(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return repo.Pull()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
func CloneRepoBranch(branch string, url string, dst string) error {
|
||||
_, stderr, err := command.ExecCmd("git", "clone", "-b", branch, url, dst)
|
||||
if err != nil {
|
||||
return concatenateError(err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SortTag ...
|
||||
type SortTag struct {
|
||||
data []string
|
||||
}
|
||||
|
||||
// Len ...
|
||||
func (t *SortTag) Len() int {
|
||||
return len(t.data)
|
||||
}
|
||||
|
||||
// Swap ...
|
||||
func (t *SortTag) Swap(i, j int) {
|
||||
t.data[i], t.data[j] = t.data[j], t.data[i]
|
||||
}
|
||||
|
||||
// Less ...
|
||||
func (t *SortTag) Less(i, j int) bool {
|
||||
return command.VerCompare(t.data[i], t.data[j]) == 1
|
||||
}
|
||||
|
||||
// Sort ...
|
||||
func (t *SortTag) Sort() []string {
|
||||
sort.Sort(t)
|
||||
return t.data
|
||||
}
|
||||
|
||||
// Repository ...
|
||||
type Repository struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
// OpenRepository ...
|
||||
func OpenRepository(repoPath string) (*Repository, error) {
|
||||
repoPath, err := filepath.Abs(repoPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !utils.IsDir(repoPath) {
|
||||
return nil, errors.New("no such file or directory")
|
||||
}
|
||||
|
||||
return &Repository{Path: repoPath}, nil
|
||||
}
|
||||
|
||||
// 拉取代码
|
||||
func (repo *Repository) Pull() error {
|
||||
beeLogger.Log.Info("git pull " + repo.Path)
|
||||
_, stderr, err := command.ExecCmdDir(repo.Path, "git", "pull")
|
||||
if err != nil {
|
||||
return concatenateError(err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取tag列表
|
||||
func (repo *Repository) GetTags() ([]string, error) {
|
||||
stdout, stderr, err := command.ExecCmdDir(repo.Path, "git", "tag", "-l")
|
||||
if err != nil {
|
||||
return nil, concatenateError(err, stderr)
|
||||
}
|
||||
tags := strings.Split(stdout, "\n")
|
||||
tags = tags[:len(tags)-1]
|
||||
|
||||
so := &SortTag{data: tags}
|
||||
return so.Sort(), nil
|
||||
}
|
||||
|
||||
// 获取两个版本之间的修改日志
|
||||
func (repo *Repository) GetChangeLogs(startVer, endVer string) ([]string, error) {
|
||||
// git log --pretty=format:"%cd %cn: %s" --date=iso v1.8.0...v1.9.0
|
||||
stdout, stderr, err := command.ExecCmdDir(repo.Path, "git", "log", "--pretty=format:%cd %cn: %s", "--date=iso", startVer+"..."+endVer)
|
||||
if err != nil {
|
||||
return nil, concatenateError(err, stderr)
|
||||
}
|
||||
|
||||
logs := strings.Split(stdout, "\n")
|
||||
return logs, nil
|
||||
}
|
||||
|
||||
// 获取两个版本之间的差异文件列表
|
||||
func (repo *Repository) GetChangeFiles(startVer, endVer string, onlyFile bool) ([]string, error) {
|
||||
// git diff --name-status -b v1.8.0 v1.9.0
|
||||
param := "--name-status"
|
||||
if onlyFile {
|
||||
param = "--name-only"
|
||||
}
|
||||
stdout, stderr, err := command.ExecCmdDir(repo.Path, "git", "diff", param, "-b", startVer, endVer)
|
||||
if err != nil {
|
||||
return nil, concatenateError(err, stderr)
|
||||
}
|
||||
lines := strings.Split(stdout, "\n")
|
||||
return lines[:len(lines)-1], nil
|
||||
}
|
||||
|
||||
// 获取两个版本间的新增或修改的文件数量
|
||||
func (repo *Repository) GetDiffFileCount(startVer, endVer string) (int, error) {
|
||||
cmd := "git diff --name-status -b " + startVer + " " + endVer + " |grep -v ^D |wc -l"
|
||||
stdout, stderr, err := command.ExecCmdDir(repo.Path, "/bin/bash", "-c", cmd)
|
||||
if err != nil {
|
||||
return 0, concatenateError(err, stderr)
|
||||
}
|
||||
count, _ := strconv.Atoi(strings.TrimSpace(stdout))
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// 导出版本到tar包
|
||||
func (repo *Repository) Export(startVer, endVer string, filename string) error {
|
||||
// git archive --format=tar.gz $endVer $(git diff --name-status -b $beginVer $endVer |grep -v ^D |grep -v Upgrade/ |awk '{print $2}') -o $tmpFile
|
||||
|
||||
cmd := ""
|
||||
if startVer == "" {
|
||||
cmd = "git archive --format=tar " + endVer + " | gzip > " + filename
|
||||
} else {
|
||||
cmd = "git archive --format=tar " + endVer + " $(dgit diff --name-status -b " + startVer + " " + endVer + "|grep -v ^D |awk '{print $2}') | gzip > " + filename
|
||||
}
|
||||
|
||||
_, stderr, err := command.ExecCmdDir(repo.Path, "/bin/bash", "-c", cmd)
|
||||
|
||||
if err != nil {
|
||||
return concatenateError(err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func concatenateError(err error, stderr string) error {
|
||||
if len(stderr) == 0 {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%v: %s", err, stderr)
|
||||
}
|
||||
|
||||
// getGitProjectName 获取项目名称
|
||||
func getGitProjectName(url string) (name string, err error) {
|
||||
if !strings.Contains(url, ".git") {
|
||||
return "", errors.New("Project address does not contain .git")
|
||||
}
|
||||
fileSlice := strings.Split(url, "/")
|
||||
projectName := fileSlice[len(fileSlice)-1]
|
||||
if projectName == "" {
|
||||
return "", errors.New("Project name does not exist")
|
||||
}
|
||||
|
||||
nameSlice := strings.Split(projectName, ".git")
|
||||
|
||||
return nameSlice[0], nil
|
||||
}
|
Reference in New Issue
Block a user