@@ -15,6 +15,8 @@ defmodule Expert.Port do
1515
1616 @ type open_opts :: [ open_opt ]
1717
18+ @ path_marker "__EXPERT_PATH__"
19+
1820 @ doc """
1921 Launches elixir in a port.
2022
@@ -62,32 +64,38 @@ defmodule Expert.Port do
6264 # or we get an incomplete PATH not including erl or any other version manager
6365 # managed programs.
6466
67+ # Disable shell session history to reduce noise
6568 env = [ { "SHELL_SESSIONS_DISABLE" , "1" } ]
6669
67- path =
70+ args =
6871 case Path . basename ( shell ) do
6972 # Ideally, it should contain the path to shell (e.g. `/usr/bin/fish`),
7073 # but it might contain only the name of the shell (e.g. `fish`).
7174 "fish" ->
7275 # Fish uses space-separated PATH, so we use the built-in `string join` command
7376 # to join the entries with colons and have a standard colon-separated PATH output
7477 # as in bash, which is expected by `:os.find_executable/2`.
75- { path , 0 } =
76- System . cmd ( shell , [ "-l" , "-c" , "cd #{ directory } && string join ':' $PATH" ] , env: env )
78+ # Also, no -i flag
79+ cmd =
80+ "cd #{ directory } ; printf \" #{ @ path_marker } :%s:#{ @ path_marker } \" (string join ':' $PATH)"
7781
78- path
82+ [ "-l" , "-c" , cmd ]
7983
8084 _ ->
81- { path , 0 } =
82- System . cmd ( shell , [ "-i" , "-l" , "-c" , "cd #{ directory } && echo $PATH" ] , env: env )
83-
84- path
85+ cmd = "cd #{ directory } && printf \" #{ @ path_marker } :%s:#{ @ path_marker } \" \" $PATH\" "
86+ [ "-i" , "-l" , "-c" , cmd ]
8587 end
8688
87- path
88- |> String . trim ( )
89- |> String . split ( "\n " )
90- |> List . last ( )
89+ { output , _ } = System . cmd ( shell , args , env: env )
90+
91+ # This ignores banners (start) and logout garbage (end)
92+ case Regex . run ( ~r/ #{ @ path_marker } :(.*?):#{ @ path_marker } / s , output ) do
93+ [ _ , clean_path ] ->
94+ clean_path
95+
96+ nil ->
97+ output |> String . trim ( ) |> String . split ( "\n " ) |> List . last ( )
98+ end
9199 end
92100
93101 @ doc """
0 commit comments