Skip to content

Commit aab89cd

Browse files
committed
Windows: use hIsTerminalDevice or isMinTTYHandle
'mintty' is a terminal emulator for 'Cygwin', 'MSYS' or 'MSYS2', and dervied projects, and for 'WSL' (Windows Subsystem for Linux). `hIsTerminalDevice` does not recognise handles to 'mintty' terminals, but `isMinTTYHandle` does. Currently, `stack` relies on `hIsTerminalDevice` in three places to detect handles to terminals and does not use `isMinTTYHandle`. `isMinTTYHandle` was first added to package `Win32-2.5.0.0` and then made robust to an upstream (ntdll-related) bug from `Win32-2.5.3.0`. The latter constraint is added to `package.yaml`.
1 parent 252bc7f commit aab89cd

6 files changed

Lines changed: 26 additions & 5 deletions

File tree

ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Behavior changes:
1111

1212
Other enhancements:
1313

14+
* On Windows, recognise a 'mintty' (false) terminal as a terminal, by default
15+
1416
Bug fixes:
1517

1618
* `~/.stack/config.yaml` and `stack.yaml` terminating by newline

package.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ when:
121121
then:
122122
cpp-options: -DWINDOWS
123123
dependencies:
124-
- Win32
124+
- Win32 >= 2.5.3.0
125125
else:
126126
build-tools:
127127
- hsc2hs

src/Stack/Docker.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,8 @@ runContainerAndExit getCmdArgs
243243
(env,isStdinTerminal,isStderrTerminal,homeDir) <- liftIO $
244244
(,,,)
245245
<$> getEnvironment
246-
<*> hIsTerminalDevice stdin
247-
<*> hIsTerminalDevice stderr
246+
<*> hIsTerminalDeviceOrMinTTY stdin
247+
<*> hIsTerminalDeviceOrMinTTY stderr
248248
<*> (parseAbsDir =<< getHomeDirectory)
249249
isStdoutTerminal <- view terminalL
250250
let dockerHost = lookup "DOCKER_HOST" env

src/Stack/FileWatch.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fileWatchConf :: WatchConfig
3535
-> IO ()
3636
fileWatchConf cfg out inner = withManagerConf cfg $ \manager -> do
3737
let putLn = hPutStrLn out
38-
outputIsTerminal <- hIsTerminalDevice out
38+
outputIsTerminal <- hIsTerminalDeviceOrMinTTY out
3939
let withColor color str = putLn $ do
4040
if outputIsTerminal
4141
then concat [color, str, reset]

src/Stack/Prelude.hs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE CPP #-}
12
{-# LANGUAGE NoImplicitPrelude #-}
23
{-# LANGUAGE OverloadedStrings #-}
34
{-# LANGUAGE ScopedTypeVariables #-}
@@ -13,6 +14,7 @@ module Stack.Prelude
1314
, readProcessNull
1415
, withProcessContext
1516
, stripCR
17+
, hIsTerminalDeviceOrMinTTY
1618
, module X
1719
) where
1820

@@ -30,6 +32,10 @@ import qualified System.Directory as Dir
3032
import qualified System.FilePath as FP
3133
import System.IO.Error (isDoesNotExistError)
3234

35+
#ifdef WINDOWS
36+
import System.Win32 (isMinTTYHandle, withHandleToHANDLE)
37+
#endif
38+
3339
import Data.Conduit.Binary (sourceHandle, sinkHandle)
3440
import qualified Data.Conduit.Binary as CB
3541
import qualified Data.Conduit.List as CL
@@ -151,3 +157,16 @@ withProcessContext pcNew inner = do
151157
-- | Remove a trailing carriage return if present
152158
stripCR :: Text -> Text
153159
stripCR = T.dropSuffix "\r"
160+
161+
-- | hIsTerminaDevice does not recognise handles to mintty terminals as terminal
162+
-- devices, but isMinTTYHandle does.
163+
hIsTerminalDeviceOrMinTTY :: MonadIO m => Handle -> m Bool
164+
#ifdef WINDOWS
165+
hIsTerminalDeviceOrMinTTY h = do
166+
isTD <- hIsTerminalDevice h
167+
if isTD
168+
then return True
169+
else liftIO $ withHandleToHANDLE h isMinTTYHandle
170+
#else
171+
hIsTerminalDeviceOrMinTTY = hIsTerminalDevice
172+
#endif

src/main/Main.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ main = do
167167
hSetTranslit stderr
168168
args <- getArgs
169169
progName <- getProgName
170-
isTerminal <- hIsTerminalDevice stdout
170+
isTerminal <- hIsTerminalDeviceOrMinTTY stdout
171171
execExtraHelp args
172172
Docker.dockerHelpOptName
173173
(dockerOptsParser False)

0 commit comments

Comments
 (0)