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 || len(f) == 4 {
58 mi := metaImport{
59 Prefix: f[0],
60 VCS: f[1],
61 RepoRoot: f[2],
62 }
63
64 if len(f) == 4 {
65 mi.SubDir = f[3]
66 }
67 imports = append(imports, mi)
68 }
69 }
70
71
72 var list []metaImport
73 var have map[string]bool
74 if mod == PreferMod {
75 have = make(map[string]bool)
76 for _, m := range imports {
77 if m.VCS == "mod" {
78 have[m.Prefix] = true
79 list = append(list, m)
80 }
81 }
82 }
83
84
85 for _, m := range imports {
86 if m.VCS != "mod" && !have[m.Prefix] {
87 list = append(list, m)
88 }
89 }
90 return list, nil
91 }
92
93
94
95 func attrValue(attrs []xml.Attr, name string) string {
96 for _, a := range attrs {
97 if strings.EqualFold(a.Name.Local, name) {
98 return a.Value
99 }
100 }
101 return ""
102 }
103
View as plain text