Skip to content

Commit

Permalink
Dev Server now ensure that build/ihp-lib exists
Browse files Browse the repository at this point in the history
  • Loading branch information
mpscholten committed Nov 13, 2020
1 parent 1803f2b commit b9132ce
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 23 deletions.
21 changes: 0 additions & 21 deletions IHP/FrameworkConfig.hs
Expand Up @@ -219,27 +219,6 @@ defaultDatabaseUrl = do
let defaultDatabaseUrl = "postgresql:///app?host=" <> cs currentDirectory <> "/build/db"
(Environment.lookupEnv "DATABASE_URL") >>= (pure . maybe defaultDatabaseUrl cs )

-- | Finds the lib
--
-- The location depends on whether the framework is installed through nix
-- or checked out from git inside the current project directory.
--
-- When it's installed with nix, the lib dir is located at @lib/ihp@
-- while the dev server binary is located at @bin/RunDevServer@.
findLibDirectory :: IO Text
findLibDirectory = do
frameworkMountedLocally <- Directory.doesDirectoryExist "IHP"
ihpLibSymlinkAvailable <- Directory.doesDirectoryExist "build/ihp-lib"
if frameworkMountedLocally
then pure "IHP/lib/IHP/"
else if ihpLibSymlinkAvailable
then do
pure "build/ihp-lib/"
else do
binDir <- cs <$> Process.readCreateProcess (Process.shell "dirname $(which RunDevServer)") ""
pure (Text.strip binDir <> "/../lib/IHP/")


-- Returns 'True' when the application is running in a given environment
isEnvironment :: (?context :: context, ConfigProvider context) => Environment -> Bool
isEnvironment environment = (getFrameworkConfig ?context |> get #environment) == environment
Expand Down
3 changes: 2 additions & 1 deletion IHP/IDE/ToolServer.hs
Expand Up @@ -50,6 +50,7 @@ import qualified IHP.AutoRefresh.Types as AutoRefresh
import IHP.Controller.Context
import qualified IHP.IDE.ToolServer.Layout as Layout
import IHP.Controller.Layout
import qualified IHP.LibDir as LibDir

startToolServer :: (?context :: Context) => IO ()
startToolServer = do
Expand Down Expand Up @@ -83,7 +84,7 @@ startToolServer' port isDebugMode = do
let ?context = requestContext
frontControllerToWAIApp toolServerApplication ErrorController.handleNotFound

libDirectory <- cs <$> Config.findLibDirectory
libDirectory <- cs <$> LibDir.findLibDirectory
let staticMiddleware :: Wai.Middleware = staticPolicy (addBase (libDirectory <> "static/"))

let openAppUrl = openUrl ("http://localhost:" <> tshow port <> "/")
Expand Down
55 changes: 55 additions & 0 deletions IHP/LibDir.hs
@@ -0,0 +1,55 @@
{-|
Module: IHP.LibDir
Description: Functions to access the IHP lib/ directory at runtime
Copyright: (c) digitally induced GmbH, 2020
-}
module IHP.LibDir (findLibDirectory, ensureSymlink) where

import IHP.Prelude
import qualified System.Directory as Directory
import qualified Data.Text as Text
import qualified System.Process as Process
import qualified System.Posix.Files as Files

-- | Finds the lib
--
-- The location depends on whether the framework is installed through nix
-- or checked out from git inside the current project directory.
--
-- When it's installed with nix, the lib dir is located at @lib/ihp@
-- while the dev server binary is located at @bin/RunDevServer@.
findLibDirectory :: IO Text
findLibDirectory = do
frameworkMountedLocally <- Directory.doesDirectoryExist "IHP"
ihpLibSymlinkAvailable <- Directory.doesDirectoryExist "build/ihp-lib"
if frameworkMountedLocally
then pure "IHP/lib/IHP/"
else if ihpLibSymlinkAvailable
then do
pure "build/ihp-lib/"
else do
binDir <- cs <$> Process.readCreateProcess (Process.shell "dirname $(which RunDevServer)") ""
pure (Text.strip binDir <> "/../lib/IHP/")

-- | Creates the build/ihp-lib symlink if missing
--
-- This is called in dev mode to make sure that build/ihp-lib points to the right IHP version.
-- Otherwise the CLI tools might not work as expected, e.g. @make db@ might fail.
--
-- If the symlink is missing, it tries to fix this by starting a new nix-shell and pinpointing the framework lib dir in there
ensureSymlink :: IO ()
ensureSymlink = do
frameworkMountedLocally <- pure False
ihpLibSymlinkAvailable <- Directory.doesDirectoryExist "build/ihp-lib"

unless ihpLibSymlinkAvailable do
-- Make sure the build directory exists, otherwise we cannot add the symlink
Directory.createDirectoryIfMissing False "build"

libDir <- if frameworkMountedLocally
then pure "../IHP/lib/IHP/"
else do
putStrLn "Building build/ihp-lib. This might take a few seconds"
binDir <- cs <$> Process.readCreateProcess (Process.shell "nix-shell --run 'dirname $(which RunDevServer)'") ""
pure (Text.strip binDir <> "/../lib/IHP/")
Files.createSymbolicLink (cs libDir) "build/ihp-lib"
1 change: 1 addition & 0 deletions IHP/Server.hs
Expand Up @@ -28,6 +28,7 @@ import qualified Control.Concurrent as Concurrent
import qualified IHP.AutoRefresh as AutoRefresh
import qualified IHP.AutoRefresh.Types as AutoRefresh
import qualified IHP.WebSocket as WS
import IHP.LibDir

run :: (FrontController RootApplication) => ConfigBuilder -> IO ()
run configBuilder = do
Expand Down
4 changes: 3 additions & 1 deletion exe/IHP/IDE/DevServer.hs
Expand Up @@ -21,12 +21,14 @@ import System.Info
import Data.String.Conversions (cs)
import qualified IHP.FrameworkConfig as Config
import IHP.Environment
import qualified IHP.LibDir as LibDir

main :: IO ()
main = do
actionVar <- newEmptyMVar
appStateRef <- newIORef emptyAppState
portConfig <- findAvailablePortConfig
LibDir.ensureSymlink

-- Start the dev server in Debug mode by setting the env var DEBUG=1
-- Like: $ DEBUG=1 ./start
Expand Down Expand Up @@ -230,7 +232,7 @@ startAppGHCI = do

let ManagedProcess { outputHandle, errorHandle } = process

libDirectory <- Config.findLibDirectory
libDirectory <- LibDir.findLibDirectory

let loadAppCommands =
[ ":script " <> cs libDirectory <> "/applicationGhciConfig"
Expand Down
1 change: 1 addition & 0 deletions ihp.cabal
Expand Up @@ -247,6 +247,7 @@ library IHPFramework
, IHP.FlashMessages.ControllerFunctions
, IHP.FlashMessages.ViewFunctions
, IHP.SchemaMigration
, IHP.LibDir

executable RunDevServer
import: shared-properties
Expand Down

0 comments on commit b9132ce

Please sign in to comment.