{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS -Wno-name-shadowing #-} module Main (main) where import Control.Monad import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.State (MonadState (..), runStateT) import Data.Text (Text) import Options.Generic (getRecord, ParseRecord) import Data.Text qualified as T import Data.Text.IO qualified as T import GHC.Generics (Generic) import RIO.Map (Map) import System.IO (openFile, IOMode (..), hFlush, hClose) import BuildConstraints (parsePackageDecl, handlePackage) import Snapshot (snapshotMap, loadSnapshot) import Types (PackageName, Version) src :: String src = "build-constraints.yaml" target :: Int -> String target major = "lts-" <> show major <> "-build-constraints.yaml" data Args = Args { major :: Int , baseSnapshotPath :: FilePath } deriving Generic instance ParseRecord Args data State = LookingForLibBounds | ProcessingLibBounds | Done main :: IO () main = do Args { major, baseSnapshotPath } <- getRecord "lts-constraints" map <- snapshotMap <$> loadSnapshot baseSnapshotPath output <- openFile (target major) WriteMode let putLine = liftIO . T.hPutStrLn output lines <- T.lines <$> T.readFile src void $ flip runStateT LookingForLibBounds $ do forM_ lines $ putLine <=< processLine map hFlush output hClose output putStrLn $ "Done. Wrote to " <> target major processLine :: MonadState State m => Map PackageName Version -> Text -> m Text processLine map line = do st <- get case st of LookingForLibBounds -> do when (line == "packages:") $ put ProcessingLibBounds pure line ProcessingLibBounds -> if line == "# end of packages" then do put Done pure line else case parsePackageDecl line of Just p -> pure $ handlePackage map p Nothing -> pure line Done -> pure line