func Download(mod *Module) (*Module, error) {
	defer countGoMods()
	app := aah.App()
	mutexModPath := modPath(mod)
	app.Log().Info("Download request recevied for ", mutexModPath)
	srcZipPath := filepath.Join(Settings.ModCachePath, mod.Path, "@v", mod.Version+".zip")
	if ess.IsFileExists(srcZipPath) {
		app.Log().Info("Module ", mutexModPath, " already exists on repository")
		return nil, nil
	}
	if _, found := modMutex[mutexModPath]; found {
		app.Log().Infof("Download already in-progress for '%s'", mutexModPath)
		return nil, nil
	}
	defer func() {
		delete(modMutex, mutexModPath)
	}()
	var err error
	mod.DecodedPath, err = DecodePath(mod.Path)
	if err != nil {
		return nil, err
	}
	dirPath, err := createTempProject()
	if err != nil {
		return nil, err
	}
	defer func() {
		if err = os.RemoveAll(dirPath); err != nil {
			app.Log().Warn(err)
		}
	}()
	downloadMode := "gomod"
	if ess.IsStrEmpty(mod.Version) || !semverPrefixRegex.MatchString(mod.Version) {
		downloadMode = "goget"  
	}
	args := []string{}
	switch downloadMode {
	case "gomod":
		args = append(args, "mod", "download", "-json", decodedModPath(mod))
	case "goget":
		args = append(args, "get", decodedModPath(mod))
	}
	env := os.Environ()
	env = append(env, fmt.Sprintf("GOPATH=%s", Settings.GoPath))
	env = append(env, fmt.Sprintf("GOCACHE=%s", Settings.GoCache))
	cmd := exec.Command(Settings.GoBinary, args...)
	cmd.Env = env
	cmd.Dir = dirPath
	stdOut, stdErr := &bytes.Buffer{}, &bytes.Buffer{}
	cmd.Stdout, cmd.Stderr = stdOut, stdErr
	app.Log().Info("Executing ", Settings.GoBinary, " ", strings.Join(args, " "))
	status, errInfo := inferExitStatus(cmd, cmd.Run())
	if status != 0 {
		app.Log().Error(strings.TrimSpace(stdErr.String()))
		app.Log().Error(errInfo)
		return nil, ErrExecFailure
	}
	resultMod := &Module{}
	switch downloadMode {
	case "gomod":
		if err = json.NewDecoder(stdOut).Decode(resultMod); err != nil {
			return nil, errors.New(stdErr.String())
		}
		if len(resultMod.Error) > 0 {
			return nil, errors.New(resultMod.Error)
		}
		resultMod.Path = mod.Path
		resultMod.DecodedPath = mod.DecodedPath
		resultMod.Action = mod.Action
	case "goget":
		modVersion := inferGoGetModVersion(mod, stdErr.Bytes())
		resultMod = mod
		resultMod.Version = modVersion
		if ess.IsStrEmpty(resultMod.Version) {
			tcmd := exec.Command(Settings.GoBinary, "mod", "download", "-json", decodedModPath(mod))
			tcmd.Env = env
			tcmd.Dir = dirPath
			b, err := tcmd.Output()
			if err == nil {
				resultMod = &Module{}
				if err = json.NewDecoder(bytes.NewReader(b)).Decode(resultMod); err != nil {
					return nil, err
				}
				if len(resultMod.Error) > 0 {
					return nil, errors.New(resultMod.Error)
				}
				resultMod.Path = mod.Path
				resultMod.DecodedPath = mod.DecodedPath
				resultMod.Action = mod.Action
			}
		}
		_ = checkAndCreateInfoFile(resultMod)
	}
	app.Log().Infof("Module [%s@%s] downloaded successfully into repository", resultMod.Path, resultMod.Version)
	return resultMod, nil
}
Download method downloads the requested go module path using 'go mod' or 'go get'
which populates the mod cache.
package gomod
import (
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"go/build"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"thumbai/app/models"
	"time"
	"aahframe.work"
	"aahframe.work/essentials"
)
var (
	ErrInvalidGoModPath = errors.New("gomod: invalid path")
	ErrGoModNotExist    = errors.New("gomod: mod not exist")
	ErrExecFailure      = errors.New("gomod: exec failure")
)
var (
	Settings = &settings{RWMutex: sync.RWMutex{}, GoVersion: "NA"}
	semverPrefixRegex = regexp.MustCompile(`(^v[0-9]+\.)`)
)
type settings struct {
	sync.RWMutex
	Enabled       bool
	GoBinary      string
	GoVersion     string
	GoPath        string
	GoCache       string
	GoProxy       string
	ModCachePath  string
	Stats         *models.ModuleStats
	storeSettings *models.ModuleSettings
}
func Infer(_ *aah.Event) {
	Settings.Lock()
	defer Settings.Unlock()
	Settings.storeSettings = GetSettings()
	Settings.Stats = &models.ModuleStats{}
	var err error
	Settings.GoBinary, err = inferGoBinary(Settings.storeSettings.GoBinary)
	if err != nil {
		aah.App().Log().Errorf("Go modules proxy server would unavailable: %v", err)
		return
	}
	Settings.GoVersion = GoVersion(Settings.GoBinary)
	if !InferGo111AndAbove(Settings.GoVersion) {
		aah.App().Log().Errorf("Go version found: %s. Minimum go1.11 & above is required to use go modules proxy server")
		return
	}
	Settings.GoPath = inferGopath(Settings.storeSettings.GoPath)
	Settings.GoCache = inferGoCache()
	Settings.ModCachePath = filepath.Join(Settings.GoPath, "pkg", "mod", "cache", "download")
	if ess.IsStrEmpty(Settings.storeSettings.GoProxy) {
		Settings.GoProxy = os.Getenv("GOPROXY")
	} else {
		Settings.GoProxy = Settings.storeSettings.GoProxy
	}
	Settings.Enabled = true
	go countGoMods()
}
const FSPathDelimiter = "/@v/"
type Module struct {
	Path        string
	DecodedPath string
	Version     string
	Error       string
	Info        string
	GoMod       string
	Zip         string
	Dir         string
	Action      string
}
func InferRequest(modReqPath string) (*Module, error) {
	parts := strings.Split(modReqPath, FSPathDelimiter)
	if len(parts) != 2 {
		return nil, ErrInvalidGoModPath
	}
	mod := &Module{Path: parts[0]}
	if parts[1] == "list" {
		mod.Action = parts[1]
		if !ess.IsFileExists(filepath.Join(Settings.ModCachePath, modReqPath)) {
			return mod, ErrGoModNotExist
		}
		return mod, nil
	}
	i := strings.LastIndexByte(parts[1], '.')
	if i == -1 {
		return nil, ErrInvalidGoModPath
	}
	mod.Version = parts[1][:i]
	mod.Action = parts[1][i+1:]
	if !ess.IsFileExists(filepath.Join(Settings.ModCachePath, modReqPath)) {
		if err := checkAndCreateInfoFile(mod); err == nil {
			return mod, nil  
		}
		return mod, ErrGoModNotExist
	}
	return mod, nil
}
var goPrg = []byte(`package main
import (
	"fmt"
)
func main() {
	fmt.Println("thumbai temp go project")
}
`)
var goMod = []byte(`module thumbai.app/tempproject`)
const tempFilePerm = os.FileMode(0644)
var modMutex = map[string]bool{}