github.com/oNaiPs/go-generate-fast@v0.3.0/src/core/generate/base/base.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package base defines shared basic pieces of the go command, 6 // in particular logging and the Command structure. 7 package base 8 9 import ( 10 "fmt" 11 "log" 12 "os" 13 "path/filepath" 14 "reflect" 15 "runtime" 16 "sync" 17 // "cmd/go/internal/cfg" 18 // "cmd/go/internal/str" 19 ) 20 21 var atExitFuncs []func() 22 23 func AtExit(f func()) { 24 atExitFuncs = append(atExitFuncs, f) 25 } 26 27 func Exit() { 28 for _, f := range atExitFuncs { 29 f() 30 } 31 os.Exit(exitStatus) 32 } 33 34 func Fatalf(format string, args ...any) { 35 Errorf(format, args...) 36 Exit() 37 } 38 39 func Errorf(format string, args ...any) { 40 log.Printf(format, args...) 41 SetExitStatus(1) 42 } 43 44 func ExitIfErrors() { 45 if exitStatus != 0 { 46 Exit() 47 } 48 } 49 50 func Error(err error) { 51 // We use errors.Join to return multiple errors from various routines. 52 // If we receive multiple errors joined with a basic errors.Join, 53 // handle each one separately so that they all have the leading "go: " prefix. 54 // A plain interface check is not good enough because there might be 55 // other kinds of structured errors that are logically one unit and that 56 // add other context: only handling the wrapped errors would lose 57 // that context. 58 if err != nil && reflect.TypeOf(err).String() == "*errors.joinError" { 59 for _, e := range err.(interface{ Unwrap() []error }).Unwrap() { 60 Error(e) 61 } 62 return 63 } 64 Errorf("go: %v", err) 65 } 66 67 func Fatal(err error) { 68 Error(err) 69 Exit() 70 } 71 72 var exitStatus = 0 73 var exitMu sync.Mutex 74 75 func SetExitStatus(n int) { 76 exitMu.Lock() 77 if exitStatus < n { 78 exitStatus = n 79 } 80 exitMu.Unlock() 81 } 82 83 func GetExitStatus() int { 84 return exitStatus 85 } 86 87 // AppendPWD returns the result of appending PWD=dir to the environment base. 88 // 89 // The resulting environment makes os.Getwd more efficient for a subprocess 90 // running in dir, and also improves the accuracy of paths relative to dir 91 // if one or more elements of dir is a symlink. 92 func AppendPWD(base []string, dir string) []string { 93 // POSIX requires PWD to be absolute. 94 // Internally we only use absolute paths, so dir should already be absolute. 95 if !filepath.IsAbs(dir) { 96 panic(fmt.Sprintf("AppendPWD with relative path %q", dir)) 97 } 98 return append(base, "PWD="+dir) 99 } 100 101 // AppendPATH returns the result of appending PATH=$GOROOT/bin:$PATH 102 // (or the platform equivalent) to the environment base. 103 func AppendPATH(base []string) []string { 104 GOROOTbin := filepath.Join(runtime.GOROOT(), "bin") 105 106 pathVar := "PATH" 107 if runtime.GOOS == "plan9" { 108 pathVar = "path" 109 } 110 111 path := os.Getenv(pathVar) 112 if path == "" { 113 return append(base, pathVar+"="+GOROOTbin) 114 } 115 return append(base, pathVar+"="+GOROOTbin+string(os.PathListSeparator)+path) 116 }