mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 17:37:46 +08:00
103 lines
2.7 KiB
Go
103 lines
2.7 KiB
Go
package gitutil
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/containerd/containerd/errdefs"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// GitRef represents a git ref.
|
|
//
|
|
// Examples:
|
|
// - "https://github.com/foo/bar.git#baz/qux:quux/quuz" is parsed into:
|
|
// {Remote: "https://github.com/foo/bar.git", ShortName: "bar", Commit:"baz/qux", SubDir: "quux/quuz"}.
|
|
type GitRef struct {
|
|
// Remote is the remote repository path.
|
|
Remote string
|
|
|
|
// ShortName is the directory name of the repo.
|
|
// e.g., "bar" for "https://github.com/foo/bar.git"
|
|
ShortName string
|
|
|
|
// Commit is a commit hash, a tag, or branch name.
|
|
// Commit is optional.
|
|
Commit string
|
|
|
|
// SubDir is a directory path inside the repo.
|
|
// SubDir is optional.
|
|
SubDir string
|
|
|
|
// IndistinguishableFromLocal is true for a ref that is indistinguishable from a local file path,
|
|
// e.g., "github.com/foo/bar".
|
|
//
|
|
// Deprecated.
|
|
// Instead, use a distinguishable form such as "https://github.com/foo/bar.git".
|
|
//
|
|
// The dockerfile frontend still accepts this form only for build contexts.
|
|
IndistinguishableFromLocal bool
|
|
|
|
// UnencryptedTCP is true for a ref that needs an unencrypted TCP connection,
|
|
// e.g., "git://..." and "http://..." .
|
|
//
|
|
// Discouraged, although not deprecated.
|
|
// Instead, consider using an encrypted TCP connection such as "git@github.com/foo/bar.git" or "https://github.com/foo/bar.git".
|
|
UnencryptedTCP bool
|
|
}
|
|
|
|
// var gitURLPathWithFragmentSuffix = regexp.MustCompile(`\.git(?:#.+)?$`)
|
|
|
|
// ParseGitRef parses a git ref.
|
|
func ParseGitRef(ref string) (*GitRef, error) {
|
|
res := &GitRef{}
|
|
|
|
var (
|
|
remote *GitURL
|
|
err error
|
|
)
|
|
|
|
if strings.HasPrefix(ref, "github.com/") {
|
|
res.IndistinguishableFromLocal = true // Deprecated
|
|
remote = fromURL(&url.URL{
|
|
Scheme: "https",
|
|
Host: "github.com",
|
|
Path: strings.TrimPrefix(ref, "github.com/"),
|
|
})
|
|
} else {
|
|
remote, err = ParseURL(ref)
|
|
if errors.Is(err, ErrUnknownProtocol) {
|
|
remote, err = ParseURL("https://" + ref)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch remote.Scheme {
|
|
case HTTPProtocol, GitProtocol:
|
|
res.UnencryptedTCP = true // Discouraged, but not deprecated
|
|
}
|
|
|
|
switch remote.Scheme {
|
|
// An HTTP(S) URL is considered to be a valid git ref only when it has the ".git[...]" suffix.
|
|
case HTTPProtocol, HTTPSProtocol:
|
|
if !strings.HasSuffix(remote.Path, ".git") {
|
|
return nil, errdefs.ErrInvalidArgument
|
|
}
|
|
}
|
|
}
|
|
|
|
res.Remote = remote.Remote
|
|
if res.IndistinguishableFromLocal {
|
|
_, res.Remote, _ = strings.Cut(res.Remote, "://")
|
|
}
|
|
if remote.Fragment != nil {
|
|
res.Commit, res.SubDir = remote.Fragment.Ref, remote.Fragment.Subdir
|
|
}
|
|
|
|
repoSplitBySlash := strings.Split(res.Remote, "/")
|
|
res.ShortName = strings.TrimSuffix(repoSplitBySlash[len(repoSplitBySlash)-1], ".git")
|
|
|
|
return res, nil
|
|
}
|