module Runner ( run ) where
import Control.Lens
import Data.Foldable as F
import Data.Functor
import Distribution.Nixpkgs.Haskell.FromStack
import Distribution.Nixpkgs.Haskell.FromStack.Package
import Distribution.Nixpkgs.Haskell.Stack
import Distribution.Nixpkgs.Haskell.Stack.PrettyPrinting as PP
import Distribution.Version (Version)
import Distribution.Compiler (AbiTag(..), unknownCompilerInfo)
import Distribution.Package (mkPackageName, pkgName)
import Distribution.Text as Text (display)
import Language.Nix as Nix
import Options.Applicative
import Paths_stackage2nix ( version )
import Runner.Cli
import Stack.Config
import Stack.Types
import Stackage.Types
import System.IO (withFile, IOMode(..), hPutStrLn, hPrint)
import Text.PrettyPrint.HughesPJClass (render)
import qualified Data.Set as Set
import qualified Data.Map as Map
import qualified LtsHaskell as LH
run :: IO ()
run = do
opts <- execParser pinfo
stackYaml <- envStackYaml >>= \case
Just p -> putStrLn "Getting project config file from STACK_YAML environment" $> p
Nothing -> pure $ opts ^. optStackYaml
stackConf <- either fail pure =<< readStackConfig stackYaml
let buildPlanFile = LH.buildPlanFilePath (opts ^. optLtsHaskellRepo) (stackConf ^. scResolver)
buildPlan <- LH.loadBuildPlan buildPlanFile
packageSetConfig <- LH.buildPackageSetConfig
(opts ^. optAllCabalHashesRepo)
(opts ^. optNixpkgsRepository)
buildPlan
let
overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
stackPackagesConfig = mkStackPackagesConfig opts
packages <- traverse (packageDerivation stackPackagesConfig (opts ^. optHackageDb))
$ stackConf ^. scPackages
let out = PP.overrideHaskellPackages overrideConfig packages
withFile (opts ^. optOutDerivation) WriteMode $ \h -> do
hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ stackYaml ^. syFilePath)
hPrint h out
let
reachable = Set.map mkPackageName
$ F.foldr1 Set.union
$ nodeDepends . mkNode <$> packages
s2nLoader mHash pkgId =
if pkgName pkgId `Set.member` reachable
then packageLoader packageSetConfig Nothing pkgId
else packageLoader packageSetConfig mHash pkgId
s2nPackageSetConfig = packageSetConfig { packageLoader = s2nLoader }
s2nPackageConfig = PackageConfig
{ enableCheck = opts ^. optDoCheckStackage
, enableHaddock = opts ^. optDoHaddockStackage }
allNodes <- traverse (uncurry (buildNodeM s2nPackageSetConfig s2nPackageConfig))
$ Map.toList (bpPackages buildPlan)
let nodes = case opts ^. optOutPackagesClosure of
True -> flip reachableDependencies allNodes
$ filter (\n -> mkPackageName (nodeName n) `Set.member` reachable) allNodes
False -> allNodes
withFile (opts ^. optOutStackagePackages) WriteMode $ \h -> do
hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ buildPlanFile)
hPutStrLn h $ render $ pPrintOutPackages (view nodeDerivation <$> nodes)
withFile (opts ^. optOutStackageConfig) WriteMode $ \h -> do
hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ buildPlanFile)
hPutStrLn h $ render $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
mkOverrideConfig :: Options -> Version -> OverrideConfig
mkOverrideConfig opts ghcVersion = OverrideConfig
{ _ocGhc = ghcVersion
, _ocStackagePackages = opts ^. optOutStackagePackages
, _ocStackageConfig = opts ^. optOutStackageConfig
, _ocNixpkgs = opts ^. optNixpkgsRepository }
mkStackPackagesConfig :: Options -> StackPackagesConfig
mkStackPackagesConfig opts = StackPackagesConfig
{ _spcHaskellResolver = const True
, _spcNixpkgsResolver = \i -> Just (Nix.binding # (i, Nix.path # [i]))
, _spcTargetPlatform = opts ^. optPlatform
, _spcTargetCompiler = unknownCompilerInfo (opts ^. optCompilerId) NoAbiTag
, _spcFlagAssignment = []
, _spcDoCheckPackages = opts ^. optDoCheckPackages
, _spcDoHaddockPackages = opts ^. optDoHaddockPackages
, _spcDoCheckStackage = opts ^. optDoCheckStackage
, _spcDoHaddockStackage = opts ^. optDoHaddockStackage }