-- Option parsing module GraphMod.Args(Opts(..), default_opts, options, IgnoreSet, IgnoreSpec(..) , defaultLocation ) where import GraphMod.Utils import qualified GraphMod.Trie as Trie import Data.Maybe(fromMaybe) import qualified Data.Map as Map import System.Console.GetOpt -- Command line options -------------------------------------------------------------------------------- data Opts = Opts { inputDir :: FilePath , quiet :: Bool , with_missing :: Bool , use_clusters :: Bool , mod_in_cluster:: Bool , ignore_mods :: IgnoreSet , collapse_quals :: Trie.Trie String Bool -- ^ The "Bool" tells us if we should collapse modules as well. -- For example, "True" says that A.B.C would collapse not only A.B.C.* -- but also the module A.B.C, if it exists. , show_version :: Bool , color_scheme :: Int , prune_edges :: Bool , graph_size :: String } type IgnoreSet = Trie.Trie String IgnoreSpec data IgnoreSpec = IgnoreAll | IgnoreSome [String] deriving Show type OptT = Opts -> Opts defaultLocation :: FilePath defaultLocation = "/root/graphmod-plugin/output" default_opts :: Opts default_opts = Opts { inputDir = defaultLocation , quiet = False , with_missing = False , use_clusters = True , mod_in_cluster = True , ignore_mods = Trie.empty , collapse_quals = Trie.empty , show_version = False , color_scheme = 0 , prune_edges = False , graph_size = "6,4" } options :: [OptDescr OptT] options = [ Option ['i'] ["indir"] (ReqArg add_indir "DIR") "Directory where the plugin placed the files" , Option ['q'] ["quiet"] (NoArg set_quiet) "Do not show warnings" , Option ['a'] ["all"] (NoArg set_all) "Add nodes for missing modules" , Option [] ["no-cluster"] (NoArg set_no_cluster) "Do not cluster directories" , Option [] ["no-module-in-cluster"] (NoArg set_no_mod_in_cluster) "Do not place modules matching a cluster's name inside it." , Option ['r'] ["remove-module"] (ReqArg add_ignore_mod "NAME") "Do not display module NAME" , Option ['R'] ["remove-qual"] (ReqArg add_ignore_qual "NAME") "Do not display modules NAME.*" , Option ['c'] ["collapse"] (ReqArg (add_collapse_qual False) "NAME") "Display modules NAME.* as one node" , Option ['C'] ["collapse-module"] (ReqArg (add_collapse_qual True) "NAME") "Display modules NAME and NAME.* as one node" , Option ['p'] ["prune-edges"] (NoArg set_prune) "Remove imports if the module is imported by another imported module" , Option ['d'] ["graph-dim"] (ReqArg set_size "SIZE,SIZE") "Set dimensions of the graph. See the `size` attribute of graphvize." , Option ['s'] ["colors"] (ReqArg add_color_scheme "NUM") "Choose a color scheme number (0-5)" , Option ['v'] ["version"] (NoArg set_show_version) "Show the current version." ] {- add_current :: OptT add_current o = case inc_dirs o of [] -> o { inc_dirs = ["."] } _ -> o -} set_quiet :: OptT set_quiet o = o { quiet = True } set_show_version :: OptT set_show_version o = o { show_version = True } set_all :: OptT set_all o = o { with_missing = True } set_no_cluster :: OptT set_no_cluster o = o { use_clusters = False } set_no_mod_in_cluster :: OptT set_no_mod_in_cluster o = o { mod_in_cluster = False } add_indir :: FilePath -> OptT add_indir d o = o { inputDir = d } add_ignore_mod :: String -> OptT add_ignore_mod s o = o { ignore_mods = ins (splitModName s) } where ins (q,m) = Trie.insert q (upd m) (ignore_mods o) upd _ (Just IgnoreAll) = IgnoreAll upd m (Just (IgnoreSome ms)) = IgnoreSome (m:ms) upd m Nothing = IgnoreSome [m] add_ignore_qual :: String -> OptT add_ignore_qual s o = o { ignore_mods = Trie.insert (splitQualifier s) (const IgnoreAll) (ignore_mods o) } add_color_scheme :: String -> OptT add_color_scheme n o = o { color_scheme = case reads n of [(x,"")] -> x _ -> color_scheme default_opts } add_collapse_qual :: Bool -> String -> OptT add_collapse_qual m s o = o { collapse_quals = upd (splitQualifier s) (collapse_quals o) } where upd [] (Trie.Sub xs (Just _)) = Trie.Sub xs (Just m) upd _ t@(Trie.Sub _ (Just _)) = t upd [] _ = Trie.Sub Map.empty (Just m) upd (q:qs) (Trie.Sub as _) = Trie.Sub (Map.alter add q as) Nothing where add j = Just $ upd qs $ fromMaybe Trie.empty j set_prune :: OptT set_prune o = o { prune_edges = True } set_size :: String -> OptT set_size s o = o { graph_size = s }