github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/bob/add.go (about)

     1  package bob
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  
     7  	"github.com/Benchkram/bob/pkg/usererror"
     8  	"github.com/Benchkram/errz"
     9  	giturls "github.com/whilp/git-urls"
    10  )
    11  
    12  // Add, adds a repositoroy to a workspace.
    13  //
    14  // Automatically tries to guess the contrary url (git@/https://)
    15  // from the given rawurl. This behavior can be deactivated
    16  // if plain is set to true. In case of a local path (file://)
    17  // plain has no effect.
    18  func (b *B) Add(rawurl string, plain bool) (err error) {
    19  	defer errz.Recover(&err)
    20  
    21  	// Check if it is a valid git repo
    22  	repo, err := Parse(rawurl)
    23  	if err != nil {
    24  		if errors.Is(err, ErrInvalidGitUrl) {
    25  			return usererror.Wrap(err)
    26  		} else {
    27  			errz.Fatal(err)
    28  		}
    29  	}
    30  
    31  	// Check for duplicates
    32  	for _, existingRepo := range b.Repositories {
    33  		if existingRepo.Name == repo.Name() {
    34  			return usererror.Wrapm(ErrRepoAlreadyAdded, "failed to add repository")
    35  		}
    36  	}
    37  
    38  	var httpsstr string
    39  	if repo.HTTPS != nil {
    40  		httpsstr = repo.HTTPS.String()
    41  	}
    42  	var sshstr string
    43  	if repo.SSH != nil {
    44  		sshstr = repo.SSH.String()
    45  	}
    46  	localstr := repo.Local
    47  
    48  	if plain {
    49  		scheme, err := getScheme(rawurl)
    50  		errz.Fatal(err)
    51  
    52  		switch scheme {
    53  		case "http":
    54  			return usererror.Wrapm(ErrInsecuredHTTPURL, "failed to add repository")
    55  		case "https":
    56  			sshstr = ""
    57  			localstr = ""
    58  		case "file":
    59  			httpsstr = ""
    60  			sshstr = ""
    61  		case "ssh":
    62  			httpsstr = ""
    63  			localstr = ""
    64  		default:
    65  			return usererror.Wrap(ErrInvalidScheme)
    66  		}
    67  
    68  	}
    69  
    70  	b.Repositories = append(b.Repositories,
    71  		Repo{
    72  			Name:     repo.Name(),
    73  			HTTPSUrl: httpsstr,
    74  			SSHUrl:   sshstr,
    75  			LocalUrl: localstr,
    76  		},
    77  	)
    78  
    79  	err = b.gitignoreAdd(repo.Name())
    80  	errz.Fatal(err)
    81  
    82  	return b.write()
    83  }
    84  
    85  // getScheme check if the url is valid,
    86  // if valid returns the url scheme
    87  func getScheme(rawurl string) (string, error) {
    88  	u, err := giturls.Parse(rawurl)
    89  	if err != nil {
    90  		return "", err
    91  	}
    92  
    93  	// giturl parse detects url like `git@github.com` without `:` as files
    94  	// which is usually done using `ssh`.
    95  	if strings.Contains(rawurl, "git@") {
    96  		return "ssh", nil
    97  	}
    98  
    99  	return u.Scheme, nil
   100  }