github.com/grafana/pyroscope@v1.18.0/pkg/frontend/vcs/source/golang/packages.go (about)

     1  //go:generate go run gen.go > packages_gen.go
     2  
     3  package golang
     4  
     5  import (
     6  	"fmt"
     7  	"log"
     8  	"net/http"
     9  	"strings"
    10  
    11  	"github.com/PuerkitoBio/goquery"
    12  )
    13  
    14  // StdPackages returns a map of all standard packages for the given version.
    15  func StdPackages(version string) (map[string]struct{}, error) {
    16  	if version != "" {
    17  		version = "@go" + version
    18  	}
    19  	res, err := http.Get(fmt.Sprintf("https://pkg.go.dev/std%s", version))
    20  	if err != nil {
    21  		return nil, err
    22  	}
    23  	defer res.Body.Close()
    24  	if res.StatusCode != 200 {
    25  		log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
    26  	}
    27  	// Load the HTML document
    28  	doc, err := goquery.NewDocumentFromReader(res.Body)
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	packages := map[string]struct{}{}
    33  	doc.Find("tbody").Each(func(i int, s *goquery.Selection) {
    34  		// For each item found, get the title
    35  		s.Find("a").Each(func(i int, s *goquery.Selection) {
    36  			href, ok := s.Attr("href")
    37  			if !ok {
    38  				return
    39  			}
    40  			// extract the package name from the href
    41  			// /crypto/internal/alias@go1.21.6
    42  			if len(strings.Split(href, "@")) > 1 {
    43  				packages[strings.Trim(strings.Split(href, "@")[0], "/")] = struct{}{}
    44  			}
    45  		})
    46  	})
    47  	return packages, nil
    48  }