github.com/ldez/gomoddirectives@v0.2.4/module.go (about)

     1  package gomoddirectives
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"os"
     9  	"os/exec"
    10  
    11  	"golang.org/x/mod/modfile"
    12  )
    13  
    14  type modInfo struct {
    15  	Path      string `json:"Path"`
    16  	Dir       string `json:"Dir"`
    17  	GoMod     string `json:"GoMod"`
    18  	GoVersion string `json:"GoVersion"`
    19  	Main      bool   `json:"Main"`
    20  }
    21  
    22  // GetModuleFile gets module file.
    23  func GetModuleFile() (*modfile.File, error) {
    24  	// https://github.com/golang/go/issues/44753#issuecomment-790089020
    25  	cmd := exec.Command("go", "list", "-m", "-json")
    26  
    27  	raw, err := cmd.Output()
    28  	if err != nil {
    29  		return nil, fmt.Errorf("command go list: %w: %s", err, string(raw))
    30  	}
    31  
    32  	var v modInfo
    33  	err = json.NewDecoder(bytes.NewBuffer(raw)).Decode(&v)
    34  	if err != nil {
    35  		return nil, fmt.Errorf("unmarshaling error: %w: %s", err, string(raw))
    36  	}
    37  
    38  	if v.GoMod == "" {
    39  		return nil, errors.New("working directory is not part of a module")
    40  	}
    41  
    42  	raw, err = os.ReadFile(v.GoMod)
    43  	if err != nil {
    44  		return nil, fmt.Errorf("reading go.mod file: %w", err)
    45  	}
    46  
    47  	return modfile.Parse("go.mod", raw, nil)
    48  }