@@ -10,12 +10,15 @@ module Hakyll.Main
12--------------------------------------------------------------------------------
12--------------------------------------------------------------------------------
13−import System.Console.CmdArgs
14−import qualified System.Console.CmdArgs.Explicit as CA
15import System.Environment (getProgName)
13import System.Environment (getProgName)
16import System.IO.Unsafe (unsafePerformIO)
14import System.IO.Unsafe (unsafePerformIO)
17import System.Exit (ExitCode(ExitSuccess), exitWith)
15import System.Exit (ExitCode(ExitSuccess), exitWith)
18+--------------------------------------------------------------------------------
19+import Options.Applicative
19--------------------------------------------------------------------------------
22--------------------------------------------------------------------------------
20import qualified Hakyll.Check as Check
23import qualified Hakyll.Check as Check
21import qualified Hakyll.Commands as Commands
24import qualified Hakyll.Commands as Commands
@@ -37,88 +40,66 @@ hakyllWith conf rules = hakyllWithExitCode conf rules >>= exitWith
38hakyllWithExitCode :: Config.Configuration -> Rules a -> IO ExitCode
41hakyllWithExitCode :: Config.Configuration -> Rules a -> IO ExitCode
39hakyllWithExitCode conf rules = do
42hakyllWithExitCode conf rules = do
40− args' <- cmdArgs (hakyllArgs conf)
43+ args' <- customExecParser (prefs showHelpOnError) (info (helper <*> optionParser conf) (fullDesc <> progDesc (progName ++ " - Static site compiler created with Hakyll")))
44+ let args'' = optCommand args'
42− let verbosity' = if verbose args' then Logger.Debug else Logger.Message
46+ let verbosity' = if verbosity args' then Logger.Debug else Logger.Message
44− if internal_links args' then Check.InternalLinks else Check.All
48+ if internal_links args'' then Check.InternalLinks else Check.All
46 logger <- Logger.new verbosity'
50 logger <- Logger.new verbosity'
47− case args' of
52+ case args'' of
48− Build _ -> Commands.build conf logger rules
53+ Build -> Commands.build conf logger rules
49− Check _ _ -> Commands.check conf logger check' >> ok
54+ Check _ -> Commands.check conf logger check' >> ok
50− Clean _ -> Commands.clean conf logger >> ok
55+ Clean -> Commands.clean conf logger >> ok
51− Deploy _ -> Commands.deploy conf
56+ Deploy -> Commands.deploy conf
52− Help _ -> showHelp >> ok
53− Preview _ p -> Commands.preview conf logger rules p >> ok
57+ Preview p -> Commands.preview conf logger rules p >> ok
54− Rebuild _ -> Commands.rebuild conf logger rules
58+ Rebuild -> Commands.rebuild conf logger rules
55− Server _ _ _ -> Commands.server conf logger (host args') (port args') >> ok
59+ Server _ _ -> Commands.server conf logger (host args'') (port args'') >> ok
56− Watch _ _ p s -> Commands.watch conf logger (host args') p (not s) rules >> ok
60+ Watch _ p s -> Commands.watch conf logger (host args'') p (not s) rules >> ok
58 ok = return ExitSuccess
62 ok = return ExitSuccess
61--------------------------------------------------------------------------------
65--------------------------------------------------------------------------------
62−-- | Show usage information.
64−showHelp = print $ CA.helpText [] CA.HelpFormatOne $ cmdArgsMode (hakyllArgs Config.defaultConfiguration)
67−--------------------------------------------------------------------------------
69− = Build {verbose :: Bool}
70− | Check {verbose :: Bool, internal_links :: Bool}
71− | Clean {verbose :: Bool}
72− | Deploy {verbose :: Bool}
73− | Help {verbose :: Bool}
74− | Preview {verbose :: Bool, port :: Int}
75− | Rebuild {verbose :: Bool}
76− | Server {verbose :: Bool, host :: String, port :: Int}
77− | Watch {verbose :: Bool, host :: String, port :: Int, no_server :: Bool }
78− deriving (Data, Typeable, Show)
81−--------------------------------------------------------------------------------
67+data Options = Options {verbosity :: Bool, optCommand :: Command}
82−hakyllArgs :: Config.Configuration -> HakyllArgs
68+ deriving (Show)
83−hakyllArgs conf = modes
69+
84− [ (Build $ verboseFlag def) &= help "Generate the site"
70+data Command
85− , (Check (verboseFlag def) (False &= help "Check internal links only")) &=
71+ = Build
86− help "Validate the site output"
72+ | Check {internal_links :: Bool}
87− , (Clean $ verboseFlag def) &= help "Clean up and remove cache"
73+ | Clean
88− , (Deploy $ verboseFlag def) &= help "Upload/deploy your site"
74+ | Deploy
89− , (Help $ verboseFlag def) &= help "Show this message" &= auto
75+ | Preview {port :: Int}
90− , (Preview (verboseFlag def) (portFlag defaultPort)) &=
76+ | Rebuild
91− help "[Deprecated] Please use the watch command"
77+ | Server {host :: String, port :: Int}
92− , (Rebuild $ verboseFlag def) &= help "Clean and build again"
78+ | Watch {host :: String, port :: Int, no_server :: Bool }
93− , (Server (verboseFlag def) (hostFlag defaultHost) (portFlag defaultPort)) &=
79+ deriving (Show)
94− help "Start a preview server"
80+
95− , (Watch (verboseFlag def) (hostFlag defaultHost) (portFlag defaultPort) (noServerFlag False) &=
81+optionParser :: Config.Configuration -> Parser Options
96− help "Autocompile on changes and start a preview server. You can watch and recompile without running a server with --no-server.")
82+optionParser conf = Options <$> verboseParser <*> (commandParser conf)
97− ] &= help "Hakyll static site compiler" &= program progName
99− defaultHost = Config.previewHost conf
100− defaultPort = Config.previewPort conf
102−--------------------------------------------------------------------------------
103−verboseFlag :: Data a => a -> a
104−verboseFlag x = x &= help "Run in verbose mode"
84+ verboseParser = switch (long "verbose" <> short 'v' <> help "Run in verbose mode")
105−{-# INLINE verboseFlag #-}
108−--------------------------------------------------------------------------------
87+commandParser :: Config.Configuration -> Parser Command
109−noServerFlag :: Data a => a -> a
88+commandParser conf = subparser $ foldr ((<>) . produceCommand) mempty commands
110−noServerFlag x = x &= help "Disable the built-in web server"
89+ where
111−{-# INLINE noServerFlag #-}
90+ produceCommand (a,b) = command a (info (helper <*> (fst b)) (snd b))
112−
91+ portParser = option auto (long "port" <> help "Port to listen on" <> value (Config.previewPort conf))
113−--------------------------------------------------------------------------------
92+ hostParser = strOption (long "host" <> help "Host to bind on" <> value (Config.previewHost conf))
114−hostFlag :: Data a => a -> a
93+ commands = [
115−hostFlag x = x &= help "Host to bind on"
94+ ("build",(pure Build,fullDesc <> progDesc "Generate the site")),
116−{-# INLINE hostFlag #-}
95+ ("check",(pure Check <*> switch (long "internal-links" <> help "Check internal links only"), fullDesc <> progDesc "Validate the site output")),
117−
96+ ("clean",(pure Clean,fullDesc <> progDesc "Clean up and remove cache")),
118−--------------------------------------------------------------------------------
97+ ("deploy",(pure Deploy,fullDesc <> progDesc "Upload/deploy your site")),
119−portFlag :: Data a => a -> a
98+ ("preview",(pure Preview <*> portParser,fullDesc <> progDesc "[DEPRECATED] Please use the watch command")),
120−portFlag x = x &= help "Port to listen on"
99+ ("rebuild",(pure Rebuild,fullDesc <> progDesc "Clean and build again")),
121−{-# INLINE portFlag #-}
100+ ("server",(pure Server <*> hostParser <*> portParser,fullDesc <> progDesc "Start a preview server")),
101+ ("watch",(pure Watch <*> hostParser <*> portParser <*> switch (long "no-server" <> help "Disable the built-in web server"),fullDesc <> progDesc "Autocompile on changes and start a preview server. You can watch and recompile without running a server with --no-server."))
124--------------------------------------------------------------------------------
105--------------------------------------------------------------------------------