// Copyright 2020 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 gocommand

import (
	
	
	
	
	
	
	
	

	
)

// ModuleJSON holds information about a module.
type ModuleJSON struct {
	Path      string      // module path
	Version   string      // module version
	Versions  []string    // available module versions (with -versions)
	Replace   *ModuleJSON // replaced by this module
	Time      *time.Time  // time version was created
	Update    *ModuleJSON // available update, if any (with -u)
	Main      bool        // is this the main module?
	Indirect  bool        // is this module only an indirect dependency of main module?
	Dir       string      // directory holding files for this module, if any
	GoMod     string      // path to go.mod file used when loading this module, if any
	GoVersion string      // go version used in module
}

var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`)

// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands
// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields,
// of which only Verb and Args are modified to run the appropriate Go command.
// Inspired by setDefaultBuildMod in modload/init.go
func ( context.Context,  Invocation,  *Runner) (bool, *ModuleJSON, error) {
	, ,  := getMainModuleAnd114(, , )
	if  != nil {
		return false, nil, 
	}

	// We check the GOFLAGS to see if there is anything overridden or not.
	.Verb = "env"
	.Args = []string{"GOFLAGS"}
	,  := .Run(, )
	if  != nil {
		return false, nil, 
	}
	 := string(bytes.TrimSpace(.Bytes()))
	 := modFlagRegexp.FindStringSubmatch()
	var  string
	if len() != 0 {
		 = [1]
	}
	// Don't override an explicit '-mod=' argument.
	if  == "vendor" {
		return true, , nil
	} else if  != "" {
		return false, nil, nil
	}
	if  == nil || ! {
		return false, nil, nil
	}
	// Check 1.14's automatic vendor mode.
	if ,  := os.Stat(filepath.Join(.Dir, "vendor"));  == nil && .IsDir() {
		if .GoVersion != "" && semver.Compare("v"+.GoVersion, "v1.14") >= 0 {
			// The Go version is at least 1.14, and a vendor directory exists.
			// Set -mod=vendor by default.
			return true, , nil
		}
	}
	return false, nil, nil
}

// getMainModuleAnd114 gets one of the main modules' information and whether the
// go command in use is 1.14+. This is the information needed to figure out
// if vendoring should be enabled.
func ( context.Context,  Invocation,  *Runner) (*ModuleJSON, bool, error) {
	const  = `{{.Path}}
{{.Dir}}
{{.GoMod}}
{{.GoVersion}}
{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}}
`
	.Verb = "list"
	.Args = []string{"-m", "-f", }
	,  := .Run(, )
	if  != nil {
		return nil, false, 
	}

	 := strings.Split(.String(), "\n")
	if len() < 5 {
		return nil, false, fmt.Errorf("unexpected stdout: %q", .String())
	}
	 := &ModuleJSON{
		Path:      [0],
		Dir:       [1],
		GoMod:     [2],
		GoVersion: [3],
		Main:      true,
	}
	return , [4] == "go1.14", nil
}