github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/goget/goget.go (about)

     1  package goget
     2  
     3  import (
     4  	"fmt"
     5  	piperhttp "github.com/SAP/jenkins-library/pkg/http"
     6  	"net/http"
     7  	"strings"
     8  
     9  	"github.com/antchfx/htmlquery"
    10  )
    11  
    12  // Client .
    13  type Client interface {
    14  	GetRepositoryURL(module string) (string, error)
    15  }
    16  
    17  // ClientImpl .
    18  type ClientImpl struct {
    19  	HTTPClient piperhttp.Sender
    20  }
    21  
    22  // GetRepositoryURL resolves the repository URL for the given go module. Only git is supported.
    23  func (c *ClientImpl) GetRepositoryURL(module string) (string, error) {
    24  	response, err := c.HTTPClient.SendRequest("GET", fmt.Sprintf("https://%s?go-get=1", module), nil, http.Header{}, nil)
    25  
    26  	if err != nil {
    27  		return "", err
    28  	} else if response.StatusCode == 404 {
    29  		return "", fmt.Errorf("module '%s' doesn't exist", module)
    30  	} else if response.StatusCode != 200 {
    31  		return "", fmt.Errorf("received unexpected response status code: %d", response.StatusCode)
    32  	}
    33  
    34  	html, err := htmlquery.Parse(response.Body)
    35  
    36  	if err != nil {
    37  		return "", fmt.Errorf("unable to parse content: %q", err)
    38  	}
    39  
    40  	metaNode := htmlquery.FindOne(html, "//meta[@name='go-import']/@content")
    41  
    42  	if metaNode == nil {
    43  		return "", fmt.Errorf("couldn't find go-import statement")
    44  	}
    45  
    46  	goImportStatement := htmlquery.SelectAttr(metaNode, "content")
    47  	goImport := strings.Split(goImportStatement, " ")
    48  
    49  	if len(goImport) != 3 || goImport[1] != "git" {
    50  		return "", fmt.Errorf("unsupported module: '%s'", module)
    51  	}
    52  
    53  	return goImport[2], nil
    54  }