Open essen opened 8 years ago
Is there even a way to get that prompt when shelling out with os:cmd?
We don't use os:cmd
, we open a port.
In this case I think we could but only if this line: https://github.com/erlang/rebar3/blob/master/src/rebar_utils.erl#L172
Drops the {line, L}
option so that whenever a prompt is hit, we can see about it right away.
Here's a test with a toy escript:
-module(e).
main(_) ->
io:format("> ~p", [io:get_line("? ")]).
And the caller:
1> P = open_port({spawn, "escript /tmp/e.erl"}, [exit_status, use_stdio, stderr_to_stdout, hide, eof]).
#Port<0.605>
2> flush().
Shell got {#Port<0.605>,{data,"? "}}
ok
3> erlang:port_command(P, "ok\n").
true
4> flush().
Shell got {#Port<0.605>,{data,"> \"ok\\n\""}}
Shell got {#Port<0.605>,{exit_status,0}}
Shell got {#Port<0.605>,eof}
Without this, we never get any content.
I'm not super comfortable replacing that shell for good so if we had to do it, I would probably keep https://github.com/erlang/rebar3/blob/master/src/rebar_utils.erl#L159 as is, but add another one like rebar_utils:promptable_sh(Command0, Options0, PromptMatch) -> ...
where PromptMatch
is a snippet or a regex for a matching expression.
So if we were to run the command above, it could be with rebar_utils:promptable_sh("git clone ...", [Opts], "^Are you sure .* \\(yes/no\\)\\?")
. If the prompt matches, all of the output accumulated so far from the port is output to the user and io:get_line("")
is called to capture the input (possibly with a timeout, so runs on travis and so on don't idle forever), which is then passed to the user.
The same situation with prompt passphrase
===> Fetching secret ({git,
"ssh://some_secret.git",
{ref,
"ohlol"}})
===> Failed to fetch and copy dep: {git,
"ssh://some_secret.git",
{ref,
"oh lol"}}
Manually:
git clone ssh://some_secret.git
Cloning into 'some_secret'...
Enter passphrase for key '/../.ssh/id_rsa':
So, I can't enter my passphrase =(
solution of my problem -- using ssh-add
❯❯❯❯ ./rebar3 get-deps
===> Verifying dependencies...
===> Upgrading def (from {git,"ssh://git@bitbucket:7999/abc/def.git",
{ref,"45d57eeee38676b495b8061ad1d19ff7e4f79013"}})
===> Failed to fetch and copy dep: {git,
"ssh://git@bitbucket:7999/abc/def.git",
{ref,
"45d57eeee38676b495b8061ad1d19ff7e4f79013"}}
❯❯❯❯ git clone ssh://git@bitbucket:7999/abc/def.git ../aaa
Cloning into '../aaa'...
remote: Enumerating objects: 356, done.
remote: Counting objects: 100% (356/356), done.
remote: Compressing objects: 100% (283/283), done.
remote: Total 356 (delta 122), reused 212 (delta 32), pack-reused 0
Receiving objects: 100% (356/356), 7.02 MiB | 0 bytes/s, done.
Resolving deltas: 100% (122/122), done.
❯❯❯❯
a quite weird behavior. is there any chance to workaround it?
We just have chosen not to implement that at this time because it is quite messy as a workflow for a somewhat rare condition (even if really annoying whenever it happens), but if someone had a solid implementation that was testable I wouldn't see much of a problem.
Trying to fetch from git+ssh from a new host that wasn't yet added to the list of allowed hosts:
Trying manually:
I'd expect rebar3 to give me the yes/no prompt, or at least a more helpful message by default.