137 lines
3.6 KiB
Haskell
137 lines
3.6 KiB
Haskell
{- git-annex command
|
|
-
|
|
- Copyright 2024 Joey Hess <id@joeyh.name>
|
|
-
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
|
-}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
module Command.MaxSize where
|
|
|
|
import Command
|
|
import qualified Remote
|
|
import Annex.RepoSize
|
|
import Logs.MaxSize
|
|
import Logs.Trust
|
|
import Utility.DataUnits
|
|
import Utility.Percentage
|
|
|
|
import qualified Data.Map as M
|
|
import qualified Data.Set as S
|
|
import qualified Data.Text as T
|
|
|
|
cmd :: Command
|
|
cmd = noMessages $ withAnnexOptions [jsonOptions] $
|
|
command "maxsize" SectionSetup
|
|
"configure maximum size of repositoriy"
|
|
(paramPair paramRepository (paramOptional paramSize))
|
|
(seek <$$> optParser)
|
|
|
|
data MaxSizeOptions = MaxSizeOptions
|
|
{ cmdparams :: CmdParams
|
|
, bytesOption :: Bool
|
|
}
|
|
|
|
optParser :: CmdParamsDesc -> Parser MaxSizeOptions
|
|
optParser desc = MaxSizeOptions
|
|
<$> cmdParams desc
|
|
<*> switch
|
|
( long "bytes"
|
|
<> help "display sizes in bytes"
|
|
)
|
|
|
|
seek :: MaxSizeOptions -> CommandSeek
|
|
seek o = case cmdparams o of
|
|
(rname:[]) -> commandAction $ do
|
|
enableNormalOutput
|
|
showCustom "maxsize" (SeekInput [rname]) $ do
|
|
u <- Remote.nameToUUID rname
|
|
v <- M.lookup u <$> getMaxSizes
|
|
maybeAddJSONField "maxsize" (fromMaxSize <$> v)
|
|
showRaw $ encodeBS $ case v of
|
|
Just (MaxSize n) ->
|
|
formatSize o (preciseSize storageUnits True) n
|
|
Nothing -> ""
|
|
return True
|
|
stop
|
|
(rname:sz:[]) -> commandAction $ do
|
|
u <- Remote.nameToUUID rname
|
|
let si = SeekInput (cmdparams o)
|
|
let ai = ActionItemOther (Just (UnquotedString rname))
|
|
startingUsualMessages "maxsize" ai si $
|
|
case readSize dataUnits sz of
|
|
Nothing -> giveup "Unable to parse size."
|
|
Just n -> do
|
|
recordMaxSize u (MaxSize n)
|
|
next $ return True
|
|
[] -> commandAction $ sizeOverview o
|
|
_ -> giveup "Too many parameters"
|
|
|
|
sizeOverview :: MaxSizeOptions -> CommandStart
|
|
sizeOverview o = do
|
|
enableNormalOutput
|
|
showCustom "maxsize" (SeekInput []) $ do
|
|
descmap <- Remote.uuidDescriptions
|
|
deadset <- S.fromList <$> trustGet DeadTrusted
|
|
maxsizes <- getMaxSizes
|
|
reposizes <- getRepoSizes True
|
|
-- Add repos too new and empty to have a reposize,
|
|
-- whose maxsize has been set.
|
|
let reposizes' = foldl'
|
|
(\m u -> M.insertWith (flip const) u (RepoSize 0) m)
|
|
reposizes
|
|
(M.keys maxsizes)
|
|
let reposizes'' = flip M.withoutKeys deadset reposizes'
|
|
let l = reverse $ sortOn snd $ M.toList $
|
|
M.mapWithKey (gather maxsizes) reposizes''
|
|
v <- Remote.prettyPrintUUIDsWith' False (Just "size")
|
|
"repositories" descmap showsizes l
|
|
showRaw $ encodeBS $ tablerow (zip widths headers)
|
|
showRaw $ encodeBS $ dropWhileEnd (== '\n') v
|
|
return True
|
|
stop
|
|
where
|
|
sizefield = "size" :: T.Text
|
|
maxsizefield = "maxsize" :: T.Text
|
|
|
|
gather maxsizes u (RepoSize currsize) = Just $ M.fromList
|
|
[ (sizefield, Just currsize)
|
|
, (maxsizefield, fromMaxSize <$> M.lookup u maxsizes)
|
|
]
|
|
|
|
(widths, headers) = unzip
|
|
[ (7, "size")
|
|
, (7, "maxsize")
|
|
, (6, "%full")
|
|
, (0, "repository")
|
|
]
|
|
|
|
showsizes m = do
|
|
size <- M.lookup sizefield m
|
|
maxsize <- M.lookup maxsizefield m
|
|
return $ tablerow $ zip widths
|
|
[ formatsize size
|
|
, formatsize maxsize
|
|
, case (size, maxsize) of
|
|
(Just size', Just maxsize')
|
|
| size' <= maxsize' ->
|
|
showPercentage 0 $
|
|
percentage maxsize' size'
|
|
| otherwise -> ">100%"
|
|
_ -> ""
|
|
, ""
|
|
]
|
|
|
|
formatsize = maybe "" (formatSize o (roughSize' storageUnits True 0))
|
|
|
|
padcolumn width s = replicate (width - length s) ' ' ++ s
|
|
|
|
tablerow [] = ""
|
|
tablerow ((_, s):[]) = " " ++ s
|
|
tablerow ((width, s):l) = padcolumn width s ++ " " ++ tablerow l
|
|
|
|
formatSize :: MaxSizeOptions -> (ByteSize -> String) -> ByteSize -> String
|
|
formatSize o f n
|
|
| bytesOption o = show n
|
|
| otherwise = f n
|