content: 
  {-| This module is based on hgold from hspec-golden-0.2.0.0, which is MIT licensed -}
  
  module Test.Sandwich.Golden.Update (
    updateGolden
    , defaultDirGoldenTest
    ) where
  
  import Control.Monad
  import Data.Maybe
  import Data.String.Interpolate
  import System.Console.ANSI
  import System.Directory
  import System.Environment
  import UnliftIO.Exception
  
  
  defaultDirGoldenTest :: FilePath
  defaultDirGoldenTest = ".golden"
  
  updateGolden :: Maybe FilePath -> IO ()
  updateGolden (fromMaybe defaultDirGoldenTest -> dir) = do
    enableColor <- lookupEnv "NO_COLOR" >>= \case
      Nothing -> return EnableColor
      Just _ -> return DisableColor
  
    putStrLnColor enableColor green "Replacing golden with actual..."
    go enableColor dir
    putStrLnColor enableColor green "Done!"
  
    where
      go enableColor dir' = listDirectory dir' >>= mapM_ (processEntry enableColor)
  
      processEntry enableColor (((dir ++ "/") ++) -> entryInDir) = do
        isDir <- doesDirectoryExist entryInDir
        when isDir $ do
          mvActualToGolden enableColor entryInDir
          go enableColor entryInDir
  
  mvActualToGolden :: EnableColor -> FilePath -> IO ()
  mvActualToGolden enableColor testPath = do
    let actualFilePath = testPath ++ "/actual"
    let goldenFilePath = testPath ++ "/golden"
  
    exists <- doesFileExist actualFilePath
    when exists $ do
      putStr [i|  #{goldenFilePath}|]
      putStrColor enableColor magenta " <-- "
      putStrLnColor enableColor red [i|#{actualFilePath}|]
  
      renameFile actualFilePath goldenFilePath
  
  green, red, magenta :: SGR
  green = SetColor Foreground Dull Green
  red = SetColor Foreground Dull Red
  magenta = SetColor Foreground Dull Magenta
  
  putStrColor :: EnableColor -> SGR -> String -> IO ()
  putStrColor EnableColor color s = bracket_ (setSGR [color]) (setSGR [Reset]) (putStr s)
  putStrColor DisableColor _ s = putStr s
  
  putStrLnColor :: EnableColor -> SGR -> String -> IO ()
  putStrLnColor EnableColor color s = bracket_ (setSGR [color]) (setSGR [Reset]) (putStrLn s)
  putStrLnColor DisableColor _ s = putStrLn s
  
  data EnableColor = EnableColor | DisableColor
  