on master help sign in
Add NIX_REMOTE workaround

- Display the workaround when any of the nix command fails - SelfTest.hs: catch this error, and re-run the test with NIX_REMOTE set. - cliapp[Process.hs]: raise ProcessFailed instead of failing abruptly - cliapp[Logging.hs]: Error logging should go to stderr - Fix thunk tests; selftest succeeds now

commitaa686f69bd0b2fa2331e954b9e0f9137c3d90aaa authorSridhar Ratnakumar <srid@srid.ca> dateWed 27 Jun 2018, 20:07 (8 years ago) parent38cc2c5
15 files changed+143−78
lib/cliapp/src/Obelisk/CliApp.hs+1 lib/cliapp/src/Obelisk/CliApp/Logging.hs+6−5 lib/cliapp/src/Obelisk/CliApp/Process.hs+12−13 lib/cliapp/src/Obelisk/CliApp/TerminalString.hs+6−6 lib/command/src/Obelisk/Command.hs+4−1 lib/command/src/Obelisk/Command/Nix.hs+28−1 lib/command/src/Obelisk/Command/Project.hs+2−1 lib/command/src/Obelisk/Command/Thunk.hs+3−2 lib/command/src/Obelisk/Command/Upgrade/Hash.hs+2−1 lib/command/src/Obelisk/Command/VmBuilder.hs+4−4 lib/selftest/obelisk-selftest.cabal+2−1 lib/selftest/src/Obelisk/SelfTest.hs+68−40 migration/554c459ff2cced3e1b11241ed403890d-6a18939264224d6ce24c7426249edfea/obelisk-handoff migration/554c459ff2cced3e1b11241ed403890d-6a18939264224d6ce24c7426249edfea/obelisk-upgrade release.nix+5−3
lib/cliapp/src/Obelisk/CliApp.hs+1
@@ -29,6 +29,7 @@ module Obelisk.CliApp
2929 , Severity (..)
3030
3131 -- .Process
32+ , ProcessFailed (..)
3233 , readProcessAndLogStderr
3334 , callProcessAndLogOutput
3435 , createProcess_
lib/cliapp/src/Obelisk/CliApp/Logging.hs+6−5
@@ -26,7 +26,7 @@ import System.Console.ANSI (Color (Red, White, Yellow), ColorIntensity (Vivid),
2626 ConsoleIntensity (FaintIntensity), ConsoleLayer (Foreground),
2727 SGR (SetColor, SetConsoleIntensity), clearLine)
2828import System.Exit (ExitCode (..), exitWith)
29−import System.IO (BufferMode (NoBuffering), hFlush, hReady, hSetBuffering, stdin, stdout)
29+import System.IO (BufferMode (NoBuffering), hFlush, hReady, hSetBuffering, stderr, stdin, stdout)
3030
3131import qualified Obelisk.CliApp.TerminalString as TS
3232import Obelisk.CliApp.Types
@@ -137,12 +137,13 @@ withExitFailMessage msg f = f `catch` \(e :: ExitCode) -> do
137137writeLog:: (MonadIO m, MonadMask m) => Bool -> Bool -> WithSeverity Text -> m ()
138138writeLog withNewLine noColor (WithSeverity severity s)
139139 | noColor && severity <= Warning = liftIO $ putFn $ T.pack (show severity) <> ": " <> s
140− | not noColor && severity <= Error = TS.putStrWithSGR errorColors withNewLine s
141− | not noColor && severity <= Warning = TS.putStrWithSGR warningColors withNewLine s
142− | not noColor && severity >= Debug = TS.putStrWithSGR debugColors withNewLine s
140+ | not noColor && severity <= Error = TS.putStrWithSGR errorColors h withNewLine s
141+ | not noColor && severity <= Warning = TS.putStrWithSGR warningColors h withNewLine s
142+ | not noColor && severity >= Debug = TS.putStrWithSGR debugColors h withNewLine s
143143 | otherwise = liftIO $ putFn s
144144 where
145− putFn = if withNewLine then T.putStrLn else T.putStr
145+ putFn = if withNewLine then (T.hPutStrLn h) else (T.hPutStr h)
146+ h = if severity <= Error then stderr else stdout
146147 errorColors = [SetColor Foreground Vivid Red]
147148 warningColors = [SetColor Foreground Vivid Yellow]
148149 debugColors = [SetColor Foreground Vivid White, SetConsoleIntensity FaintIntensity]
lib/cliapp/src/Obelisk/CliApp/Process.hs+12−13
@@ -9,7 +9,8 @@
99-- | An extension of `System.Process` that integrates with logging (`Obelisk.CLI.Logging`)
1010-- and is thus spinner friendly.
1111module Obelisk.CliApp.Process
12− ( readProcessAndLogStderr
12+ ( ProcessFailed (..)
13+ , readProcessAndLogStderr
1314 , callProcessAndLogOutput
1415 , createProcess
1516 , createProcess_
@@ -19,9 +20,8 @@ module Obelisk.CliApp.Process
1920
2021import Control.Applicative (liftA2)
2122import Control.Monad (void, (<=<))
22−import Control.Monad.Catch (MonadMask)
23−import Control.Monad.IO.Class (liftIO)
24−import Control.Monad.Reader (MonadIO)
23+import Control.Monad.Catch (Exception, MonadMask, throwM)
24+import Control.Monad.IO.Class (MonadIO, liftIO)
2525import qualified Data.ByteString.Char8 as BSC
2626import Data.Function (fix)
2727import Data.Monoid ((<>))
@@ -38,10 +38,14 @@ import System.Process (CreateProcess, ProcessHandle, StdStream (CreatePipe), cmd
3838import qualified System.Process as Process
3939
4040import Control.Monad.Log (Severity (..))
41−import Obelisk.CliApp.Logging (failWith, putLog, putLogRaw)
41+import Obelisk.CliApp.Logging (putLog, putLogRaw)
4242import Obelisk.CliApp.Types (Cli)
4343
44−-- | Like `System.Process.readProcess` but logs the stderr instead of letting the external process inherit it.
44+data ProcessFailed = ProcessFailed Process.CmdSpec Int -- exit code
45+ deriving Show
46+
47+instance Exception ProcessFailed
48+
4549readProcessAndLogStderr
4650 :: (MonadIO m, MonadMask m, Cli m)
4751 => Severity -> CreateProcess -> m String
@@ -104,7 +108,6 @@ withProcess
104108 :: (MonadIO m, MonadMask m, Cli m)
105109 => CreateProcess -> (Handle -> Handle -> m ()) -> m (Handle, Handle)
106110withProcess process f = do -- TODO: Use bracket.
107− let procTitle = T.pack $ show $ cmdspec process
108111 -- FIXME: Using `withCreateProcess` here leads to something operating illegally on closed handles.
109112 (_, Just out, Just err, p) <- createProcess $ process
110113 { std_out = CreatePipe , std_err = CreatePipe }
@@ -112,12 +115,8 @@ withProcess process f = do -- TODO: Use bracket.
112115 f out err -- Pass the handles to the passed function
113116
114117 liftIO (waitForProcess p) >>= \case
115− ExitSuccess -> return ()
116− ExitFailure code -> do
117− -- Log an error. We also fail immediately; however we should probably let the caller control that.
118− failWith $ procTitle <> " failed with exit code: " <> T.pack (show code)
119− return (out, err) -- Return the handles
120−
118+ ExitSuccess -> return (out, err)
119+ ExitFailure code -> throwM $ ProcessFailed (cmdspec process) code
121120
122121-- Create an input stream from the file handle, associating each item with the given severity.
123122streamHandle :: Severity -> Handle -> IO (InputStream (Severity, BSC.ByteString))
lib/cliapp/src/Obelisk/CliApp/TerminalString.hs+6−6
@@ -18,9 +18,9 @@ import Data.Semigroup ((<>))
1818import Data.Text (Text)
1919import qualified Data.Text as T
2020import qualified Data.Text.IO as T
21−import System.Console.ANSI (Color, ColorIntensity (Vivid), ConsoleLayer (Foreground), SGR (Reset, SetColor),
22− SGR, setSGR, setSGRCode)
21+import System.Console.ANSI
2322import qualified System.Console.Terminal.Size as TerminalSize
23+import System.IO (Handle)
2424
2525-- | Printable text on terminals
2626--
@@ -65,11 +65,11 @@ colorizeText color s = mconcat
6565 ]
6666
6767-- | Safely print the string with the given ANSI control codes, resetting in the end.
68−putStrWithSGR :: MonadIO m => [SGR] -> Bool -> Text -> m ()
69−putStrWithSGR sgr withNewLine s = liftIO $ bracket_ (setSGR sgr) reset $ T.putStr s
68+putStrWithSGR :: MonadIO m => [SGR] -> Handle -> Bool -> Text -> m ()
69+putStrWithSGR sgr h withNewLine s = liftIO $ bracket_ (hSetSGR h sgr) reset $ T.hPutStr h s
7070 where
71− reset = setSGR [Reset] >> newline -- New line should come *after* reset (to reset cursor color).
72− newline = when withNewLine $ T.putStrLn ""
71+ reset = hSetSGR h [Reset] >> newline -- New line should come *after* reset (to reset cursor color).
72+ newline = when withNewLine $ T.hPutStrLn h ""
7373
7474-- | Code for https://en.wikipedia.org/wiki/Enquiry_character
7575enquiryCode :: String
lib/command/src/Obelisk/Command.hs+4−1
@@ -8,6 +8,7 @@
88module Obelisk.Command where
99
1010import Control.Monad
11+import Control.Monad.Catch (catch)
1112import Control.Monad.IO.Class (liftIO)
1213import qualified Data.Binary as Binary
1314import Data.Bool (bool)
@@ -37,7 +38,7 @@ import Obelisk.Command.Run
3738import Obelisk.Command.Thunk
3839import Obelisk.Command.Upgrade
3940import Obelisk.Command.Upgrade.Hash (getDirectoryHash, getHashAtGitRevision)
40−import Obelisk.Command.Utils (getObeliskExe)
41+import Obelisk.Command.Utils
4142import qualified Obelisk.Command.VmBuilder as VmBuilder
4243import Obelisk.Migration (Hash)
4344
@@ -291,6 +292,8 @@ main' argsCfg = do
291292 ]
292293
293294 (mainWithHandOff argsCfg <=< parseHandoff) =<< liftIO getArgs
295+ `catch`
296+ \(ProcessFailed p code) -> failWith $ "Process exited with code " <> tshow code <> "; " <> tshow p
294297
295298-- Type representing the result of a handoff calculation.
296299data HandOff m
lib/command/src/Obelisk/Command/Nix.hs+28−1
@@ -1,19 +1,25 @@
11{-# LANGUAGE FlexibleContexts #-}
2+{-# LANGUAGE LambdaCase #-}
23{-# LANGUAGE MultiParamTypeClasses #-}
34{-# LANGUAGE OverloadedStrings #-}
45{-# LANGUAGE ScopedTypeVariables #-}
56module Obelisk.Command.Nix
67 ( nixBuild
8+ , withNixRemoteCheck
79 , NixBuildConfig (..)
810 , Target (..)
911 , OutLink (..)
1012 , Arg (..)
1113 ) where
1214
15+import Control.Monad.Catch (catch, throwM)
16+import Control.Monad.IO.Class (liftIO)
1317import Data.Default
1418import Data.List (intercalate)
1519import Data.Monoid ((<>))
1620import qualified Data.Text as T
21+import System.Directory
22+import System.Environment
1723import System.Process (proc)
1824
1925import Obelisk.App (MonadObelisk)
@@ -57,7 +63,7 @@ instance Default NixBuildConfig where
5763
5864nixBuild :: MonadObelisk m => NixBuildConfig -> m FilePath
5965nixBuild cfg = withSpinner' ("Running nix-build on " <> desc) (Just $ const $ "Built " <> desc) $ do
60− readProcessAndLogStderr Debug $ proc "nix-build" $ mconcat
66+ withNixRemoteCheck $ readProcessAndLogStderr Debug $ proc "nix-build" $ mconcat
6167 [[path], attrArg, args, outLink, buildersArg]
6268 where
6369 path = _target_path $ _nixBuildConfig_target cfg
@@ -74,3 +80,24 @@ nixBuild cfg = withSpinner' ("Running nix-build on " <> desc) (Just $ const $ "B
7480 buildersArg = case _nixBuildConfig_builders cfg of
7581 [] -> []
7682 builders -> ["--builders", intercalate ";" builders]
83+
84+-- | If a nix command fails, and this may be related to the NIX_REMOTE issue,
85+-- tell the user what to do.
86+--
87+-- Added: June, 2018. Consider removing this eventually.
88+withNixRemoteCheck :: MonadObelisk m => m a -> m a
89+withNixRemoteCheck f = f `catch` \e@(ProcessFailed _ _) -> do
90+ liftIO (lookupEnv "NIX_REMOTE") >>= \case
91+ Just _ -> throwM e
92+ Nothing -> liftIO (writable <$> getPermissions "/nix/var/nix/db") >>= \case
93+ True -> throwM e
94+ False -> do
95+ putLog Error "!!! "
96+ putLog Error "!!! A nix command failed to run. You might need to set the NIX_REMOTE environment variable"
97+ putLog Error "!!! to `daemon`. To do this, run the following before running obelisk:"
98+ putLog Error "!!! "
99+ putLog Error "!!! export NIX_REMOTE=daemon"
100+ putLog Error "!!! "
101+ putLog Error "!!! For details, see https://github.com/NixOS/nixpkgs/issues/5713"
102+ putLog Error "!!! "
103+ throwM e
lib/command/src/Obelisk/Command/Project.hs+2−1
@@ -35,6 +35,7 @@ import GitHub.Data.Name (Name)
3535import Obelisk.App (MonadObelisk)
3636import Obelisk.CliApp
3737import Obelisk.Command.Thunk
38+import Obelisk.Command.Nix (withNixRemoteCheck)
3839--TODO: Make this module resilient to random exceptions
3940
4041--TODO: Don't hardcode this
@@ -201,7 +202,7 @@ inImpureProjectShell shellName command = withProjectRoot "." $ \root ->
201202 projectShell root False shellName command
202203
203204projectShell :: MonadObelisk m => FilePath -> Bool -> String -> String -> m ()
204−projectShell root isPure shellName command = do
205+projectShell root isPure shellName command = withNixRemoteCheck $ do
205206 (_, _, _, ph) <- createProcess_ "runNixShellAttr" $ setCwd (Just root) $ proc "nix-shell" $
206207 [ "--pure" | isPure ] <>
207208 [ "-A"
lib/command/src/Obelisk/Command/Thunk.hs+3−2
@@ -74,6 +74,7 @@ import System.Process (proc)
7474
7575import Obelisk.App (MonadObelisk)
7676import Obelisk.CliApp
77+import Obelisk.Command.Nix (withNixRemoteCheck)
7778import Obelisk.Command.Utils
7879
7980--TODO: Support symlinked thunk data
@@ -135,13 +136,13 @@ commitNameToRef (N c) = Ref.fromHex $ encodeUtf8 c
135136getNixSha256ForUriUnpacked :: MonadObelisk m => URI -> m NixSha256
136137getNixSha256ForUriUnpacked uri =
137138 withExitFailMessage ("nix-prefetch-url: Failed to determine sha256 hash of URL " <> T.pack (show uri)) $ do
138− fmap T.pack $ readProcessAndLogStderr Debug $
139+ fmap T.pack $ withNixRemoteCheck $ readProcessAndLogStderr Debug $
139140 proc "nix-prefetch-url" ["--unpack" , "--type" , "sha256" , show uri]
140141
141142nixPrefetchGit :: MonadObelisk m => URI -> Text -> Bool -> m NixSha256
142143nixPrefetchGit uri rev fetchSubmodules =
143144 withExitFailMessage ("nix-prefetch-git: Failed to determine sha256 hash of Git repo " <> T.pack (show uri) <> " at " <> rev) $ do
144− out <- readProcessAndLogStderr Debug $
145+ out <- withNixRemoteCheck $ readProcessAndLogStderr Debug $
145146 proc "nix-prefetch-git" $ filter (/="")
146147 [ "--url", show uri
147148 , "--rev", T.unpack rev
lib/command/src/Obelisk/Command/Upgrade/Hash.hs+2−1
@@ -23,6 +23,7 @@ import System.Process (cwd, proc)
2323
2424import Obelisk.App (MonadObelisk)
2525import Obelisk.CliApp
26+import Obelisk.Command.Nix (withNixRemoteCheck)
2627import Obelisk.Command.Utils
2728
2829import Obelisk.Migration
@@ -87,7 +88,7 @@ getHashAtGitRevision revs excludes dir = withSystemTempDirectory "obelisk-hashre
8788 return result
8889
8990nixHash :: MonadObelisk m => FilePath -> m Hash
90−nixHash dir = withSpinnerNoTrail "Running `nix-hash`" $
91+nixHash dir = withSpinnerNoTrail "Running `nix-hash`" $ withNixRemoteCheck $
9192 readProc $ proc "nix-hash" [dir]
9293
9394-- | Clean up the following files in the git working copy
lib/command/src/Obelisk/Command/VmBuilder.hs+4−4
@@ -16,13 +16,13 @@ import qualified Data.Text as T
1616import qualified Data.Text.IO as T
1717import System.Directory (createDirectoryIfMissing)
1818import System.Exit (ExitCode)
19−import System.FilePath ((</>), (<.>))
19+import System.FilePath ((<.>), (</>))
2020import qualified System.Info
2121import System.Process (proc)
2222
2323import Obelisk.App (MonadObelisk, getObeliskUserStateDir)
24−import Obelisk.CliApp (Severity (..), callProcessAndLogOutput, failWith, readProcessAndLogStderr,
25− withExitFailMessage, withSpinner)
24+import Obelisk.CliApp
25+import Obelisk.Command.Nix (withNixRemoteCheck)
2626
2727-- | Generate the `--builders` argument string to enable the VM builder after ensuring it is available.
2828getNixBuildersArg :: MonadObelisk m => m String
@@ -131,7 +131,7 @@ getDockerBuilderStateDir = liftA2 (</>) getObeliskUserStateDir (pure "nix-docker
131131-- | Run a test build to see if a Linux build can finish successfully.
132132testLinuxBuild :: MonadObelisk m => FilePath -> m Bool
133133testLinuxBuild stateDir =
134− fmap (isRight :: Either ExitCode () -> Bool) $ try $
134+ fmap (isRight :: Either ExitCode () -> Bool) $ try $ withNixRemoteCheck $
135135 callProcessAndLogOutput (Debug, Debug) $ proc "nix-build"
136136 [ "-E", "(import <nixpkgs> { system = \"x86_64-linux\"; }).writeText \"test\" builtins.currentTime"
137137 , "--builders", nixBuildersArgString stateDir
lib/selftest/obelisk-selftest.cabal+2−1
@@ -6,7 +6,6 @@ build-type: Simple
66cabal-version: >=1.8
77
88library
9− default-language: Haskell2010
109 hs-source-dirs: src
1110 build-depends:
1211 base
@@ -16,6 +15,7 @@ library
1615 , http-client
1716 , http-types
1817 , HUnit
18+ , obelisk-cliapp
1919 , obelisk-run
2020 , process
2121 , network
@@ -24,6 +24,7 @@ library
2424 , text
2525 exposed-modules:
2626 Obelisk.SelfTest
27+ ghc-options: -Wall
2728
2829executable obelisk-selftest
2930 main-is: src-bin/obelisk-selftest.hs
lib/selftest/src/Obelisk/SelfTest.hs+68−40
@@ -1,14 +1,15 @@
11{-# LANGUAGE LambdaCase #-}
22{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE PatternGuards #-}
4+{-# LANGUAGE ScopedTypeVariables #-}
35{-# LANGUAGE TypeApplications #-}
46module Obelisk.SelfTest where
57
6−import Control.Exception (Exception, throw, bracket)
8+import Control.Exception (bracket, throw)
79import Control.Monad
810import Control.Monad.IO.Class
911import Data.Bool (bool)
1012import Data.Function (fix)
11−import Data.Maybe (isJust)
1213import Data.Semigroup (Semigroup, (<>))
1314import qualified Data.Set as Set
1415import Data.String
@@ -21,15 +22,17 @@ import qualified Network.Socket as Socket
2122import Shelly
2223import System.Directory (withCurrentDirectory)
2324import System.Environment
24−import System.Exit (ExitCode (..), exitWith)
25+import System.Exit (ExitCode (..))
2526import System.Info
2627import System.IO (Handle, hClose)
2728import System.IO.Temp
29+import System.Process (readProcessWithExitCode)
2830import System.Timeout
2931import Test.Hspec
3032import Test.HUnit.Base
31−import System.Process (readProcessWithExitCode)
3233
34+import Obelisk.CliApp hiding (runCli)
35+import qualified Obelisk.CliApp as CliApp
3336import Obelisk.Run (getConfigRoute)
3437
3538data ObRunState
@@ -50,18 +53,44 @@ commit msg = void $ run "git"
5053 , doubleQuotes msg
5154 ]
5255
56+runCli :: MonadIO m => CliT IO a -> m a
57+runCli f = liftIO $ do
58+ c <- newCliConfig Notice False False
59+ CliApp.runCli c f
60+
61+tshow :: Show a => a -> Text
62+tshow = T.pack . show
63+
64+-- | Like `shelly` but used when running `ob` commands
65+--
66+-- This tests the NIX_REMOTE workaround, whether that gets printed
67+-- on failure, and whether retrying with the suggested workaround
68+-- leads to the test succeeding.
69+shellyOb :: MonadIO m => (Sh a -> Sh a) -> Sh a -> m a
70+shellyOb f obTest = shelly $ f $ do
71+ obTest `catch_sh` \(e :: RunFailed) -> do
72+ obStderr <- lastStderr
73+ if T.isInfixOf "export NIX_REMOTE" obStderr
74+ then do
75+ runCli $ do
76+ putLog Notice "Detected NIX_REMOTE suggestion in stderr of failed ob"
77+ putLog Warning "Retrying this test with NIX_REMOTE=daemon"
78+ setenv "NIX_REMOTE" "daemon"
79+ f obTest
80+ else throw e
81+
5382main :: IO ()
5483main = do
55− isVerbose <- getArgs >>= \case
56− ["-v"] -> pure True
57− [] -> putStrLn "Tests may take longer to run if there are unbuilt derivations: use -v for verbose output" *> pure False
58− _ -> putStrLn "Usage: selftest [-v]" *> exitWith (ExitFailure 2)
84+ -- Note: you can pass hspec arguments as well, eg: `-m <pattern>`
85+ isVerbose <- (elem "-v") <$> getArgs
86+ unless isVerbose $
87+ putStrLn "Tests may take longer to run if there are unbuilt derivations: use -v for verbose output"
5988 let verbosity = bool silently verbosely isVerbose
6089 obeliskImpl <- fromString <$> getEnv "OBELISK_IMPL"
6190 httpManager <- HTTP.newManager HTTP.defaultManagerSettings
6291 withSystemTempDirectory "blank-project" $ \blankProject ->
6392 hspec $ do
64− let shelly_ = void . shelly . verbosity
93+ let shelly_ = void . shellyOb verbosity
6594
6695 inProj :: Sh a -> IO ()
6796 inProj = shelly_ . chdir (fromString blankProject)
@@ -75,7 +104,7 @@ main = do
75104 revParseHead = T.strip <$> run "git" ["rev-parse", "HEAD"]
76105
77106 commitAll = do
78− run "git" ["add", "."]
107+ run_ "git" ["add", "."]
79108 commit "checkpoint"
80109 revParseHead
81110
@@ -92,31 +121,32 @@ main = do
92121 it "works with symlink" $ inTmp $ \_ -> run "ob" ["init", "--symlink", obeliskImpl]
93122
94123 it "doesn't create anything when given an invalid impl" $ inTmp $ \tmp -> do
95− errExit False $ run "ob" ["init", "--symlink", "/dev/null"]
124+ void $ errExit False $ run "ob" ["init", "--symlink", "/dev/null"]
96125 ls tmp >>= liftIO . assertEqual "" []
97126
98127 it "produces a valid route config" $ inTmp $ \tmp -> do
99− run "ob" ["init"]
128+ run_ "ob" ["init"]
100129 liftIO $ withCurrentDirectory (T.unpack $ toTextIgnore tmp) $ getConfigRoute `shouldNotReturn` Nothing
101130
102131 describe "ob run" $ do
103132 it "works in root directory" $ inTmp $ \_ -> do
104− run "ob" ["init"]
133+ run_ "ob" ["init"]
105134 testObRunInDir Nothing httpManager
106135 it "works in sub directory" $ inTmp $ \_ -> do
107− run "ob" ["init"]
136+ run_ "ob" ["init"]
108137 testObRunInDir (Just "frontend") httpManager
109138
110139 describe "obelisk project" $ parallel $ do
111140 it "can build obelisk command" $ shelly_ $ run "nix-build" ["-A", "command" , obeliskImpl]
112141 it "can build obelisk skeleton" $ shelly_ $ run "nix-build" ["-A", "skeleton", obeliskImpl]
113142 it "can build obelisk shell" $ shelly_ $ run "nix-build" ["-A", "shell", obeliskImpl]
114− it "can build everything" $ shelly_ $ run "nix-build" [obeliskImpl]
143+ -- See https://github.com/obsidiansystems/obelisk/issues/101
144+ -- it "can build everything" $ shelly_ $ run "nix-build" [obeliskImpl]
115145
116146 describe "blank initialized project" $ do
117147 it "can be created" $ inProj $ do
118− run "ob" ["init"]
119− run "git" ["init"]
148+ run_ "ob" ["init"]
149+ run_ "git" ["init"]
120150 commitAll
121151
122152 it "can build ghc.backend" $ inProj $ do
@@ -131,7 +161,7 @@ main = do
131161 forM_ ["ghc", "ghcjs"] $ \compiler -> do
132162 let
133163 shell = "shells." <> compiler
134− inShell cmd = run "nix-shell" ["-A", fromString shell, "--run", cmd]
164+ inShell cmd' = run "nix-shell" ["-A", fromString shell, "--run", cmd']
135165 it ("can enter " <> shell) $ inProj $ inShell "exit"
136166 it ("can build in " <> shell) $ inProj $ inShell $ "cabal new-build --" <> fromString compiler <> " all"
137167
@@ -156,15 +186,15 @@ main = do
156186 assertRevNE e eu
157187
158188 it "can pack and unpack plain git repos" $ do
159− withSystemTempDirectory "git-repo" $ \dir -> shelly_ $ do
189+ shelly_ $ withSystemTempDirectory "git-repo" $ \dir -> do
160190 let repo = toTextIgnore $ dir </> ("repo" :: String)
161− run_ "git" ["clone", "https://git.haskell.org/packages/primitive.git", repo]
191+ run_ "git" ["clone", "https://github.com/haskell/process.git", repo]
162192 origHash <- chdir (fromText repo) revParseHead
163193
164194 run_ "ob" ["thunk", "pack", repo]
165195 packedFiles <- Set.fromList <$> ls (fromText repo)
166− liftIO $ assertEqual "" packedFiles $
167− Set.fromList $ (repo </>) <$> ["default.nix", "git.json", ".attr-cache" :: String]
196+ liftIO $ assertEqual "" packedFiles $ Set.fromList $ (repo </>) <$>
197+ ["default.nix", "github.json", ".attr-cache" :: String]
168198
169199 run_ "ob" ["thunk", "unpack", repo]
170200 chdir (fromText repo) $ do
@@ -174,7 +204,7 @@ main = do
174204 testThunkPack $ fromText repo
175205
176206 it "aborts thunk pack when there are uncommitted files" $ inProj $ do
177− unpack
207+ void $ unpack
178208 testThunkPack (blankProject </> thunk)
179209
180210-- | Run `ob run` in the given directory (maximum of one level deep)
@@ -191,33 +221,31 @@ testObRunInDir mdir httpManager = handle_sh (\case ExitSuccess -> pure (); e ->
191221 maybe id (\_ -> chdir "..") mdir $ alterRouteTo newUri stdout
192222 (_, runningUri) <- handleObRunStdout httpManager stdout
193223 if runningUri /= newUri
194− then errorExit $ "Reloading failed: expected " <> newUri <> " but got " <> runningUri
195− else exit 0
224+ then errorExit $ "Reloading failed: expected " <> newUri <> " but got " <> runningUri
225+ else exit 0
196226
197227testThunkPack :: Shelly.FilePath -> Sh ()
198−testThunkPack path = withTempFile (T.unpack $ toTextIgnore path) "test-file" $ \file handle -> do
199− let try_sh :: Exception e => Sh a -> Sh (Either e a)
200− try_sh a = catch_sh (a >>= pure . Right) (pure . Left)
201− pack' = readProcessWithExitCode "ob" ["thunk", "pack", T.unpack $ toTextIgnore path] ""
202− ensureThunkPackFails err = liftIO $ pack' >>= \case
203− (code, out, _err)
228+testThunkPack path' = withTempFile (T.unpack $ toTextIgnore path') "test-file" $ \file handle -> do
229+ let pack' = readProcessWithExitCode "ob" ["thunk", "pack", T.unpack $ toTextIgnore path'] ""
230+ ensureThunkPackFails q = liftIO $ pack' >>= \case
231+ (code, out, err)
204232 | code == ExitSuccess -> fail "ob thunk pack succeeded when it should have failed"
205− | err `T.isInfixOf` T.pack out -> pure ()
206− | otherwise -> fail $ "ob thunk pack failed for an unexpected reason: " <> show out
207− git = chdir path . run "git"
233+ | q `T.isInfixOf` T.pack (out <> err) -> pure ()
234+ | otherwise -> fail $ "ob thunk pack failed for an unexpected reason: " <> show out <> "\nstderr: " <> err
235+ git = chdir path' . run "git"
208236 -- Untracked files
209− ensureThunkPackFails "unsaved modifications"
210− git ["add", T.pack file]
237+ ensureThunkPackFails "Untracked files"
238+ void $ git ["add", T.pack file]
211239 -- Uncommitted files (staged)
212− ensureThunkPackFails "unsaved modifications"
213− chdir path $ commit "test commit"
240+ ensureThunkPackFails "unsaved"
241+ chdir path' $ commit "test commit"
214242 -- Non-pushed commits in any branch
215243 ensureThunkPackFails "not been pushed"
216244 -- Uncommitted files (unstaged)
217245 liftIO $ T.hPutStrLn handle "test file" >> hClose handle
218− ensureThunkPackFails "unsaved modifications"
246+ ensureThunkPackFails "modified"
219247 -- Existing stashes
220− git ["stash"]
248+ void $ git ["stash"]
221249 ensureThunkPackFails "has stashes"
222250
223251-- | Blocks until a non-empty line is available
migration/554c459ff2cced3e1b11241ed403890d-6a18939264224d6ce24c7426249edfea/obelisk-handoffnew file

No changes to the content.

migration/554c459ff2cced3e1b11241ed403890d-6a18939264224d6ce24c7426249edfea/obelisk-upgradenew file

No changes to the content.

release.nix+5−3
@@ -26,14 +26,16 @@ with pkgs;
2626 nix # obelisk uses `nix-hash`
2727 ];
2828 } ''
29− set -xe
29+ set -e
3030 # Fix permissions so `removePathForcibly` works on copied-to-tmp paths
3131 cp -a ${self.pathGit} $TMPDIR/obelisk
3232 cd $TMPDIR/obelisk
3333 chmod -R u+w .
3434
35− ob internal hash
36− ob internal verify-migration
35+ (set -x;
36+ ob internal hash;
37+ ob internal verify-migration;
38+ )
3739
3840 mkdir -p $out
3941 touch $out/done