{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell   #-}

module Stack.Constants.Config
  ( distDirFromDir
  , rootDistDirFromDir
  , setupConfigFromDir
  , workDirFromDir
  , distRelativeDir
  , imageStagingDir
  , projectDockerSandboxDir
  , configCabalMod
  , configSetupConfigMod
  , configPackageProjectRoot
  , buildCachesDir
  , testSuccessFile
  , testBuiltFile
  , hpcRelativeDir
  , hpcDirFromDir
  , objectInterfaceDirL
  , ghciDirL
  , templatesDir
  ) where

import           Path
import           Stack.Constants
import           Stack.Prelude
import           Stack.Types.Config

-- | Output .o/.hi directory.

objectInterfaceDirL :: HasBuildConfig env => Getting r env (Path Abs Dir)
objectInterfaceDirL :: forall env r. HasBuildConfig env => Getting r env (Path Abs Dir)
objectInterfaceDirL = forall s a. (s -> a) -> SimpleGetter s a
to forall a b. (a -> b) -> a -> b
$ \env
env -> -- FIXME is this idiomatic lens code?

  let workDir :: Path Rel Dir
workDir = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall env. HasConfig env => Lens' env (Path Rel Dir)
workDirL env
env
      root :: Path Abs Dir
root = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall env r. HasBuildConfig env => Getting r env (Path Abs Dir)
projectRootL env
env
   in Path Abs Dir
root forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
workDir forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelDir "odir/")

-- | GHCi files directory.

ghciDirL :: HasBuildConfig env => Getting r env (Path Abs Dir)
ghciDirL :: forall env r. HasBuildConfig env => Getting r env (Path Abs Dir)
ghciDirL = forall s a. (s -> a) -> SimpleGetter s a
to forall a b. (a -> b) -> a -> b
$ \env
env -> -- FIXME is this idiomatic lens code?

  let workDir :: Path Rel Dir
workDir = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall env. HasConfig env => Lens' env (Path Rel Dir)
workDirL env
env
      root :: Path Abs Dir
root = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall env r. HasBuildConfig env => Getting r env (Path Abs Dir)
projectRootL env
env
   in Path Abs Dir
root forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
workDir forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelDir "ghci/")

-- | The directory containing the files used for dirtiness check of source files.

buildCachesDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
               => Path Abs Dir      -- ^ Package directory.

               -> m (Path Abs Dir)
buildCachesDir :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
buildCachesDir Path Abs Dir
dir =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
        (forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelDir "stack-build-caches"))
        (forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
distDirFromDir Path Abs Dir
dir)

-- | The filename used to mark tests as having succeeded

testSuccessFile :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
                => Path Abs Dir -- ^ Package directory

                -> m (Path Abs File)
testSuccessFile :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
testSuccessFile Path Abs Dir
dir =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
        (forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelFile "stack-test-success"))
        (forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
distDirFromDir Path Abs Dir
dir)

-- | The filename used to mark tests as having built

testBuiltFile :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
              => Path Abs Dir -- ^ Package directory

              -> m (Path Abs File)
testBuiltFile :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
testBuiltFile Path Abs Dir
dir =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
        (forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelFile "stack-test-built"))
        (forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
distDirFromDir Path Abs Dir
dir)

-- | The filename used for modification check of .cabal

configCabalMod :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
               => Path Abs Dir      -- ^ Package directory.

               -> m (Path Abs File)
configCabalMod :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
configCabalMod Path Abs Dir
dir =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
        (forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelFile "stack-cabal-mod"))
        (forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
distDirFromDir Path Abs Dir
dir)

-- | The filename used for modification check of setup-config

configSetupConfigMod :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
                     => Path Abs Dir      -- ^ Package directory.

                     -> m (Path Abs File)
configSetupConfigMod :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
configSetupConfigMod Path Abs Dir
dir =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
        (forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelFile "stack-setup-config-mod"))
        (forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
distDirFromDir Path Abs Dir
dir)

-- | The filename used for the project root from the last build of a package

configPackageProjectRoot :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
                     => Path Abs Dir      -- ^ Package directory.

                     -> m (Path Abs File)
configPackageProjectRoot :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
configPackageProjectRoot Path Abs Dir
dir =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
        (forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelFile "stack-project-root"))
        (forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
distDirFromDir Path Abs Dir
dir)

-- | Directory for HPC work.

hpcDirFromDir
    :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
    => Path Abs Dir  -- ^ Package directory.

    -> m (Path Abs Dir)
hpcDirFromDir :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
hpcDirFromDir Path Abs Dir
fp =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Path Abs Dir
fp forall b t. Path b Dir -> Path Rel t -> Path b t
</>) forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
m (Path Rel Dir)
hpcRelativeDir

-- | Relative location of directory for HPC work.

hpcRelativeDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
               => m (Path Rel Dir)
hpcRelativeDir :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
m (Path Rel Dir)
hpcRelativeDir =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelDir "hpc")) forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
m (Path Rel Dir)
distRelativeDir

-- | Package's setup-config storing Cabal configuration

setupConfigFromDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
                   => Path Abs Dir
                   -> m (Path Abs File)
setupConfigFromDir :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs File)
setupConfigFromDir Path Abs Dir
fp = do
    Path Abs Dir
dist <- forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
distDirFromDir Path Abs Dir
fp
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Path Abs Dir
dist forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelFile "setup-config")

-- | Package's build artifacts directory.

distDirFromDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
               => Path Abs Dir
               -> m (Path Abs Dir)
