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  }