libgo: update to Go 1.11
[official-gcc.git] / libgo / go / cmd / go / internal / modload / build.go
blob558401d01f6c6212c424732cad7993a7bf2b51eb
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package modload
7 import (
8 "bytes"
9 "cmd/go/internal/base"
10 "cmd/go/internal/cfg"
11 "cmd/go/internal/modfetch"
12 "cmd/go/internal/modinfo"
13 "cmd/go/internal/module"
14 "cmd/go/internal/search"
15 "encoding/hex"
16 "fmt"
17 "internal/goroot"
18 "os"
19 "path/filepath"
20 "strings"
23 var (
24 infoStart, _ = hex.DecodeString("3077af0c9274080241e1c107e6d618e6")
25 infoEnd, _ = hex.DecodeString("f932433186182072008242104116d8f2")
28 func isStandardImportPath(path string) bool {
29 return findStandardImportPath(path) != ""
32 func findStandardImportPath(path string) string {
33 if search.IsStandardImportPath(path) {
34 if goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) {
35 return filepath.Join(cfg.GOROOT, "src", path)
37 if goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, "vendor/"+path) {
38 return filepath.Join(cfg.GOROOT, "src/vendor", path)
41 return ""
44 func PackageModuleInfo(pkgpath string) *modinfo.ModulePublic {
45 if isStandardImportPath(pkgpath) || !Enabled() {
46 return nil
48 return moduleInfo(findModule(pkgpath, pkgpath), true)
51 func ModuleInfo(path string) *modinfo.ModulePublic {
52 if !Enabled() {
53 return nil
56 if i := strings.Index(path, "@"); i >= 0 {
57 return moduleInfo(module.Version{Path: path[:i], Version: path[i+1:]}, false)
60 for _, m := range BuildList() {
61 if m.Path == path {
62 return moduleInfo(m, true)
66 return &modinfo.ModulePublic{
67 Path: path,
68 Error: &modinfo.ModuleError{
69 Err: "module not in current build",
74 // addUpdate fills in m.Update if an updated version is available.
75 func addUpdate(m *modinfo.ModulePublic) {
76 if m.Version != "" {
77 if info, err := Query(m.Path, "latest", Allowed); err == nil && info.Version != m.Version {
78 m.Update = &modinfo.ModulePublic{
79 Path: m.Path,
80 Version: info.Version,
81 Time: &info.Time,
87 // addVersions fills in m.Versions with the list of known versions.
88 func addVersions(m *modinfo.ModulePublic) {
89 m.Versions, _ = versions(m.Path)
92 func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic {
93 if m == Target {
94 info := &modinfo.ModulePublic{
95 Path: m.Path,
96 Version: m.Version,
97 Main: true,
98 Dir: ModRoot,
99 GoMod: filepath.Join(ModRoot, "go.mod"),
101 if modFile.Go != nil {
102 info.GoVersion = modFile.Go.Version
104 return info
107 info := &modinfo.ModulePublic{
108 Path: m.Path,
109 Version: m.Version,
110 Indirect: fromBuildList && loaded != nil && !loaded.direct[m.Path],
112 if loaded != nil {
113 info.GoVersion = loaded.goVersion[m.Path]
116 if cfg.BuildMod == "vendor" {
117 info.Dir = filepath.Join(ModRoot, "vendor", m.Path)
118 return info
121 // complete fills in the extra fields in m.
122 complete := func(m *modinfo.ModulePublic) {
123 if m.Version != "" {
124 if q, err := Query(m.Path, m.Version, nil); err != nil {
125 m.Error = &modinfo.ModuleError{Err: err.Error()}
126 } else {
127 m.Version = q.Version
128 m.Time = &q.Time
131 mod := module.Version{Path: m.Path, Version: m.Version}
132 gomod, err := modfetch.CachePath(mod, "mod")
133 if err == nil {
134 if info, err := os.Stat(gomod); err == nil && info.Mode().IsRegular() {
135 m.GoMod = gomod
138 dir, err := modfetch.DownloadDir(mod)
139 if err == nil {
140 if info, err := os.Stat(dir); err == nil && info.IsDir() {
141 m.Dir = dir
145 if cfg.BuildMod == "vendor" {
146 m.Dir = filepath.Join(ModRoot, "vendor", m.Path)
150 complete(info)
152 if fromBuildList {
153 if r := Replacement(m); r.Path != "" {
154 info.Replace = &modinfo.ModulePublic{
155 Path: r.Path,
156 Version: r.Version,
157 GoVersion: info.GoVersion,
159 if r.Version == "" {
160 if filepath.IsAbs(r.Path) {
161 info.Replace.Dir = r.Path
162 } else {
163 info.Replace.Dir = filepath.Join(ModRoot, r.Path)
166 complete(info.Replace)
167 info.Dir = info.Replace.Dir
168 info.GoMod = filepath.Join(info.Dir, "go.mod")
169 info.Error = nil // ignore error loading original module version (it has been replaced)
173 return info
176 func PackageBuildInfo(path string, deps []string) string {
177 if isStandardImportPath(path) || !Enabled() {
178 return ""
180 target := findModule(path, path)
181 mdeps := make(map[module.Version]bool)
182 for _, dep := range deps {
183 if !isStandardImportPath(dep) {
184 mdeps[findModule(path, dep)] = true
187 var mods []module.Version
188 delete(mdeps, target)
189 for mod := range mdeps {
190 mods = append(mods, mod)
192 module.Sort(mods)
194 var buf bytes.Buffer
195 fmt.Fprintf(&buf, "path\t%s\n", path)
196 tv := target.Version
197 if tv == "" {
198 tv = "(devel)"
200 fmt.Fprintf(&buf, "mod\t%s\t%s\t%s\n", target.Path, tv, modfetch.Sum(target))
201 for _, mod := range mods {
202 mv := mod.Version
203 if mv == "" {
204 mv = "(devel)"
206 r := Replacement(mod)
207 h := ""
208 if r.Path == "" {
209 h = "\t" + modfetch.Sum(mod)
211 fmt.Fprintf(&buf, "dep\t%s\t%s%s\n", mod.Path, mod.Version, h)
212 if r.Path != "" {
213 fmt.Fprintf(&buf, "=>\t%s\t%s\t%s\n", r.Path, r.Version, modfetch.Sum(r))
216 return buf.String()
219 func findModule(target, path string) module.Version {
220 // TODO: This should use loaded.
221 if path == "." {
222 return buildList[0]
224 for _, mod := range buildList {
225 if maybeInModule(path, mod.Path) {
226 return mod
229 base.Fatalf("build %v: cannot find module for path %v", target, path)
230 panic("unreachable")
233 func ModInfoProg(info string) []byte {
234 return []byte(fmt.Sprintf(`
235 package main
236 import _ "unsafe"
237 //go:linkname __debug_modinfo__ runtime/debug.modinfo
238 var __debug_modinfo__ string
239 func init() {
240 __debug_modinfo__ = %q
242 `, string(infoStart)+info+string(infoEnd)))