Search code examples
ioelixirelixir-mix

Save color of the System.cmd output in placing it to IO in elixir


I have a pretty simple mix task, actually it wraps npm command and returns it output to the command line:

defmodule Mix.Tasks.JsLint do
  use Mix.Task

  @shortdoc "Runs javascript lint"
  def run(_args) do
    System.cmd("npm", ["run", "lint"], into: IO.stream(:stdio, :line), stderr_to_stdout: true)
  end
end

The problem is that if I run npm run lint in the command line, it returns coloured output. But if I running mix js_lint it returns not-coloured output.

Where I loose colours? How can I fix that?

UPDATE I'm using eslint.


Solution

  • The problem here is that most terminal applications use isatty (or equivalent) to check if stdout is an interactive shell, and disable colored output if it is, so that the escape sequences to change colors don't end up in your log files etc. I don't know of any simple way to spawn a process and make that process think it's attached to a terminal (there are some, like this or using a package like porcelain), but since you're using eslint, you can force it to output colors even if it think it's not running interactively by passing --color to it. You can add that to the "lint" entry in package.json, so if your old entry was:

    "lint": "eslint ."
    

    change that to:

    "lint": "eslint . --color"