moonrepo / proto

A pluggable multi-language version manager.
https://moonrepo.dev/proto
MIT License
631 stars 30 forks source link

PROTO_HOME not being exported during proto activate #550

Closed W1M0R closed 1 month ago

W1M0R commented 1 month ago

What version?

0.38.2

Which command?

proto activate --export pwsh

What happened?

To prevent proto from breaking the environment for non-proto projects, I am currently taking the approach of manually setting the process environment variables in proto projects, by running a lightweight script to configure the environment before executing proto (or other commands that need to run in the proto environment).

These are the environment setup steps:

$Env:PROTO_HOME = Join-Path $Env:USERPROFILE ".proto"

# Here we establish the pecking order of commands we want to execute in the environment. First try proto, then try pixi, then wasmer, then scoop.
$Env:PATH = @(
  (Join-Path $Env:USERPROFILE ".proto/shims")
  (Join-Path $Env:USERPROFILE ".proto/bin")
  (Join-Path $Env:USERPROFILE ".pixi/bin")
  (Join-Path $Env:USERPROFILE ".wasmer/bin")
  (Join-Path $Env:USERPROFILE "scoop/shims")
  $Env:PATH
) -join [IO.Path]::PathSeparator

# If proto is not installed, download the installer script and execute it with custom flags to prevent environment modification.
if (-Not (Get-Command proto -ErrorAction SilentlyContinue)) {
  $tmpScriptPath = Join-Path -Path $Env:TEMP -ChildPath "proto.ps1"
  $wc = New-Object Net.Webclient
  [void]($wc.downloadFile("https://moonrepo.dev/install/proto.ps1", $tmpScriptPath))
  & $tmpScriptPath --no-modify-profile --no-modify-path --yes
}

proto upgrade
echo "Your profile is here: $PROFILE"
proto setup --shell pwsh --no-modify-profile --no-modify-path --yes

# intentionally only printing the activation script, not evaluating the activation
proto activate --export pwsh

proto use
proto diagnose --shell pwsh

The output of proto activate --export pwsh is:

$env:PATH = @(
  "C:\Users\user2\.proto\shims"
  "\\?\C:\Users\user2\go\bin"
  "C:\Users\user2\.proto\bin"
  $env:PATH
) -join [IO.PATH]::PathSeparator;

There are two things strange here:

  1. "\\?\C:\Users\user2\go\bin" - I don't know why this is in the output (I suspect it might have to do with the go plugin globals) - but the format uses UNC path, which is strange. And it also inserts a non-proto package in between the proto paths. Unless this is the proto version of go somehow installed outside the proto folders.
  2. The activation script does not set $env:PROTO_HOME.

Searching for PROTO_HOME in the codebase, it looks like it is used by shims or elsewhere, so it should probably be set. In my script I am setting PROTO_HOME and PATH manually, but ideally I would just call proto activate --export pwsh | iex (or something to that effect), and it would set PROTO_HOME and PATH.

This installation approach is not the conventional method, so I understand that PROTO_HOME can typically be assumed to have been set at installation time - at least for the PowerShell profile (not in the user environment variables - I think).

To accomodate this non-conventional installation method, the proto activate command could potentially check if a PROTO_HOME is present, and if not, calculate a value for it (probably based on the location of the running proto instance) and add it to the list of exported variables. Alternatively, always export PROTO_HOME since overwriting an existing value shouldn't really matter.

Trace logs?

❯ proto activate --export pwsh
...
[DEBUG 21:35:09.321] proto_core::tool  Resolved to 1.30.0 (without validation)  tool="just" version="1.30.0"
[DEBUG 21:35:09.322] proto_core::tool  Checking if tool is installed  tool="go" install_dir="C:\\Users\\user2\\.proto\\tools\\go\\1.19.13"
[DEBUG 21:35:09.322] proto_core::tool  Tool has already been installed, locating binaries and shims  tool="task" install_dir="C:\\Users\\user2\\.proto\\tools\\task\\3.38.0"
[DEBUG 21:35:09.323] proto_core::tool  Locating executable for tool  tool="pixi"
[DEBUG 21:35:09.323] proto_core::tool  Checking if tool is installed  tool="sttr" install_dir="C:\\Users\\user2\\.proto\\tools\\sttr\\0.2.22"
[DEBUG 21:35:09.323] proto_core::tool  Checking if tool is installed  tool="aqua" install_dir="C:\\Users\\user2\\.proto\\tools\\aqua\\2.29.2"
[DEBUG 21:35:09.323] proto_core::tool  Checking if tool is installed  tool="just" install_dir="C:\\Users\\user2\\.proto\\tools\\just\\1.30.0"
[DEBUG 21:35:09.324] proto_core::tool  Locating executable for tool  tool="watchexec"
[DEBUG 21:35:09.324] proto_core::tool  Tool has already been installed, locating binaries and shims  tool="go" install_dir="C:\\Users\\user2\\.proto\\tools\\go\\1.19.13"
[DEBUG 21:35:09.324] proto_core::tool  Locating executable for tool  tool="task"
[DEBUG 21:35:09.325] proto_core::tool  Tool has already been installed, locating binaries and shims  tool="sttr" install_dir="C:\\Users\\user2\\.proto\\tools\\sttr\\0.2.22"
[DEBUG 21:35:09.326] proto_core::tool  Tool has already been installed, locating binaries and shims  tool="just" install_dir="C:\\Users\\user2\\.proto\\tools\\just\\1.30.0"
[DEBUG 21:35:09.326] proto_core::tool  Tool has already been installed, locating binaries and shims  tool="aqua" install_dir="C:\\Users\\user2\\.proto\\tools\\aqua\\2.29.2"
[DEBUG 21:35:09.327] proto_core::tool  Locating executable for tool  tool="go"
[TRACE 21:35:09.327] warpgate::plugin  Calling plugin function locate_executables  id="pixi" plugin="d1f76fac-9c7a-48f3-83c7-afef0595262e" input={"context":{"proto_version":"0.38.2","tool_dir":{"path":"/proto/tools/pixi/0.25.0","virtual_prefix":"/proto","real_prefix":"C:\\Users\\user2\\.proto"},"version":"0.25.0"}}
[DEBUG 21:35:09.328] proto_core::tool  Locating executable for tool  tool="sttr"
[TRACE 21:35:09.328] warpgate::plugin  Calling plugin function locate_executables  id="watchexec" plugin="b583f052-99ec-4819-b089-430d03c78881" input={"context":{"proto_version":"0.38.2","tool_dir":{"path":"/proto/tools/watchexec/2.0.0","virtual_prefix":"/proto","real_prefix":"C:\\Users\\user2\\.proto"},"version":"2.0.0"}}
[DEBUG 21:35:09.329] proto_core::tool  Locating executable for tool  tool="aqua"
[DEBUG 21:35:09.329] proto_core::tool  Locating executable for tool  tool="just"
[TRACE 21:35:09.328] warpgate::plugin  Calling plugin function locate_executables  id="task" plugin="5ff347c6-2343-412d-84a8-ecd6a2adb88c" input={"context":{"proto_version":"0.38.2","tool_dir":{"path":"/proto/tools/task/3.38.0","virtual_prefix":"/proto","real_prefix":"C:\\Users\\user2\\.proto"},"version":"3.38.0"}}
[TRACE 21:35:09.330] warpgate::plugin  Calling plugin function locate_executables  id="go" plugin="a965a210-1afc-4cc5-b680-1ce0b248d7f1" input={"context":{"proto_version":"0.38.2","tool_dir":{"path":"/proto/tools/go/1.19.13","virtual_prefix":"/proto","real_prefix":"C:\\Users\\user2\\.proto"},"version":"1.19.13"}}
[TRACE 21:35:09.330] warpgate::plugin  Called plugin function locate_executables  id="pixi" plugin="d1f76fac-9c7a-48f3-83c7-afef0595262e" output={"primary":{"exe_path":"pixi.exe"}}
[TRACE 21:35:09.331] warpgate::plugin  Calling plugin function locate_executables  id="sttr" plugin="c642488f-4223-4e47-a5d3-d6b76151d21c" input={"context":{"proto_version":"0.38.2","tool_dir":{"path":"/proto/tools/sttr/0.2.22","virtual_prefix":"/proto","real_prefix":"C:\\Users\\user2\\.proto"},"version":"0.2.22"}}
[TRACE 21:35:09.332] warpgate::plugin  Calling plugin function locate_executables  id="just" plugin="4818e271-1533-4050-b511-365e5fddd7f4" input={"context":{"proto_version":"0.38.2","tool_dir":{"path":"/proto/tools/just/1.30.0","virtual_prefix":"/proto","real_prefix":"C:\\Users\\user2\\.proto"},"version":"1.30.0"}}
[TRACE 21:35:09.331] warpgate::plugin  Called plugin function locate_executables  id="watchexec" plugin="b583f052-99ec-4819-b089-430d03c78881" output={"primary":{"exe_path":"watchexec.exe"}}
[TRACE 21:35:09.332] warpgate::plugin  Called plugin function locate_executables  id="task" plugin="5ff347c6-2343-412d-84a8-ecd6a2adb88c" output={"primary":{"exe_path":"task.exe"}}
[TRACE 21:35:09.332] warpgate::plugin  Calling plugin function locate_executables  id="aqua" plugin="9d57a14d-dfc2-4097-93bb-6ceb209cacd0" input={"context":{"proto_version":"0.38.2","tool_dir":{"path":"/proto/tools/aqua/2.29.2","virtual_prefix":"/proto","real_prefix":"C:\\Users\\user2\\.proto"},"version":"2.29.2"}}
[DEBUG 21:35:09.333] proto_core::tool  Found an executable  tool="pixi" exe_path="C:\\Users\\user2\\.proto\\tools\\pixi\\0.25.0\\pixi.exe"
[TRACE 21:35:09.333] warpgate::plugin  Called plugin function locate_executables  id="go" plugin="a965a210-1afc-4cc5-b680-1ce0b248d7f1" output={"globals_lookup_dirs":["$GOBIN","$GOROOT/bin","$GOPATH/bin","$HOME/go/bin"],"primary":{"exe_path":"bin/go.exe"},"secondary":{"gofmt":{"exe_path":"bin/gofmt.exe"}}}
[DEBUG 21:35:09.335] proto_core::tool  Found an executable  tool="task" exe_path="C:\\Users\\user2\\.proto\\tools\\task\\3.38.0\\task.exe"
[DEBUG 21:35:09.335] proto_core::tool  Found an executable  tool="watchexec" exe_path="C:\\Users\\user2\\.proto\\tools\\watchexec\\2.0.0\\watchexec.exe"
[TRACE 21:35:09.335] warpgate::plugin  Called plugin function locate_executables  id="sttr" plugin="c642488f-4223-4e47-a5d3-d6b76151d21c" output={"primary":{"exe_path":"sttr.exe"}}
[TRACE 21:35:09.336] warpgate::plugin  Called plugin function locate_executables  id="just" plugin="4818e271-1533-4050-b511-365e5fddd7f4" output={"primary":{"exe_path":"just.exe"}}
[DEBUG 21:35:09.337] proto_core::tool  Found an executable  tool="go" exe_path="C:\\Users\\user2\\.proto\\tools\\go\\1.19.13\\bin/go.exe"
[TRACE 21:35:09.338] warpgate::plugin  Called plugin function locate_executables  id="aqua" plugin="9d57a14d-dfc2-4097-93bb-6ceb209cacd0" output={"primary":{"exe_path":"aqua.exe"}}
[DEBUG 21:35:09.339] proto_core::tool  Found an executable  tool="sttr" exe_path="C:\\Users\\user2\\.proto\\tools\\sttr\\0.2.22\\sttr.exe"
[DEBUG 21:35:09.339] proto_core::tool  Found an executable  tool="just" exe_path="C:\\Users\\user2\\.proto\\tools\\just\\1.30.0\\just.exe"
[DEBUG 21:35:09.341] proto_core::tool  Found an executable  tool="aqua" exe_path="C:\\Users\\user2\\.proto\\tools\\aqua\\2.29.2\\aqua.exe"
[DEBUG 21:35:09.342] proto_core::tool  Locating globals bin directories for tool  tool="pixi"
[DEBUG 21:35:09.343] proto_core::tool  Locating globals bin directories for tool  tool="watchexec"
[DEBUG 21:35:09.344] proto_core::tool  Locating globals bin directories for tool  tool="task"
[DEBUG 21:35:09.345] proto_core::tool  Locating globals bin directories for tool  tool="sttr"
[DEBUG 21:35:09.345] proto_core::tool  Located possible globals directories  tool="pixi" dirs=[]
[DEBUG 21:35:09.346] proto_core::tool  Locating globals bin directories for tool  tool="go"
[DEBUG 21:35:09.346] proto_core::tool  Locating globals bin directories for tool  tool="just"
[DEBUG 21:35:09.346] proto_core::tool  Located possible globals directories  tool="watchexec" dirs=[]
[DEBUG 21:35:09.346] proto_core::tool  Located possible globals directories  tool="task" dirs=[]
[DEBUG 21:35:09.347] proto_core::tool  Locating globals bin directories for tool  tool="aqua"
[DEBUG 21:35:09.348] proto_core::tool  Located possible globals directories  tool="sttr" dirs=[]
[DEBUG 21:35:09.349] proto_core::tool  Located possible globals directories  tool="go" dirs=["C:\\Users\\user2/go/bin"]
[DEBUG 21:35:09.349] proto_core::tool  Located possible globals directories  tool="just" dirs=[]
[DEBUG 21:35:09.350] proto_core::tool  Located possible globals directories  tool="aqua" dirs=[]
$env:PATH = @(
  "C:\Users\user2\.proto\shims"
  "\\?\C:\Users\user2\go\bin"
  "C:\Users\user2\.proto\bin"
  $env:PATH
) -join [IO.PATH]::PathSeparator;
[TRACE 21:35:09.879] starbase_utils::net::offline  Resolving 142.251.47.174:80
[TRACE 21:35:09.927] starbase_utils::net  Online!
[TRACE 21:35:09.928] starbase_utils::fs  Reading file  file="C:\\Users\\user2\\.proto\\temp\\.last-version-check"
[TRACE 21:35:09.930] starbase::app  Running shutdown phase
...

