繁体   English   中英

Elixir - 从命令行运行时,记录器 output 是彩色的,从 iex 运行时不是这样

[英]Elixir - Logger output is colorful when run from command line, not so when run from iex

在我的 Elixir 混合应用程序中运行测试时,我有一些实例包括对Logger.debug()的一些调用以监视行为。 我发现,当我从命令行调用mix test时,Logger output 是浅蓝色的,如果我在.debug()调用中添加自定义颜色,output 会相应地着色 -

test "some behavior" do
  Logger.debug("foo", ansi_color: :yellow)
  assert true
end

正如预期的那样,以黄色写入日志行。

但是,我注意到,如果我从iex session 中运行测试,则不会应用 colors,只是以默认字体颜色(在我的情况下为灰色)写入终端 -

iex(1)> Mix.shell().cmd(
          "mix test --color",
          env: [{"MIX_ENV", "test"}]
        )

为什么从 bash 命令行运行测试会导致彩色 output,而从 iex 中运行它们会导致我的默认字体颜色?

对于上下文 - 我在 Mac (Mojave) 上运行此程序,来自 bash 命令行(如前所述),Elixir 版本 1.8.1。

Admittedly, this is a fairly trivial matter in itself - but I'm trying to get a better understanding of the Elixir shell and Mix's various interactions with the shell and system, and cracking this might help me to get a better understanding of what's going on一般在引擎盖下。 这不是我所期望的,我想知道为什么。

解释在thisthis article中,但TL; DR如下:

您需要通过以下方式在iex中启用 colors:

iex> Application.put_env(:elixir, :ansi_enabled, true)

但这只是 session scope。 如果要使其永久化,则需要在当前目录或主目录中创建.iex.exs文件:

timestamp = fn ->
  {_date, {hour, minute, _second}} = :calendar.local_time
  [hour, minute]
  |> Enum.map(&(String.pad_leading(Integer.to_string(&1), 2, "0")))
  |> Enum.join(":")
end

IEx.configure(
  colors: [
    syntax_colors: [
      number: :light_yellow,
      atom: :light_cyan,
      string: :light_black,
      boolean: :red,
      nil: [:magenta, :bright],
    ],
    ls_directory: :cyan,
    ls_device: :yellow,
    doc_code: :green,
    doc_inline_code: :magenta,
    doc_headings: [:cyan, :underline],
    doc_title: [:cyan, :bright, :underline],
  ],
)

IEx.configure(
  default_prompt:
    "#{IO.ANSI.green}%prefix#{IO.ANSI.reset} " <>
    "[#{IO.ANSI.magenta}#{timestamp.()}#{IO.ANSI.reset} " <>
    ":: #{IO.ANSI.cyan}%counter#{IO.ANSI.reset}] >"
)

就这样

推理很简单 - 当标准输出在连接到标准输出的“真实”终端和 pipe 或文件时运行时,标准输出具有不同的特性。 运行时可以看到相同的行为:

mix test | cat

因为这将附加 pipe,而不是“真正的”终端(实际上它是终端仿真器,但这不在问题的 scope 范围内)。 这意味着 Elixir 不能假设生成的 stream 将支持 ANSI 转义码。 当您使用 pipe 命令来分隔工具或文件以进行进一步处理时,这一点很重要,因为这些工具中的许多工具不理解 ANSI 转义码并会导致错误的结果。

IEx中运行mix test并保留所有当前配置的最佳方法是简单地执行以下操作:

Mix.Task.rerun(:test)

这将重用当前配置。 当然,它会在当前环境下运行,但也可以通过运行MIX_ENV=test iex -S mix来访问 shell 中的整个测试环境。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM