diff --git a/README.md b/README.md index 5eedd73..757ad16 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,18 @@ The bots that drive Git Workflow for package management * devel-importer -- helper to import an OBS devel project into a Gitea organization * gitea-events-rabbitmq-publisher -- takes all events from a Gitea organization (webhook) and publishes it on a RabbitMQ instance - * maintainer-bot -- review bot to make sure maintainer signed off + * maintainer-and-policy-bot -- review bot to make sure maintainer signed off on reviews, along with necessary other entities * obs-staging-bot -- build bot for a PR * obs-status-service -- report build status of an OBS project as an SVG * pr-review -- keeps PR to _ObsPrj consistent with a PR to a package update * prjgit-updater -- update _ObsPrj based on direct pushes and repo creations/removals from organization - + * staging-utils -- review tooling for PR + - list PR + - merge PR + - split PR + - diff PR + - accept/reject PR + * random -- random utils and tools Bugs ---- diff --git a/bots-common/git_utils.go b/bots-common/git_utils.go index c01ddb7..7de381b 100644 --- a/bots-common/git_utils.go +++ b/bots-common/git_utils.go @@ -126,13 +126,13 @@ func (e *RequestHandler) GitBranchHead(gitDir, branchName string) (string, error path, err := findGitDir(path.Join(e.GitPath, gitDir)) if err != nil { - e.LogError("Error identifying gitdir in `%s`: %#v", gitDir, err) + e.ErrLogger.Printf("Error identifying gitdir in `%s`: %v\n", gitDir, err) e.Error = err } refs, err := processRefs(path) if err != nil { - e.LogError("Error finding branches (%s): %#v", branchName, err) + e.ErrLogger.Printf("Error finding branches (%s): %v\n", branchName, err) e.Error = err return "", e.Error } @@ -144,7 +144,7 @@ func (e *RequestHandler) GitBranchHead(gitDir, branchName string) (string, error } e.Error = fmt.Errorf("Can't find default remote branch: %s", branchName) - e.LogError("%s", e.Error.Error()) + e.ErrLogger.Println(e.Error.Error()) return "", e.Error } @@ -201,16 +201,16 @@ func (e *RequestHandler) GitExec(cwd string, params ...string) ExecStream { } cmd.Dir = filepath.Join(e.GitPath, cwd) cmd.Stdout = writeFunc(func(data []byte) (int, error) { - e.Logger.Log("%s", data) + e.StdLogger.Println(data) return len(data), nil }) cmd.Stderr = writeFunc(func(data []byte) (int, error) { - e.Logger.LogError("%s", data) + e.ErrLogger.Println(data) return len(data), nil }) cmd.Stdin = nil - e.Log("git execute: %#v", cmd.Args) + e.StdLogger.Printf("git execute: %#v\n", cmd.Args) e.Error = cmd.Run() return e @@ -508,7 +508,7 @@ func (e *RequestHandler) GitCatFile(cwd, commitId, filename string) []byte { c, err := parseGitCommit(data_in.ch) if err != nil { e.Error = err - e.LogError("Error parsing git commit: %v", err) + e.ErrLogger.Printf("Error parsing git commit: %v\n", err) return } data_out.Write([]byte(c.Tree)) @@ -517,7 +517,7 @@ func (e *RequestHandler) GitCatFile(cwd, commitId, filename string) []byte { if err != nil { e.Error = err - e.LogError("Error parsing git tree: %v", err) + e.ErrLogger.Printf("Error parsing git tree: %v\n", err) return } @@ -528,14 +528,14 @@ func (e *RequestHandler) GitCatFile(cwd, commitId, filename string) []byte { data, err = parseGitBlob(data_in.ch) if err != nil { e.Error = err - e.LogError("Error reading blob data: %v", err) + e.ErrLogger.Printf("Error reading blob data: %v\n", err) } return } } e.Error = fmt.Errorf("file not found: '%s'", filename) - e.LogPlainError(e.Error) + e.ErrLogger.Println(e.Error.Error()) }() cmd := exec.Command("/usr/bin/git", "cat-file", "--batch", "-Z") @@ -547,10 +547,10 @@ func (e *RequestHandler) GitCatFile(cwd, commitId, filename string) []byte { cmd.Stdout = &data_in cmd.Stdin = &data_out cmd.Stderr = writeFunc(func(data []byte) (int, error) { - e.Logger.LogError("%s", data) + e.ErrLogger.Println(data) return len(data), nil }) - e.Log("command run: %v", cmd.Args) + e.StdLogger.Printf("command run: %v\n", cmd.Args) e.Error = cmd.Run() done.Lock() @@ -577,7 +577,7 @@ func (e *RequestHandler) GitSubmoduleList(cwd, commitId string) map[string]strin c, err := parseGitCommit(data_in.ch) if err != nil { e.Error = err - e.LogError("Error parsing git commit: %v", err) + e.ErrLogger.Printf("Error parsing git commit: %v\n", err) return } data_out.Write([]byte(c.Tree)) @@ -586,7 +586,7 @@ func (e *RequestHandler) GitSubmoduleList(cwd, commitId string) map[string]strin if err != nil { e.Error = err - e.LogError("Error parsing git tree: %v", err) + e.ErrLogger.Printf("Error parsing git tree: %v\n", err) return } @@ -606,10 +606,10 @@ func (e *RequestHandler) GitSubmoduleList(cwd, commitId string) map[string]strin cmd.Stdout = &data_in cmd.Stdin = &data_out cmd.Stderr = writeFunc(func(data []byte) (int, error) { - e.Logger.LogError("%s", data) + e.ErrLogger.Println(data) return len(data), nil }) - e.Log("command run: %v", cmd.Args) + e.StdLogger.Printf("command run: %v\n", cmd.Args) e.Error = cmd.Run() done.Lock() @@ -627,7 +627,7 @@ func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, commitId string) foundLock.Lock() - e.Log("getting commit id '%s' from git at '%s' with packageName: %s", commitId, cwd, packageName) + e.StdLogger.Printf("getting commit id '%s' from git at '%s' with packageName: %s\n", commitId, cwd, packageName) go func() { defer foundLock.Unlock() @@ -638,7 +638,7 @@ func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, commitId string) c, err := parseGitCommit(data_in.ch) if err != nil { e.Error = err - e.LogError("Error parsing git commit: %v", err) + e.ErrLogger.Printf("Error parsing git commit: %v\n", err) return } data_out.Write([]byte(c.Tree)) @@ -647,7 +647,7 @@ func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, commitId string) if err != nil { e.Error = err - e.LogError("Error parsing git tree: %v", err) + e.ErrLogger.Printf("Error parsing git tree: %v\n", err) return } @@ -668,10 +668,10 @@ func (e *RequestHandler) GitSubmoduleCommitId(cwd, packageName, commitId string) cmd.Stdout = &data_in cmd.Stdin = &data_out cmd.Stderr = writeFunc(func(data []byte) (int, error) { - e.Logger.LogError("%s", data) + e.ErrLogger.Println(data) return len(data), nil }) - e.Log("command run: %v", cmd.Args) + e.StdLogger.Printf("command run: %v\n", cmd.Args) e.Error = cmd.Run() foundLock.Lock() diff --git a/bots-common/git_utils_test.go b/bots-common/git_utils_test.go index 6627e06..de754ec 100644 --- a/bots-common/git_utils_test.go +++ b/bots-common/git_utils_test.go @@ -241,9 +241,11 @@ func TestCommitTreeParsingOfHead(t *testing.T) { t.Run("reads HEAD and parses the tree", func(t *testing.T) { const nodejs21 = "c678c57007d496a98bec668ae38f2c26a695f94af78012f15d044ccf066ccb41" + stdLogger, errLogger:= CreateStdoutLogger(os.Stdout, os.Stdout) h := RequestHandler{ GitPath: gitDir, - Logger: CreateTestLogger(t), + StdLogger: stdLogger, + ErrLogger: errLogger, } id, ok := h.GitSubmoduleCommitId("", "nodejs21", commitId) if !ok { @@ -255,9 +257,11 @@ func TestCommitTreeParsingOfHead(t *testing.T) { }) t.Run("reads README.md", func (t *testing.T) { + stdLogger, errLogger:= CreateStdoutLogger(os.Stdout, os.Stdout) h := RequestHandler{ GitPath: gitDir, - Logger: CreateTestLogger(t), + StdLogger: stdLogger, + ErrLogger: errLogger, } data := h.GitCatFile("", commitId, "README.md") if h.HasError() { diff --git a/bots-common/gitea_utils.go b/bots-common/gitea_utils.go index b795e2e..8486a39 100644 --- a/bots-common/gitea_utils.go +++ b/bots-common/gitea_utils.go @@ -62,7 +62,7 @@ func (h *RequestHandler) GetPullRequestAndReviews(org, project string, num int64 if err != nil { h.Error = err - h.LogPlainError(err) + h.ErrLogger.Println(err.Error()) return nil, nil, err } @@ -79,7 +79,7 @@ func (h *RequestHandler) GetPullRequestAndReviews(org, project string, num int64 if err != nil { h.Error = err - h.LogPlainError(err) + h.ErrLogger.Println(err.Error()) return nil, nil, err } @@ -133,7 +133,7 @@ func (h *RequestHandler) SetNotificationRead(notificationId int64) error { ) if err != nil { - h.LogError("Error setting notification: %d: %v", notificationId, err) + h.ErrLogger.Printf("Error setting notification: %d: %v\n", notificationId, err) h.Error = err return err } @@ -159,7 +159,7 @@ func (h *RequestHandler) CreateRepositoryIfNotExist(org Organization, repoName s if err != nil { switch err.(type) { case *repository.RepoGetNotFound: - h.Log("repo '%s' does not exist. Trying to create it ....", repoName) + h.StdLogger.Printf("repo '%s' does not exist. Trying to create it ....\n", repoName) repo, err := client.Organization.CreateOrgRepo( organization.NewCreateOrgRepoParams().WithDefaults().WithBody( @@ -175,14 +175,14 @@ func (h *RequestHandler) CreateRepositoryIfNotExist(org Organization, repoName s if err != nil { switch err.(type) { case *organization.CreateOrgRepoCreated: - h.Log("repo '%s' created, with notification error?", repoName) + h.StdLogger.Printf("repo '%s' created, with notification error?\n", repoName) default: h.Error = err - h.LogError("error creating repo '%s' under '%s': %s", repoName, org.Username, err.Error()) + h.ErrLogger.Printf("error creating repo '%s' under '%s': %s\n", repoName, org.Username, err.Error()) return nil } } else { - h.Log("repo '%s' created", repoName) + h.StdLogger.Printf("repo '%s' created\n", repoName) } // initialize repository @@ -209,7 +209,7 @@ func (h *RequestHandler) CreateRepositoryIfNotExist(org Organization, repoName s return repo.Payload default: h.Error = err - h.LogError("cannot fetch repo data for '%s' / '%s' : %w", org.Username, repoName, err) + h.ErrLogger.Printf("cannot fetch repo data for '%s' / '%s' : %v\n", org.Username, repoName, err) } } @@ -241,13 +241,13 @@ func (h *RequestHandler) CreatePullRequest(repo *models.Repository, srcId, targe ) if err != nil { - h.LogError("Cannot create pull request: %v", err) + h.ErrLogger.Printf("Cannot create pull request: %v\n", err) h.Error = err return nil } if !pr.IsSuccess() { - h.LogError("PR creation failed: %s", pr.Error()) + h.ErrLogger.Printf("PR creation failed: %s\n", pr.Error()) h.Error = errors.New(pr.Error()) return nil } @@ -277,13 +277,13 @@ func (h *RequestHandler) RequestReviews(pr *models.PullRequest, reviewer string) ) if err != nil { - h.LogError("Cannot create pull request: %v", err) + h.ErrLogger.Printf("Cannot create pull request: %v\n", err) h.Error = err return nil } if !review.IsSuccess() { - h.LogError("PR creation failed: %s", review.Error()) + h.ErrLogger.Printf("PR creation failed: %s\n", review.Error()) h.Error = errors.New(review.Error()) return nil } @@ -358,7 +358,7 @@ func (h *RequestHandler) IsReviewed(pr *models.PullRequest) (bool, error) { func (h *RequestHandler) AddReviewComment(pr *models.PullRequest, state models.ReviewStateType, comment string) (*models.PullReview, error) { transport, client := h.allocateGiteaTransport() - h.Log("%#v", *pr) + h.StdLogger.Printf("%#v", *pr) c, err := client.Repository.RepoCreatePullReview( repository.NewRepoCreatePullReviewParams(). @@ -438,7 +438,7 @@ func (h *RequestHandler) GetAssociatedPrjGitPR(pr *PullRequestAction) *models.Pu } prLine := fmt.Sprintf(PrPattern, pr.Repository.Owner.Username, pr.Repository.Name, pr.Number) - h.Log("attemping to match line: '%s'", prLine) + h.StdLogger.Printf("attemping to match line: '%s'\n", prLine) // payload_processing: for _, pr := range prs.Payload { diff --git a/bots-common/listen.go b/bots-common/listen.go index e58ef0e..b63f7b8 100644 --- a/bots-common/listen.go +++ b/bots-common/listen.go @@ -42,7 +42,7 @@ func StartServerWithAddress(listenDefs ListenDefinitions, addr string) { hdr := req.Header[GiteaRequestHeader] if len(hdr) != 1 { - h.LogError("Unsupported number of %s headers: %d: %#v\n", GiteaRequestHeader, len(hdr), hdr) + h.ErrLogger.Printf("Unsupported number of %s headers: %d: %#v\n", GiteaRequestHeader, len(hdr), hdr) h.WriteError() res.WriteHeader(http.StatusInternalServerError) return @@ -60,24 +60,24 @@ func StartServerWithAddress(listenDefs ListenDefinitions, addr string) { case RequestType_PR_sync: h.parsePullRequestSync(req.Body) default: - h.LogError("Unhandled request type: %s", reqType) + h.ErrLogger.Printf("Unhandled request type: %s\n", reqType) res.WriteHeader(http.StatusInternalServerError) return } if h.HasError() { - h.LogError("error in parser %s: %v", reqType, h.Error) + h.ErrLogger.Printf("error in parser %s: %v\n", reqType, h.Error) res.WriteHeader(http.StatusInternalServerError) return } if err := handler(h); err != nil { - h.LogError("error in handler for %s: %v", reqType, err) + h.ErrLogger.Printf("error in handler for %s: %v\n", reqType, err) res.WriteHeader(http.StatusInternalServerError) return } } else { - h.LogError("Unsupported request type: %s", reqType) + h.ErrLogger.Printf("Unsupported request type: %s\n", reqType) res.WriteHeader(http.StatusInternalServerError) return } diff --git a/bots-common/log.go b/bots-common/log.go index b84698f..3699a22 100644 --- a/bots-common/log.go +++ b/bots-common/log.go @@ -3,79 +3,16 @@ package common import ( "fmt" "io" - "time" + "log" ) -type Logger interface { - LogPlainError(err error) (int, error) - LogError(str string, fmt ...any) (int, error) - Log(str string, fmt ...any) (int, error) -} - -type StdoutLogging struct { - Id uint - Stdout, Stderr io.StringWriter - Date time.Time -} - var id uint -func CreateStdoutLogger(stdout io.StringWriter, stderr io.StringWriter) Logger { +func CreateStdoutLogger(stdout, stderr io.Writer) (*log.Logger, *log.Logger) { id++ - - log := &StdoutLogging{ - Id: id, - Stdout: stdout, - Stderr: stderr, - Date: time.Now(), - } - - return log + idStr := fmt.Sprintf("[%d] ", id) + stdLogger := log.New(stdout, idStr, log.Lmsgprefix) + errLogger := log.New(stderr, idStr, log.Lmsgprefix) + return stdLogger, errLogger } -func prepareMsg(time time.Duration, id uint, str string, params ...any) string { - var allParams []any = []any{ - id, - time.String(), - } - allParams = append(allParams, params...) - - return fmt.Sprintf("[%x] [%s]: "+str+"\n", allParams...) -} - -func (s *StdoutLogging) LogPlainError(err error) (int, error) { - return s.Stderr.WriteString(prepareMsg(time.Since(s.Date), s.Id, "%s\n", err.Error())) -} - -func (s *StdoutLogging) LogError(str string, params ...any) (int, error) { - return s.Stderr.WriteString(prepareMsg(time.Since(s.Date),s.Id, str, params...)) -} - -func (s *StdoutLogging) Log(str string, params ...any) (int, error) { - return s.Stdout.WriteString(prepareMsg(time.Since(s.Date), s.Id, str, params...)) -} - -type LoggingWriteCloser struct { - err bool - *StdoutLogging -} - -func (l *LoggingWriteCloser) Write(data []byte) (int, error) { - if l.err { - return l.LogError("%s", data) - } - - return l.Log("%s", data) -} - -func (l *LoggingWriteCloser) Close() error { - return nil -} - -func (s *StdoutLogging) CreateLogWriter(err bool) io.WriteCloser { - logger := new(LoggingWriteCloser) - logger.StdoutLogging = s - logger.err = err - - return logger -} diff --git a/bots-common/log_test.go b/bots-common/log_test.go index 76dc01b..4331a13 100644 --- a/bots-common/log_test.go +++ b/bots-common/log_test.go @@ -1,6 +1,7 @@ package common import ( + "bytes" "regexp" "testing" ) @@ -9,37 +10,33 @@ type TestWriter struct { str string } -func (s *TestWriter) WriteString(str2 string) (int, error) { - s.str += str2 - return len(s.str), nil -} - func TestLogging(t *testing.T) { t.Run("basic logging", func(t *testing.T) { - var strWriter, errWriter TestWriter + var strWriter, errWriter *bytes.Buffer - if len(strWriter.str) != 0 || len(errWriter.str) != 0 { - t.Fatal("non-null empty logging?") - } + strWriter = bytes.NewBuffer(make([]byte, 0, 10000)) + errWriter = bytes.NewBuffer(make([]byte, 0, 10000)) - logger := CreateStdoutLogger(&strWriter, &errWriter) - logger.LogError("%d", 100) - logger.Log("OKA %d Done", 77) - logger.Log("Another line") + stdLogger, errLogger := CreateStdoutLogger(strWriter, errWriter) + errLogger.Printf("%d\n", 100) + stdLogger.Printf("OKA %d Done\n", 77) + stdLogger.Println("Another line") - const prefixMatch = `\[\d+\] \[[^\]]+\]: ` + const prefixMatch = `\[\d+\]: ` - if ok, err := regexp.MatchString("^"+prefixMatch+"100\n$", errWriter.str); !ok { + err := errWriter.String() + if ok, err := regexp.MatchString("^"+prefixMatch+"100\n$", err); !ok { if err != nil { t.Logf("err: %v", err) } - t.Fatal(errWriter) + t.Fatal(err) } - if ok, err := regexp.MatchString("^"+prefixMatch+"OKA 77 Done\n"+prefixMatch+"Another line\n$", strWriter.str); !ok { + str := strWriter.String() + if ok, err := regexp.MatchString("^"+prefixMatch+"OKA 77 Done\n"+prefixMatch+"Another line\n$", str); !ok { if err != nil { t.Logf("err: %v", err) } - t.Fatal(strWriter.str) + t.Fatal(str) } }) } diff --git a/bots-common/request_handler.go b/bots-common/request_handler.go index b61e791..d18e64f 100644 --- a/bots-common/request_handler.go +++ b/bots-common/request_handler.go @@ -1,6 +1,9 @@ package common -import "os" +import ( + "log" + "os" +) type Request struct { @@ -15,29 +18,29 @@ type RequestHandler struct { GitCommiter, GitPath string Branch []string - Logger + StdLogger, ErrLogger *log.Logger Request } func (r *RequestHandler) WriteError() { - r.LogError("%s", "internal error sent") + r.ErrLogger.Println("internal error sent") } func CreateRequestHandler(git_author, name string) *RequestHandler { var h *RequestHandler = new(RequestHandler) - h.Logger = CreateStdoutLogger(os.Stdout, os.Stderr) + h.StdLogger, h.ErrLogger = CreateStdoutLogger(os.Stdout, os.Stderr) h.GitCommiter = git_author h.GitPath, h.Error = os.MkdirTemp("", name) if h.Error != nil { - h.Logger.LogError("Cannot create temp dir: %v", h.Error) + h.ErrLogger.Printf("Cannot create temp dir: %v\n", h.Error) return h } if h.Error = os.Chmod(h.GitPath, 0700); h.Error != nil { - h.Logger.LogError("Cannot fix permissions of temp dir: %v", h.Error) + h.ErrLogger.Printf("Cannot fix permissions of temp dir: %v\n", h.Error) return h } return h diff --git a/bots-common/request_pr.go b/bots-common/request_pr.go index 92b9784..374fa0f 100644 --- a/bots-common/request_pr.go +++ b/bots-common/request_pr.go @@ -43,21 +43,20 @@ func (h *RequestHandler) parsePullRequest(data io.Reader) *PullRequestAction { h.Error = json.NewDecoder(data).Decode(&action) if h.HasError() { - h.LogError("Got error while parsing: %v", h.Error) + h.ErrLogger.Printf("Got error while parsing: %v\n", h.Error) return nil } repoIdx := strings.LastIndex(action.Repository.Ssh_Url, "/") if repoIdx == -1 || action.Repository.Ssh_Url[repoIdx+1:] != action.Repository.Name+".git" { - h.LogError("Unexpected URL for SSH repository: '%s'", action.Repository.Name) - h.LogError("%#v", action) + h.ErrLogger.Printf("Unexpected URL for SSH repository: '%s'\n", action.Repository.Name) + h.ErrLogger.Printf("%#v\n", action) return nil } h.PrjGit = action.Repository.Ssh_Url[:repoIdx+1] + DefaultGitPrj + ".git" h.Data = &action // sanity checks on request - return &action } diff --git a/bots-common/request_pr_test.go b/bots-common/request_pr_test.go index 92b91fa..28257b1 100644 --- a/bots-common/request_pr_test.go +++ b/bots-common/request_pr_test.go @@ -1,6 +1,7 @@ package common import ( + "os" "strings" "testing" ) @@ -8,7 +9,7 @@ import ( func TestPrParsing(t *testing.T) { t.Run("Test parsing", func(t *testing.T) { var h RequestHandler - h.Logger = CreateTestLogger(t) + h.StdLogger, h.ErrLogger = CreateStdoutLogger(os.Stdout, os.Stdout) pr := h.parsePullRequest(strings.NewReader(samplePR_JSON)) if pr == nil { diff --git a/bots-common/request_push.go b/bots-common/request_push.go index e7d6ce2..0c5c144 100644 --- a/bots-common/request_push.go +++ b/bots-common/request_push.go @@ -30,21 +30,21 @@ func (h *RequestHandler) parsePushRequest(data io.Reader) *PushRequest { h.Error = json.NewDecoder(data).Decode(&action) if h.HasError() { - h.LogError("Got error while parsing: %v", h.Error) + h.ErrLogger.Printf("Got error while parsing: %v\n", h.Error) return nil } repoIdx := strings.LastIndex(action.Repository.Ssh_Url, "/") if repoIdx == -1 || action.Repository.Ssh_Url[repoIdx+1:] != action.Repository.Name+".git" { - h.LogError("Unexpected URL for SSH repository: '%s'", action.Repository.Name) + h.ErrLogger.Printf("Unexpected URL for SSH repository: '%s'\n", action.Repository.Name) return nil } h.PrjGit = action.Repository.Ssh_Url[:repoIdx+1] + DefaultGitPrj + ".git" - h.Log("Request push for repo: %s", action.Repository.Full_Name) + h.StdLogger.Printf("Request push for repo: %s\n", action.Repository.Full_Name) h.Data = action if len(action.Commits) < 1 || len(action.Head_Commit.Id) != 64 { - h.LogError("Request has no action .... skipping") + h.ErrLogger.Println("Request has no action .... skipping") return nil } diff --git a/bots-common/request_push_test.go b/bots-common/request_push_test.go index ad576e2..33480a8 100644 --- a/bots-common/request_push_test.go +++ b/bots-common/request_push_test.go @@ -1,41 +1,16 @@ package common import ( + "os" "strings" "testing" ) -type TestLogger struct { - t *testing.T -} - -func (s *TestLogger) Log(str string, fmt ...any) (int, error) { - s.t.Logf(str, fmt...) - return 10, nil -} - -func (s *TestLogger) LogError(str string, fmt ...any) (int, error) { - s.t.Errorf(str, fmt...) - return 10, nil -} - -func (s *TestLogger) LogPlainError(err error) (int, error) { - s.t.Error(err) - return 10, nil -} - -func CreateTestLogger(t *testing.T) Logger { - var logger TestLogger - - logger.t = t - return &logger -} - func TestPushRequestParsing(t *testing.T) { t.Run("parsing repo creation message", func(t *testing.T) { var h RequestHandler - h.Logger = CreateTestLogger(t) + h.StdLogger, h.ErrLogger = CreateStdoutLogger(os.Stdout, os.Stdout) json := h.parsePushRequest(strings.NewReader(examplePushJSON)) if json == nil { t.Fatalf("failed to parser push request: %v", h.Error) diff --git a/bots-common/request_repo.go b/bots-common/request_repo.go index dc8ee47..39c91c0 100644 --- a/bots-common/request_repo.go +++ b/bots-common/request_repo.go @@ -57,16 +57,16 @@ func (h *RequestHandler) parseRepositoryRequest(dataReader io.Reader) *Repositor repoIdx := strings.LastIndex(data.Repository.Ssh_Url, "/") if repoIdx == -1 || data.Repository.Ssh_Url[repoIdx+1:] != data.Repository.Name+".git" { h.Error = fmt.Errorf("No data, skipping") - h.LogError("Unexpected URL for SSH repository: %s", data.Repository.Name) + h.ErrLogger.Printf("Unexpected URL for SSH repository: %s\n", data.Repository.Name) return nil } data.PrjGit = data.Repository.Ssh_Url[:repoIdx+1] + DefaultGitPrj + ".git" - h.Log("Request '%s' for repo: %s", data.Action, data.Repository.Full_Name) + h.StdLogger.Printf("Request '%s' for repo: %s\n", data.Action, data.Repository.Full_Name) if len(data.Action) < 1 { h.Error = fmt.Errorf("No data, skipping") - h.LogError("Request has no data.... skipping") + h.ErrLogger.Println("Request has no data.... skipping") } h.Data = data diff --git a/bots-common/request_repo_test.go b/bots-common/request_repo_test.go index 435884a..484f52e 100644 --- a/bots-common/request_repo_test.go +++ b/bots-common/request_repo_test.go @@ -1,6 +1,7 @@ package common import ( + "os" "strings" "testing" ) @@ -17,10 +18,9 @@ func (s *testLogger) WriteString(str2 string) (int, error) { func TestRepositoryRequestParsing(t *testing.T) { t.Run("parsing repo creation message", func(t *testing.T) { - var strStr, errStr testLogger var h RequestHandler - h.Logger = CreateStdoutLogger(&strStr, &errStr) + h.StdLogger, h.ErrLogger = CreateStdoutLogger(os.Stdout, os.Stdout) json := h.parseRepositoryRequest(strings.NewReader(repoCreateJSON)) if h.HasError() { t.Fatalf("Can't parse struct: %s", h.Error) diff --git a/gitea-events-rabbitmq-publisher/main.go b/gitea-events-rabbitmq-publisher/main.go index 9f6026e..ef5551c 100644 --- a/gitea-events-rabbitmq-publisher/main.go +++ b/gitea-events-rabbitmq-publisher/main.go @@ -1,8 +1,10 @@ package main import ( + "encoding/json" "flag" "fmt" + "io" "log" "net/http" "os" @@ -39,6 +41,65 @@ func main() { connectToRabbitMQ() + connectionId := 1 + + http.HandleFunc("POST /test", func(res http.ResponseWriter, req *http.Request) { + if len(req.Header.Get("Content-Type")) == 0 || + req.Header["Content-Type"][0] != "application/json" || + req.Method != "POST" { + + res.WriteHeader(http.StatusInternalServerError) + return + } + + hdr := req.Header[common.GiteaRequestHeader] + if len(hdr) != 1 { + res.WriteHeader(http.StatusInternalServerError) + log.Printf("Multiple Gitea headers received. %#v\n", hdr) + if DebugMode { + log.Println(req.Header) + } + return + } + // reqType := hdr[0] + data, err := io.ReadAll(req.Body) + if err != nil { + errorStr := fmt.Sprintf("error reading hook info: %v", err) + res.Header().Add("Content-Type", "plain/text") + res.Write([]byte(errorStr)) + res.WriteHeader(http.StatusBadRequest) + + if DebugMode { + log.Printf(errorStr) + } + } + + if !json.Valid(data) { + if DebugMode { + log.Println("send invalid json request") + } + res.WriteHeader(http.StatusBadRequest) + } + + // write to file for review + os.WriteFile("test_data."+fmt.Sprint(connectionId), data, 0644) + + /* + err = PublishMessage(reqType, req.PathValue("Org"), data) + if err != nil { + errorStr := fmt.Sprintf("hook (%s) processing error: %v\n", reqType, err) + res.Header().Add("Content-Type", "plain/text") + res.Write([]byte(errorStr)) + res.WriteHeader(http.StatusBadRequest) + + if DebugMode { + log.Println(errorStr) + } + } else {*/ + res.WriteHeader(http.StatusOK) + // } + }) + http.HandleFunc("POST /rabbitmq-forwarder/{Org}", func(res http.ResponseWriter, req *http.Request) { if len(req.Header.Get("Content-Type")) == 0 || req.Header["Content-Type"][0] != "application/json" || @@ -58,7 +119,19 @@ func main() { return } reqType := hdr[0] - err := PublishMessage(reqType, req.PathValue("Org"), req.Body) + data, err := io.ReadAll(req.Body) + if err != nil { + errorStr := fmt.Sprintf("error reading hook info: %v", err) + res.Header().Add("Content-Type", "plain/text") + res.Write([]byte(errorStr)) + res.WriteHeader(http.StatusBadRequest) + + if DebugMode { + log.Printf(errorStr) + } + } + + err = PublishMessage(req.PathValue("Org"), reqType, data) if err != nil { errorStr := fmt.Sprintf("hook (%s) processing error: %v\n", reqType, err) res.Header().Add("Content-Type", "plain/text") diff --git a/gitea-events-rabbitmq-publisher/rabbitmq.go b/gitea-events-rabbitmq-publisher/rabbitmq.go index 0ea5a0c..c7146a4 100644 --- a/gitea-events-rabbitmq-publisher/rabbitmq.go +++ b/gitea-events-rabbitmq-publisher/rabbitmq.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "io" "log" "time" @@ -26,32 +25,44 @@ type Message struct { var messageQueue chan Message -func PublishMessage(giteaWebhookType, giteaOrg string, msgBody io.Reader) error { +func PublicActionMessage(giteaOrg, giteaWebhookType, action string, data []byte) error { if messageQueue == nil { return fmt.Errorf("Queue not initialized") } - data, err := io.ReadAll(msgBody) - if err != nil { - return fmt.Errorf("Error reading JSON data. Err: %v", err) - } - if !json.Valid(data) { return errors.New("Invalid JSON in request") } - select { - case messageQueue <- Message{ - Topic: fmt.Sprintf("opensuse.gitea.%s.%s", giteaOrg, giteaWebhookType), - Body: data, - }: + var msg Message + if len(action) > 0 { + msg = Message{ + Topic: fmt.Sprintf("opensuse.gitea.%s.%s.%s", giteaOrg, giteaWebhookType, action), + Body: data, + } + } else { + msg = Message{ + Topic: fmt.Sprintf("opensuse.gitea.%s.%s", giteaOrg, giteaWebhookType), + Body: data, + } + } + if len(action) > 0 { + msg.Topic = msg.Topic + "." + action + } + + select { + case messageQueue <- msg: default: return errors.New("Enable to queue message. Possibly queue full.") } return nil } +func PublishMessage(giteaWebhookType, giteaOrg string, data []byte) error { + return PublicActionMessage(giteaOrg, giteaWebhookType, "", data) +} + func ConnectToExchangeForPublish(host, username, password string) { defer func() { if r := recover(); r != nil {