active_sh.erl 879 B

12345678910111213141516171819202122232425262728293031323334
  1. -module(active_sh).
  2. -export([
  3. reduce/0,
  4. run/1,
  5. sh/1,
  6. sh/3,
  7. exe/1
  8. ]).
  9. % {status,code,msg} = :active_sh.exe(String.to_charlist("mix compile"))
  10. reduce() ->
  11. fun({_, Chunk}, Acc) ->
  12. [Chunk|Acc]
  13. end.
  14. run(Args) ->
  15. erlang:open_port({spawn_executable, os:find_executable("sh")},
  16. [stream, in, out, eof, use_stdio, stderr_to_stdout, binary, exit_status,
  17. {args, ["-c", Args]}, {cd, erlang:element(2, file:get_cwd())}, {env, []}]).
  18. sh(Port) -> sh(Port, reduce(), []).
  19. sh(Port, Fun, Acc) ->
  20. receive
  21. {Port, {exit_status, Status}} -> {done, Status, erlang:iolist_to_binary(lists:reverse(Acc))};
  22. {Port, {data, {eol, Line}}} -> sh(Port, Fun, Fun({eol, Line}, Acc));
  23. {Port, {data, {noeol, Line}}} -> sh(Port, Fun, Fun({noeol, Line}, Acc));
  24. {Port, {data, Data}} -> sh(Port, Fun, Fun({data,Data}, Acc))
  25. end.
  26. exe(X) -> sh(run(X)).