use Alternative when parsing mutually exclusive fsck options

This commit is contained in:
Joey Hess 2015-07-09 12:26:25 -04:00
parent 8a9d2a6e9d
commit 94e703e8b8

View file

@ -50,12 +50,15 @@ cmd = command "fsck" SectionMaintenance
data FsckOptions = FsckOptions data FsckOptions = FsckOptions
{ fsckFiles :: CmdParams { fsckFiles :: CmdParams
, fsckFromOption :: Maybe RemoteName , fsckFromOption :: Maybe RemoteName
, startIncrementalOption :: Bool , incrementalOpt :: Maybe IncrementalOpt
, moreIncrementalOption :: Bool
, incrementalScheduleOption :: Maybe Duration
, keyOptions :: KeyOptions , keyOptions :: KeyOptions
} }
data IncrementalOpt
= StartIncrementalO
| MoreIncrementalO
| ScheduleIncrementalO Duration
optParser :: CmdParamsDesc -> Parser FsckOptions optParser :: CmdParamsDesc -> Parser FsckOptions
optParser desc = FsckOptions optParser desc = FsckOptions
<$> cmdParams desc <$> cmdParams desc
@ -63,19 +66,22 @@ optParser desc = FsckOptions
( long "from" <> short 'f' <> metavar paramRemote ( long "from" <> short 'f' <> metavar paramRemote
<> help "check remote" <> help "check remote"
)) ))
<*> switch <*> optional parseincremental
( long "incremental" <> short 'S'
<> help "start an incremental fsck"
)
<*> switch
( long "more" <> short 'm'
<> help "continue an incremental fsck"
)
<*> optional (option (str >>= parseDuration)
( long "incremental-schedule" <> metavar paramTime
<> help "schedule incremental fscking"
))
<*> parseKeyOptions False <*> parseKeyOptions False
where
parseincremental =
flag' StartIncrementalO
( long "incremental" <> short 'S'
<> help "start an incremental fsck"
)
<|> flag' MoreIncrementalO
( long "more" <> short 'm'
<> help "continue an incremental fsck"
)
<|> (ScheduleIncrementalO <$> option (str >>= parseDuration)
( long "incremental-schedule" <> metavar paramTime
<> help "schedule incremental fscking"
))
-- TODO: annexedMatchingOptions -- TODO: annexedMatchingOptions
@ -83,7 +89,7 @@ seek :: FsckOptions -> CommandSeek
seek o = do seek o = do
from <- Remote.byNameWithUUID (fsckFromOption o) from <- Remote.byNameWithUUID (fsckFromOption o)
u <- maybe getUUID (pure . Remote.uuid) from u <- maybe getUUID (pure . Remote.uuid) from
i <- getIncremental u o i <- prepIncremental u (incrementalOpt o)
withKeyOptions (keyOptions o) False withKeyOptions (keyOptions o) False
(\k -> startKey i k =<< getNumCopies) (\k -> startKey i k =<< getNumCopies)
(withFilesInGit $ whenAnnexed $ start from i) (withFilesInGit $ whenAnnexed $ start from i)
@ -511,33 +517,26 @@ getStartTime u = do
data Incremental = StartIncremental FsckDb.FsckHandle | ContIncremental FsckDb.FsckHandle | NonIncremental data Incremental = StartIncremental FsckDb.FsckHandle | ContIncremental FsckDb.FsckHandle | NonIncremental
getIncremental :: UUID -> FsckOptions -> Annex Incremental prepIncremental :: UUID -> Maybe IncrementalOpt -> Annex Incremental
getIncremental u o = do prepIncremental _ Nothing = pure NonIncremental
i <- maybe (return False) checkschedule (incrementalScheduleOption o) prepIncremental u (Just StartIncrementalO) = do
case (i, startIncrementalOption o, moreIncrementalOption o) of recordStartTime u
(False, False, False) -> return NonIncremental ifM (FsckDb.newPass u)
(False, True, False) -> startIncremental ( StartIncremental <$> FsckDb.openDb u
(False ,False, True) -> contIncremental , error "Cannot start a new --incremental fsck pass; another fsck process is already running."
(True, False, False) -> )
maybe startIncremental (const contIncremental) prepIncremental u (Just MoreIncrementalO) =
=<< getStartTime u ContIncremental <$> FsckDb.openDb u
_ -> error "Specify only one of --incremental, --more, or --incremental-schedule" prepIncremental u (Just (ScheduleIncrementalO delta)) = do
where Annex.addCleanup FsckCleanup $ do
startIncremental = do v <- getStartTime u
recordStartTime u case v of
ifM (FsckDb.newPass u) Nothing -> noop
( StartIncremental <$> FsckDb.openDb u Just started -> do
, error "Cannot start a new --incremental fsck pass; another fsck process is already running." now <- liftIO getPOSIXTime
) when (now - realToFrac started >= durationToPOSIXTime delta) $
contIncremental = ContIncremental <$> FsckDb.openDb u resetStartTime u
started <- getStartTime u
checkschedule delta = do prepIncremental u $ Just $ case started of
Annex.addCleanup FsckCleanup $ do Nothing -> StartIncrementalO
v <- getStartTime u Just _ -> MoreIncrementalO
case v of
Nothing -> noop
Just started -> do
now <- liftIO getPOSIXTime
when (now - realToFrac started >= durationToPOSIXTime delta) $
resetStartTime u
return True