git-annex/Annex/Sim/File.hs

95 lines
3.2 KiB
Haskell
Raw Normal View History

2024-09-11 15:53:25 +00:00
{- sim files
-
- Copyright 2024 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
module Annex.Sim.File where
import Annex.Sim
import Annex.Common
import Utility.DataUnits
import Data.Char
import Text.Read
parseSimFile :: String -> Either String [SimCommand]
parseSimFile = go [] . lines
where
go c [] = Right c
go c (l:ls) = case parseSimFileLine l of
Right cs -> go (c ++ cs) ls
Left err -> Left err
parseSimFileLine :: String -> Either String [SimCommand]
parseSimFileLine s
| "#" `isPrefixOf` s = Right [CommandComment s]
| all isSpace s = Right [CommandBlank]
| otherwise = case words s of
("init":name:[]) ->
Right [CommandInit (RepoName name)]
("initremote":name:[]) ->
Right [CommandInitRemote (RepoName name)]
("use":name:rest) ->
Right [CommandUse (RepoName name) (unwords rest)]
("connect":rest) ->
parseConnect CommandConnect rest
("disconnect":rest) ->
parseConnect CommandDisconnect rest
("addtree":name:rest) ->
Right [CommandAddTree(RepoName name) (unwords rest)]
("add":filename:size:repos) ->
case readSize dataUnits size of
Just sz -> Right [CommandAdd (toRawFilePath filename) sz (map RepoName repos)]
Nothing -> Left $ "Unable to parse file size \"" ++ size ++ "\""
("step":n:[]) ->
case readMaybe n of
Just n' -> Right [CommandStep n']
Nothing -> Left $ "Unable to parse step value \"" ++ n ++ "\""
("action":repo:"pull":remote:[]) ->
Right [CommandAction (RepoName repo) (ActionPull (RemoteName remote))]
("action":repo:"push":remote:[]) ->
Right [CommandAction (RepoName repo) (ActionPush (RemoteName remote))]
("action":repo:"getwanted":remote:[]) ->
Right [CommandAction (RepoName repo) (ActionGetWanted (RemoteName remote))]
("action":repo:"dropunwanted":[]) ->
Right [CommandAction (RepoName repo) (ActionDropUnwanted Nothing)]
("action":repo:"dropunwanted":remote:[]) ->
Right [CommandAction (RepoName repo) (ActionDropUnwanted (Just (RemoteName remote)))]
("action":repo:"gitpush":remote:[]) ->
Right [CommandAction (RepoName repo) (ActionGitPush (RemoteName remote))]
("action":repo:"gitpull":remote:[]) ->
Right [CommandAction (RepoName repo) (ActionGitPull (RemoteName remote))]
("seed":n:[]) ->
case readMaybe n of
Just n' -> Right [CommandSeed n']
Nothing -> Left $ "Unable to parse seed value \"" ++ n ++ "\""
("present":repo:file:[]) ->
Right [CommandPresent (RepoName repo) (toRawFilePath file)]
("notpresent":repo:file:[]) ->
Right [CommandNotPresent (RepoName repo) (toRawFilePath file)]
-- TODO rest
_ -> Left $ "Unable to parse sim file line: \"" ++ s ++ "\""
parseConnect :: (RepoName -> RemoteName -> SimCommand) -> [String] -> Either String [SimCommand]
parseConnect mk = go []
where
go c [] = Right c
go c (r1:"->":r2:rest) =
go (mk (RepoName r1) (RemoteName r2):c)
(chain r2 rest)
go c (r1:"<-":r2:rest) =
go (mk (RepoName r2) (RemoteName r1):c)
(chain r2 rest)
go c (r1:"<->":r2:rest) =
go (mk (RepoName r2) (RemoteName r1)
: mk (RepoName r1) (RemoteName r2)
: c
)
(chain r2 rest)
go _ rest = Left $ "Bad connect syntax near \"" ++ unwords rest ++ "\""
chain v rest = if null rest then rest else v:rest