Сохраните цвет вывода System.cmd, поместив его в IO в elixir.

У меня есть довольно простая задача микширования, на самом деле она оборачивает команду npm и возвращает ее вывод в командную строку:

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

Проблема в том, что если я запускаю npm run lint в командной строке, он возвращает цветной вывод. Но если я запускаю mix js_lint, он возвращает нецветный вывод.

Где я теряю цвета? Как я могу это исправить?

ОБНОВЛЕНИЕ Я использую eslint.


person asiniy    schedule 23.09.2016    source источник
comment
Какую команду выполняет lint? eslint? Если это так, попробуйте добавить --color к вызову eslint.   -  person Dogbert    schedule 23.09.2016
comment
@Dogbert Я считаю, что проблема глубже: npm lint достаточно умен, чтобы видеть, что он выводит в канал, а не на консоль для подавления цветов. По сути, он внутренне проверяет is_tty или что-то подобное, получает false и подавляет цвета, чтобы удалить [^033 мусор в файле журнала.   -  person Aleksei Matiushkin    schedule 23.09.2016
comment
@Dogbert, этот трюк работает. Не могли бы вы ответить и объяснить, как это работает, пожалуйста?   -  person asiniy    schedule 23.09.2016
comment
@mudasobwa да, верно, и --color заставит включить цвета в eslint.   -  person Dogbert    schedule 23.09.2016


Ответы (1)


Проблема здесь в том, что большинство терминальных приложений используют isatty (или эквивалент), чтобы проверить, является ли stdout интерактивной оболочкой, и отключить цветной вывод, если это так, чтобы escape-последовательности для изменения цветов не попадали в ваши файлы журналов и т. д. Я не знаю какого-либо простого способа создать процесс и заставить этот процесс думать, что он подключен к терминалу (есть некоторые, например этот или с помощью такого пакета, как фарфор), но поскольку вы используете eslint, вы можете заставить его выводить цвета, даже если он считает, что он не работает в интерактивном режиме, передав ему --color. Вы можете добавить это к записи "lint" в package.json, поэтому, если ваша старая запись была:

"lint": "eslint ."

изменить это на:

"lint": "eslint . --color"
person Dogbert    schedule 23.09.2016