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 }