{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} module Stack2nix ( Args(..) , stack2nix , version ) where import Control.Monad (unless, void) import Data.Maybe (isJust) import Data.Monoid ((<>)) import Paths_stack2nix (version) import Stack2nix.External.Stack import Stack2nix.External.Util (runCmdFrom, failHard) import Stack2nix.External.VCS.Git (Command (..), ExternalCmd (..), InternalCmd (..), git) import Stack2nix.Types (Args (..)) import Stack2nix.Util import System.Directory (doesFileExist, getCurrentDirectory, withCurrentDirectory) import System.Environment (getEnv, setEnv) import System.FilePath (()) import System.IO.Temp (withSystemTempDirectory) stack2nix :: Args -> IO () stack2nix args@Args{..} = do ensureExecutableExists "cabal" "cabal-install" ensureExecutableExists "git" "git" ensureExecutableExists "nix-prefetch-git" "nix-prefetch-scripts" assertMinVer "git" "2" assertMinVer "cabal" "2" setEnv "GIT_QUIET" "y" updateCabalPackageIndex -- cwd <- getCurrentDirectory -- let projRoot = if isAbsolute argUri then argUri else cwd argUri let projRoot = argUri isLocalRepo <- doesFileExist $ projRoot argStackYaml logDebug args $ "stack2nix (isLocalRepo): " ++ show isLocalRepo logDebug args $ "stack2nix (projRoot): " ++ show projRoot logDebug args $ "stack2nix (argUri): " ++ show argUri if isLocalRepo then handleStackConfig Nothing projRoot else withSystemTempDirectory "s2n-" $ \tmpDir -> tryGit tmpDir >> handleStackConfig (Just argUri) tmpDir where updateCabalPackageIndex :: IO () updateCabalPackageIndex = do home <- getEnv "HOME" out <- runCmdFrom home "cabal" ["update"] void $ failHard out tryGit :: FilePath -> IO () tryGit tmpDir = do void $ git $ OutsideRepo $ Clone argUri tmpDir case argRev of Just r -> void $ git $ InsideRepo tmpDir (Checkout r) Nothing -> return mempty handleStackConfig :: Maybe String -> FilePath -> IO () handleStackConfig remoteUri localDir = do cwd <- getCurrentDirectory logDebug args $ "handleStackConfig (cwd): " ++ cwd logDebug args $ "handleStackConfig (localDir): " ++ localDir logDebug args $ "handleStackConfig (remoteUri): " ++ show remoteUri let stackFile = localDir argStackYaml alreadyExists <- doesFileExist stackFile unless alreadyExists $ error $ stackFile <> " does not exist. Use 'stack init' to create it." logDebug args $ "handleStackConfig (alreadyExists): " ++ show alreadyExists let go = if isJust remoteUri then withCurrentDirectory localDir else id go $ runPlan localDir remoteUri args