Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b5440fc7d2 | |||
| 4b21adadf1 | |||
| 78ae77780b | |||
| ccb95bcbee | |||
| 21ac670bbe | |||
| 8b54dee66c | |||
| dad926f3ba | |||
| a298d949b5 |
@@ -44,12 +44,6 @@ ghcup-gen check -f ghcup-${JSON_VERSION}.json
|
|||||||
|
|
||||||
eghcup --numeric-version
|
eghcup --numeric-version
|
||||||
|
|
||||||
# TODO: rm once we have tarballs
|
|
||||||
if [ "${OS}" = "FREEBSD" ] ; then
|
|
||||||
GHC_VERSION=8.6.3
|
|
||||||
CABAL_VERSION=2.4.1.0
|
|
||||||
fi
|
|
||||||
|
|
||||||
eghcup install ${GHC_VERSION}
|
eghcup install ${GHC_VERSION}
|
||||||
eghcup set ${GHC_VERSION}
|
eghcup set ${GHC_VERSION}
|
||||||
eghcup install-cabal ${CABAL_VERSION}
|
eghcup install-cabal ${CABAL_VERSION}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
# Revision history for ghcup
|
# Revision history for ghcup
|
||||||
|
|
||||||
|
## 0.1.8 -- 2020-07-21
|
||||||
|
|
||||||
|
* Fix bug in logging thread dying on newlines
|
||||||
|
* Allow to install from arbitrary bindists: `ghcup -n install ghc -u '{"dlHash": "", "dlSubdir": "ghc-8.10.1", "dlUri": "https://github.com/commercialhaskell/ghc/releases/download/ghc-8.10.1-release/ghc-8.10.1-x86_64-deb9-linux.tar.xz"}' 8.10.1`
|
||||||
|
|
||||||
## 0.1.7 -- 2020-07-20
|
## 0.1.7 -- 2020-07-20
|
||||||
|
|
||||||
* Fix a bug in libarchive not unpacking some uncleanly packed bindists
|
* Fix a bug in libarchive not unpacking some uncleanly packed bindists
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import Control.Monad.Fail ( MonadFail )
|
|||||||
import Control.Monad.Logger
|
import Control.Monad.Logger
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.Trans.Resource
|
import Control.Monad.Trans.Resource
|
||||||
|
import Data.Aeson ( eitherDecode )
|
||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.Char
|
import Data.Char
|
||||||
import Data.Either
|
import Data.Either
|
||||||
@@ -68,6 +69,7 @@ import URI.ByteString
|
|||||||
|
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.ByteString.UTF8 as UTF8
|
import qualified Data.ByteString.UTF8 as UTF8
|
||||||
|
import qualified Data.ByteString.Lazy.UTF8 as BLU
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.IO as T
|
import qualified Data.Text.IO as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
@@ -119,6 +121,7 @@ data InstallCommand = InstallGHC InstallOptions
|
|||||||
data InstallOptions = InstallOptions
|
data InstallOptions = InstallOptions
|
||||||
{ instVer :: Maybe ToolVersion
|
{ instVer :: Maybe ToolVersion
|
||||||
, instPlatform :: Maybe PlatformRequest
|
, instPlatform :: Maybe PlatformRequest
|
||||||
|
, instBindist :: Maybe DownloadInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
data SetCommand = SetGHC SetOptions
|
data SetCommand = SetGHC SetOptions
|
||||||
@@ -405,7 +408,7 @@ installParser =
|
|||||||
|
|
||||||
installOpts :: Parser InstallOptions
|
installOpts :: Parser InstallOptions
|
||||||
installOpts =
|
installOpts =
|
||||||
(flip InstallOptions)
|
(\p u v -> InstallOptions v p u)
|
||||||
<$> (optional
|
<$> (optional
|
||||||
(option
|
(option
|
||||||
(eitherReader platformParser)
|
(eitherReader platformParser)
|
||||||
@@ -417,6 +420,17 @@ installOpts =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
<*> (optional
|
||||||
|
(option
|
||||||
|
(eitherReader bindistParser)
|
||||||
|
( short 'u'
|
||||||
|
<> long "url"
|
||||||
|
<> metavar "BINDIST_URL"
|
||||||
|
<> help
|
||||||
|
"Provide DownloadInfo as json string, e.g.: '{ \"dlHash\": \"<sha256 hash>\", \"dlSubdir\": \"ghc-<ver>\", \"dlUri\": \"<uri>\" }'"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
<*> optional toolVersionArgument
|
<*> optional toolVersionArgument
|
||||||
|
|
||||||
|
|
||||||
@@ -800,6 +814,8 @@ platformParser s' = case MP.parse (platformP <* MP.eof) "" (T.pack s') of
|
|||||||
pure v
|
pure v
|
||||||
|
|
||||||
|
|
||||||
|
bindistParser :: String -> Either String DownloadInfo
|
||||||
|
bindistParser = eitherDecode . BLU.fromString
|
||||||
|
|
||||||
|
|
||||||
toSettings :: Options -> Settings
|
toSettings :: Options -> Settings
|
||||||
@@ -1047,7 +1063,9 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
let installGHC InstallOptions{..} =
|
let installGHC InstallOptions{..} =
|
||||||
(runInstTool $ do
|
(runInstTool $ do
|
||||||
v <- liftE $ fromVersion dls instVer GHC
|
v <- liftE $ fromVersion dls instVer GHC
|
||||||
liftE $ installGHCBin dls (_tvVersion v) (fromMaybe pfreq instPlatform) -- FIXME: ugly sharing of tool version
|
case instBindist of
|
||||||
|
Nothing -> liftE $ installGHCBin dls (_tvVersion v) (fromMaybe pfreq instPlatform)
|
||||||
|
Just uri -> liftE $ installGHCBindist uri (_tvVersion v) (fromMaybe pfreq instPlatform)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight _ -> do
|
VRight _ -> do
|
||||||
@@ -1081,7 +1099,9 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
let installCabal InstallOptions{..} =
|
let installCabal InstallOptions{..} =
|
||||||
(runInstTool $ do
|
(runInstTool $ do
|
||||||
v <- liftE $ fromVersion dls instVer Cabal
|
v <- liftE $ fromVersion dls instVer Cabal
|
||||||
liftE $ installCabalBin dls (_tvVersion v) (fromMaybe pfreq instPlatform) -- FIXME: ugly sharing of tool version
|
case instBindist of
|
||||||
|
Nothing -> liftE $ installCabalBin dls (_tvVersion v) (fromMaybe pfreq instPlatform)
|
||||||
|
Just uri -> liftE $ installCabalBindist uri (_tvVersion v) (fromMaybe pfreq instPlatform)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight _ -> do
|
VRight _ -> do
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
cabal-version: 3.0
|
cabal-version: 3.0
|
||||||
name: ghcup
|
name: ghcup
|
||||||
version: 0.1.7
|
version: 0.1.8
|
||||||
synopsis: ghc toolchain installer as an exe/library
|
synopsis: ghc toolchain installer as an exe/library
|
||||||
description:
|
description:
|
||||||
A rewrite of the shell script ghcup, for providing
|
A rewrite of the shell script ghcup, for providing
|
||||||
@@ -341,6 +341,7 @@ executable ghcup
|
|||||||
import:
|
import:
|
||||||
config
|
config
|
||||||
, base
|
, base
|
||||||
|
, aeson
|
||||||
, bytestring
|
, bytestring
|
||||||
, containers
|
, containers
|
||||||
, haskus-utils-variant
|
, haskus-utils-variant
|
||||||
|
|||||||
117
lib/GHCup.hs
117
lib/GHCup.hs
@@ -77,7 +77,7 @@ import qualified Data.Text.Encoding as E
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
installGHCBin :: ( MonadFail m
|
installGHCBindist :: ( MonadFail m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
, MonadCatch m
|
, MonadCatch m
|
||||||
, MonadReader Settings m
|
, MonadReader Settings m
|
||||||
@@ -85,7 +85,7 @@ installGHCBin :: ( MonadFail m
|
|||||||
, MonadResource m
|
, MonadResource m
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
)
|
)
|
||||||
=> GHCupDownloads
|
=> DownloadInfo
|
||||||
-> Version
|
-> Version
|
||||||
-> PlatformRequest
|
-> PlatformRequest
|
||||||
-> Excepts
|
-> Excepts
|
||||||
@@ -102,14 +102,13 @@ installGHCBin :: ( MonadFail m
|
|||||||
]
|
]
|
||||||
m
|
m
|
||||||
()
|
()
|
||||||
installGHCBin bDls ver pfreq@(PlatformRequest {..}) = do
|
installGHCBindist dlinfo ver (PlatformRequest {..}) = do
|
||||||
let tver = (mkTVer ver)
|
let tver = (mkTVer ver)
|
||||||
lift $ $(logDebug) [i|Requested to install GHC with #{ver}|]
|
lift $ $(logDebug) [i|Requested to install GHC with #{ver}|]
|
||||||
whenM (liftIO $ ghcInstalled tver)
|
whenM (liftIO $ ghcInstalled tver)
|
||||||
$ (throwE $ AlreadyInstalled GHC ver)
|
$ (throwE $ AlreadyInstalled GHC ver)
|
||||||
|
|
||||||
-- download (or use cached version)
|
-- download (or use cached version)
|
||||||
dlinfo <- lE $ getDownloadInfo GHC ver pfreq bDls
|
|
||||||
dl <- liftE $ downloadCached dlinfo Nothing
|
dl <- liftE $ downloadCached dlinfo Nothing
|
||||||
|
|
||||||
-- unpack
|
-- unpack
|
||||||
@@ -150,32 +149,62 @@ installGHCBin bDls ver pfreq@(PlatformRequest {..}) = do
|
|||||||
| otherwise = []
|
| otherwise = []
|
||||||
|
|
||||||
|
|
||||||
installCabalBin :: ( MonadMask m
|
installGHCBin :: ( MonadFail m
|
||||||
, MonadCatch m
|
, MonadMask m
|
||||||
, MonadReader Settings m
|
, MonadCatch m
|
||||||
, MonadLogger m
|
, MonadReader Settings m
|
||||||
, MonadResource m
|
, MonadLogger m
|
||||||
, MonadIO m
|
, MonadResource m
|
||||||
, MonadFail m
|
, MonadIO m
|
||||||
)
|
)
|
||||||
=> GHCupDownloads
|
=> GHCupDownloads
|
||||||
-> Version
|
-> Version
|
||||||
-> PlatformRequest
|
-> PlatformRequest
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ AlreadyInstalled
|
'[ AlreadyInstalled
|
||||||
, CopyError
|
, BuildFailed
|
||||||
, DigestError
|
, DigestError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, NoDownload
|
, NoDownload
|
||||||
, NotInstalled
|
, NotInstalled
|
||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
#if !defined(TAR)
|
#if !defined(TAR)
|
||||||
, ArchiveResult
|
, ArchiveResult
|
||||||
#endif
|
#endif
|
||||||
]
|
]
|
||||||
m
|
m
|
||||||
()
|
()
|
||||||
installCabalBin bDls ver pfreq@(PlatformRequest {..}) = do
|
installGHCBin bDls ver pfreq = do
|
||||||
|
dlinfo <- lE $ getDownloadInfo GHC ver pfreq bDls
|
||||||
|
installGHCBindist dlinfo ver pfreq
|
||||||
|
|
||||||
|
|
||||||
|
installCabalBindist :: ( MonadMask m
|
||||||
|
, MonadCatch m
|
||||||
|
, MonadReader Settings m
|
||||||
|
, MonadLogger m
|
||||||
|
, MonadResource m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadFail m
|
||||||
|
)
|
||||||
|
=> DownloadInfo
|
||||||
|
-> Version
|
||||||
|
-> PlatformRequest
|
||||||
|
-> Excepts
|
||||||
|
'[ AlreadyInstalled
|
||||||
|
, CopyError
|
||||||
|
, DigestError
|
||||||
|
, DownloadFailed
|
||||||
|
, NoDownload
|
||||||
|
, NotInstalled
|
||||||
|
, UnknownArchive
|
||||||
|
#if !defined(TAR)
|
||||||
|
, ArchiveResult
|
||||||
|
#endif
|
||||||
|
]
|
||||||
|
m
|
||||||
|
()
|
||||||
|
installCabalBindist dlinfo ver (PlatformRequest {..}) = do
|
||||||
lift $ $(logDebug) [i|Requested to install cabal version #{ver}|]
|
lift $ $(logDebug) [i|Requested to install cabal version #{ver}|]
|
||||||
|
|
||||||
bindir <- liftIO ghcupBinDir
|
bindir <- liftIO ghcupBinDir
|
||||||
@@ -190,7 +219,6 @@ installCabalBin bDls ver pfreq@(PlatformRequest {..}) = do
|
|||||||
$ (throwE $ AlreadyInstalled Cabal ver)
|
$ (throwE $ AlreadyInstalled Cabal ver)
|
||||||
|
|
||||||
-- download (or use cached version)
|
-- download (or use cached version)
|
||||||
dlinfo <- lE $ getDownloadInfo Cabal ver pfreq bDls
|
|
||||||
dl <- liftE $ downloadCached dlinfo Nothing
|
dl <- liftE $ downloadCached dlinfo Nothing
|
||||||
|
|
||||||
-- unpack
|
-- unpack
|
||||||
@@ -227,6 +255,37 @@ installCabalBin bDls ver pfreq@(PlatformRequest {..}) = do
|
|||||||
Overwrite
|
Overwrite
|
||||||
|
|
||||||
|
|
||||||
|
installCabalBin :: ( MonadMask m
|
||||||
|
, MonadCatch m
|
||||||
|
, MonadReader Settings m
|
||||||
|
, MonadLogger m
|
||||||
|
, MonadResource m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadFail m
|
||||||
|
)
|
||||||
|
=> GHCupDownloads
|
||||||
|
-> Version
|
||||||
|
-> PlatformRequest
|
||||||
|
-> Excepts
|
||||||
|
'[ AlreadyInstalled
|
||||||
|
, CopyError
|
||||||
|
, DigestError
|
||||||
|
, DownloadFailed
|
||||||
|
, NoDownload
|
||||||
|
, NotInstalled
|
||||||
|
, UnknownArchive
|
||||||
|
#if !defined(TAR)
|
||||||
|
, ArchiveResult
|
||||||
|
#endif
|
||||||
|
]
|
||||||
|
m
|
||||||
|
()
|
||||||
|
installCabalBin bDls ver pfreq = do
|
||||||
|
dlinfo <- lE $ getDownloadInfo Cabal ver pfreq bDls
|
||||||
|
installCabalBindist dlinfo ver pfreq
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---------------------
|
---------------------
|
||||||
--[ Set GHC/cabal ]--
|
--[ Set GHC/cabal ]--
|
||||||
|
|||||||
@@ -866,9 +866,9 @@ ghc_8101_32_alpine = DownloadInfo
|
|||||||
|
|
||||||
ghc_8101_64_freebsd :: DownloadInfo
|
ghc_8101_64_freebsd :: DownloadInfo
|
||||||
ghc_8101_64_freebsd = DownloadInfo
|
ghc_8101_64_freebsd = DownloadInfo
|
||||||
[uri|https://downloads.haskell.org/ghc/8.10.1/ghc-8.10.1-x86_64-portbld-freebsd.tar.xz|]
|
[uri|https://files.hasufell.de/ghc/ghc-8.10.1-x86_64-portbld-freebsd.tar.xz|]
|
||||||
(Just [rel|ghc-8.10.1|])
|
(Just [rel|ghc-8.10.1|])
|
||||||
"52d27dbf9de82005dde9bfc521bff612e381b5228af194259c2306d2b75825c2"
|
"e8646ec9b60fd40aa9505ee055f22f04601290ab7a1342c2cf37c34de9d3f142"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import GHCup.Utils.Prelude
|
|||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
|
|
||||||
import Control.Concurrent
|
import Control.Concurrent
|
||||||
|
import Control.Concurrent.Async
|
||||||
import Control.Exception ( evaluate )
|
import Control.Exception ( evaluate )
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
@@ -57,14 +58,6 @@ import qualified "unix-bytestring" System.Posix.IO.ByteString
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- | Bool signals whether the regions should be cleaned.
|
|
||||||
data StopThread = StopThread Bool
|
|
||||||
deriving Show
|
|
||||||
|
|
||||||
instance Exception StopThread
|
|
||||||
|
|
||||||
|
|
||||||
data ProcessError = NonZeroExit Int ByteString [ByteString]
|
data ProcessError = NonZeroExit Int ByteString [ByteString]
|
||||||
| PTerminated ByteString [ByteString]
|
| PTerminated ByteString [ByteString]
|
||||||
| PStopped ByteString [ByteString]
|
| PStopped ByteString [ByteString]
|
||||||
@@ -131,10 +124,9 @@ execLogged exe spath args lfile chdir env = do
|
|||||||
pState <- newEmptyMVar
|
pState <- newEmptyMVar
|
||||||
done <- newEmptyMVar
|
done <- newEmptyMVar
|
||||||
void
|
void
|
||||||
$ forkOS
|
$ forkIO
|
||||||
$ EX.handle (\(_ :: StopThread) -> pure ())
|
|
||||||
$ EX.handle (\(_ :: IOException) -> pure ())
|
$ EX.handle (\(_ :: IOException) -> pure ())
|
||||||
$ flip finally (putMVar done ())
|
$ flip EX.finally (putMVar done ())
|
||||||
$ (if verbose
|
$ (if verbose
|
||||||
then tee fd stdoutRead
|
then tee fd stdoutRead
|
||||||
else printToRegion fd stdoutRead 6 pState
|
else printToRegion fd stdoutRead 6 pState
|
||||||
@@ -157,7 +149,7 @@ execLogged exe spath args lfile chdir env = do
|
|||||||
e <- toProcessError exe args <$!> SPPB.getProcessStatus True True pid
|
e <- toProcessError exe args <$!> SPPB.getProcessStatus True True pid
|
||||||
putMVar pState (either (const False) (const True) e)
|
putMVar pState (either (const False) (const True) e)
|
||||||
|
|
||||||
takeMVar done
|
void $ race (takeMVar done) (threadDelay (1000000 * 3))
|
||||||
closeFd stdoutRead
|
closeFd stdoutRead
|
||||||
|
|
||||||
pure e
|
pure e
|
||||||
@@ -225,33 +217,41 @@ execLogged exe spath args lfile chdir env = do
|
|||||||
| BS.length bs > w && w > 5 -> BS.take (w - 4) bs <> "..."
|
| BS.length bs > w && w > 5 -> BS.take (w - 4) bs <> "..."
|
||||||
| otherwise -> bs
|
| otherwise -> bs
|
||||||
|
|
||||||
-- read an entire line from the file descriptor (removes the newline char)
|
-- Consecutively read from Fd in 512 chunks until we hit
|
||||||
readLine :: MonadIO m => Fd -> ByteString -> m (ByteString, ByteString)
|
-- newline or EOF.
|
||||||
readLine fd = go
|
readLine :: MonadIO m
|
||||||
|
=> Fd -- ^ input file descriptor
|
||||||
|
-> ByteString -- ^ rest buffer (read across newline)
|
||||||
|
-> m (ByteString, ByteString, Bool) -- ^ (full line, rest, eof)
|
||||||
|
readLine fd = \inBs -> go inBs
|
||||||
where
|
where
|
||||||
go inBs = do
|
go inBs = do
|
||||||
bs <-
|
-- if buffer is not empty, process it first
|
||||||
liftIO
|
mbs <- if BS.length inBs == 0
|
||||||
$ handleIO (\e -> if isEOFError e then pure "" else ioError e)
|
-- otherwise attempt read
|
||||||
$ SPIB.fdRead fd 512
|
then liftIO
|
||||||
let nbs = BS.append inBs bs
|
$ handleIO (\e -> if isEOFError e then pure Nothing else ioError e)
|
||||||
(line, rest) = BS.span (/= _lf) nbs
|
$ fmap Just
|
||||||
if
|
$ SPIB.fdRead fd 512
|
||||||
| BS.length rest /= 0 -> pure (line, BS.tail rest)
|
else pure $ Just inBs
|
||||||
| BS.length line == 0 -> pure (mempty, mempty)
|
case mbs of
|
||||||
| otherwise -> (\(l, r) -> (line <> l, r)) <$!> go mempty
|
Nothing -> pure ("", "", True)
|
||||||
|
Just bs -> do
|
||||||
|
-- split on newline
|
||||||
|
let (line, rest) = BS.span (/= _lf) bs
|
||||||
|
if
|
||||||
|
| BS.length rest /= 0 -> pure (line, BS.tail rest, False)
|
||||||
|
-- if rest is empty, then there was no newline, process further
|
||||||
|
| otherwise -> (\(l, r, b) -> (line <> l, r, b)) <$!> go mempty
|
||||||
|
|
||||||
readTilEOF :: MonadIO m => (ByteString -> m a) -> Fd -> m ()
|
readTilEOF :: MonadIO m => (ByteString -> m a) -> Fd -> m ()
|
||||||
readTilEOF ~action' fd' = go mempty
|
readTilEOF ~action' fd' = go mempty
|
||||||
where
|
where
|
||||||
go bs' = do
|
go bs' = do
|
||||||
(bs, rest) <- readLine fd' bs'
|
(bs, rest, eof) <- readLine fd' bs'
|
||||||
if
|
if eof
|
||||||
| BS.length bs == 0 -> liftIO
|
then liftIO $ ioError (mkIOError eofErrorType "" Nothing Nothing)
|
||||||
$ ioError (mkIOError eofErrorType "" Nothing Nothing)
|
else (void $ action' bs) >> go rest
|
||||||
| otherwise -> do
|
|
||||||
void $ action' bs
|
|
||||||
go rest
|
|
||||||
|
|
||||||
|
|
||||||
-- | Capture the stdout and stderr of the given action, which
|
-- | Capture the stdout and stderr of the given action, which
|
||||||
@@ -288,13 +288,12 @@ captureOutStreams action = do
|
|||||||
done <- newEmptyMVar
|
done <- newEmptyMVar
|
||||||
_ <-
|
_ <-
|
||||||
forkIO
|
forkIO
|
||||||
$ EX.handle (\(_ :: StopThread) -> pure ())
|
|
||||||
$ EX.handle (\(_ :: IOException) -> pure ())
|
$ EX.handle (\(_ :: IOException) -> pure ())
|
||||||
$ flip finally (putMVar done ())
|
$ flip EX.finally (putMVar done ())
|
||||||
$ writeStds parentStdoutRead parentStderrRead refOut refErr
|
$ writeStds parentStdoutRead parentStderrRead refOut refErr
|
||||||
|
|
||||||
status <- SPPB.getProcessStatus True True pid
|
status <- SPPB.getProcessStatus True True pid
|
||||||
takeMVar done
|
void $ race (takeMVar done) (threadDelay (1000000 * 3))
|
||||||
|
|
||||||
case status of
|
case status of
|
||||||
-- readFd will take care of closing the fd
|
-- readFd will take care of closing the fd
|
||||||
@@ -314,13 +313,13 @@ captureOutStreams action = do
|
|||||||
void
|
void
|
||||||
$ forkIO
|
$ forkIO
|
||||||
$ hideError eofErrorType
|
$ hideError eofErrorType
|
||||||
$ flip finally (putMVar doneOut ())
|
$ flip EX.finally (putMVar doneOut ())
|
||||||
$ readTilEOF (\x -> modifyIORef' rout (<> x)) pout
|
$ readTilEOF (\x -> modifyIORef' rout (<> x)) pout
|
||||||
doneErr <- newEmptyMVar
|
doneErr <- newEmptyMVar
|
||||||
void
|
void
|
||||||
$ forkIO
|
$ forkIO
|
||||||
$ hideError eofErrorType
|
$ hideError eofErrorType
|
||||||
$ flip finally (putMVar doneErr ())
|
$ flip EX.finally (putMVar doneErr ())
|
||||||
$ readTilEOF (\x -> modifyIORef' rerr (<> x)) perr
|
$ readTilEOF (\x -> modifyIORef' rerr (<> x)) perr
|
||||||
takeMVar doneOut
|
takeMVar doneOut
|
||||||
takeMVar doneErr
|
takeMVar doneErr
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ ghcupURL :: URI
|
|||||||
ghcupURL = [uri|https://www.haskell.org/ghcup/data/ghcup-0.0.2.json|]
|
ghcupURL = [uri|https://www.haskell.org/ghcup/data/ghcup-0.0.2.json|]
|
||||||
|
|
||||||
ghcUpVer :: PVP
|
ghcUpVer :: PVP
|
||||||
ghcUpVer = [pver|0.1.7|]
|
ghcUpVer = [pver|0.1.8|]
|
||||||
|
|
||||||
numericVer :: String
|
numericVer :: String
|
||||||
numericVer = T.unpack . prettyPVP $ ghcUpVer
|
numericVer = T.unpack . prettyPVP $ ghcUpVer
|
||||||
|
|||||||
Reference in New Issue
Block a user