@@ -8,7 +8,6 @@ import (
"fmt"
"io"
"net/http"
"os"
"os/exec"
"regexp"
"strings"
@@ -34,12 +33,13 @@ type Gitea struct {
PRBody string
Repository string
Owner string
pulls [ ] * giteaPull
}
func NewGitea ( cfg configcli . Config ) * Gitea {
return & Gitea {
URL : cfg . Source . APIURL ,
Token : os . Getenv ( "gitea_token" ) ,
Token : cfg . Source . Token ,
PRTitle : cfg . PullRequestTitle ,
PRBody : cfg . PullRequestBody ,
Repository : cfg . Source . Repository ,
@@ -59,8 +59,12 @@ type giteaPull struct {
ID int64 ` json:"id" `
}
func ( g * Gitea ) Name ( ) string {
return "gitea"
}
func ( g * Gitea ) RequestOpen ( ctx context . Context , branch string , path string , mod modules . Update ) error {
logger . Debug ( ctx , fmt . Sprintf ( "RequestOpen start, mod title: %s" , path ) )
logger . Debugf ( ctx , fmt . Sprintf ( "RequestOpen start, mod title: %s" , path ) )
var buf [ ] byte
var err error
@@ -97,16 +101,16 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
if err != nil {
logger . Fatal ( ctx , fmt . Sprintf ( "failed to open repo: %v" , err ) )
}
// извлекаем ссылки с объектами из удаленного объекта??
//извлекаем ссылки с объектами из удаленного объекта??
if err = repo . FetchContext ( ctx , & git . FetchOptions {
Auth : & httpauth . BasicAuth { Username : g . Token , Password : g . Token } ,
Force : true ,
} ) ; err != nil && err != git . NoErrAlreadyUpToDate {
logger . Fatal ( ctx , fmt . Sprintf ( "failed to fetch repo: %v" , err ) )
} // обновляем репозиторий
} //обновляем репозиторий
var headRef * plumbing . Reference // вроде ссылка на гит
refIter , err := repo . Branches ( ) // получение веток
refIter , err := repo . Branches ( ) //получение веток
if err != nil {
logger . Fatal ( ctx , fmt . Sprintf ( "failed to get branches: %v" , err ) )
return err
@@ -116,11 +120,11 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
if err != nil {
break
}
if strings . Contains ( ref. Name ( ) . String ( ) , branch ) { // todo вот тут возможно нужно переделать
if ref . Name ( ) . Short ( ) == branch { //todo вот тут возможно нужно переделать
headRef = ref
break
}
} // перебираем получение ветки и когда находим нужную выходим из цикла записав ветку в headRef
} //перебираем получение ветки и когда находим нужную выходим из цикла записав ветку в headRef
refIter . Close ( )
if headRef == nil {
@@ -130,19 +134,18 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
logger . Info ( ctx , fmt . Sprintf ( "repo head %s" , headRef ) )
wtree , err := repo . Worktree ( ) // todo вроде рабочее дерево не нужно
wtree , err := repo . Worktree ( ) //todo вроде рабочее дерево не нужно
if err != nil {
logger . Fatal ( ctx , fmt . Sprintf ( "failed to get worktree: %v" , err ) )
}
pulls , err : = GetPulls ( ctx , g . URL , g . Owner , g . Repository , g . Token )
g . pulls, err = GetPulls ( ctx , g . URL , g . Owner , g . Repository , g . Token )
if err != nil && err != ErrPRNotExist {
logger . Error ( ctx , fmt . Sprintf ( "GetPulls error: %s" , err ) )
return err
}
for _ , pull := range pulls {
logger . Debug ( ctx , fmt . Sprintf ( "PULL title - %s | ref - %s" , pull . Title , pull . Base . Ref ) )
for _ , pull := range g . pulls {
if strings . Contains ( pull . Title , path ) && strings . Contains ( pull . Base . Ref , branch ) {
logger . Info ( ctx , fmt . Sprintf ( "PR for %s exists %s, call RequestUpdate" , path , pull . URL ) )
return g . RequestUpdate ( ctx , branch , path , mod )
@@ -154,7 +157,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
logger . Info ( ctx , "reset worktree" )
if err = wtree . Reset ( & git . ResetOptions { Mode : git . HardReset } ) ; err != nil {
logger . Error ( ctx , fmt . Sprintf ( "failed to reset repo branch: %v" , err ) )
} // вроде меняем ветку todo вроде можно удалить
} //вроде меняем ветку todo вроде можно удалить
if err = wtree . PullContext ( ctx , & git . PullOptions {
Auth : & httpauth . BasicAuth { Username : g . Token , Password : g . Token } ,
@@ -163,7 +166,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
Force : true ,
RemoteName : "origin" ,
} ) ; err != nil && err != git . NoErrAlreadyUpToDate {
logger . Error ( ctx , fmt . Sprintf ( "failed to pull repo: %v" , err ) ) // подтягиваем изменения с удаленого репозитория
logger . Error ( ctx , fmt . Sprintf ( "failed to pull repo: %v" , err ) ) //подтягиваем изменения с удаленого репозитория
}
logger . Info ( ctx , fmt . Sprintf ( "checkout ref %s" , headRef ) )
@@ -175,7 +178,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
} ) ; err != nil {
logger . Error ( ctx , fmt . Sprintf ( "failed to checkout tree: %v" , err ) )
return err
} // создаем новую ветку
} //создаем новую ветку
epath , err := exec . LookPath ( "go" )
if errors . Is ( err , exec . ErrDot ) {
@@ -226,7 +229,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
logger . Fatal ( ctx , fmt . Sprintf ( "failed to commit: %v" , err ) )
}
refspec := gitconfig . RefSpec ( fmt . Sprintf ( "+refs/heads/pkgdash/go_modules/%s-%s:refs/heads/pkgdash/go_modules/%s-%s" , path , mod . Version , path , mod . Version ) ) // todo как будто нужно переделать
refspec := gitconfig . RefSpec ( fmt . Sprintf ( "+refs/heads/pkgdash/go_modules/%s-%s:refs/heads/pkgdash/go_modules/%s-%s" , path , mod . Version , path , mod . Version ) ) //todo как будто нужно переделать
logger . Info ( ctx , fmt . Sprintf ( "try to push refspec %s" , refspec ) )
@@ -256,7 +259,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
req , err := http . NewRequestWithContext (
ctx ,
http . MethodPost ,
fmt . Sprintf ( "%s /repos/%s/%s/pulls?token=%s" , g . URL , g . Owner , g . Repository , g . Token ) ,
fmt . Sprintf ( "https://%s/api/v1 /repos/%s/%s/pulls?token=%s" , g . URL , g . Owner , g . Repository , g . Token ) ,
bytes . NewReader ( buf ) ,
)
if err != nil {
@@ -268,7 +271,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
rsp , err := http . DefaultClient . Do ( req )
if err != nil {
return err
} // Вроде создаем новый реквест на создание пулл реквеста
} //Вроде создаем новый реквест на создание пулл реквеста
if rsp . StatusCode != http . StatusCreated {
buf , _ = io . ReadAll ( rsp . Body )
return fmt . Errorf ( "unknown error: %s" , buf )
@@ -276,11 +279,16 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod
logger . Info ( ctx , fmt . Sprintf ( "PR create for %s-%s" , path , mod . Version ) )
repo , err = git . PlainOpenWithOptions ( "." , & git . PlainOpenOptions { DetectDotGit : true } )
if err != nil {
logger . Fatal ( ctx , fmt . Sprintf ( "failed to open repo: %v" , err ) )
}
return nil
}
func ( g * Gitea ) RequestClose ( ctx context . Context , branch string , path string ) error {
logger . Debug ( ctx , fmt . Sprintf ( "RequestClose start, mod title: %s" , path ) )
logger . Debugf ( ctx , fmt . Sprintf ( "RequestClose start, mod title: %s" , path ) )
pulls , err := GetPulls ( ctx , g . URL , g . Owner , g . Repository , g . Token )
if err != nil {
@@ -309,7 +317,7 @@ func (g *Gitea) RequestClose(ctx context.Context, branch string, path string) er
}
rsp , err := http . DefaultClient . Do ( req )
if err != nil {
logger . Error ( ctx , fmt . Sprintf ( "failed to do request for delete the branch: %s, err: %s, code: %s " , branch , err , rsp . StatusCode ) )
logger . Error ( ctx , fmt . Sprintf ( "failed to do request for delete the branch: %s, err: %s, code: %v " , branch , err , rsp . StatusCode ) )
return err
}
@@ -318,19 +326,22 @@ func (g *Gitea) RequestClose(ctx context.Context, branch string, path string) er
}
func ( g * Gitea ) RequestUpdate ( ctx context . Context , branch string , path string , mod modules . Update ) error {
logger . Debug ( ctx , fmt . Sprintf ( "RequestUpdate start, mod title: %s" , path ) )
logger . Debugf ( ctx , fmt . Sprintf ( "RequestUpdate start, mod title: %s" , path ) )
var err error
pulls , err := GetPulls ( ctx , g . URL , g . Owner , g . Repository , g . Token )
if err ! = nil {
logger . Error ( ctx , fmt . Sprintf ( "GetPulls error: %s" , err ) )
return err
if len ( g . pulls ) == 0 {
g . pulls , err = GetPulls ( ctx , g . URL , g . Owner , g . Repository , g . Token )
if err != nil {
logger . Error ( ctx , fmt . Sprintf ( "GetPulls error: %s" , err ) )
return err
}
}
prExist := false
for _ , pull := range pulls {
for _ , pull := range g . pulls {
if strings . Contains ( pull . Title , path ) && pull . Base . Ref == branch {
logger . Info ( ctx , fmt . Sprintf ( "don't skip %s since pr exist %s" , path , pull . URL ) ) // todo
tVersion := getVersions ( pull . Head . Ref ) // Надо взять просто из названия ветки последнюю версию
logger . Info ( ctx , fmt . Sprintf ( "don't skip %s since pr exist %s" , path , pull . URL ) ) //todo
tVersion := getVersions ( pull . Head . Ref ) //Надо взять просто из названия ветки последнюю версию
if modules . IsNewerVersion ( tVersion , mod . Version , false ) {
reqDel , err := DeleteBranch ( ctx , g . URL , g . Owner , g . Repository , pull . Head . Ref , g . Token )
if err != nil {
@@ -340,10 +351,11 @@ func (g *Gitea) RequestUpdate(ctx context.Context, branch string, path string, m
rsp , err := http . DefaultClient . Do ( reqDel )
if err != nil {
logger . Error ( ctx , fmt . Sprintf ( "Error with do request for branch: %s, err: %s, code: %v" , branch , err , rsp . StatusCode ) )
continue // думаю что если не можем удалить ветку не стоит заканчивать работу, а перейти к следующей итерации
continue //думаю что если не можем удалить ветку не стоит заканчивать работу, а перейти к следующей итерации
}
logger . Info ( ctx , fmt . Sprintf ( "Old pr %s successful delete" , pull . Head . Ref ) )
} else {
logger . Debugf ( ctx , "The existing PR is relevant" )
return nil
}
prExist = true
@@ -360,7 +372,7 @@ func (g *Gitea) RequestUpdate(ctx context.Context, branch string, path string, m
}
func ( g * Gitea ) RequestList ( ctx context . Context , branch string ) ( map [ string ] string , error ) {
logger . Debug ( ctx , fmt . Sprintf ( "RequestList for %s" , branch ) )
logger . Debugf ( ctx , fmt . Sprintf ( "RequestList for %s" , branch ) )
gPulls , err := GetPulls ( ctx , g . URL , g . Owner , g . Repository , g . Token )
if err != nil {
@@ -371,7 +383,10 @@ func (g *Gitea) RequestList(ctx context.Context, branch string) (map[string]stri
rMap := make ( map [ string ] string )
for _ , pull := range gPulls {
path = strings . Split ( pull . Title , " " ) [ 1 ] // todo Работет только для дефолтного шаблона
if ! strings . HasPrefix ( pull . Title , "Bump " ) { //добавляем только реквесты бота по обновлению модулей
continue
}
path = strings . Split ( pull . Title , " " ) [ 1 ] //todo Работет только для дефолтного шаблона
rMap [ path ] = pull . Title
}
@@ -388,7 +403,7 @@ func getVersions(s string) string {
func DeleteBranch ( ctx context . Context , url , owner , repo , branch , token string ) ( * http . Request , error ) {
var buf [ ] byte
req , err := http . NewRequestWithContext ( ctx , http . MethodDelete , fmt . Sprintf ( "%s /repos/%s/%s/branches/%s?token=%s" , url , owner , repo , branch , token ) , bytes . NewReader ( buf ) )
req , err := http . NewRequestWithContext ( ctx , http . MethodDelete , fmt . Sprintf ( "https://%s/api/v1 /repos/%s/%s/branches/%s?token=%s" , url , owner , repo , branch , token ) , bytes . NewReader ( buf ) )
if err != nil {
return nil , err
}
@@ -398,39 +413,48 @@ func DeleteBranch(ctx context.Context, url, owner, repo, branch, token string) (
}
func GetPulls ( ctx context . Context , url , owner , repo , token string ) ( [ ] * giteaPull , error ) {
var pulls [ ] * giteaPull
var err error
var pullsAll , pulls [ ] * giteaPull
page := 1
req , err := http . NewRequestWithContext (
ctx ,
http . MethodGet ,
fmt . Sprintf ( "%s/repos/%s/%s/pulls?state=open&token=%s" , url , owner , repo , token ) ,
nil )
if err != nil {
return nil , err
} // вроде запроса к репозиторию
for {
req , err := http . NewRequestWithContext (
ctx ,
http . MethodGet ,
fmt . Sprintf ( "https://%s/api/v1//repos/%s/%s/pulls?state=open&page=%v&token=%s" , url , owner , repo , page , token ) ,
nil )
if err != nil {
return nil , err
} //вроде запроса к репозиторию
req . Header . Add ( "Accept" , "application/json" )
req . Header . Add ( "Content-Type" , "application/json" )
req . Header . Add ( "Accept" , "application/json" )
req . Header . Add ( "Content-Type" , "application/json" )
rsp , err := http . DefaultClient . Do ( req ) // выполнение запроса
if err != nil {
return nil , err
}
buf , _ := io . ReadAll ( rsp . Body )
switch rsp . StatusCode {
case http . StatusOK :
if err = json . Unmarshal ( buf , & pulls ) ; err != nil {
logger . Error ( ctx , fmt . Sprintf ( "failed to decode response %s err: %v" , buf , err ) )
rsp , err := http . DefaultClient . Do ( req ) // выполнение запроса
if err != nil {
return nil , err
}
return pulls , nil
case http . StatusNotFound :
logger . Info ( ctx , "PL is not exist for %s" , repo )
return nil , ErrPRNotExist
default :
return nil , fmt . Errorf ( "unknown error: %s" , buf )
buf , _ := io . ReadAll ( rsp . Body )
switch rsp . StatusCode {
case http . StatusOK :
if err = json . Unmarshal ( buf , & pulls ) ; err != nil {
logger . Error ( ctx , fmt . Sprintf ( "failed to decode response %s err: %v" , buf , err ) )
return nil , err
}
pullsAll = append ( pullsAll , pulls ... )
page ++
case http . StatusNotFound :
logger . Info ( ctx , "PL is not exist for %s" , repo )
return nil , ErrPRNotExist
default :
return nil , fmt . Errorf ( "unknown error: %s" , buf )
}
if len ( pulls ) == 0 {
break
}
}
return pullsAll , nil
}