Ctrl K
ComunidadGuías…

internal/env/env.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// Package env answers where Encore tools and resources are located.
package env

import (
	"os"
	"path/filepath"

	"github.com/rs/zerolog/log"

	"encr.dev/pkg/option"
)

// These can be overwritten using
// `go build -ldflags "-X encr.dev/cli/internal/env.alternativeEncoreRuntimesPath=$HOME/src/github.com/encoredev/encore/runtimes"`.
var (
	alternativeEncoreRuntimesPath = ""
	alternativeEncoreGoPath       = ""
)

// EncoreRuntimesPath reports the path to the Encore runtime.
// It can be overridden by setting ENCORE_RUNTIMES_PATH.
func EncoreRuntimesPath() string {
	p := encoreRuntimesPath()
	if p == "" {
		log.Fatal().Msg("could not determine Encore install root. " +
			"You can specify the path to the Encore runtimes manually by setting the ENCORE_RUNTIMES_PATH environment variable.")
	}
	return p
}

// EncoreGoRoot reports the path to the Encore Go root.
// It can be overridden by setting ENCORE_GOROOT.
func EncoreGoRoot() string {
	p := encoreGoRoot()
	if p == "" {
		log.Fatal().Msg("could not determine Encore install root. " +
			"You can specify the path to the Encore GOROOT manually by setting the ENCORE_GOROOT environment variable.")
	}
	return p
}

// EncoreBin reports the path to the directory containing the Encore installation's binaries.
func EncoreBin() option.Option[string] {
	if root, ok := determineRoot(); ok {
		return option.Some(filepath.Join(root, "bin"))
	}
	return option.None[string]()
}

// OptEncoreGoRoot reports the path to the Encore Go root.
// It can be overridden by setting ENCORE_GOROOT.
// If the goroot can't be found, it reports None.
func OptEncoreGoRoot() option.Option[string] {
	return option.AsOptional(encoreGoRoot())
}

func encoreRuntimesPath() string {
	if p := os.Getenv("ENCORE_RUNTIMES_PATH"); p != "" {
		return p
	} else if //goland:noinspection GoBoolExpressions
	alternativeEncoreRuntimesPath != "" {
		return alternativeEncoreRuntimesPath
	} else if root, ok := determineRoot(); ok {
		return filepath.Join(root, "runtimes")
	}
	return ""
}

// EncoreRuntimeLib reports the path to the Encore runtime library for
// node.js. It can be overridden by setting ENCORE_RUNTIME_LIB.
func EncoreRuntimeLib() string {
	if p := os.Getenv("ENCORE_RUNTIME_LIB"); p != "" {
		return p
	} else if rt := encoreRuntimesPath(); rt != "" {
		return filepath.Join(rt, "js", "encore-runtime.node")
	}
	return ""
}

// EncoreDaemonLogPath reports the path to the Encore daemon log file.
// It can be overridden by setting ENCORE_DAEMON_LOG_PATH.
func EncoreDaemonLogPath() string {
	if p := os.Getenv("ENCORE_DAEMON_LOG_PATH"); p != "" {
		return p
	}
	cache, err := os.UserCacheDir()
	if err != nil {
		log.Fatal().Err(err).Msg("unable to determine user cache directory")
	}
	return filepath.Join(cache, "encore", "daemon.log")
}

// EncoreDevDashListenAddr reports the listen address for
// where the daemon exposes the dev dash.
// It can be overridden by setting ENCORE_DEVDASH_LISTEN_ADDR.
func EncoreDevDashListenAddr() option.Option[string] {
	if p := os.Getenv("ENCORE_DEVDASH_LISTEN_ADDR"); p != "" {
		return option.Some(p)
	}
	return option.None[string]()
}

// EncoreMCPSSEListenAddr reports the listen address for
// where the daemon exposes the MCP SSE endpoint.
// It can be overridden by setting ENCORE_MCPSSE_LISTEN_ADDR.
func EncoreMCPSSEListenAddr() option.Option[string] {
	if p := os.Getenv("ENCORE_MCPSSE_LISTEN_ADDR"); p != "" {
		return option.Some(p)
	}
	return option.None[string]()
}

func EncoreObjectStorageListAddr() option.Option[string] {
	if p := os.Getenv("ENCORE_OBJECTSTORAGE_LISTEN_ADDR"); p != "" {
		return option.Some(p)
	}
	return option.None[string]()
}

// EncoreDebug reports the value of the ENCOREDEBUG environment variable,
// a comma-separated list of key=value pairs that toggle non-default daemon
// behavior (e.g. ENCOREDEBUG=sqldbrole=legacy).
func EncoreDebug() option.Option[string] {
	if p := os.Getenv("ENCOREDEBUG"); p != "" {
		return option.Some(p)
	}
	return option.None[string]()
}

func encoreGoRoot() string {
	if p := os.Getenv("ENCORE_GOROOT"); p != "" {
		return p
	} else if //goland:noinspection GoBoolExpressions
	alternativeEncoreGoPath != "" {
		return alternativeEncoreGoPath
	} else if root, ok := determineRoot(); ok {
		return filepath.Join(root, "encore-go")
	}
	return ""
}

// List reports Encore environment variables, in the same format as os.Environ().
func List() []string {
	return []string{
		"ENCORE_GOROOT=" + encoreGoRoot(),
		"ENCORE_RUNTIMES_PATH=" + encoreRuntimesPath(),
		"ENCORE_RUNTIME_LIB=" + EncoreRuntimeLib(),
		"ENCORE_DAEMON_LOG_PATH=" + EncoreDaemonLogPath(),
	}
}

// determineRoot determines encore root by checking the location relative
// to the executable, to enable relocatable installs.
func determineRoot() (root string, ok bool) {
	exe, err := os.Executable()
	if err == nil {
		// Homebrew uses a lot of symlinks, so we need to get back to the actual location
		// to be able to use the heuristic below.
		if sym, err := filepath.EvalSymlinks(exe); err == nil {
			exe = sym
		}

		root := filepath.Dir(filepath.Dir(exe))
		// Heuristic: check if "encore-go" and "runtime" dirs exist in this location.
		_, err1 := os.Stat(filepath.Join(root, "encore-go"))
		_, err2 := os.Stat(filepath.Join(root, "runtimes", "go"))
		if err1 == nil && err2 == nil {
			return root, true
		}
	}
	return "", false
}

// IsSSH reports whether the current session is an SSH session.
func IsSSH() bool {
	if os.Getenv("SSH_TTY") != "" || os.Getenv("SSH_CONNECTION") != "" || os.Getenv("SSH_CLIENT") != "" {
		return true
	}
	return false
}