bitwalker / distillery

Simplify deployments in Elixir with OTP releases!
MIT License
2.97k stars 400 forks source link

Some IEx autocomplete features do not work in a distillery remote console #343

Closed myronmarston closed 6 years ago

myronmarston commented 7 years ago

Steps to reproduce

  1. On a host running a deployed distillery app, run bin/<app_name> remote_console to get an IEx console.
  2. Create a map and bind it to a variable, like map = %{foo: 1}.
  3. Try autocompleting the map variable by typing m<TAB> -- it does not autocomplete ap
  4. Try autocompleting the map keys by typing map.f<TAB> -- it does not autocomplete oo

Verbose Logs

I don't have this handy, since I'm reporting this after connecting to a running node with remote_console. I doubt it's necessary but let me know if you need it.

Description of issue

I expect the remote_console IEx to work like any other IEx session, which supports auto completion of variables and map keys which are atoms.

Also, I've noticed that in remote_console, the output is not in color (e.g. syntax highlighting for Elixir data structures, or when printing the help output), but that never bothered me enough to report. Seems related, though: the version of IEx running for remote_console does not support all the usual features.

Ubuntu 12.04, OTP 20, Elixir 1.5.1

# Import all plugins from `rel/plugins`
# They can then be used by adding `plugin MyPlugin` to
# either an environment, or release definition, where
# `MyPlugin` is the name of the plugin module.
Path.join(["rel", "plugins", "*.exs"])
|> Path.wildcard()
|> Enum.map(&Code.eval_file(&1))

use Mix.Releases.Config,
    # This sets the default release built by `mix release`
    default_release: :default,
    # This sets the default environment used by `mix release`
    default_environment: Mix.env()

# For a full list of config options for both releases
# and environments, visit https://hexdocs.pm/distillery/configuration.html

# You may define one or more environments in this file,
# an environment's settings will override those of a release
# when building in that environment, this combination of release
# and environment configuration is called a profile

environment :dev do
  set dev_mode: true
  set include_erts: false
  set cookie: :redacted
end

environment :prod do
  set include_erts: true
  set include_src: false
  set cookie: :redacted
end

# You may define one or more releases in this file.
# If you have not set a default release, or selected one
# when running `mix release`, the first release in the file
# will be used by default

overlays_for = fn app_name ->
  app_dir = Path.expand("apps/#{app_name}", __DIR__)

  copy_commands =
    Path.wildcard("#{app_dir}/script/**/*")
    |> Enum.map(fn file_name ->
         {:copy, file_name, "script/#{Path.basename(file_name)}"}
       end)

  [{:mkdir, "script"} | copy_commands]
end

release :admin do
  set version: current_version(:admin)
  set applications: [
    :runtime_tools
  ]
  set config: Path.expand("apps/admin/config/per_app_prod_config.exs", __DIR__)
  set overlays: overlays_for.(:admin)
  set vm_args: Path.expand("rel/vm.args", __DIR__)
end

release :api do
  set version: current_version(:api)
  set applications: [
    :runtime_tools
  ]
  set config: Path.expand("apps/api/config/per_app_prod_config.exs", __DIR__)
  set overlays: overlays_for.(:api)
  set vm_args: Path.expand("rel/vm.args", __DIR__)
end

release :build_manager do
  set version: current_version(:build_manager)
  set applications: [
    :runtime_tools
  ]
  set config: Path.expand("apps/build_manager/config/per_app_prod_config.exs", __DIR__)
  set overlays: overlays_for.(:build_manager)
  set vm_args: Path.expand("rel/vm.args", __DIR__)
end

I can't find any docs that specifically call out any limitations of remote_console. If these are known limitations that can't easily be addressed, it would be nice to document them :).

bitwalker commented 7 years ago

I suspect this has to do with one of two things:

1.) the remote node is running under TERM=<something not supporting fancy features> 2.) Erlang treats remote shells differently than local ones somehow

We're not doing anything special with releases to modify the way shells are handled, the only exception is that we set TERM=xterm if TERM isn't set, or is set to dumb - this should support all of those features as far as I'm aware. Do you have the same problem when you run bin/myapp console or only with the remote console?

myronmarston commented 7 years ago

bin/myapp console does indeed fix the issue. FWIW, System.get_env("TERM") returns xterm from a remote_console.

bitwalker commented 7 years ago

Can you run bin/myapp console on that same system? If so, does it work as you expect? I'm trying to determine if the problem lies in the TERM variable/host capabilities, or in the way Erlang handles remote shells.

myronmarston commented 7 years ago

Yes, bin/myapp console fixes the issue when I run it on the same remote system.

bitwalker commented 6 years ago

I think this is due to the way Elixir determines whether the current shell is ANSI-capable, i.e. it seems to be that if IO.ANSI.enabled? is false, then color is disabled. Autocomplete appears to work fine though, at least on macOS, it may not be the case for all platforms though.