1
2
3
4
5 package vcs
6
7 import (
8 "encoding/xml"
9 "fmt"
10 "io"
11 "strings"
12 )
13
14
15
16
17
18
19
20 func charsetReader(charset string, input io.Reader) (io.Reader, error) {
21 switch strings.ToLower(charset) {
22 case "utf-8", "ascii":
23 return input, nil
24 default:
25 return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
26 }
27 }
28
29
30
31 func parseMetaGoImports(r io.Reader, mod ModuleMode) ([]metaImport, error) {
32 d := xml.NewDecoder(r)
33 d.CharsetReader = charsetReader
34 d.Strict = false
35 var imports []metaImport
36 for {
37 t, err := d.RawToken()
38 if err != nil {
39 if err != io.EOF && len(imports) == 0 {
40 return nil, err
41 }
42 break
43 }
44 if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
45 break
46 }
47 if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
48 break
49 }
50 e, ok := t.(xml.StartElement)
51 if !ok || !strings.EqualFold(e.Name.Local, "meta") {
52 continue
53 }
54 if attrValue(e.Attr, "name") != "go-import" {
55 continue
56 }
57 if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
58 imports = append(imports, metaImport{
59 Prefix: f[0],
60 VCS: f[1],
61 RepoRoot: f[2],
62 })
63 }
64 }
65
66
67 var list []metaImport
68 var have map[string]bool
69 if mod == PreferMod {
70 have = make(map[string]bool)
71 for _, m := range imports {
72 if m.VCS == "mod" {
73 have[m.Prefix] = true
74 list = append(list, m)
75 }
76 }
77 }
78
79
80 for _, m := range imports {
81 if m.VCS != "mod" && !have[m.Prefix] {
82 list = append(list, m)
83 }
84 }
85 return list, nil
86 }
87
88
89
90 func attrValue(attrs []xml.Attr, name string) string {
91 for _, a := range attrs {
92 if strings.EqualFold(a.Name.Local, name) {
93 return a.Value
94 }
95 }
96 return ""
97 }
98
View as plain text