diff --git a/bots-common/git_utils.go b/bots-common/git_utils.go index 0e25434..facff90 100644 --- a/bots-common/git_utils.go +++ b/bots-common/git_utils.go @@ -303,7 +303,8 @@ func parseGitMsg(data <-chan byte) (gitMsg, error) { id = id[:pos] pos = 0 - for c := <-data; c != ' '; c = <-data { + var c byte + for c = <-data; c != ' ' && c != '\x00'; c = <-data { if c >= 'a' && c <= 'z' { msgType[pos] = c pos++ @@ -314,13 +315,22 @@ func parseGitMsg(data <-chan byte) (gitMsg, error) { msgType = msgType[:pos] switch string(msgType) { - case "commit", "tree": + case "commit", "tree", "blob": break + case "missing": + if c != '\x00' { + return gitMsg{}, fmt.Errorf("Missing format weird") + } + return gitMsg{ + hash: string(id[:]), + itemType: "missing", + size: 0, + }, fmt.Errorf("Object not found: '%s'", string(id)) default: return gitMsg{}, fmt.Errorf("Invalid object type: '%s'", string(msgType)) } - for c := <-data; c != '\000'; c = <-data { + for c = <-data; c != '\000'; c = <-data { if c >= '0' && c <= '9' { size = size*10 + (int(c) - '0') } else { @@ -357,6 +367,12 @@ func parseGitCommitMsg(data <-chan byte, l int) (string, error) { for c := <-data; c != '\x00'; c = <-data { msg = append(msg, c) + l-- + } +// l-- + + if l != 0 { + return "", fmt.Errorf("Unexpected data in the git commit msg: l=%d", l) } return string(msg), nil @@ -434,7 +450,8 @@ func parseGitTree(data <-chan byte) (tree, error) { // max capacity to length of hash t := tree{items: make([]tree_entry, 0, hdr.size/len(hdr.hash))} - for parsedLen := 0; parsedLen+1 < hdr.size; { + parsedLen := 0 + for parsedLen < hdr.size { entry, err := parseTreeEntry(data, len(hdr.hash)/2) if err != nil { return tree{}, nil @@ -443,10 +460,103 @@ func parseGitTree(data <-chan byte) (tree, error) { t.items = append(t.items, entry) parsedLen += entry.size } + c := <-data // \0 read + + if c != '\x00' { + return t, fmt.Errorf("Unexpected character during git tree data read") + } + + if parsedLen != hdr.size { + return t, fmt.Errorf("Invalid size of git tree data") + } return t, nil } +func parseGitBlob(data <-chan byte) ([]byte, error) { + hdr, err := parseGitMsg(data) + if err != nil { + return []byte{}, err + } + + d := make([]byte, hdr.size) + for l:=0; l 1720709149 +0200 @@ -115,7 +115,7 @@ committer Adam Majer 1720709149 +0200 }) t.Run("parse multiline headers", func(t *testing.T) { - const commitData = "cae5831ab48470ff060a5aaa12eb6e5a7acaf91e commit 1492\x00" + + const commitData = "cae5831ab48470ff060a5aaa12eb6e5a7acaf91e commit 1491\x00" + `tree 1f9c8fe8099615d6d3921528402ac53f09213b02 parent e08a654fae0ecc91678819e0b62a2e014bad3339 author Yagiz Nizipli 1720967314 -0400 @@ -253,4 +253,22 @@ func TestCommitTreeParsingOfHead(t *testing.T) { t.Errorf("hash doesn't match: %s vs. expected %s", id, nodejs21) } }) + + t.Run("reads README.md", func (t *testing.T) { + h := RequestHandler{ + GitPath: gitDir, + Logger: CreateTestLogger(t), + } + data := h.GitCatFile("", commitId, "README.md") + if h.HasError() { + t.Errorf("failed parse: %v", h.Error) + } + if string(data) != "foo\n" || len(data) != 4 { + t.Errorf("Wrong data of len: %d", len(data)) + } + }) + + t.Run("try to parse unknown item", func(t *testing.T) { + }) } + diff --git a/bots-common/tsetup.sh b/bots-common/tsetup.sh index 9085500..0754504 100755 --- a/bots-common/tsetup.sh +++ b/bots-common/tsetup.sh @@ -1,8 +1,12 @@ #!/usr/bin/bash git init -q --bare --object-format=sha256 + +# 81aba862107f1e2f5312e165453955485f424612f313d6c2fb1b31fef9f82a14 blobA=$(echo "help" | git hash-object --stdin -w) +# 47d6aca82756ff2e61e53520bfdf1faa6c86d933be4854eb34840c57d12e0c85 blobB=$(echo "foo" | git hash-object --stdin -w) + tree=$(printf "100644 blob $blobA help\n100644 blob $blobB README.md\n160000 commit dc55b828328c8e494f67874a7d8c03dd1c6b4e02d16b86e08e47d70ecd799680 mingw32-gcc\n160000 commit d6a74c08406ce40cc8f7bff2d5cf309087a8728361cc75354b0862ba508193b8 nodejs-common\n160000 commit c678c57007d496a98bec668ae38f2c26a695f94af78012f15d044ccf066ccb41 nodejs21\n160000 commit 873a323b262ebb3bd77b2592b2e11bdd08dbc721cbf4ac9f97637e58e1fffce7 nodejs22\n160000 commit 35c702e8501eedeb5ce43d6f3460d11c791cfefaa77248f08cad55d00c37e73a python311\n"|git mktree) commit=$(git commit-tree -m 'OK' $tree) git reset --soft $commit diff --git a/obs-staging-bot/main.go b/obs-staging-bot/main.go index 57a481f..5dfe5ea 100644 --- a/obs-staging-bot/main.go +++ b/obs-staging-bot/main.go @@ -45,6 +45,16 @@ func fetchPrGit(h *common.RequestHandler, pr *models.PullRequest) error { return h.Error } +func getObsProjectAssociatedWithPr(baseProject string, pr *models.PullRequest) string { + return fmt.Sprintf( + "%s:%s:%s:PR:%d", + baseProject, + common.ObsSafeProjectName(pr.Base.Repo.Owner.UserName), + common.ObsSafeProjectName(pr.Base.Repo.Name), + pr.Index, + ) +} + func processPullNotification(h *common.RequestHandler, notification *models.NotificationSubject) { rx := regexp.MustCompile(`^https://src\.(?:open)?suse\.(?:org|de)/api/v\d+/repos/(?[a-zA-Z0-9]+)/(?[_a-zA-Z0-9]+)/issues/(?[0-9]+)$`) match := rx.FindStringSubmatch(notification.URL) @@ -104,38 +114,40 @@ func processPullNotification(h *common.RequestHandler, notification *models.Noti continue } - err := fetchPrGit(h, pr) - if err != nil { - h.LogError("Cannot fetch PR git: %s", pr.URL) - return - } - - dir := pr.Head.Sha - headSubmodules := h.GitSubmoduleList(dir, pr.Head.Sha) - baseSubmodules := h.GitSubmoduleList(dir, pr.Base.Sha) - - modifiedOrNew := make([]string, 0, 16) - for pkg, headOid := range headSubmodules { - if baseOid, exists := baseSubmodules[pkg]; !exists || baseOid != headOid { - modifiedOrNew = append(modifiedOrNew, pkg) - } - } - - // find modified submodules and new submodules -- build them - h.Log("processing state...") switch review.State { // create build project, if doesn't exist, and add it to pending requests case common.ReviewStateUnknown, common.ReviewStateRequestReview: - h.Log("repo content fetching ...") - buildPrjBytes, err := h.GetPullRequestFileContent(pr, "project.build") + err := fetchPrGit(h, pr) if err != nil { - h.LogPlainError(err) + h.LogError("Cannot fetch PR git: %s", pr.URL) + return + } + + // find modified submodules and new submodules -- build them + dir := pr.Head.Sha + headSubmodules := h.GitSubmoduleList(dir, pr.Head.Sha) + baseSubmodules := h.GitSubmoduleList(dir, pr.Base.Sha) + + modifiedOrNew := make([]string, 0, 16) + for pkg, headOid := range headSubmodules { + if baseOid, exists := baseSubmodules[pkg]; !exists || baseOid != headOid { + modifiedOrNew = append(modifiedOrNew, pkg) + } + } + + h.Log("repo content fetching ...") + buildPrjBytes := h.GitCatFile(dir, pr.Head.Sha, "project.build") +// buildPrjBytes, err := h.GetPullRequestFileContent(pr, "project.build") + if h.HasError() { + h.LogPlainError(h.Error) + /* _, err := h.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project") if err != nil { h.LogPlainError(err) } +*/ return } @@ -150,12 +162,7 @@ func processPullNotification(h *common.RequestHandler, notification *models.Noti // disable publishing // TODO: escape things here - meta.Name = fmt.Sprintf("%s:%s:%s:PR:%d", - obsClient.HomeProject, - common.ObsSafeProjectName(pr.Base.Repo.Owner.UserName), - common.ObsSafeProjectName(pr.Base.Repo.Name), - pr.Index, - ) + meta.Name = getObsProjectAssociatedWithPr(obsClient.HomeProject, pr) meta.Description = fmt.Sprintf(`Pull request build job: %s%s PR#%d`, "https://src.opensuse.org", pr.Base.Repo.Name, pr.Index) urlPkg := make([]string, 0, len(modifiedOrNew)) @@ -185,12 +192,14 @@ func processPullNotification(h *common.RequestHandler, notification *models.Noti // set the review state to pending case common.ReviewStatePending: - // waiting for build results + // waiting for build results +// project := getObsProjectAssociatedWithPr(obsClient.HomeProject, pr) case common.ReviewStateApproved: - // done, mark notification as read + // done, mark notification as read + h.Log("processing request for success build ...") case common.ReviewStateRequestChanges: - h.Log("processing request for failed request changes...") // build failures, nothing to do here, mark notification as read + h.Log("processing request for failed request changes...") } break