Operating system?

Windows

Architecture?

x64

milesj commented 1 month ago

@W1M0R To start, PROTO_HOME is not required. It just defaults to ~/.proto if not defined. It really only needs to be set when changing to a different location then that, but our proto setup just writes it to the profile anyways.

"\\?\C:\Users\user2\go\bin" - I don't know why this is in the output (I suspect it might have to do with the go plugin globals) - but the format uses UNC path, which is strange. And it also inserts a non-proto package in between the proto paths. Unless this is the proto version of go somehow installed outside the proto folders.

proto activate includes bin directory paths from all tools, for both locally installed bins (in the tool directory itself), and globally installed bins (via a package manager or something else). So that go/bin path is coming from the go plugin.

As for the UNC path, does that actually cause issues? Rust just uses UNC internally when things are canonicalized.

W1M0R commented 1 month ago

I've seen the UNC path cause issues on Windows in other environments:

  1. https://github.com/watchexec/watchexec/issues/830
  2. https://github.com/casey/just/issues/1167#issuecomment-2225595826

But in terms of proto, go executes as expected.

W1M0R commented 1 month ago

I'm guessing this check for PROTO_HOME is not such a big deal then:

  1. https://github.com/moonrepo/proto/blob/de3803ef40b1982a36722d8f088505246e4eb19d/crates/cli/src/commands/diagnose.rs#L181-L189
milesj commented 1 month ago

Ah yeah. That's why it's a warning right now, but it's more like an informational message.

I'll look into trimming UNC, because I hate dealing with them anyways.

milesj commented 1 month ago

Fixed both of these in 0.39.1