Files
autogits/common/utils.go
Adam Majer 0e06ba5993 common: classifying rm branches on name
Branches with suffixes

  -rm
  -removed
  -deleted

are now classified as removed. This is important in case project
config refers to default branch names which must exist so we need
to be able to classify such branches to either use them or ignore
them
2025-11-04 18:00:21 +01:00

212 lines
4.8 KiB
Go

package common
/*
* This file is part of Autogits.
*
* Copyright © 2024 SUSE LLC
*
* Autogits is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 2 of the License, or (at your option) any later
* version.
*
* Autogits is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"bufio"
"errors"
"fmt"
"net/http"
"net/url"
"regexp"
"slices"
"strings"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
func SplitLines(str string) []string {
return SplitStringNoEmpty(str, "\n")
}
func SplitStringNoEmpty(str, sep string) []string {
ret := slices.DeleteFunc(strings.Split(str, sep), func(s string) bool {
return len(strings.TrimSpace(s)) == 0
})
for i := range ret {
ret[i] = strings.TrimSpace(ret[i])
}
return ret
}
func TranslateHttpsToSshUrl(url string) (string, error) {
const (
url1 = "https://src.opensuse.org/"
url2 = "https://src.suse.de/"
url1_len = len(url1)
url2_len = len(url2)
)
if len(url) > 10 && (url[0:10] == "gitea@src." || url[0:10] == "ssh://gite") {
return url, nil
}
if len(url) > url1_len && url[0:url1_len] == url1 {
return "ssh://gitea@src.opensuse.org/" + url[url1_len:], nil
}
if len(url) > url2_len && url[0:url2_len] == url2 {
return "ssh://gitea@src.suse.de/" + url[url2_len:], nil
}
return "", fmt.Errorf("Unknown input url %s", url)
}
func TranslateSshNativeToUrl(urlString string) (string, error) {
rx := regexp.MustCompile("^([^:@]+)@?([^:]*):(.+)$")
m := rx.FindAllStringSubmatch(urlString, -1)
if m == nil {
return "", fmt.Errorf("Cannot match expected native SSH schema: %s", urlString)
}
if len(m[0][2]) > 0 {
// with user
return "ssh://" + m[0][1] + "@" + m[0][2] + "/" + m[0][3], nil
}
// without user
return "ssh://" + m[0][1] + "/" + m[0][3], nil
}
type GitUrl struct {
Org string
Repo string
Commit string
}
var valid_schemas []string = []string{"https", "ssh", "http", "file"}
func ParseGitRemoteUrl(urlString string) (*GitUrl, error) {
url, err := url.Parse(urlString)
if url != nil && url.Scheme == "file" && err == nil {
return nil, nil
}
if err != nil || !slices.Contains(valid_schemas, url.Scheme) {
u, err := TranslateSshNativeToUrl(urlString)
if err != nil {
return nil, fmt.Errorf("Unable to parse url: %w", err)
}
return ParseGitRemoteUrl(u)
}
e := SplitStringNoEmpty(url.Path, "/")
if len(e) != 2 {
return nil, fmt.Errorf("Unexpected format for Gitea URL: %s", e)
}
org := e[0]
repo := strings.TrimSuffix(e[1], ".git")
u := GitUrl{
Org: org,
Repo: repo,
Commit: url.Fragment,
}
return &u, nil
}
func (giturl *GitUrl) RemoteName() string {
if giturl == nil || len(giturl.Org) == 0 || len(giturl.Repo) == 0 {
return "origin"
}
return strings.ToLower(giturl.Org) + "_" + strings.ToLower(giturl.Repo)
}
func PRtoString(pr *models.PullRequest) string {
if pr == nil {
return "(null)"
}
return fmt.Sprintf("%s/%s!%d", pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Index)
}
type DevelProject struct {
Project, Package string
}
type DevelProjects []*DevelProject
func FetchDevelProjects() (DevelProjects, error) {
res, err := http.Get("https://src.opensuse.org/openSUSE/Factory/raw/branch/main/pkgs/_meta/devel_packages")
if err != nil {
return nil, err
}
defer res.Body.Close()
scanner := bufio.NewScanner(res.Body)
ret := []*DevelProject{}
for scanner.Scan() {
d := SplitStringNoEmpty(scanner.Text(), " ")
if len(d) == 2 {
ret = append(ret, &DevelProject{
Project: d[1],
Package: d[0],
})
}
}
return ret, nil
}
var DevelProjectNotFound = errors.New("Devel project not found")
func (d DevelProjects) GetDevelProject(pkg string) (string, error) {
for _, item := range d {
if item.Package == pkg {
return item.Project, nil
}
}
return "", DevelProjectNotFound
}
var removedBranchNameSuffixes []string = []string{
"-rm",
"-removed",
"-deleted",
}
func findRemovedBranchSuffix(branchName string) string {
branchName = strings.ToLower(branchName)
for _, suffix := range removedBranchNameSuffixes {
if len(suffix) < len(branchName) && strings.HasSuffix(branchName, suffix) {
return suffix
}
}
return ""
}
func IsRemovedBranch(branchName string) bool {
return len(findRemovedBranchSuffix(branchName)) > 0
}
func TrimRemovedBranchSuffix(branchName string) string {
suffix := findRemovedBranchSuffix(branchName)
if len(suffix) > 0 {
return branchName[0 : len(branchName)-len(suffix)]
}
return branchName
}