{-# LANGUAGE OverloadedStrings #-} module CommandLine where import Options.Applicative -- Define data types for our commands and options data Command = ExtIP ExtIPOptions | Version VersionOptions | Kernel KernelOptions | Sleep SleepOptions | ZfsCheck ZfsCheckOptions | WireGuard WireGuardOptions | NetMan NetManOptions | SysNet SysNetOptions deriving Show data ExtIPOptions = ExtIPOptions { nolocation :: Bool , ipv6 :: Bool } deriving Show data KernelOptions = KernelOptions { justVersion :: Bool } deriving Show data SleepOptions = SleepOptions { secondsToSleep :: Maybe Int } deriving Show data VersionOptions = VersionOptions Bool deriving Show data ZfsCheckOptions = ZfsCheckOptions { full :: Bool } deriving Show data WireGuardOptions = WireGuardOptions { listWGs :: Bool , activateWG :: Maybe String , enableWG :: Maybe String , deactivateWG :: Bool , disableWG :: Bool , reactivateWG :: Bool } deriving Show data NetManOptions = NetManOptions { activateNM :: Bool , enableNM :: Bool , deactivateNM :: Bool , disableNM :: Bool , reactivateNM :: Bool } deriving Show data SysNetOptions = SysNetOptions { activateSN :: Bool , enableSN :: Bool , deactivateSN :: Bool , disableSN :: Bool , reactivateSN :: Bool } deriving Show data GlobalOptions = GlobalOptions { verbose :: Bool } deriving Show globalOptionsParser :: Parser GlobalOptions globalOptionsParser = GlobalOptions <$> switch ( long "verbose" <> short 'v' <> help "Enable verbose mode" ) extipOptionsParser :: Parser ExtIPOptions extipOptionsParser = ExtIPOptions <$> switch ( long "nolocation" <> short 'n' <> help "Don't display location information" ) <*> switch ( long "ipv6" <> short 'i' <> help "Display the IPv6 address" ) kernelOptionsParser :: Parser KernelOptions kernelOptionsParser = KernelOptions <$> switch ( long "justversion" <> short 'j' <> help "Just display the numerical version number, no adjoining text." ) -- version has no options versionOptionsParser :: Parser VersionOptions versionOptionsParser = VersionOptions <$> switch ( long "noop" ) sleepOptionsParser :: Parser SleepOptions sleepOptionsParser = SleepOptions <$> optional (option auto ( long "wait" <> short 'w' <> metavar "SECONDS" <> help "Seconds to wait before going to sleep")) zfscheckOptionsParser :: Parser ZfsCheckOptions zfscheckOptionsParser = ZfsCheckOptions <$> switch ( long "full" <> short 'f' <> help "Check all kernel versions" ) wgOptionsParser :: Parser WireGuardOptions wgOptionsParser = WireGuardOptions <$> switch ( long "list" <> short 'l' <> help "List all installed WireGuardG VPNs") <*> optional (strOption ( long "activate" <> short 'a' <> metavar "WGVPN" <> help "WireGuard VPN to activate")) <*> optional (strOption ( long "enable" <> short 'A' <> metavar "WGVPN" <> help "WireGuard VPN to enable and activate")) <*> switch ( long "deactivate" <> short 'd' <> help "Deactivate (but not disable) all WireGuard VPNs") <*> switch ( long "disable" <> short 'D' <> help "Disable (but not deactivate) all WireGuard VPNs") <*> switch ( long "reactivate" <> short 'r' <> help "Reactivate currently active WireGuardG VPNs") nmOptionsParser :: Parser NetManOptions nmOptionsParser = NetManOptions <$> switch ( long "activate" <> short 'a' <> help "Activate (start) NetworkManager") <*> switch ( long "enable" <> short 'A' <> help "Enable and Activate (start) NetworkManager") <*> switch ( long "deactivate" <> short 'd' <> help "Deactivate (stop) NetworkManager") <*> switch ( long "disable" <> short 'D' <> help "Disable and Deactivate (stop) NetworkManager") <*> switch ( long "reactivate" <> short 'r' <> help "Reactivate (restart) NetworkManager") snOptionsParser :: Parser SysNetOptions snOptionsParser = SysNetOptions <$> switch ( long "activate" <> short 'a' <> help "Activate (start) systemd-networkd socket and service") <*> switch ( long "enable" <> short 'A' <> help "Enable and Activate (start) systemd-networkd socket and service") <*> switch ( long "deactivate" <> short 'd' <> help "Deactivate (stop) systemd-networkd socket and service") <*> switch ( long "disable" <> short 'D' <> help "Disable and Deactivate (stop) systemd-networkd socket and service") <*> switch ( long "reactivate" <> short 'r' <> help "Reactivate (restart) systemd-networkd socket and service") -- Combine the subcommand parsers commandParser :: Parser Command commandParser = subparser ( command "extip" (info (ExtIP <$> extipOptionsParser) (progDesc "Display external IP address")) <> command "kernel" (info (Kernel <$> kernelOptionsParser) (progDesc "Display kernel information, both installed and currently running")) <> command "sleep" (info (Sleep <$> sleepOptionsParser) (progDesc "Put the machine to sleep")) <> command "version" (info (Version <$> versionOptionsParser) (progDesc "Version of Swiss Army Knife")) <> command "zfscheck" (info (ZfsCheck <$> zfscheckOptionsParser) (progDesc "Check zfs availibility for the current kernel")) <> command "wg" (info (WireGuard <$> wgOptionsParser) (progDesc "Manage WireGuard VPNs")) <> command "nm" (info (NetMan <$> nmOptionsParser) (progDesc "Manage NetworkManager")) <> command "sn" (info (SysNet <$> snOptionsParser) (progDesc "Manage systemd-networkd")) ) -- Combine global options with the command parser opts :: Parser (GlobalOptions, Command) opts = (,) <$> globalOptionsParser <*> commandParser