diff --git a/internal/source/gitea/gitea.go b/internal/source/gitea/gitea.go index bbf5328..bf84be8 100644 --- a/internal/source/gitea/gitea.go +++ b/internal/source/gitea/gitea.go @@ -10,12 +10,14 @@ import ( "net/http" "os" "os/exec" + "regexp" "strings" "text/template" "time" "git.unistack.org/unistack-org/pkgdash/internal/configcli" "git.unistack.org/unistack-org/pkgdash/internal/modules" + "git.unistack.org/unistack-org/pkgdash/internal/source" "github.com/go-git/go-git/v5" gitconfig "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" @@ -82,7 +84,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, cfg *configcli.Config, branch s Force: true, }); err != nil && err != git.NoErrAlreadyUpToDate { logger.Fatalf(ctx, "failed to fetch repo: %v", err) - } + } //обновляем репозиторий var headRef *plumbing.Reference // вроде ссылка на гит refIter, err := repo.Branches() //получение веток @@ -94,7 +96,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, cfg *configcli.Config, branch s if err != nil { break } - if ref.Name().String() == branch { + if ref.Name().String() == branch { //todo вот тут возможно нужно переделать headRef = ref break } @@ -107,7 +109,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, cfg *configcli.Config, branch s logger.Infof(ctx, "repo head %s", headRef) - wtree, err := repo.Worktree() + wtree, err := repo.Worktree() //todo вроде рабочее дерево не нужно if err != nil { logger.Fatalf(ctx, "failed to get worktree: %v", err) } @@ -116,7 +118,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, cfg *configcli.Config, branch s req, err := http.NewRequestWithContext(ctx, http.MethodGet, cfg.Source.APIURL+"/repos/"+cfg.Source.Repository+"/pulls?state=open&token="+cfg.Source.Token, nil) if err != nil { return err - } //вроде запроса к репозиторию + } //Получаем список пулл реквестов req.Header.Add("Accept", "application/json") req.Header.Add("Content-Type", "application/json") @@ -138,19 +140,16 @@ func (g *Gitea) RequestOpen(ctx context.Context, cfg *configcli.Config, branch s for _, pull := range pulls { if strings.Contains(pull.Title, path) && pull.Base.Ref == branch { logger.Infof(ctx, "skip %s as pr already exists %s", path, pull.URL) - return nil - } + return source.ErrPRExist + } // хотим проверить есть ли пулл реквест для этой ветки, если есть то выходим } - wTitle.Reset() - wBody.Reset() - logger.Infof(ctx, "update %s from %s to %s", path, mod.Module.Version, mod.Version) logger.Infof(ctx, "reset worktree") if err = wtree.Reset(&git.ResetOptions{Mode: git.HardReset}); err != nil { logger.Fatalf(ctx, "failed to reset repo branch: %v", err) - } //вроде меняем ветку + } //вроде меняем ветку todo вроде можно удалить if err = wtree.PullContext(ctx, &git.PullOptions{ Auth: &httpauth.BasicAuth{Username: cfg.Source.Token, Password: cfg.Source.Token}, @@ -159,18 +158,18 @@ func (g *Gitea) RequestOpen(ctx context.Context, cfg *configcli.Config, branch s Force: true, RemoteName: "origin", }); err != nil && err != git.NoErrAlreadyUpToDate { - logger.Fatalf(ctx, "failed to pull repo: %v", err) + logger.Fatalf(ctx, "failed to pull repo: %v", err) //подтягиваем изменения с удаленого репозитория } logger.Infof(ctx, "checkout ref %s", headRef) if err = wtree.Checkout(&git.CheckoutOptions{ Hash: headRef.Hash(), - Branch: plumbing.NewBranchReferenceName(fmt.Sprintf("pkgdash-1/go_modules/%s-%s", path, mod.Version)), + Branch: plumbing.NewBranchReferenceName(fmt.Sprintf("pkgdash/go_modules/%s-%s", path, mod.Version)), Create: true, Force: true, }); err != nil { logger.Fatalf(ctx, "failed to checkout tree: %v", err) - } //вроде как переходим на другую ветку + } //создаем новую ветку epath, err := exec.LookPath("go") if errors.Is(err, exec.ErrDot) { @@ -224,7 +223,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, cfg *configcli.Config, branch s } */ - refspec := gitconfig.RefSpec(fmt.Sprintf("+refs/heads/pkgdash-1/go_modules/%s-%s:refs/heads/pkgdash-1/go_modules/%s-%s", path, mod.Version, path, mod.Version)) + refspec := gitconfig.RefSpec(fmt.Sprintf("+refs/heads/pkgdash/go_modules/%s-%s:refs/heads/pkgdash/go_modules/%s-%s", path, mod.Version, path, mod.Module.Version)) //todo как будто нужно переделать logger.Infof(ctx, "try to push refspec %s", refspec) @@ -356,19 +355,30 @@ func (g *Gitea) RequestClose(ctx context.Context, cfg *configcli.Config, branch } // записываем ответ от гита по пулл реквестам, видимо существующим // перебираем наши модификации и если они уже есть в гите удаляем их из mods + prExist := false for _, pull := range pulls { - if !strings.Contains(pull.Title, path) && pull.Base.Ref != branch { + if strings.Contains(pull.Title, path) && pull.Base.Ref == branch { logger.Infof(ctx, "skip %s since pr does not exist %s", path, pull.URL) - return nil + prExist = true } } + if !prExist { + logger.Errorf(ctx, " skip %s since pr does not exist", path) + return source.ErrPRNotExist + } - if err = repo.DeleteBranch(path); err != nil { - logger.Errorf(ctx, "failed to delete the branch: %s", path) + req, err = DeleteBranch(ctx, cfg, branch) + if err != nil { + logger.Errorf(ctx, "failed to create request for delete the branch: %s, err: %s", branch, err) + return err + } + rsp, err = http.DefaultClient.Do(req) + if err != nil { + logger.Errorf(ctx, "failed to do request for delete the branch: %s, err: %s, code: %s", branch, err, rsp.StatusCode) return err } - logger.Infof(ctx, "Delete branch %s successful", path) + logger.Infof(ctx, "Delete branch %s successful", branch) return nil } @@ -465,15 +475,30 @@ func (g *Gitea) RequestUpdate(ctx context.Context, cfg *configcli.Config, branch } // записываем ответ от гита по пулл реквестам, видимо существующим // перебираем наши модификации и если они уже есть в гите удаляем их из mods + prExist := false for _, pull := range pulls { - if !strings.Contains(pull.Title, path) && pull.Base.Ref != branch { - logger.Infof(ctx, "skip %s since pr does not exist %s", path, pull.URL) - return nil + if strings.Contains(pull.Title, path) && pull.Base.Ref != branch { + logger.Infof(ctx, "skip %s since pr does not exist %s", path, pull.URL) //todo + titleVersions := getVersions(pull.Title) + if modules.IsNewerVersion(titleVersions.NewV, mod.Version, false) { + reqDel, err := DeleteBranch(ctx, cfg, branch) + if err != nil { + logger.Errorf(ctx, "Error with create request for branch: %s, err: %s", branch, err) + continue + } + rsp, err := http.DefaultClient.Do(reqDel) + if err != nil { + logger.Errorf(ctx, "Error with do request for branch: %s, err: %s, code: %v", branch, err, rsp.StatusCode) + continue //думаю что если не можем удалить ветку не стоит заканчивать работу, а перейти к следующей итерации + } + } + prExist = true } } - - wTitle.Reset() - wBody.Reset() + if !prExist { + logger.Errorf(ctx, " skip %s since pr does not exist", path) + return source.ErrPRNotExist + } logger.Infof(ctx, "update %s from %s to %s", path, mod.Module.Version, mod.Version) @@ -612,3 +637,36 @@ func (g *Gitea) RequestUpdate(ctx context.Context, cfg *configcli.Config, branch return nil } + +func getVersions(s string) *Tmod { + rsp := new(Tmod) + re := regexp.MustCompile("[0-9]+\\.[0-9]+\\.[0-9]+") + versions := re.FindAllString(s, -1) + if len(versions) < 2 { + return nil + } + if modules.IsNewerVersion(versions[0], versions[1], false) { + rsp.OldV = versions[0] + rsp.NewV = versions[1] + return rsp + } + rsp.OldV = versions[1] + rsp.NewV = versions[0] + return rsp +} + +type Tmod struct { + OldV string + NewV string +} + +func DeleteBranch(ctx context.Context, cfg *configcli.Config, branch string) (*http.Request, error) { + var buf []byte + req, err := http.NewRequestWithContext(ctx, http.MethodDelete, cfg.Source.APIURL+"/repos/"+cfg.Source.Repository+"/branches/"+branch+"?token="+cfg.Source.Token, bytes.NewReader(buf)) + if err != nil { + return nil, err + } + req.Header.Add("Accept", "application/json") + req.Header.Add("Content-Type", "application/json") + return req, err +} diff --git a/internal/source/source.go b/internal/source/source.go index 5f72dc2..87e8f3d 100644 --- a/internal/source/source.go +++ b/internal/source/source.go @@ -1,16 +1,26 @@ package source import ( + "context" + "errors" + + "git.unistack.org/unistack-org/pkgdash/internal/configcli" + "git.unistack.org/unistack-org/pkgdash/internal/modules" "git.unistack.org/unistack-org/pkgdash/internal/source/gitea" "git.unistack.org/unistack-org/pkgdash/internal/source/github" "git.unistack.org/unistack-org/pkgdash/internal/source/gitlab" "git.unistack.org/unistack-org/pkgdash/internal/source/gogs" ) +var ( + ErrPRExist = errors.New("Pull request exists") + ErrPRNotExist = errors.New("Pull request does not exist") +) + type SourceControl interface { - RequestOpen() - RequestClose() - RequestUpdate() + RequestOpen(ctx context.Context, cfg *configcli.Config, branch string, path string, mod modules.Update) error + RequestClose(ctx context.Context, cfg *configcli.Config, branch string, path string) error + RequestUpdate(ctx context.Context, cfg *configcli.Config, branch string, path string, mod modules.Update) error } func NewSourceControl(system, token string) SourceControl {