@@ -14,8 +14,7 @@ module Obelisk.Command.Run where
1414import Control.Arrow ((&&&))
1515import Control.Exception (Exception, bracket)
1616import Control.Lens (ifor, (.~), (&))
17−import Control.Concurrent (forkIO)
18−import Control.Monad (filterM, void)
17+import Control.Monad (filterM)
1918import Control.Monad.Except (runExceptT, throwError)
2019import Control.Monad.IO.Class (liftIO)
2120import Control.Monad.Reader (MonadIO)
@@ -46,23 +45,13 @@ import Debug.Trace (trace)
4645import Distribution.Compiler (CompilerFlavor(..))
4746import Distribution.PackageDescription.Parsec (parseGenericPackageDescription)
4847import Distribution.Parsec.ParseResult (runParseResult)
49−import Distribution.Pretty (prettyShow)
50−import Distribution.Simple.Compiler (PackageDB (GlobalPackageDB))
51−import Distribution.Simple.Configure (configCompilerEx, getInstalledPackages)
52−import Distribution.Simple.PackageIndex (InstalledPackageIndex, lookupDependency)
53−import Distribution.Simple.Program.Db (defaultProgramDb)
5448import qualified Distribution.System as Dist
55−import Distribution.Types.BuildInfo (buildable, cppOptions, defaultExtensions, defaultLanguage, hsSourceDirs, options, targetBuildDepends)
49+import Distribution.Types.BuildInfo (buildable, cppOptions, defaultExtensions, defaultLanguage, hsSourceDirs, options)
5650import Distribution.Types.CondTree (simplifyCondTree)
57−import Distribution.Types.Dependency (Dependency (..), depPkgName)
5851import Distribution.Types.GenericPackageDescription (ConfVar (Arch, Impl, OS), condLibrary)
59−import Distribution.Types.InstalledPackageInfo (compatPackageKey)
6052import Distribution.Types.Library (libBuildInfo)
61−import Distribution.Types.PackageName (mkPackageName)
62−import Distribution.Types.VersionRange (anyVersion)
6353import Distribution.Utils.Generic (toUTF8BS, readUTF8File)
6454import qualified Distribution.Parsec.Common as Dist
65−import qualified Distribution.Verbosity as Verbosity (silent)
6655import qualified Hpack.Config as Hpack
6756import qualified Hpack.Render as Hpack
6857import qualified Hpack.Yaml as Hpack
@@ -72,16 +61,12 @@ import System.Directory
7261import System.Environment (getExecutablePath)
7362import System.FilePath
7463import qualified System.Info
75−import System.IO (hClose, hGetLine)
7664import System.IO.Temp (withSystemTempDirectory)
77−import System.Process (CreateProcess (..), StdStream (..))
7865
79−import Obelisk.App (MonadObelisk, getObelisk, runObelisk)
66+import Obelisk.App (MonadObelisk)
8067import Obelisk.CliApp (
8168 Severity (..),
82− createProcess_,
8369 failWith,
84− overCreateProcess,
8570 proc,
8671 putLog,
8772 readCreateProcessWithExitCode,
@@ -92,7 +77,7 @@ import Obelisk.CliApp (
9277 withSpinner,
9378 )
9479import Obelisk.Command.Nix
95−import Obelisk.Command.Project
80+import Obelisk.Command.Project (nixShellWithoutPkgs, withProjectRoot, findProjectAssets, bashEscape)
9681import Obelisk.Command.Thunk (attrCacheFileName)
9782import Obelisk.Command.Utils (findExePath, ghcidExePath)
9883
@@ -111,8 +96,6 @@ data CabalPackageInfo = CabalPackageInfo
11196 -- ^ List of compiler-specific options (e.g., the "ghc-options" field of the cabal file)
11297 , _cabalPackageInfo_cppOptions :: [String]
11398 -- ^ List of CPP (C Preprocessor) options (e.g. the "cpp-options" field of the cabal file)
114− , _cabalPackageInfo_buildDepends :: [Dependency]
115− -- ^ List of build dependencies listed in the cabal file
11699 }
117100
118101-- | 'Bool' with a better name for its purpose.
@@ -161,8 +144,8 @@ profile profileBasePattern rtsFlags = withProjectRoot "." $ \root -> do
161144 , _target_attr = Just "__unstable__.profiledObRun"
162145 , _target_expr = Nothing
163146 }
164− (assetType, assets) <- findProjectAssets root
165− putLog Debug $ describeImpureAssetSource assetType assets
147+ assets <- findProjectAssets root
148+ putLog Debug $ "Assets impurely loaded from: " <> assets
166149 time <- liftIO getCurrentTime
167150 let profileBaseName = formatTime defaultTimeLocale profileBasePattern time
168151 liftIO $ createDirectoryIfMissing True $ takeDirectory $ root </> profileBaseName
@@ -180,16 +163,9 @@ profile profileBasePattern rtsFlags = withProjectRoot "." $ \root -> do
180163run :: MonadObelisk m => FilePath -> PathTree Interpret -> m ()
181164run root interpretPaths = do
182165 pkgs <- getParsedLocalPkgs root interpretPaths
183− (assetType, assets) <- findProjectAssets root
184− manifestPkg <- parsePackagesOrFail . (:[]) . T.unpack =<< getHaskellManifestProjectPath root
185− putLog Debug $ describeImpureAssetSource assetType assets
186− case assetType of
187− AssetSource_Derivation -> do
188− ob <- getObelisk
189− putLog Debug "Starting static file derivation watcher..."
190− void $ liftIO $ forkIO $ runObelisk ob $ watchStaticFilesDerivation root
191− _ -> pure ()
192− ghciArgs <- getGhciSessionSettings (pkgs <> manifestPkg) root True
166+ assets <- findProjectAssets root
167+ putLog Debug $ "Assets impurely loaded from: " <> assets
168+ ghciArgs <- getGhciSessionSettings pkgs root True
193169 freePort <- getFreePort
194170 withGhciScriptArgs pkgs $ \dotGhciArgs -> do
195171 runGhcid root True (ghciArgs <> dotGhciArgs) pkgs $ Just $ unwords
@@ -246,12 +222,7 @@ getLocalPkgs root interpretPaths = do
246222 let rootsAndExclusions = calcIntepretFinds "" interpretPaths
247223
248224 fmap fold $ for (MMap.toAscList rootsAndExclusions) $ \(interpretPathRoot, exclusions) ->
249− let allExclusions = obeliskPackageExclusions
250− <> exclusions
251− <> Set.singleton ("*" </> attrCacheFileName)
252− <> Set.singleton ("*" </> "lib/asset/manifest") -- NB: obelisk-asset-manifest is excluded because it generates
253− -- a module that in turn imports it. This will cause ob run to
254− -- fail in its current implementation.
225+ let allExclusions = obeliskPackageExclusions <> exclusions <> Set.singleton ("*" </> attrCacheFileName)
255226 in fmap (Set.fromList . map normalise) $ runFind $
256227 ["-L", interpretPathRoot, "(", "-name", "*.cabal", "-o", "-name", Hpack.packageConfig, ")", "-a", "-type", "f"]
257228 <> concat [["-not", "-path", p </> "*"] | p <- toList allExclusions]
@@ -383,7 +354,6 @@ parseCabalPackage' pkg = runExceptT $ do
383354 defaultLanguage $ libBuildInfo lib
384355 , _cabalPackageInfo_compilerOptions = options $ libBuildInfo lib
385356 , _cabalPackageInfo_cppOptions = cppOptions $ libBuildInfo lib
386− , _cabalPackageInfo_buildDepends = targetBuildDepends $ libBuildInfo lib
387357 }
388358 Right Nothing -> pure Nothing
389359 Left (_, errors) ->
@@ -430,8 +400,7 @@ withGhciScriptArgs
430400 => f CabalPackageInfo -- ^ List of packages to load into ghci
431401 -> ([String] -> m ()) -- ^ Action to run with the extra ghci arguments
432402 -> m ()
433−withGhciScriptArgs packageInfos f = withGhciScript loadPreludeManually packageInfos $ \fp ->
434− f ["-XNoImplicitPrelude", "-ghci-script", fp]
403+withGhciScriptArgs packageInfos f = withGhciScript loadPreludeManually packageInfos $ \fp -> f ["-XNoImplicitPrelude", "-ghci-script", fp]
435404 where
436405 -- These lines must be first and allow the session to support a custom Prelude when @-XNoImplicitPrelude@
437406 -- is passed to the ghci session.
@@ -481,7 +450,6 @@ getGhciSessionSettings (toList -> packageInfos) pathBase useRelativePaths = do
481450 -- all paths to 'pathBase'.
482451 selfExe <- liftIO $ canonicalizePath =<< getExecutablePath
483452 canonicalPathBase <- liftIO $ canonicalizePath pathBase
484− installedPackageIndex <- loadPackageIndex pathBase
485453
486454 (pkgFiles, pkgSrcPaths :: [NonEmpty FilePath]) <- fmap unzip $ liftIO $ for packageInfos $ \pkg -> do
487455 canonicalSrcDirs <- traverse canonicalizePath $ (_cabalPackageInfo_packageRoot pkg </>) <$> _cabalPackageInfo_sourceDirs pkg
@@ -490,52 +458,16 @@ getGhciSessionSettings (toList -> packageInfos) pathBase useRelativePaths = do
490458
491459 pure
492460 $ baseGhciOptions
493− <> ["-DOBELISK_ASSET_PASSTHRU"] -- For passthrough static assets
494461 <> ["-F", "-pgmF", selfExe, "-optF", preprocessorIdentifier]
495462 <> concatMap (\p -> ["-optF", p]) pkgFiles
496463 <> [ "-i" <> intercalate ":" (concatMap toList pkgSrcPaths) ]
497− <> concatMap (\packageId -> ["-package-id", packageId ])
498− (packageIds installedPackageIndex)
499464 where
500465 relativeTo' = if useRelativePaths then relativeTo else const
501− -- Package names we're building and not needed from the package DB
502− packageNames =
503− map (mkPackageName . T.unpack . _cabalPackageInfo_packageName)
504− packageInfos
505− packageIds installedPackageIndex =
506− map (dependencyPackageId installedPackageIndex) $
507− filter ((`notElem` packageNames) . depPkgName) $
508− concatMap _cabalPackageInfo_buildDepends packageInfos <>
509− [Dependency (mkPackageName "obelisk-run") anyVersion]
510− dependencyPackageId installedPackageIndex dep =
511− case lookupDependency installedPackageIndex dep of
512− ((_version,installedPackageInfo:_) :_) ->
513− compatPackageKey installedPackageInfo
514− _ -> error $ "Couldn't resolve dependency for " <> prettyShow dep
515−
516−-- Load the package index used by the GHC in this path's nix project
517−loadPackageIndex :: (MonadObelisk m) => FilePath -> m InstalledPackageIndex
518−loadPackageIndex root = do
519− ghcPath <- getPathInNixEnvironment "bash -c 'type -p ghc'"
520− ghcPkgPath <- getPathInNixEnvironment "bash -c 'type -p ghc-pkg'"
521− (compiler, _platform, programDb) <- liftIO
522− $ configCompilerEx (Just GHC) (Just ghcPath) (Just ghcPkgPath) defaultProgramDb Verbosity.silent
523− liftIO $ getInstalledPackages Verbosity.silent compiler [GlobalPackageDB] programDb
524− where
525− getPathInNixEnvironment cmd = do
526− procSpec <- runProc <$> nixShellRunConfig root True (Just cmd)
527− (_,Just h,_,_) <- createProcess_ "loadPackageIndex" procSpec
528− path <- liftIO $ hGetLine h >>= canonicalizePath
529− liftIO $ hClose h
530− pure path
531− runProc =
532− overCreateProcess (\cs -> cs { std_out = CreatePipe }) . nixShellRunProc
533466
534467baseGhciOptions :: [String]
535468baseGhciOptions =
536469 [ "-ignore-dot-ghci"
537470 , "-no-user-package-db"
538− , "-hide-all-packages"
539471 , "-package-env", "-"
540472 ]
541473