/ nix / script / exe / gen-gnu-wrapper.hs
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