distDirFromDir :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
distDirFromDir Path Abs Dir
fp =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Path Abs Dir
fp forall b t. Path b Dir -> Path Rel t -> Path b t
</>) forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
m (Path Rel Dir)
distRelativeDir

-- | The directory containing all dist directories, including all

-- different GHC/Cabal combos.

rootDistDirFromDir
  :: (MonadReader env m, HasConfig env)
  => Path Abs Dir
  -> m (Path Abs Dir)
rootDistDirFromDir :: forall env (m :: * -> *).
(MonadReader env m, HasConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
rootDistDirFromDir Path Abs Dir
fp =
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Path Abs Dir
fp forall b t. Path b Dir -> Path Rel t -> Path b t
</>) forall env (m :: * -> *).
(MonadReader env m, HasConfig env) =>
m (Path Rel Dir)
rootDistRelativeDir

-- | Relative directory to the top dist directory, containing

-- individual GHC/Cabal combo as subdirs.

rootDistRelativeDir
  :: (MonadReader env m, HasConfig env)
  => m (Path Rel Dir)
rootDistRelativeDir :: forall env (m :: * -> *).
(MonadReader env m, HasConfig env) =>
m (Path Rel Dir)
rootDistRelativeDir = do
    Path Rel Dir
workDir <- forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall env. HasConfig env => Lens' env (Path Rel Dir)
workDirL
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Path Rel Dir
workDir forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelDir "dist")

-- | Package's working directory.

workDirFromDir :: (MonadReader env m, HasConfig env)
               => Path Abs Dir
               -> m (Path Abs Dir)
workDirFromDir :: forall env (m :: * -> *).
(MonadReader env m, HasConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
workDirFromDir Path Abs Dir
fp = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall a b. (a -> b) -> a -> b
$ forall env. HasConfig env => Lens' env (Path Rel Dir)
workDirLforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall s a. (s -> a) -> SimpleGetter s a
to (Path Abs Dir
fp forall b t. Path b Dir -> Path Rel t -> Path b t
</>)

-- | Directory for project templates.

templatesDir :: Config -> Path Abs Dir
templatesDir :: Config -> Path Abs Dir
templatesDir Config
config = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall s. HasConfig s => Lens' s (Path Abs Dir)
stackRootL Config
config forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelDir "templates")

-- | Relative location of build artifacts.

distRelativeDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
                => m (Path Rel Dir)
distRelativeDir :: forall (m :: * -> *) env.
(MonadThrow m, MonadReader env m, HasEnvConfig env) =>
m (Path Rel Dir)
distRelativeDir = do
    Version
cabalPkgVer <- forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall env. HasCompiler env => SimpleGetter env Version
cabalVersionL
    Path Rel Dir
platform <- forall env (m :: * -> *).
(MonadReader env m, HasEnvConfig env, MonadThrow m) =>
m (Path Rel Dir)
platformGhcRelDir
    -- Cabal version

    Path Rel Dir
envDir <-
        forall (m :: * -> *). MonadThrow m => FilePath -> m (Path Rel Dir)
parseRelDir forall a b. (a -> b) -> a -> b
$
        PackageIdentifier -> FilePath
packageIdentifierString forall a b. (a -> b) -> a -> b
$
        PackageName -> Version -> PackageIdentifier
PackageIdentifier PackageName
cabalPackageName Version
cabalPkgVer
    Path Rel Dir
platformAndCabal <- forall (m :: * -> *).
MonadThrow m =>
Path Rel Dir -> m (Path Rel Dir)
useShaPathOnWindows (Path Rel Dir
platform forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
envDir)
    Path Rel Dir
allDist <- forall env (m :: * -> *).
(MonadReader env m, HasConfig env) =>
m (Path Rel Dir)
rootDistRelativeDir
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Path Rel Dir
allDist forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
platformAndCabal

-- | Docker sandbox from project root.

projectDockerSandboxDir :: (MonadReader env m, HasConfig env)
  => Path Abs Dir      -- ^ Project root

  -> m (Path Abs Dir)  -- ^ Docker sandbox

projectDockerSandboxDir :: forall env (m :: * -> *).
(MonadReader env m, HasConfig env) =>
Path Abs Dir -> m (Path Abs Dir)
projectDockerSandboxDir Path Abs Dir
projectRoot = do
  Path Rel Dir
workDir <- forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall env. HasConfig env => Lens' env (Path Rel Dir)
workDirL
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Path Abs Dir
projectRoot forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
workDir forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelDir "docker/")

-- | Image staging dir from project root.

imageStagingDir :: (MonadReader env m, HasConfig env, MonadThrow m)
  => Path Abs Dir      -- ^ Project root

  -> Int               -- ^ Index of image

  -> m (Path Abs Dir)  -- ^ Docker sandbox

imageStagingDir :: forall env (m :: * -> *).
(MonadReader env m, HasConfig env, MonadThrow m) =>
Path Abs Dir -> Int -> m (Path Abs Dir)
imageStagingDir Path Abs Dir
projectRoot Int
imageIdx = do
  Path Rel Dir
workDir <- forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall env. HasConfig env => Lens' env (Path Rel Dir)
workDirL
  Path Rel Dir
idxRelDir <- forall (m :: * -> *). MonadThrow m => FilePath -> m (Path Rel Dir)
parseRelDir (forall a. Show a => a -> FilePath
show Int
imageIdx)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Path Abs Dir
projectRoot forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
workDir forall b t. Path b Dir -> Path Rel t -> Path b t
</> $(mkRelDir "image") forall b t. Path b Dir -> Path Rel t -> Path b t
</> Path Rel Dir
idxRelDir