github.com/msoap/go-carpet@v1.10.1-0.20240316220419-b690da179708/mod.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"log"
     7  	"os"
     8  	"os/exec"
     9  	"path"
    10  	"strings"
    11  
    12  	"github.com/msoap/byline"
    13  )
    14  
    15  var goModFilename *string
    16  
    17  func getGoModFilename() string {
    18  	if goModFilename != nil {
    19  		return *goModFilename
    20  	}
    21  
    22  	file := ""
    23  	out, err := exec.Command("go", "env", "GOMOD").Output()
    24  	if err != nil {
    25  		log.Printf("failed to load 'go env GOMOD' content: %s", err)
    26  		goModFilename = &file
    27  		return ""
    28  	}
    29  
    30  	file = strings.TrimSpace(string(out))
    31  	goModFilename = &file
    32  
    33  	return file
    34  }
    35  
    36  func guessAbsPathInGoMod(relPath string) (string, error) {
    37  	modFilename := getGoModFilename()
    38  	if modFilename == "" {
    39  		return "", errIsNotInGoMod
    40  	}
    41  
    42  	modFile, err := os.Open(modFilename)
    43  	if err != nil {
    44  		return "", err
    45  	}
    46  	defer func() {
    47  		if err := modFile.Close(); err != nil {
    48  			log.Printf("failed to close %s file: %s", modFilename, err)
    49  		}
    50  	}()
    51  
    52  	moduleName := ""
    53  	if err := byline.NewReader(modFile).AWKMode(func(_ string, fields []string, vars byline.AWKVars) (string, error) {
    54  		if vars.NF == 2 && fields[0] == "module" && fields[1] != "" {
    55  			moduleName = fields[1]
    56  			return "", io.EOF
    57  		}
    58  
    59  		return "", nil
    60  	}).Discard(); err != nil {
    61  		return "", err
    62  	}
    63  	if moduleName == "" {
    64  		return "", errIsNotInGoMod
    65  	}
    66  
    67  	absPath := path.Dir(modFilename) + strings.TrimPrefix(relPath, moduleName)
    68  	if stat, err := os.Stat(absPath); err != nil {
    69  		return "", err
    70  	} else if !stat.Mode().IsRegular() {
    71  		return "", fmt.Errorf("%s is not regular file", absPath)
    72  	}
    73  
    74  	return absPath, nil
    75  }