gen-gnu-wrapper.hs
1 #!/usr/bin/env runghc 2 {-# LANGUAGE OverloadedStrings #-} 3 4 {- | 5 Generate typed Haskell wrapper for a GNU getopt_long CLI tool 6 7 Usage: 8 ./gen-gnu-wrapper.hs <command> [module-name] 9 10 Examples: 11 ./gen-gnu-wrapper.hs ls # generates Ls.hs 12 ./gen-gnu-wrapper.hs grep Grep # generates Grep.hs 13 ./gen-gnu-wrapper.hs tar > Tar.hs 14 -} 15 module Main where 16 17 import Data.Char (toUpper) 18 import Data.Text (Text) 19 import qualified Data.Text as T 20 import qualified Data.Text.IO as TIO 21 import System.Environment (getArgs, getProgName) 22 import System.Exit (exitFailure) 23 import System.IO (hPutStrLn, stderr) 24 import System.Process (readProcess) 25 26 import Aleph.Script.Getopt (generateModule, parseHelp) 27 28 main :: IO () 29 main = do 30 args <- getArgs 31 case args of 32 [] -> usage 33 [cmd] -> generateWrapper cmd (defaultModuleName cmd) 34 [cmd, modName] -> generateWrapper cmd (T.pack modName) 35 _ -> usage 36 37 usage :: IO () 38 usage = do 39 prog <- getProgName 40 hPutStrLn stderr $ 41 unlines 42 [ "Usage: " ++ prog ++ " <command> [module-name]" 43 , "" 44 , "Generate typed Haskell wrapper for a GNU getopt_long CLI tool." 45 , "" 46 , "Examples:" 47 , " " ++ prog ++ " ls # generates wrapper for ls" 48 , " " ++ prog ++ " grep Grep # use 'Grep' as module name" 49 , " " ++ prog ++ " tar > Tar.hs # save to file" 50 ] 51 exitFailure 52 53 -- | Generate default module name from command 54 defaultModuleName :: String -> Text 55 defaultModuleName cmd = case cmd of 56 [] -> "Unknown" 57 (c : cs) -> T.pack (toUpper c : cs) 58 59 -- | Run the generator 60 generateWrapper :: String -> Text -> IO () 61 generateWrapper cmd moduleName = do 62 helpText <- readProcess cmd ["--help"] "" 63 let parsed = parseHelp (T.pack helpText) 64 generated = generateModule moduleName (T.pack cmd) parsed 65 TIO.putStr generated