github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/lfs/endpoint.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package lfs 7 8 import ( 9 "fmt" 10 "net/url" 11 "os" 12 "path" 13 "path/filepath" 14 "strings" 15 16 "github.com/gitbundle/modules/log" 17 ) 18 19 // DetermineEndpoint determines an endpoint from the clone url or uses the specified LFS url. 20 func DetermineEndpoint(cloneurl, lfsurl string) *url.URL { 21 if len(lfsurl) > 0 { 22 return endpointFromURL(lfsurl) 23 } 24 return endpointFromCloneURL(cloneurl) 25 } 26 27 func endpointFromCloneURL(rawurl string) *url.URL { 28 ep := endpointFromURL(rawurl) 29 if ep == nil { 30 return ep 31 } 32 33 ep.Path = strings.TrimSuffix(ep.Path, "/") 34 35 if ep.Scheme == "file" { 36 return ep 37 } 38 39 if path.Ext(ep.Path) == ".git" { 40 ep.Path += "/info/lfs" 41 } else { 42 ep.Path += ".git/info/lfs" 43 } 44 45 return ep 46 } 47 48 func endpointFromURL(rawurl string) *url.URL { 49 if strings.HasPrefix(rawurl, "/") { 50 return endpointFromLocalPath(rawurl) 51 } 52 53 u, err := url.Parse(rawurl) 54 if err != nil { 55 log.Error("lfs.endpointFromUrl: %v", err) 56 return nil 57 } 58 59 switch u.Scheme { 60 case "http", "https": 61 return u 62 case "git": 63 u.Scheme = "https" 64 return u 65 case "file": 66 return u 67 default: 68 if _, err := os.Stat(rawurl); err == nil { 69 return endpointFromLocalPath(rawurl) 70 } 71 72 log.Error("lfs.endpointFromUrl: unknown url") 73 return nil 74 } 75 } 76 77 func endpointFromLocalPath(path string) *url.URL { 78 var slash string 79 if abs, err := filepath.Abs(path); err == nil { 80 if !strings.HasPrefix(abs, "/") { 81 slash = "/" 82 } 83 path = abs 84 } 85 86 var gitpath string 87 if filepath.Base(path) == ".git" { 88 gitpath = path 89 path = filepath.Dir(path) 90 } else { 91 gitpath = filepath.Join(path, ".git") 92 } 93 94 if _, err := os.Stat(gitpath); err == nil { 95 path = gitpath 96 } else if _, err := os.Stat(path); err != nil { 97 return nil 98 } 99 100 path = fmt.Sprintf("file://%s%s", slash, filepath.ToSlash(path)) 101 102 u, _ := url.Parse(path) 103 104 return u 105 }