on master help sign in
Merge remote-tracking branch 'origin/qa' into eac@ob-hoogle
commitacc1adeeb23bd7ad571876c86a02ac49e77ab183 authorElliot Cameron <eacameron@gmail.com> dateThu 30 Jan 2020, 19:07 (7 years ago) parent443dbd7085e349
6 files changed+114−75
ChangeLog.md+1−1 default.nix+3−2 lib/command/src/Obelisk/Command/Project.hs+11−13 lib/command/src/Obelisk/Command/Run.hs+22−17 lib/selftest/src/Obelisk/SelfTest.hs+76−41 lib/snap-extras/obelisk-snap-extras.cabal+1−1
ChangeLog.md+1−1
@@ -5,7 +5,7 @@ This project's release branch is `master`. This log is written from the perspect
55## Unreleased
66
77* Add `Obelisk.Route.(?/)`, a convenience function for constructing routes nested in `Maybe`. ([#457](https://github.com/obsidiansystems/obelisk/pull/457))
8−* Add local unpacked packages to the `ob run` and `ob repl` sessions. Any `.cabal` or hpack package inside the current obelisk project will be loaded into the session. For `ob run` this means the test server will automatically reload when you save a source file in any of those packages. For `ob repl` it means that `:r` will reload changes to any of those packages. There are some edge cases where this integration is still rough. Report any issues you encounter. ([#489](https://github.com/obsidiansystems/obelisk/pull/489))
8+* Add local unpacked packages to the `ob run`, `ob watch`, and `ob repl` sessions. Any `.cabal` or hpack package inside the current obelisk project will be loaded into the session. For `ob run`/`ob watch` this means the session will automatically reload when you save a source file in any of those packages. For `ob repl` it means that `:r` will reload changes to any of those packages. There are some edge cases where this integration is still rough. Report any issues you encounter. ([#489](https://github.com/obsidiansystems/obelisk/pull/489))
99* Add `ob hoogle` command to start a local [Hoogle](https://hoogle.haskell.org/) server for the project. ([#628](https://github.com/obsidiansystems/obelisk/pull/628))
1010
1111## v0.4.0.0 - 2020-01-10
default.nix+3−2
@@ -71,6 +71,8 @@ let
7171 librarySystemDepends = [
7272 pkgs.cabal-install
7373 pkgs.coreutils
74+ pkgs.git
75+ pkgs.nix
7476 ];
7577 };
7678 obelisk-snap-extras = self.callCabal2nix "obelisk-snap-extras" (cleanSource ./lib/snap-extras) {};
@@ -130,8 +132,7 @@ in rec {
130132 set -euo pipefail
131133
132134 PATH="${command}/bin:$PATH"
133− export OBELISK_IMPL="$(mktemp -d)"
134− ${pkgs.git}/bin/git clone file://${pathGit} $OBELISK_IMPL
135+ cd ${./.}
135136 "${ghcObelisk.obelisk-selftest}/bin/obelisk-selftest" +RTS -N -RTS "$@"
136137 '';
137138 skeleton = pkgs.runCommand "skeleton" {
lib/command/src/Obelisk/Command/Project.hs+11−13
@@ -270,20 +270,21 @@ nixShellRunConfig root isPure command = do
270270 , c
271271 ])
272272
273−nixShellRunProc :: FilePath -> NixShellConfig -> ProcessSpec
274−nixShellRunProc root cfg = setDelegateCtlc True $ setCwd (Just root) $ proc "nix-shell" $ runNixShellConfig cfg
273+nixShellRunProc :: NixShellConfig -> ProcessSpec
274+nixShellRunProc cfg = setDelegateCtlc True $ proc "nix-shell" $ runNixShellConfig cfg
275275
276−nixShellWithPkgs :: MonadObelisk m => FilePath -> Bool -> Map Text FilePath -> Maybe String -> m ()
277−nixShellWithPkgs root isPure packageNamesAndPaths command = do
276+nixShellWithPkgs :: MonadObelisk m => FilePath -> Bool -> Bool -> Map Text FilePath -> Maybe String -> m ()
277+nixShellWithPkgs root isPure chdirToRoot packageNamesAndPaths command = do
278278 packageNamesAndAbsPaths <- liftIO $ for packageNamesAndPaths makeAbsolute
279279 defShellConfig <- nixShellRunConfig root isPure command
280− (_, _, _, ph) <- createProcess_ "nixShellWithPkgs" $ nixShellRunProc root $ defShellConfig
280+ let setCwd_ = if chdirToRoot then setCwd (Just root) else id
281+ (_, _, _, ph) <- createProcess_ "nixShellWithPkgs" $ setCwd_ $ nixShellRunProc $ defShellConfig
281282 & nixShellConfig_common . nixCmdConfig_target . target_expr ?~
282283 "{root, pkgs}: ((import root {}).passthru.__unstable__.self.extend (_: _: {\
283284 \shellPackages = builtins.fromJSON pkgs;\
284285 \})).project.shells.ghc"
285286 & nixShellConfig_common . nixCmdConfig_args .~
286− [ rawArg "root" $ toNixPath root
287+ [ rawArg "root" $ toNixPath $ if chdirToRoot then "." else root
287288 , strArg "pkgs" (T.unpack $ decodeUtf8 $ BSL.toStrict $ Json.encode packageNamesAndAbsPaths)
288289 ]
289290 void $ liftIO $ waitForProcess ph
@@ -291,21 +292,18 @@ nixShellWithPkgs root isPure packageNamesAndPaths command = do
291292nixShellWithHoogle :: MonadObelisk m => FilePath -> Bool -> String -> Maybe String -> m ()
292293nixShellWithHoogle root isPure shell' command = do
293294 defShellConfig <- nixShellRunConfig root isPure command
294− (_, _, _, ph) <- createProcess_ "nixShellWithHoogle" $ nixShellRunProc root $ defShellConfig
295+ (_, _, _, ph) <- createProcess_ "nixShellWithHoogle" $ setCwd (Just root) $ nixShellRunProc $ defShellConfig
295296 & nixShellConfig_common . nixCmdConfig_target . target_expr ?~
296− "{root, shell}: ((import root {}).passthru.__unstable__.self.extend (_: super: {\
297+ "{shell}: ((import ./. {}).passthru.__unstable__.self.extend (_: super: {\
297298 \userSettings = super.userSettings // { withHoogle = true; };\
298299 \})).project.shells.${shell}"
299− & nixShellConfig_common . nixCmdConfig_args .~
300− [ rawArg "root" $ toNixPath root
301− , strArg "shell" shell'
302− ]
300+ & nixShellConfig_common . nixCmdConfig_args .~ [ strArg "shell" shell' ]
303301 void $ liftIO $ waitForProcess ph
304302
305303projectShell :: MonadObelisk m => FilePath -> Bool -> String -> Maybe String -> m ()
306304projectShell root isPure shellName command = do
307305 defShellConfig <- nixShellRunConfig root isPure command
308− (_, _, _, ph) <- createProcess_ "runNixShellAttr" $ nixShellRunProc root $ defShellConfig
306+ (_, _, _, ph) <- createProcess_ "runNixShellAttr" $ setCwd (Just root) $ nixShellRunProc $ defShellConfig
309307 & nixShellConfig_common . nixCmdConfig_target . target_path ?~ "default.nix"
310308 & nixShellConfig_common . nixCmdConfig_target . target_attr ?~ ("shells." <> shellName)
311309 void $ liftIO $ waitForProcess ph
lib/command/src/Obelisk/Command/Run.hs+22−17
@@ -72,7 +72,7 @@ preprocessorIdentifier = "__preprocessor-apply-packages"
7272run :: MonadObelisk m => m ()
7373run = withProjectRoot "." $ \root -> do
7474 pkgs <- fmap toList . parsePackagesOrFail =<< getLocalPkgs root
75− withGhciScript pkgs $ \dotGhciPath -> do
75+ withGhciScript pkgs root $ \dotGhciPath -> do
7676 freePort <- getFreePort
7777 assets <- do
7878 let importableRoot = toNixPath root
@@ -96,7 +96,7 @@ run = withProjectRoot "." $ \root -> do
9696 else readProcessAndLogStderr Debug $
9797 proc nixExePath ["eval", "-f", root, "passthru.staticFilesImpure", "--raw"]
9898 putLog Debug $ "Assets impurely loaded from: " <> assets
99− runGhcid dotGhciPath pkgs $ Just $ unwords
99+ runGhcid root True dotGhciPath pkgs $ Just $ unwords
100100 [ "Obelisk.Run.run"
101101 , show freePort
102102 , "(Obelisk.Run.runServeAsset " ++ show assets ++ ")"
@@ -105,15 +105,16 @@ run = withProjectRoot "." $ \root -> do
105105 ]
106106
107107runRepl :: MonadObelisk m => m ()
108−runRepl = do
109− pkgs <- fmap toList . parsePackagesOrFail =<< withProjectRoot "." getLocalPkgs
110− withGhciScript pkgs $ \dotGhciPath -> do
111− runGhciRepl pkgs dotGhciPath
108+runRepl = withProjectRoot "." $ \root -> do
109+ pkgs <- fmap toList . parsePackagesOrFail =<< getLocalPkgs root
110+ withGhciScript pkgs "." $ \dotGhciPath ->
111+ runGhciRepl root pkgs dotGhciPath
112112
113113runWatch :: MonadObelisk m => m ()
114−runWatch = do
115− pkgs <- fmap toList . parsePackagesOrFail =<< withProjectRoot "." getLocalPkgs
116− withGhciScript pkgs $ \dotGhciPath -> runGhcid dotGhciPath pkgs Nothing
114+runWatch = withProjectRoot "." $ \root -> do
115+ pkgs <- fmap toList . parsePackagesOrFail =<< getLocalPkgs root
116+ withGhciScript pkgs root $ \dotGhciPath ->
117+ runGhcid root True dotGhciPath pkgs Nothing
117118
118119-- | Relative paths to local packages of an obelisk project.
119120--
@@ -254,9 +255,10 @@ packageInfoToNamePathMap = Map.fromList . map (_cabalPackageInfo_packageName &&&
254255withGhciScript
255256 :: MonadObelisk m
256257 => [CabalPackageInfo] -- ^ List of packages to load into ghci
258+ -> FilePath -- ^ All paths written to the .ghci file will be relative to this path
257259 -> (FilePath -> m ()) -- ^ Action to run with the path to generated temporary .ghci
258260 -> m ()
259−withGhciScript packageInfos f = do
261+withGhciScript packageInfos pathBase f = do
260262 selfExe <- liftIO getExecutablePath
261263 let
262264 packageNames = Set.fromList $ map _cabalPackageInfo_packageName packageInfos
@@ -281,28 +283,31 @@ withGhciScript packageInfos f = do
281283
282284 where
283285 rootedSourceDirs pkg = NE.toList $
284− (_cabalPackageInfo_packageRoot pkg </>) <$> _cabalPackageInfo_sourceDirs pkg
286+ makeRelative pathBase . (_cabalPackageInfo_packageRoot pkg </>) <$> _cabalPackageInfo_sourceDirs pkg
285287
286288-- | Run ghci repl
287289runGhciRepl
288290 :: MonadObelisk m
289− => [CabalPackageInfo]
291+ => FilePath -- ^ Path to project root
292+ -> [CabalPackageInfo]
290293 -> FilePath -- ^ Path to .ghci
291294 -> m ()
292−runGhciRepl packages dotGhci = withProjectRoot "." $ \root ->
295+runGhciRepl root packages dotGhci =
293296 -- NOTE: We do *not* want to use $(staticWhich "ghci") here because we need the
294297 -- ghc that is provided by the shell in the user's project.
295− nixShellWithPkgs root True (packageInfoToNamePathMap packages) $ Just $ "ghci " <> makeBaseGhciOptions dotGhci -- TODO: Shell escape
298+ nixShellWithPkgs root True False (packageInfoToNamePathMap packages) $ Just $ "ghci " <> makeBaseGhciOptions dotGhci -- TODO: Shell escape
296299
297300-- | Run ghcid
298301runGhcid
299302 :: MonadObelisk m
300− => FilePath -- ^ Path to .ghci
303+ => FilePath -- ^ Path to project root
304+ -> Bool -- ^ Should we chdir to root when running this process?
305+ -> FilePath -- ^ Path to .ghci
301306 -> [CabalPackageInfo]
302307 -> Maybe String -- ^ Optional command to run at every reload
303308 -> m ()
304−runGhcid dotGhci packages mcmd = withProjectRoot "." $ \root ->
305− nixShellWithPkgs root True (packageInfoToNamePathMap packages) (Just $ unwords $ ghcidExePath : opts) -- TODO: Shell escape
309+runGhcid root chdirToRoot dotGhci packages mcmd =
310+ nixShellWithPkgs root True chdirToRoot (packageInfoToNamePathMap packages) (Just $ unwords $ ghcidExePath : opts) -- TODO: Shell escape
306311 where
307312 opts =
308313 [ "-W"
lib/selftest/src/Obelisk/SelfTest.hs+76−41
@@ -1,3 +1,4 @@
1+{-# LANGUAGE DoAndIfThenElse #-}
12{-# LANGUAGE EmptyCase #-}
23{-# LANGUAGE LambdaCase #-}
34{-# LANGUAGE OverloadedStrings #-}
@@ -23,13 +24,13 @@ import qualified Network.HTTP.Client as HTTP
2324import qualified Network.HTTP.Types as HTTP
2425import qualified Network.Socket as Socket
2526import Shelly hiding (cp)
26−import System.Directory (withCurrentDirectory, getDirectoryContents)
27+import System.Directory (getCurrentDirectory, withCurrentDirectory, getDirectoryContents)
2728import System.Environment
2829import System.Exit (ExitCode (..))
2930import System.FilePath (replaceBaseName, takeBaseName)
3031import System.Which (staticWhich)
3132import qualified System.Info
32−import System.IO (Handle, hClose)
33+import System.IO (Handle, hClose, hIsEOF, hGetContents)
3334import System.IO.Temp
3435import System.Process (readProcessWithExitCode, CreateProcess(cwd), readCreateProcessWithExitCode, proc)
3536import Test.Hspec
@@ -52,11 +53,32 @@ cp = $(staticWhich "cp")
5253cabalPath :: FilePath
5354cabalPath = $(staticWhich "cabal")
5455
56+gitPath :: FilePath
57+gitPath = $(staticWhich "git")
58+
59+chownPath :: FilePath
60+chownPath = $(staticWhich "chown")
61+
62+chmodPath :: FilePath
63+chmodPath = $(staticWhich "chmod")
64+
65+whoamiPath :: FilePath
66+whoamiPath = $(staticWhich "whoami")
67+
68+nixBuildPath :: FilePath
69+nixBuildPath = $(staticWhich "nix-build")
70+
71+lnPath :: FilePath
72+lnPath = $(staticWhich "ln")
73+
74+rmPath :: FilePath
75+rmPath = $(staticWhich "rm")
76+
5577gitUserConfig :: [Text]
5678gitUserConfig = ["-c", "user.name=Obelisk Selftest", "-c", "user.email=noreply@example.com"]
5779
5880commit :: Text -> Sh ()
59−commit msg = void $ run "git" $ gitUserConfig <> [ "commit"
81+commit msg = void $ run gitPath $ gitUserConfig <> [ "commit"
6082 , "--no-gpg-sign"
6183 , "--allow-empty"
6284 , "-m"
@@ -92,20 +114,26 @@ main = do
92114 unless isVerbose $
93115 putStrLn "Tests may take longer to run if there are unbuilt derivations: use -v for verbose output"
94116 let verbosity = bool silently verbosely isVerbose
95− nixBuild args = run "nix-build" ("--no-out-link" : args)
96− obeliskImplRaw <- fromString <$> getEnv "OBELISK_IMPL"
117+ nixBuild args = run nixBuildPath ("--no-out-link" : args)
118+ obeliskImplDirtyReadOnly <- fromString <$> getCurrentDirectory
97119 let runOb_ = augmentWithVerbosity run_ ob isVerbose
98120 let runOb = augmentWithVerbosity run ob isVerbose
99121 let testObRunInDir' = augmentWithVerbosity testObRunInDir ob isVerbose ["run"]
100122 let testThunkPack' = augmentWithVerbosity testThunkPack ob isVerbose []
101123 let
102− withObeliskImpl f =
124+ withObeliskImplClean f =
125+ withSystemTempDirectory "obelisk-impl-clean" $ \(fromString -> obeliskImpl) -> do
126+ void . shellyOb verbosity $ chdir obeliskImpl $ do
127+ run_ gitPath ["clone", "file://" <> toTextIgnore obeliskImplDirtyReadOnly, toTextIgnore obeliskImpl]
128+ f obeliskImpl
129+
130+ withObeliskImplDirty f =
103131 withSystemTempDirectory "obelisk-impl-copy" $ \(fromString -> obeliskImpl) -> do
104132 void . shellyOb verbosity $ chdir obeliskImpl $ do
105− user <- T.strip <$> run "whoami" []
106− run_ cp ["-rT", toTextIgnore obeliskImplRaw, toTextIgnore obeliskImpl]
107− run_ "chown" ["-R", user, toTextIgnore obeliskImpl]
108− run_ "chmod" ["-R", "g-rw,o-rw", toTextIgnore obeliskImpl]
133+ user <- T.strip <$> run whoamiPath []
134+ run_ cp ["-rT", "--no-preserve=mode", toTextIgnore obeliskImplDirtyReadOnly, toTextIgnore obeliskImpl]
135+ run_ chownPath ["-R", user, toTextIgnore obeliskImpl]
136+ run_ chmodPath ["-R", "g-rw,o-rw", toTextIgnore obeliskImpl]
109137 f obeliskImpl
110138
111139 withInitCache f obeliskImpl =
@@ -113,16 +141,16 @@ main = do
113141 -- Setup the ob init cache
114142 void . shellyOb verbosity $ chdir initCache $ do
115143 runOb_ ["init", "--symlink", toTextIgnore obeliskImpl]
116− run_ "git" ["init"]
144+ run_ gitPath ["init"]
117145
118146 f initCache
119147
120− withObeliskImplAndInitCache f =
121− withObeliskImpl $ \impl -> withInitCache (f impl) impl
148+ withObeliskImplDirtyAndInitCache f =
149+ withObeliskImplDirty $ \impl -> withInitCache (f impl) impl
122150
123151 httpManager <- HTTP.newManager HTTP.defaultManagerSettings
124152
125− withObeliskImplAndInitCache $ \obeliskImpl initCache ->
153+ withObeliskImplDirtyAndInitCache $ \obeliskImplDirty initCache ->
126154 hspec $ parallel $ do
127155 let shelly_ = void . shellyOb verbosity
128156
@@ -142,18 +170,18 @@ main = do
142170
143171 -- To be used in tests that change the obelisk impl directory
144172 inTmpObInitWithImplCopy f = inTmpObInit $ \dir ->
145− withObeliskImpl $ \(fromString -> implCopy) -> do
146− run_ "rm" [thunk]
147− run_ "ln" ["-s", implCopy, thunk]
173+ withObeliskImplClean $ \(fromString -> implClean) -> do
174+ run_ rmPath [thunk]
175+ run_ lnPath ["-s", implClean, thunk]
148176 f dir
149177
150178 assertRevEQ a b = liftIO . assertEqual "" "" =<< diff a b
151179 assertRevNE a b = liftIO . assertBool "" . (/= "") =<< diff a b
152180
153− revParseHead = T.strip <$> run "git" ["rev-parse", "HEAD"]
181+ revParseHead = T.strip <$> run gitPath ["rev-parse", "HEAD"]
154182
155183 commitAll = do
156− run_ "git" ["add", "."]
184+ run_ gitPath ["add", "."]
157185 commit "checkpoint"
158186 revParseHead
159187
@@ -162,12 +190,12 @@ main = do
162190 pack = runOb ["thunk", "pack", thunk] >> commitAll
163191 unpack = runOb ["thunk", "unpack", thunk] >> commitAll
164192
165− diff a b = run "git" ["diff", a, b]
193+ diff a b = run gitPath ["diff", a, b]
166194
167195 describe "ob init" $ parallel $ do
168196 it "works with default impl" $ inTmp $ \_ -> runOb ["init"]
169197 it "works with master branch impl" $ inTmp $ \_ -> runOb ["init", "--branch", "master"]
170− it "works with symlink" $ inTmp $ \_ -> runOb ["init", "--symlink", toTextIgnore obeliskImpl]
198+ it "works with symlink" $ inTmp $ \_ -> runOb ["init", "--symlink", toTextIgnore obeliskImplDirty]
171199 it "doesn't silently overwrite existing files" $ withSystemTempDirectory "ob-init λ" $ \dir -> do
172200 let p force = (System.Process.proc ob $ "--no-handoff" : "-v" : "init" : ["--force"|force]) { cwd = Just dir }
173201 (ExitSuccess, _, _) <- readCreateProcessWithExitCode (p False) ""
@@ -194,10 +222,10 @@ main = do
194222 testObRunInDir' Nothing httpManager
195223
196224 describe "obelisk project" $ parallel $ do
197− it "can build obelisk command" $ inTmpObInit $ \_ -> nixBuild ["-A", "command" , toTextIgnore obeliskImpl]
198− it "can build obelisk skeleton" $ inTmpObInit $ \_ -> nixBuild ["-A", "skeleton", toTextIgnore obeliskImpl]
199− it "can build obelisk shell" $ inTmpObInit $ \_ -> nixBuild ["-A", "shell", toTextIgnore obeliskImpl]
200− it "can build everything" $ inTmpObInit $ \_ -> nixBuild [toTextIgnore obeliskImpl]
225+ it "can build obelisk command" $ inTmpObInit $ \_ -> nixBuild ["-A", "command" , toTextIgnore obeliskImplDirty]
226+ it "can build obelisk skeleton" $ inTmpObInit $ \_ -> nixBuild ["-A", "skeleton", toTextIgnore obeliskImplDirty]
227+ it "can build obelisk shell" $ inTmpObInit $ \_ -> nixBuild ["-A", "shell", toTextIgnore obeliskImplDirty]
228+ it "can build everything" $ inTmpObInit $ \_ -> nixBuild [toTextIgnore obeliskImplDirty]
201229
202230 describe "blank initialized project" $ parallel $ do
203231
@@ -247,16 +275,16 @@ main = do
247275
248276 it "unpacks the correct branch" $ withTmp $ \dir -> do
249277 let branch = "master"
250− run_ "git" ["clone", "https://github.com/reflex-frp/reflex.git", toTextIgnore dir, "--branch", branch]
278+ run_ gitPath ["clone", "https://github.com/reflex-frp/reflex.git", toTextIgnore dir, "--branch", branch]
251279 runOb_ ["thunk", "pack", toTextIgnore dir]
252280 runOb_ ["thunk", "unpack", toTextIgnore dir]
253− branch' <- chdir dir $ run "git" ["rev-parse", "--abbrev-ref", "HEAD"]
281+ branch' <- chdir dir $ run gitPath ["rev-parse", "--abbrev-ref", "HEAD"]
254282 liftIO $ assertEqual "" branch (T.strip branch')
255283
256284 it "can pack and unpack plain git repos" $
257285 shelly_ $ withSystemTempDirectory "git-repo" $ \dir -> do
258286 let repo = toTextIgnore $ dir </> ("repo" :: String)
259− run_ "git" ["clone", "https://github.com/haskell/process.git", repo]
287+ run_ gitPath ["clone", "https://github.com/haskell/process.git", repo]
260288 origHash <- chdir (fromText repo) revParseHead
261289
262290 runOb_ ["thunk", "pack", repo]
@@ -271,20 +299,20 @@ main = do
271299
272300 testThunkPack' $ fromText repo
273301
274− it "aborts thunk pack when there are uncommitted files" $ inTmpObInit $ \dir -> do
302+ it "aborts thunk pack when there are uncommitted files" $ inTmpObInitWithImplCopy $ \dir -> do
275303 testThunkPack' (dir </> thunk)
276304
277305 describe "ob thunk update --branch" $ parallel $ do
278306 it "can change a thunk to the latest version of a desired branch" $ withTmp $ \dir -> do
279307 let branch1 = "master"
280308 branch2 = "develop"
281− run_ "git" ["clone", "https://github.com/reflex-frp/reflex.git", toTextIgnore dir, "--branch", branch1]
309+ run_ gitPath ["clone", "https://github.com/reflex-frp/reflex.git", toTextIgnore dir, "--branch", branch1]
282310 runOb_ ["thunk" , "pack", toTextIgnore dir]
283311 runOb_ ["thunk", "update", toTextIgnore dir, "--branch", branch2]
284312
285313 it "doesn't create anything when given an invalid branch" $ withTmp $ \dir -> do
286314 let checkDir dir' = liftIO $ getDirectoryContents $ T.unpack $ toTextIgnore dir'
287− run_ "git" ["clone", "https://github.com/reflex-frp/reflex.git", toTextIgnore dir, "--branch", "master"]
315+ run_ gitPath ["clone", "https://github.com/reflex-frp/reflex.git", toTextIgnore dir, "--branch", "master"]
288316 runOb_ ["thunk" , "pack", toTextIgnore dir]
289317 startingContents <- checkDir dir
290318 void $ errExit False $ runOb ["thunk", "update", toTextIgnore dir, "--branch", "dumble-palooza"]
@@ -314,13 +342,13 @@ testObRunInDir executable extraArgs mdir httpManager = maskExitSuccess $ do
314342 [p0, p1] <- liftIO $ getFreePorts 2
315343 let uri p = "http://localhost:" <> T.pack (show p) <> "/" -- trailing slash required for comparison
316344 writefile "config/common/route" $ uri p0
317− maybe id chdir mdir $ runHandle executable extraArgs $ \stdout -> do
318− firstUri <- handleObRunStdout httpManager stdout
345+ maybe id chdir mdir $ runHandles executable extraArgs [] $ \_stdin stdout stderr -> do
346+ firstUri <- handleObRunStdout httpManager stdout stderr
319347 let newUri = uri p1
320348 when (firstUri == newUri) $ errorExit $
321349 "Startup URI (" <> firstUri <> ") is the same as test URI (" <> newUri <> ")"
322350 maybe id (\_ -> chdir "..") mdir $ alterRouteTo newUri stdout
323− runningUri <- handleObRunStdout httpManager stdout
351+ runningUri <- handleObRunStdout httpManager stdout stderr
324352 if runningUri /= newUri
325353 then errorExit $ "Reloading failed: expected " <> newUri <> " but got " <> runningUri
326354 else exit 0
@@ -330,10 +358,10 @@ testThunkPack executable args path' = withTempFile (T.unpack $ toTextIgnore path
330358 let pack' = readProcessWithExitCode executable (T.unpack <$> ["thunk", "pack", toTextIgnore path'] ++ args) ""
331359 ensureThunkPackFails q = liftIO $ pack' >>= \case
332360 (code, out, err)
333− | code == ExitSuccess -> fail "ob thunk pack succeeded when it should have failed"
361+ | code == ExitSuccess -> fail $ "ob thunk pack succeeded when it should have failed with error '" <> show q <> "'"
334362 | q `T.isInfixOf` T.pack (out <> err) -> pure ()
335− | otherwise -> fail $ "ob thunk pack failed for an unexpected reason: " <> show out <> "\nstderr: " <> err
336− git = chdir path' . run "git"
363+ | otherwise -> fail $ "ob thunk pack failed for an unexpected reason, expecting '" <> show q <> "', received: " <> show out <> "\nstderr: " <> err
364+ git = chdir path' . run gitPath
337365 -- Untracked files
338366 ensureThunkPackFails "Untracked files"
339367 void $ git ["add", T.pack file]
@@ -367,9 +395,12 @@ alterRouteTo uri stdout = do
367395 "Reloading failed: " <> T.pack (show t)
368396
369397-- | Handle stdout of `ob run`: check that the frontend and backend servers are started correctly
370−handleObRunStdout :: HTTP.Manager -> Handle -> Sh Text
371−handleObRunStdout httpManager stdout = flip fix (ObRunState_Init, []) $ \loop (state, msgs) ->
372− liftIO (T.hGetLine stdout) >>= \t -> case state of
398+handleObRunStdout :: HTTP.Manager -> Handle -> Handle -> Sh Text
399+handleObRunStdout httpManager stdout stderr = flip fix (ObRunState_Init, []) $ \loop (state, msgs) -> do
400+ isEOF <- liftIO $ hIsEOF stdout
401+ if isEOF
402+ then handleObRunError msgs
403+ else liftIO (T.hGetLine stdout) >>= \t -> case state of
373404 ObRunState_Init
374405 | "Running test..." `T.isPrefixOf` t -> loop (ObRunState_BackendStarted, msgs)
375406 ObRunState_Startup
@@ -381,8 +412,12 @@ handleObRunStdout httpManager stdout = flip fix (ObRunState_Init, []) $ \loop (s
381412 obRunCheck httpManager stdout uri
382413 pure uri
383414 | not (T.null t) -> errorExit $ "Started: " <> t -- If theres any other output here, startup failed
384− _ | "Failed" `T.isPrefixOf` t -> errorExit $ "ob run failed: " <> T.unlines (reverse $ t : msgs)
415+ _ | "Failed" `T.isPrefixOf` t -> handleObRunError (t : msgs)
385416 | otherwise -> loop (state, t : msgs)
417+ where
418+ handleObRunError msgs = do
419+ stderrContent <- liftIO $ hGetContents stderr
420+ errorExit $ "ob run failed: " <> T.unlines (reverse msgs) <> " stderr: " <> T.pack stderrContent
386421
387422-- | Make requests to frontend/backend servers to check they are working properly
388423obRunCheck :: HTTP.Manager -> Handle -> Text -> Sh ()
lib/snap-extras/obelisk-snap-extras.cabal+1−1
@@ -1,6 +1,6 @@
11name: obelisk-snap-extras
22version: 0.1
3−synopsys: Extra functionality for Snap that should be considered for upstreaming
3+synopsis: Extra functionality for Snap that should be considered for upstreaming
44license: BSD3
55build-type: Simple
66cabal-version: >=1.2