blob: 8d5fd5b6d4213bbadaf29c2ee4aba45f9feb482d [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package gerrit
import (
"fmt"
"net/url"
"strconv"
"strings"
"go.chromium.org/luci/common/api/gerrit"
)
const (
fuchsiaReviewHost = "fuchsia-review.googlesource.com/"
turquoiseInternalReviewHost = "turquoise-internal-review.googlesource.com/"
)
var prefixes = []string{
"https://",
"http://",
"go/",
}
var shortLinkMap = map[string]string{
"fxrev.dev/": fuchsiaReviewHost,
"fxr/": fuchsiaReviewHost,
"tqr/": turquoiseInternalReviewHost,
}
// ResolveChangeUrl resolves common change URLs for fuchsia hosts,
// returning a canonical gerrit host and change ID.
//
// Note: only supports numeric change IDs, and does not support
// deprecated change IDs.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
// In practice however, deprecated change IDs are very unlikely to be
// used as inputs.
//
// Examples:
//
// fxr/<change_id>
// -> fuchsia-review.googlesource.com, <change_id>
// tqr/<change_id>
// -> turquoise-internal-review.googlesource.com, <change_id>
// go/fxr/<change_id>
// -> fuchsia-review.googlesource.com, <change_id>
// go/tqr/<change_id>
// -> turquoise-internal-review.googlesource.com, <change_id>
// http://go/fxr/<change_id>
// -> fuchsia-review.googlesource.com, <change_id>
// fxrev.dev/<change_id>
// -> fuchsia-review.googlesource.com, <change_id>
// https://fxrev.dev/<change_id>
// -> fuchsia-review.googlesource.com, <change_id>
// http://go/tqr/<change_id>
// -> turquoise-internal-review.googlesource.com, <change_id>
// https://fuchsia-review.googlesource.com/<change_id>
// -> fuchsia-review.googlesource.com, <change_id>
// https://fuchsia-review.googlesource.com/<change_id>/
// -> fuchsia-review.googlesource.com, <change_id>
// https://turquoise-internal-review.googlesource.com/<change_id>
// -> turquoise-internal-review.googlesource.com, <change_id>
// https://fuchsia-review.googlesource.com/c/<project>/+/<change_id>
// -> fuchsia-review.googlesource.com, <change_id>
// https://turquoise-internal-review.googlesource.com/c/<project>/+/<change_id>
// -> turquoise-internal-review.googlesource.com, <change_id>
// https://turquoise-internal-review.git.corp.google.com/c/<project>/+/<change_id>
// -> turquoise-internal-review.googlesource.com, <change_id>
func ResolveChangeUrl(changeUrl *url.URL) (host string, changeId int64, err error) {
host, changeId, err = "", 0, nil
change := changeUrl.String()
// Replace corp with googlesource.
change = strings.Replace(change, ".git.corp.google.com", ".googlesource.com", 1)
// Trim prefixes in order.
for _, prefix := range prefixes {
if strings.HasPrefix(change, prefix) {
change = strings.TrimPrefix(change, prefix)
}
}
// Map short-link to full host.
for k, v := range shortLinkMap {
if strings.HasPrefix(change, k) {
change = strings.Replace(change, k, v, 1)
break
}
}
// Trim trailing slash.
change = strings.TrimSuffix(change, "/")
// Split by slash and take the first and last elements, ignoring anything in-between.
// This should be the host and change ID.
sp := strings.Split(change, "/")
if len(sp) < 2 {
err = fmt.Errorf("%s is not a valid change URL", changeUrl)
return
}
host = sp[0]
err = gerrit.ValidateGerritURL("https://" + host)
if err != nil {
return
}
// Change ID can only be numeric.
num, err := strconv.Atoi(sp[len(sp)-1])
if err != nil {
err = fmt.Errorf("%s is not a valid numeric changeID: %v", sp[len(sp)-1], err)
return
}
changeId = int64(num)
return
}