.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.0 / go / packages / packagestest / modules.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/go/packages/packagestest/modules.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/go/packages/packagestest/modules.go
new file mode 100644 (file)
index 0000000..42b6206
--- /dev/null
@@ -0,0 +1,222 @@
+// Copyright 2018 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 packagestest
+
+import (
+       "context"
+       "fmt"
+       "io/ioutil"
+       "os"
+       "path"
+       "path/filepath"
+       "regexp"
+       "strings"
+
+       "golang.org/x/tools/internal/gocommand"
+       "golang.org/x/tools/internal/packagesinternal"
+       "golang.org/x/tools/internal/proxydir"
+)
+
+// Modules is the exporter that produces module layouts.
+// Each "repository" is put in it's own module, and the module file generated
+// will have replace directives for all other modules.
+// Given the two files
+//     golang.org/repoa#a/a.go
+//     golang.org/repob#b/b.go
+// You would get the directory layout
+//     /sometemporarydirectory
+//     ├── repoa
+//     │   ├── a
+//     │   │   └── a.go
+//     │   └── go.mod
+//     └── repob
+//         ├── b
+//         │   └── b.go
+//         └── go.mod
+// and the working directory would be
+//     /sometemporarydirectory/repoa
+var Modules = modules{}
+
+type modules struct{}
+
+type moduleAtVersion struct {
+       module  string
+       version string
+}
+
+func (modules) Name() string {
+       return "Modules"
+}
+
+func (modules) Filename(exported *Exported, module, fragment string) string {
+       if module == exported.primary {
+               return filepath.Join(primaryDir(exported), fragment)
+       }
+       return filepath.Join(moduleDir(exported, module), fragment)
+}
+
+func (modules) Finalize(exported *Exported) error {
+       // Write out the primary module. This module can use symlinks and
+       // other weird stuff, and will be the working dir for the go command.
+       // It depends on all the other modules.
+       primaryDir := primaryDir(exported)
+       if err := os.MkdirAll(primaryDir, 0755); err != nil {
+               return err
+       }
+       exported.Config.Dir = primaryDir
+       if exported.written[exported.primary] == nil {
+               exported.written[exported.primary] = make(map[string]string)
+       }
+
+       // Create a map of modulepath -> {module, version} for modulepaths
+       // that are of the form `repoa/mod1@v1.1.0`.
+       versions := make(map[string]moduleAtVersion)
+       for module := range exported.written {
+               if splt := strings.Split(module, "@"); len(splt) > 1 {
+                       versions[module] = moduleAtVersion{
+                               module:  splt[0],
+                               version: splt[1],
+                       }
+               }
+       }
+
+       // If the primary module already has a go.mod, write the contents to a temp
+       // go.mod for now and then we will reset it when we are getting all the markers.
+       if gomod := exported.written[exported.primary]["go.mod"]; gomod != "" {
+               contents, err := ioutil.ReadFile(gomod)
+               if err != nil {
+                       return err
+               }
+               if err := ioutil.WriteFile(gomod+".temp", contents, 0644); err != nil {
+                       return err
+               }
+       }
+
+       exported.written[exported.primary]["go.mod"] = filepath.Join(primaryDir, "go.mod")
+       primaryGomod := "module " + exported.primary + "\nrequire (\n"
+       for other := range exported.written {
+               if other == exported.primary {
+                       continue
+               }
+               version := moduleVersion(other)
+               // If other is of the form `repo1/mod1@v1.1.0`,
+               // then we need to extract the module and the version.
+               if v, ok := versions[other]; ok {
+                       other = v.module
+                       version = v.version
+               }
+               primaryGomod += fmt.Sprintf("\t%v %v\n", other, version)
+       }
+       primaryGomod += ")\n"
+       if err := ioutil.WriteFile(filepath.Join(primaryDir, "go.mod"), []byte(primaryGomod), 0644); err != nil {
+               return err
+       }
+
+       // Create the mod cache so we can rename it later, even if we don't need it.
+       if err := os.MkdirAll(modCache(exported), 0755); err != nil {
+               return err
+       }
+
+       // Write out the go.mod files for the other modules.
+       for module, files := range exported.written {
+               if module == exported.primary {
+                       continue
+               }
+               dir := moduleDir(exported, module)
+               modfile := filepath.Join(dir, "go.mod")
+               // If other is of the form `repo1/mod1@v1.1.0`,
+               // then we need to extract the module name without the version.
+               if v, ok := versions[module]; ok {
+                       module = v.module
+               }
+               if err := ioutil.WriteFile(modfile, []byte("module "+module+"\n"), 0644); err != nil {
+                       return err
+               }
+               files["go.mod"] = modfile
+       }
+
+       // Zip up all the secondary modules into the proxy dir.
+       modProxyDir := filepath.Join(exported.temp, "modproxy")
+       for module, files := range exported.written {
+               if module == exported.primary {
+                       continue
+               }
+               version := moduleVersion(module)
+               // If other is of the form `repo1/mod1@v1.1.0`,
+               // then we need to extract the module and the version.
+               if v, ok := versions[module]; ok {
+                       module = v.module
+                       version = v.version
+               }
+               if err := writeModuleFiles(modProxyDir, module, version, files); err != nil {
+                       return fmt.Errorf("creating module proxy dir for %v: %v", module, err)
+               }
+       }
+
+       // Discard the original mod cache dir, which contained the files written
+       // for us by Export.
+       if err := os.Rename(modCache(exported), modCache(exported)+".orig"); err != nil {
+               return err
+       }
+       exported.Config.Env = append(exported.Config.Env,
+               "GO111MODULE=on",
+               "GOPATH="+filepath.Join(exported.temp, "modcache"),
+               "GOMODCACHE=",
+               "GOPROXY="+proxydir.ToURL(modProxyDir),
+               "GOSUMDB=off",
+       )
+       gocmdRunner := &gocommand.Runner{}
+       packagesinternal.SetGoCmdRunner(exported.Config, gocmdRunner)
+
+       // Run go mod download to recreate the mod cache dir with all the extra
+       // stuff in cache. All the files created by Export should be recreated.
+       inv := gocommand.Invocation{
+               Verb:       "mod",
+               Args:       []string{"download"},
+               Env:        exported.Config.Env,
+               BuildFlags: exported.Config.BuildFlags,
+               WorkingDir: exported.Config.Dir,
+       }
+       if _, err := gocmdRunner.Run(context.Background(), inv); err != nil {
+               return err
+       }
+       return nil
+}
+
+func writeModuleFiles(rootDir, module, ver string, filePaths map[string]string) error {
+       fileData := make(map[string][]byte)
+       for name, path := range filePaths {
+               contents, err := ioutil.ReadFile(path)
+               if err != nil {
+                       return err
+               }
+               fileData[name] = contents
+       }
+       return proxydir.WriteModuleVersion(rootDir, module, ver, fileData)
+}
+
+func modCache(exported *Exported) string {
+       return filepath.Join(exported.temp, "modcache/pkg/mod")
+}
+
+func primaryDir(exported *Exported) string {
+       return filepath.Join(exported.temp, path.Base(exported.primary))
+}
+
+func moduleDir(exported *Exported, module string) string {
+       if strings.Contains(module, "@") {
+               return filepath.Join(modCache(exported), module)
+       }
+       return filepath.Join(modCache(exported), path.Dir(module), path.Base(module)+"@"+moduleVersion(module))
+}
+
+var versionSuffixRE = regexp.MustCompile(`v\d+`)
+
+func moduleVersion(module string) string {
+       if versionSuffixRE.MatchString(path.Base(module)) {
+               return path.Base(module) + ".0.0"
+       }
+       return "v1.0.0"
+}