github.com/triarius/goreleaser@v1.12.5/internal/git/config.go (about)

     1  package git
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"net/url"
     8  	"path"
     9  	"strings"
    10  
    11  	"github.com/caarlos0/log"
    12  	"github.com/triarius/goreleaser/pkg/config"
    13  )
    14  
    15  // ExtractRepoFromConfig gets the repo name from the Git config.
    16  func ExtractRepoFromConfig(ctx context.Context) (result config.Repo, err error) {
    17  	if !IsRepo(ctx) {
    18  		return result, errors.New("current folder is not a git repository")
    19  	}
    20  	out, err := Clean(Run(ctx, "ls-remote", "--get-url"))
    21  	if err != nil {
    22  		return result, fmt.Errorf("no remote configured to list refs from")
    23  	}
    24  	log.WithField("rawurl", out).Debugf("got git url")
    25  	return ExtractRepoFromURL(out)
    26  }
    27  
    28  func ExtractRepoFromURL(rawurl string) (config.Repo, error) {
    29  	// removes the .git suffix and any new lines
    30  	s := strings.TrimSuffix(strings.TrimSpace(rawurl), ".git")
    31  
    32  	// if the URL contains a :, indicating a SSH config,
    33  	// remove all chars until it, including itself
    34  	// on HTTP and HTTPS URLs it will remove the http(s): prefix,
    35  	// which is ok. On SSH URLs the whole user@server will be removed,
    36  	// which is required.
    37  
    38  	// If the url contains more than 1 ':' character, assume we are doing an
    39  	// http URL with a username/password in it, and normalize the URL.
    40  	// Gitlab-CI uses this type of URL
    41  	if strings.Count(s, ":") == 1 {
    42  		s = s[strings.LastIndex(s, ":")+1:]
    43  	}
    44  
    45  	// now we can parse it with net/url
    46  	u, err := url.Parse(s)
    47  	if err != nil {
    48  		return config.Repo{
    49  			RawURL: rawurl,
    50  		}, err
    51  	}
    52  
    53  	// split the parsed url path by /, the last parts should be the owner and name
    54  	ss := strings.Split(strings.TrimPrefix(u.Path, "/"), "/")
    55  
    56  	// if empty, returns an error
    57  	if len(ss) == 0 || ss[0] == "" {
    58  		return config.Repo{
    59  			RawURL: rawurl,
    60  		}, fmt.Errorf("unsupported repository URL: %s", rawurl)
    61  	}
    62  
    63  	// if less than 2 parts, its likely not a valid repository, but we'll allow it.
    64  	if len(ss) < 2 {
    65  		return config.Repo{
    66  			RawURL: rawurl,
    67  			Owner:  ss[0],
    68  		}, nil
    69  	}
    70  	repo := config.Repo{
    71  		RawURL: rawurl,
    72  		Owner:  path.Join(ss[:len(ss)-1]...),
    73  		Name:   ss[len(ss)-1],
    74  	}
    75  	log.WithField("owner", repo.Owner).WithField("name", repo.Name).Debugf("parsed url")
    76  	return repo, nil
    77  }