package trunk import ( "fmt" "strings" "git.novox.be/novox/mesh-sdk/go/keys" ) // RepositoryName is the repository as the forge names it, "owner/name", from either spelling the mesh holds: the name // itself, or the clone URL a build record carries ("http://host:port/owner/name.git", with or without ".git" or a // trailing slash). A string of fewer than two path segments is returned as it is, trimmed (issue 1281). func RepositoryName(s string) string { s = strings.TrimSpace(s) s = strings.TrimRight(s, "/") s = strings.TrimSuffix(s, ".git") s = strings.TrimRight(s, "/") parts := strings.FieldsFunc(s, func(r rune) bool { return r == '/' || r == ':' }) if len(parts) < 2 { return s } return parts[len(parts)-2] + "/" + parts[len(parts)-1] } // SameRepository is whether two spellings name one repository: the same owner and name, whichever way each is written // (RepositoryName), compared without regard to case as the forge does. An empty spelling names none (issue 1281). func SameRepository(a, b string) bool { a, b = RepositoryName(a), RepositoryName(b) return a != "" && strings.EqualFold(a, b) } // RepositoryKey is a repository's key in the indexer's state `taken` and the view's state `reach`: its forge name `owner/name` (RepositoryName), in // lower case as the forge compares it, escaped as a key part (keys.EscapeName). An empty spelling, or one with no owner, is // refused. func RepositoryKey(repository string) (string, error) { name := strings.ToLower(RepositoryName(repository)) if owner, repo, ok := strings.Cut(name, "/"); !ok || owner == "" || repo == "" { return "", fmt.Errorf("trunk: %q names no repository as owner/name", repository) } return keys.EscapeName(name), nil }