Add option to convert pre/post qualified

This commit is contained in:
Ali Abrar 2023-07-24 11:36:19 -04:00
parent 3bea6e1ccb
commit d11e3fcfa5
2 changed files with 41 additions and 18 deletions

View File

@ -6,23 +6,29 @@ import Options.Applicative
import SortImports (sortImports) import SortImports (sortImports)
import System.Environment (getArgs) import System.Environment (getArgs)
import System.IO (hReady, stdin) import System.IO (hReady, stdin)
import SortImports.Types (Qualified(..))
versionNumber :: String versionNumber :: String
versionNumber = "v1.2.0" versionNumber = "v1.2.0"
version :: Parser Options version :: Parser Mode
version = flag' Version $ mconcat version = flag' Version $ mconcat
[ long "version" [ long "version"
, short 'v' , short 'v'
, help "Version number" , help "Version number"
] ]
data Options data Mode
= Version = Version
| FileInput FilePath | FileInput FilePath
| StdInput | StdInput
fileInput :: Parser Options data Options = Options
{ _options_mode :: Mode
, _options_convert :: Maybe Qualified
}
fileInput :: Parser Mode
fileInput = FileInput <$> strOption (mconcat fileInput = FileInput <$> strOption (mconcat
[ long "file" [ long "file"
, short 'f' , short 'f'
@ -30,27 +36,40 @@ fileInput = FileInput <$> strOption (mconcat
, help "Input file" , help "Input file"
]) ])
stdInput :: Parser Options stdInput :: Parser Mode
stdInput = flag' StdInput $ mconcat stdInput = flag' StdInput $ mconcat
[ long "stdin" [ long "stdin"
, help "Read input from stdin" , help "Read input from stdin"
] ]
convertToQualifiedPost :: Parser Bool
convertToQualifiedPost = switch (long "convert-to-qualified-post" <> help "Whether to convert all qualified imports to use ImportQualifiedPost")
convertToQualifiedPre :: Parser Bool
convertToQualifiedPre = switch (long "convert-to-qualified-pre" <> help "Whether to convert all ImportQualifiedPost imports to use older \"import qualified\" syntax")
options :: Parser Options options :: Parser Options
options = version <|> fileInput <|> stdInput options = Options
<$> (version <|> fileInput <|> stdInput)
<*> (post <|> pre)
where
post = ((\x -> if x then Just Qualified_Post else Nothing) <$> convertToQualifiedPost)
pre = ((\x -> if x then Just Qualified_Pre else Nothing) <$> convertToQualifiedPre)
run :: Options -> IO () run :: Options -> IO ()
run = \case run opts = case _options_mode opts of
Version -> putStrLn versionNumber Version -> putStrLn versionNumber
FileInput path -> readFile path >>= putStr . sortImports FileInput path -> readFile path >>= putStr . (sortImports convert)
StdInput -> interact sortImports StdInput -> interact (sortImports convert)
where
convert = _options_convert opts
main :: IO () main :: IO ()
main = do main = do
noArgs <- null <$> getArgs noArgs <- null <$> getArgs
anyStdin <- hReady stdin anyStdin <- hReady stdin
if noArgs && anyStdin if noArgs && anyStdin
then run StdInput then run (Options StdInput Nothing)
else execParser opts >>= run else execParser opts >>= run
where opts = info (options <**> helper) $ mconcat where opts = info (options <**> helper) $ mconcat
[ briefDesc [ briefDesc

View File

@ -93,8 +93,8 @@ exposure = do
hiding <- isJust <$> optional (rword "hiding") hiding <- isJust <$> optional (rword "hiding")
(if hiding then Hidden else Exposed) <$> exports (if hiding then Hidden else Exposed) <$> exports
module' :: Parser Module module' :: Maybe Qualified -> Parser Module
module' = do module' cfgQualified = do
void $ rword "import" void $ rword "import"
_qualified' <- isJust <$> optional (rword "qualified") _qualified' <- isJust <$> optional (rword "qualified")
_name <- moduleName _name <- moduleName
@ -102,15 +102,19 @@ module' = do
_alias <- optional alias _alias <- optional alias
_exports <- optional exposure _exports <- optional exposure
space space
let _qualified = if _qualified' then Just Qualified_Pre else if _qualified'' then Just Qualified_Post else Nothing let _qualified = case cfgQualified of
Nothing -> if _qualified'
then Just Qualified_Pre
else if _qualified'' then Just Qualified_Post else Nothing
Just q -> if (_qualified' || _qualified'') then Just q else Nothing
pure Module {..} pure Module {..}
sortExports :: Module -> Module sortExports :: Module -> Module
sortExports m = m { _exports = fmap sort <$> _exports m } sortExports m = m { _exports = fmap sort <$> _exports m }
lineType :: String -> LineType lineType :: Maybe Qualified -> String -> LineType
lineType x = lineType mq x =
case parse module' "" x of case parse (module' mq) "" x of
Left _ -> CodeLine x Left _ -> CodeLine x
Right m -> ModuleLine m Right m -> ModuleLine m
@ -127,12 +131,12 @@ sortIfModules xs@(ModuleLine _:_) = sort . fmap f $ xs
where f (ModuleLine x) = ModuleLine $ sortExports x where f (ModuleLine x) = ModuleLine $ sortExports x
f x = x f x = x
sortImports :: String -> String sortImports :: Maybe Qualified -> String -> String
sortImports sortImports mq
= unlines = unlines
. fmap (\case CodeLine x -> x . fmap (\case CodeLine x -> x
ModuleLine x -> view x) ModuleLine x -> view x)
. concatMap sortIfModules . concatMap sortIfModules
. groupLines . groupLines
. map lineType . map (lineType mq)
. lines . lines