apply-refact-0.9.2.0: src/Refact/Run.hs
{-# LANGUAGE RecordWildCards #-}
module Refact.Run (refactMain, runPipe) where
import Language.Haskell.GHC.ExactPrint.Utils
import Refact.Apply (parseExtensions)
import qualified Refact.Types as R
import Refact.Types hiding (SrcSpan)
import Refact.Fixity
import Refact.Internal
( Verbosity(..)
, apply
, onError
, parseModuleWithArgs
)
import Refact.Options (Options(..), optionsWithHelp)
import Control.Monad
import Data.List hiding (find)
import Data.Maybe
import Data.Version
import Options.Applicative
import System.IO.Extra
import System.FilePath.Find
import System.Exit
import qualified System.PosixCompat.Files as F
import Paths_apply_refact
import Debug.Trace
refactMain :: IO ()
refactMain = do
o@Options{..} <- execParser optionsWithHelp
when optionsVersion (putStr ("v" ++ showVersion version) >> exitSuccess)
unless (isJust optionsTarget || isJust optionsRefactFile) . die $
"Must specify either the target file, or the refact file, or both.\n"
++ "If either the target file or the refact file is not specified, "
++ "it will be read from stdin.\n"
++ "To show usage, run 'refactor -h'."
case optionsTarget of
Nothing ->
withTempFile $ \fp -> do
getContents >>= writeFileUTF8 fp
runPipe o fp
Just target -> do
targetStatus <- F.getFileStatus target
if F.isDirectory targetStatus
then findHsFiles target >>= mapM_ (runPipe o)
else runPipe o target
-- Given base directory finds all haskell source files
findHsFiles :: FilePath -> IO [FilePath]
findHsFiles = find filterDirectory filterFilename
filterDirectory :: FindClause Bool
filterDirectory =
p <$> fileName
where
p x
| "." `isPrefixOf` x = False
| otherwise = True
filterFilename :: FindClause Bool
filterFilename = do
ext <- extension
fname <- fileName
pure (ext == ".hs" && p fname)
where
p x
| "Setup.hs" `isInfixOf` x = False
| otherwise = True
runPipe :: Options -> FilePath -> IO ()
runPipe Options{..} file = do
let verb = optionsVerbosity
rawhints <- getHints optionsRefactFile
when (verb == Loud) (traceM "Got raw hints")
let inp :: [(String, [Refactoring R.SrcSpan])] = read rawhints
n = length inp
when (verb == Loud) (traceM $ "Read " ++ show n ++ " hints")
output <- if null inp then readFileUTF8' file else do
when (verb == Loud) (traceM "Parsing module")
let (enabledExts, disabledExts, invalidExts) = parseExtensions optionsLanguage
unless (null invalidExts) . when (verb >= Normal) . putStrLn $
"Invalid extensions: " ++ intercalate ", " invalidExts
(as, m) <- either (onError "runPipe") (uncurry applyFixities)
=<< parseModuleWithArgs (enabledExts, disabledExts) file
when optionsDebug (putStrLn (showAnnData as 0 m))
apply optionsPos optionsStep inp (Just file) verb as m
if optionsInplace && isJust optionsTarget
then writeFileUTF8 file output
else case optionsOutput of
Nothing -> putStr output
Just f -> do
when (verb == Loud) (traceM $ "Writing result to " ++ f)
writeFileUTF8 f output
getHints :: Maybe FilePath -> IO String
getHints (Just hintFile) = readFileUTF8' hintFile
getHints Nothing = getContents