Commit 209b3711 authored by Iustin Pop's avatar Iustin Pop
Browse files

Split common CLI functionality into a module

This patch moves the common CLI functionality (as much as currently
possible) into a separate module. This means we only have one parseOpts
and that Utils.hs doesn't keep this kind of functions anymore.
parent 6e75a445
{-| Implementation of command-line functions.
This module holds the common cli-related functions for the binaries,
separated into this module since Utils.hs is used in many other places
and this is more I/O oriented.
-}
module Ganeti.HTools.CLI
(
parseOpts
, showVersion
) where
import System.Console.GetOpt
import System.IO
import System.Info
import System
import Monad
import Text.Printf (printf)
import qualified Data.Version
import qualified Ganeti.HTools.Version as Version(version)
-- | Command line parser, using the 'options' structure.
parseOpts :: [String] -- ^ The command line arguments
-> String -- ^ The program name
-> [OptDescr (b -> b)] -- ^ The supported command line options
-> b -- ^ The default options record
-> (b -> Bool) -- ^ The function which given the options
-- tells us whether we need to show help
-> IO (b, [String]) -- ^ The resulting options a leftover
-- arguments
parseOpts argv progname options defaultOptions fn =
case getOpt Permute options argv of
(o, n, []) ->
do
let resu@(po, _) = (foldl (flip id) defaultOptions o, n)
when (fn po) $ do
putStr $ usageInfo header options
exitWith ExitSuccess
return resu
(_, _, errs) ->
ioError (userError (concat errs ++ usageInfo header options))
where header = printf "%s %s\nUsage: %s [OPTION...]"
progname Version.version progname
-- | Return a version string for the program
showVersion :: String -- ^ The program name
-> String -- ^ The formatted version and other information data
showVersion name =
printf "%s %s\ncompiled with %s %s\nrunning on %s %s\n"
name Version.version
compilerName (Data.Version.showVersion compilerVersion)
os arch
{-| Utility functions -}
module Ganeti.HTools.Utils where
module Ganeti.HTools.Utils
(
debug
, isLeft
, fromLeft
, fromRight
, sepSplit
, swapPairs
, varianceCoeff
, readData
) where
import Data.Either
import Data.List
import qualified Data.Version
import Monad
import System
import System.IO
import System.Info
import Text.Printf
import qualified Ganeti.HTools.Version as Version
import Debug.Trace
......@@ -68,7 +74,6 @@ stdDev lst =
bv = sqrt (av / (fromIntegral $ length lst))
in bv
-- | Coefficient of variation.
varianceCoeff :: Floating a => [a] -> a
varianceCoeff lst = (stdDev lst) / (fromIntegral $ length lst)
......@@ -82,11 +87,3 @@ readData fn host = do
putStrLn $ fromLeft nd
exitWith $ ExitFailure 1
return $ fromRight nd
showVersion :: String -- ^ The program name
-> String -- ^ The formatted version and other information data
showVersion name =
printf "%s %s\ncompiled with %s %s\nrunning on %s %s\n"
name Version.version
compilerName (Data.Version.showVersion compilerVersion)
os arch
......@@ -16,8 +16,8 @@ import Text.Printf (printf)
import qualified Ganeti.HTools.Container as Container
import qualified Ganeti.HTools.Cluster as Cluster
import qualified Ganeti.HTools.Version as Version
import qualified Ganeti.HTools.Node as Node
import qualified Ganeti.HTools.CLI as CLI
import Ganeti.HTools.Rapi
import Ganeti.HTools.Utils
......@@ -31,8 +31,9 @@ data Options = Options
, optMaxLength :: Int -- ^ Stop after this many steps
, optMaster :: String -- ^ Collect data from RAPI
, optVerbose :: Int -- ^ Verbosity level
, optShowVer :: Bool -- ^ Just show the program version
, optOffline :: [String] -- ^ Names of offline nodes
, optShowVer :: Bool -- ^ Just show the program version
, optShowHelp :: Bool -- ^ Just show the help
} deriving Show
-- | Default values for the command line options.
......@@ -46,8 +47,9 @@ defaultOptions = Options
, optMaxLength = -1
, optMaster = ""
, optVerbose = 0
, optShowVer = False
, optOffline = []
, optShowVer = False
, optShowHelp = False
}
-- | Options list and functions
......@@ -76,28 +78,19 @@ options =
"cap the solution at this many moves (useful for very unbalanced \
\clusters)"
, Option ['v'] ["verbose"]
(NoArg (\ opts -> let nv = (optVerbose opts)
in opts { optVerbose = nv + 1 }))
(NoArg (\ opts -> opts { optVerbose = (optVerbose opts) + 1 }))
"increase the verbosity level"
, Option ['V'] ["version"]
(NoArg (\ opts -> opts { optShowVer = True}))
"show the version of the program"
, Option ['O'] ["offline"]
(ReqArg (\ n opts -> opts { optOffline = n:optOffline opts }) "NODE")
" set node as offline"
, Option ['V'] ["version"]
(NoArg (\ opts -> opts { optShowVer = True}))
"show the version of the program"
, Option ['h'] ["help"]
(NoArg (\ opts -> opts { optShowHelp = True}))
"show help"
]
-- | Command line parser, using the 'options' structure.
parseOpts :: [String] -> IO (Options, [String])
parseOpts argv =
case getOpt Permute options argv of
(o,n,[] ) ->
return (foldl (flip id) defaultOptions o, n)
(_,_,errs) ->
ioError (userError (concat errs ++ usageInfo header options))
where header = printf "hbal %s\nUsage: hbal [OPTION...]"
Version.version
{- | Start computing the solution at the given depth and recurse until
we find a valid solution or we exceed the maximum depth.
......@@ -144,10 +137,10 @@ iterateDepth ini_tbl max_rounds ktn kti nmlen imlen cmd_strs oneline =
main :: IO ()
main = do
cmd_args <- System.getArgs
(opts, _) <- parseOpts cmd_args
(opts, _) <- CLI.parseOpts cmd_args "hbal" options defaultOptions optShowHelp
when (optShowVer opts) $ do
putStr $ showVersion "hbal"
putStr $ CLI.showVersion "hbal"
exitWith ExitSuccess
let oneline = optOneline opts
......
......@@ -17,7 +17,7 @@ import Text.Printf (printf)
import qualified Ganeti.HTools.Container as Container
import qualified Ganeti.HTools.Instance as Instance
import qualified Ganeti.HTools.Cluster as Cluster
import qualified Ganeti.HTools.Version as Version
import qualified Ganeti.HTools.CLI as CLI
import Ganeti.HTools.Rapi
import Ganeti.HTools.Utils
......@@ -33,6 +33,7 @@ data Options = Options
, optMaxDelta :: Int
, optMaster :: String
, optShowVer :: Bool -- ^ Just show the program version
, optShowHelp :: Bool -- ^ Just show the help
} deriving Show
-- | Default values for the command line options.
......@@ -48,6 +49,7 @@ defaultOptions = Options
, optMaxDelta = -1
, optMaster = ""
, optShowVer = False
, optShowHelp = False
}
{- | Start computing the solution at the given depth and recurse until
......@@ -112,27 +114,19 @@ options =
, Option ['V'] ["version"]
(NoArg (\ opts -> opts { optShowVer = True}))
"show the version of the program"
, Option ['h'] ["help"]
(NoArg (\ opts -> opts { optShowHelp = True}))
"show help"
]
-- | Command line parser, using the 'options' structure.
parseOpts :: [String] -> IO (Options, [String])
parseOpts argv =
case getOpt Permute options argv of
(o,n,[] ) ->
return (foldl (flip id) defaultOptions o, n)
(_,_,errs) ->
ioError (userError (concat errs ++ usageInfo header options))
where header = printf "hn1 %s\nUsage: hn1 [OPTION...]"
Version.version
-- | Main function.
main :: IO ()
main = do
cmd_args <- System.getArgs
(opts, _) <- parseOpts cmd_args
(opts, _) <- CLI.parseOpts cmd_args "hn1" options defaultOptions optShowHelp
when (optShowVer opts) $ do
printf $ showVersion "hn1"
printf $ CLI.showVersion "hn1"
exitWith ExitSuccess
let min_depth = optMinDepth opts
......
......@@ -18,9 +18,9 @@ import Text.Printf (printf)
import qualified Ganeti.HTools.Container as Container
import qualified Ganeti.HTools.Cluster as Cluster
import qualified Ganeti.HTools.Version as Version
import qualified Ganeti.HTools.Node as Node
import qualified Ganeti.HTools.Instance as Instance
import qualified Ganeti.HTools.CLI as CLI
import Ganeti.HTools.Rapi
import Ganeti.HTools.Utils
......@@ -29,8 +29,9 @@ data Options = Options
{ optShowNodes :: Bool -- ^ Whether to show node status
, optOutPath :: FilePath -- ^ Path to the output directory
, optVerbose :: Int -- ^ Verbosity level
, optShowVer :: Bool -- ^ Just show the program version
, optNoHeader :: Bool -- ^ Do not show a header line
, optShowVer :: Bool -- ^ Just show the program version
, optShowHelp :: Bool -- ^ Just show the help
} deriving Show
-- | Default values for the command line options.
......@@ -39,8 +40,9 @@ defaultOptions = Options
{ optShowNodes = False
, optOutPath = "."
, optVerbose = 0
, optShowVer = False
, optNoHeader = False
, optShowVer = False
, optShowHelp = False
}
-- | Options list and functions
......@@ -55,25 +57,17 @@ options =
, Option ['v'] ["verbose"]
(NoArg (\ opts -> opts { optVerbose = (optVerbose opts) + 1 }))
"increase the verbosity level"
, Option ['V'] ["version"]
(NoArg (\ opts -> opts { optShowVer = True}))
"show the version of the program"
, Option [] ["no-headers"]
(NoArg (\ opts -> opts { optNoHeader = True }))
"do not show a header line"
, Option ['V'] ["version"]
(NoArg (\ opts -> opts { optShowVer = True}))
"show the version of the program"
, Option ['h'] ["help"]
(NoArg (\ opts -> opts { optShowHelp = True}))
"show help"
]
-- | Command line parser, using the 'options' structure.
parseOpts :: [String] -> IO (Options, [String])
parseOpts argv =
case getOpt Permute options argv of
(o, n, []) ->
return (foldl (flip id) defaultOptions o, n)
(_, _, errs) ->
ioError (userError (concat errs ++ usageInfo header options))
where header = printf "hscan %s\nUsage: hscan [OPTION...] cluster..."
Version.version
-- | Generate node file data from node objects
serializeNodes :: Cluster.NodeList -> String -> Cluster.NameList -> String
serializeNodes nl csf ktn =
......@@ -137,10 +131,11 @@ printCluster nl il ktn kti =
main :: IO ()
main = do
cmd_args <- System.getArgs
(opts, clusters) <- parseOpts cmd_args
(opts, clusters) <- CLI.parseOpts cmd_args "hscan" options
defaultOptions optShowHelp
when (optShowVer opts) $ do
putStr $ showVersion "hscan"
putStr $ CLI.showVersion "hscan"
exitWith ExitSuccess
let odir = optOutPath opts
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment