github.com/madlambda/nash@v0.2.2-0.20230113003044-f2284521680b/tests/cfg.go (about)

     1  package tests
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"runtime"
     8  )
     9  
    10  var (
    11  	// Nashcmd is the nash's absolute binary path in source
    12  	Nashcmd string
    13  
    14  	// Projectpath is the path to nash source code
    15  	Projectpath string
    16  
    17  	// Testdir is the test assets directory
    18  	Testdir string
    19  
    20  	// Stdbindir is the stdbin directory
    21  	Stdbindir string
    22  )
    23  
    24  func init() {
    25  
    26  	Projectpath = findProjectRoot()
    27  	Testdir = filepath.Join(Projectpath, "testfiles")
    28  	Nashcmd = filepath.Join(Projectpath, "cmd", "nash", "nash")
    29  	Stdbindir = filepath.Join(Projectpath, "stdbin")
    30  
    31  	if runtime.GOOS == "windows" {
    32  		Nashcmd += ".exe"
    33  	}
    34  
    35  	if _, err := os.Stat(Nashcmd); err != nil {
    36  		msg := fmt.Sprintf("Unable to find nash command at %q.\n", Nashcmd)
    37  		msg += "Please, run make build before running tests"
    38  		panic(msg)
    39  	}
    40  }
    41  
    42  func findProjectRoot() string {
    43  	// We used to use GOPATH as a way to infer the root of the
    44  	// project, now with Go modules this doesn't work anymore.
    45  	// Since module definition files only appear on the root
    46  	// of the project we use them instead, recursively going
    47  	// backwards in the file system until we find them.
    48  	//
    49  	// From: https://blog.golang.org/using-go-modules
    50  	// A module is a collection of Go packages stored in a file tree with a go.mod file at its root
    51  	//
    52  	// RIP GOPATH :-(
    53  
    54  	separator := string(filepath.Separator)
    55  	dir, err := os.Getwd()
    56  	if err != nil {
    57  		panic(fmt.Sprintf("failed to get current working directory:%v", err))
    58  	}
    59  
    60  	for !hasGoModFile(dir) {
    61  		if dir == separator {
    62  			// FIXME: not sure if this will work on all OS's, perhaps we need some
    63  			// other protection against infinite loops... or just trust go test timeout.
    64  			panic("reached root of file system without finding project root")
    65  		}
    66  		dir = filepath.Dir(dir)
    67  	}
    68  
    69  	return dir
    70  }
    71  
    72  func hasGoModFile(path string) bool {
    73  	info, err := os.Stat(path)
    74  	if err != nil {
    75  		return false
    76  	}
    77  	if !info.IsDir() {
    78  		return false
    79  	}
    80  
    81  	gomodpath := filepath.Join(path, "go.mod")
    82  	modinfo, err := os.Stat(gomodpath)
    83  	if err != nil {
    84  		return false
    85  	}
    86  	if modinfo.IsDir() {
    87  		return false
    88  	}
    89  	return true
    90  }