module Main (main) where import Converge import Data.Maybe (fromMaybe) import Data.Text (Text) import Options.Applicative import System.IO (hPutStrLn, stderr) data CliArgs = CliArgs { cliConfig :: !(Maybe FilePath) -- ^ Optional path to a YAML config file. , cliRepo :: !(Maybe FilePath) -- ^ Optional single repo path (requires --config to be absent). , cliRemote :: !Text -- ^ Remote name (used only in single-repo mode). , cliBranch :: !Text -- ^ Branch name (used only in single-repo mode). , cliDebounce :: !(Maybe Int) -- ^ Debounce override for both modes. } cliParser :: Parser CliArgs cliParser = CliArgs <$> optional ( strOption ( long "config" <> short 'c' <> metavar "FILE" <> help "Path to YAML config file listing repositories" ) ) <*> optional ( strOption ( long "repo" <> short 'r' <> metavar "PATH" <> help "Path to a single git repository to watch (default: cwd)" ) ) <*> strOption ( long "remote" <> metavar "NAME" <> value "origin" <> showDefault <> help "Remote name to pull from (single-repo mode)" ) <*> strOption ( long "branch" <> short 'b' <> metavar "NAME" <> value "main" <> showDefault <> help "Branch to pull (single-repo mode)" ) <*> optional ( option auto ( long "debounce" <> short 'd' <> metavar "MS" <> help "Debounce window in milliseconds (overrides config file)" ) ) parserInfo :: ParserInfo CliArgs parserInfo = info (cliParser <**> helper) ( fullDesc <> progDesc "Auto-sync git repos by watching, committing, and pulling" <> header "converge - keep git repos in sync" ) main :: IO () main = do cli <- execParser parserInfo let mDebounceOverride = cliDebounce cli options <- case cliConfig cli of Just cfgPath -> do cfg <- loadConfig cfgPath let opts = configToOptions cfg pure $ case mDebounceOverride of Just ms -> opts{optDebounceMs = ms} Nothing -> opts Nothing -> pure $ defaultOptions { optRepos = [ defaultRepoConfig { rcPath = fromMaybe "." (cliRepo cli) , rcRemote = cliRemote cli , rcBranch = cliBranch cli } ] , optDebounceMs = fromMaybe 5000 mDebounceOverride } hPutStrLn stderr $ "Converge watching " <> show (length (optRepos options)) <> " repo(s)" <> " (debounce: " <> show (optDebounceMs options) <> "ms)" mapM_ (\r -> hPutStrLn stderr (" - " <> rcPath r)) (optRepos options) runConverge options