...
Run Format

Source file src/cmd/go/internal/get/discovery.go

Documentation: cmd/go/internal/get

  // Copyright 2012 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package get
  
  import (
  	"encoding/xml"
  	"fmt"
  	"io"
  	"strings"
  )
  
  // charsetReader returns a reader for the given charset. Currently
  // it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
  // error which is printed by go get, so the user can find why the package
  // wasn't downloaded if the encoding is not supported. Note that, in
  // order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
  // greater than 0x7f are not rejected).
  func charsetReader(charset string, input io.Reader) (io.Reader, error) {
  	switch strings.ToLower(charset) {
  	case "ascii":
  		return input, nil
  	default:
  		return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
  	}
  }
  
  // parseMetaGoImports returns meta imports from the HTML in r.
  // Parsing ends at the end of the <head> section or the beginning of the <body>.
  func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
  	d := xml.NewDecoder(r)
  	d.CharsetReader = charsetReader
  	d.Strict = false
  	var t xml.Token
  	for {
  		t, err = d.RawToken()
  		if err != nil {
  			if err == io.EOF || len(imports) > 0 {
  				err = nil
  			}
  			return
  		}
  		if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
  			return
  		}
  		if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
  			return
  		}
  		e, ok := t.(xml.StartElement)
  		if !ok || !strings.EqualFold(e.Name.Local, "meta") {
  			continue
  		}
  		if attrValue(e.Attr, "name") != "go-import" {
  			continue
  		}
  		if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
  			// Ignore VCS type "mod", which is new Go modules.
  			// This code is for old go get and must ignore the new mod lines.
  			// Otherwise matchGoImport will complain about two
  			// different metaImport lines for the same Prefix.
  			if f[1] == "mod" {
  				continue
  			}
  			imports = append(imports, metaImport{
  				Prefix:   f[0],
  				VCS:      f[1],
  				RepoRoot: f[2],
  			})
  		}
  	}
  }
  
  // attrValue returns the attribute value for the case-insensitive key
  // `name', or the empty string if nothing is found.
  func attrValue(attrs []xml.Attr, name string) string {
  	for _, a := range attrs {
  		if strings.EqualFold(a.Name.Local, name) {
  			return a.Value
  		}
  	}
  	return ""
  }
  

View as plain text