Запуск команд оболочки из Haskell в NixOS
Я довольно новичок в NixOS и пытаюсь вызвать emacs из программы на Haskell, используя следующую функцию:
ediff :: String -> String -> String -> IO ()
ediff testName a b = do
a' <- writeSystemTempFile (testName ++ ".expected") a
b' <- writeSystemTempFile (testName ++ ".received") b
let quote s = "\"" ++ s ++ "\""
callCommand $ "emacs --eval \'(ediff-files " ++ quote a' ++ quote b' ++ ")\'"
Когда я запускаю программу, которая вызывает эту команду, используя stack test
, Я получаю следующий результат (в сочетании с результатами модульного теста):
/bin/sh: emacs: command not found
Exception: callCommand: emacs --eval '(ediff-files "/run/user/1000/ast1780695788709393584.expected" "/run/user/1000/ast4917054031918502651.received")'
Когда я запускаю команду, которая не запускалась выше из моей оболочки, она работает безупречно. Как я могу запускать процессы из Haskell в NixOS, как если бы я вызывал их напрямую, чтобы они могли получать доступ к тем же командам и конфигурациям, что и мой пользователь?
1 ответ
И ваша оболочка и callCommand
использовать PATH
переменная окружения, поэтому кажется, что стек меняет это. Оказывается, в стеке по умолчанию используется чисто nix-оболочка, но вы также хотите получить доступ к своей пользовательской среде, которая является "нечистой".
Процитировать стековую документацию
По умолчанию, стек будет запускать сборку в чистой среде сборки Nix (или в оболочке), что означает, что сборка должна завершиться сбоем, если вы не указали все зависимости в пакетах: раздел файла stack.yaml, даже если эти зависимости установлены в другом месте в вашей системе. Такое поведение обеспечивает полное описание среды сборки для облегчения воспроизводимости. Чтобы переопределить это поведение, добавьте pure: false в ваш stack.yaml или передайте опцию --no-nix-pure в командную строку.
Другое решение - добавить Emacs в nix.dependencies
в stack.yaml
(спасибо @chepner). Преимущество состоит в том, что некоторые версии Emacs всегда будут доступны, когда разработчик запускает тесты, но Emacs может не быть тем Emacs, который они хотят использовать. Вы можете обойти это, используя что-то вроде ~/.config/nixpkgs/config.nix
, если они не настроили свой Emacs где-либо еще, например, в конфигурации системы или, возможно, в качестве домашнего менеджера. Я бы предпочел простой, но нечистый $PATH
решение.