-- |
--
-- Copyright:
--   This file is part of the package vimeta. It is subject to the
--   license terms in the LICENSE file found in the top-level
--   directory of this distribution and at:
--
--     https://github.com/pjones/vimeta
--
--   No part of this package, including this file, may be copied,
--   modified, propagated, or distributed except according to the terms
--   contained in the LICENSE file.
--
-- License: BSD-2-Clause
--
-- | Utility functions for running external commands.
module Vimeta.Core.Process
  ( tagFile,
  )
where

import System.Exit (ExitCode (..))
import System.Process
import Vimeta.Core.Config
import Vimeta.Core.Vimeta

-- | Run the tagging command unless dry-run mode is in effect.
tagFile :: Text -> Vimeta IO ()
tagFile :: Text -> Vimeta IO ()
tagFile Text
cmd = do
  Bool
dryRun <- Config -> Bool
configDryRun (Config -> Bool) -> Vimeta IO Config -> Vimeta IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Context -> Config) -> Vimeta IO Config
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Context -> Config
ctxConfig
  if Bool
dryRun then Vimeta IO ()
doDryRun else Vimeta IO ()
doRealRun
  where
    doDryRun :: Vimeta IO ()
    doDryRun :: Vimeta IO ()
doDryRun =
      Text -> Vimeta IO ()
forall (m :: * -> *). MonadIO m => Text -> Vimeta m ()
verbose Text
"dry run: skipping tagging command"
        Vimeta IO () -> Vimeta IO () -> Vimeta IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Vimeta IO ()
forall (m :: * -> *). MonadIO m => Text -> Vimeta m ()
verbose Text
cmd
    doRealRun :: Vimeta IO ()
    doRealRun :: Vimeta IO ()
doRealRun = do
      Text -> Vimeta IO ()
forall (m :: * -> *). MonadIO m => Text -> Vimeta m ()
verbose Text
cmd
      ExitCode
code <- IO ExitCode -> Vimeta IO ExitCode
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO ProcessHandle
spawnCommand (Text -> String
forall a. ToString a => a -> String
toString Text
cmd) IO ProcessHandle -> (ProcessHandle -> IO ExitCode) -> IO ExitCode
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ProcessHandle -> IO ExitCode
waitForProcess)

      case ExitCode
code of
        ExitCode
ExitSuccess ->
          Vimeta IO ()
forall (f :: * -> *). Applicative f => f ()
pass
        ExitFailure Int
n ->
          String -> Vimeta IO ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String
"command failed (" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall b a. (Show a, IsString b) => a -> b
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"): " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. ToString a => a -> String
toString Text
cmd)