[commit: packages/directory] master: Hook test suite to `cabal test` (b80a204)

git at git.haskell.org git at git.haskell.org
Thu Mar 19 11:38:14 UTC 2015


Repository : ssh://git@git.haskell.org/directory

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/b80a2041a72d0408f774fa05f7b0685a927d2c71/directory

>---------------------------------------------------------------

commit b80a2041a72d0408f774fa05f7b0685a927d2c71
Author: Phil Ruffwind <rf at rufflewind.com>
Date:   Mon Mar 2 05:09:03 2015 -0500

    Hook test suite to `cabal test`
    
    `cabal test` now invokes the GHC test framework to run the tests.  In
    effect, it's just a wrapper that runs `tools/run-tests` with the correct
    environment.
    
    This is somewhat complicated by the fact that we cannot add `process` as
    a dependency, so we have to reinvent the wheel just to launch the shell
    script.


>---------------------------------------------------------------

b80a2041a72d0408f774fa05f7b0685a927d2c71
 directory.cabal         | 14 +++++------
 test/main.hs            | 20 ----------------
 tools/dispatch-tests.hs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 27 deletions(-)

diff --git a/directory.cabal b/directory.cabal
index c648e0d..d134c05 100644
--- a/directory.cabal
+++ b/directory.cabal
@@ -64,10 +64,10 @@ Library
     ghc-options: -Wall
 
 test-suite test
-  default-language: Haskell2010
-  hs-source-dirs: test
-  main-is: main.hs
-  type: exitcode-stdio-1.0
-  build-depends: base
-               , directory
-               , containers
+    default-language: Haskell2010
+    other-extensions: CPP ForeignFunctionInterface
+    ghc-options:      -Wall
+    hs-source-dirs:   tools
+    main-is:          dispatch-tests.hs
+    type:             exitcode-stdio-1.0
+    build-depends:    base, directory
diff --git a/test/main.hs b/test/main.hs
deleted file mode 100644
index 7a9fcb3..0000000
--- a/test/main.hs
+++ /dev/null
@@ -1,20 +0,0 @@
-{-# LANGUAGE NoImplicitPrelude #-}
--- Simplistic test suite for now. Worthwhile to add a dependency on a
--- test framework at some point.
-module Main (main) where
-
-import qualified Data.Set         as Set
-import           Prelude          (IO, error, fmap, return, show, (==))
-import           System.Directory (getDirectoryContents)
-
-main :: IO ()
-main = do
-    let expected = Set.fromList
-            [ "."
-            , ".."
-            , "main.hs"
-            ]
-    actual <- fmap Set.fromList (getDirectoryContents "test")
-    if expected == actual
-        then return ()
-        else error (show (expected, actual))
diff --git a/tools/dispatch-tests.hs b/tools/dispatch-tests.hs
new file mode 100644
index 0000000..598cd8b
--- /dev/null
+++ b/tools/dispatch-tests.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE CPP, ForeignFunctionInterface #-}
+module Main (main) where
+import Foreign (Ptr)
+import Foreign.C (CChar(..), CInt(..), withCString)
+import Data.Functor ((<$>))
+import System.Directory ()     -- to make sure `directory` is built beforehand
+import System.Environment (getArgs)
+import System.Exit (ExitCode(ExitSuccess, ExitFailure), exitWith)
+
+main :: IO ()
+main = do
+
+  -- check if 'cabal exec' is supported (didn't exist until 1.20)
+  cabalExecTest <- rawSystem "sh" ["-c", "cabal >/dev/null 2>&1 exec true"]
+
+  -- execute in the Cabal sandbox environment if possible
+  let prefix = case cabalExecTest of
+                 ExitSuccess   -> ["cabal", "exec", "--"]
+                 ExitFailure _ -> []
+
+  args <- getArgs
+  let command : arguments = prefix ++ ["sh", "tools/run-tests"] ++ args
+  exitWith =<< normalizeExitCode <$> rawSystem command arguments
+
+makeExitCode :: Int -> ExitCode
+makeExitCode 0 = ExitSuccess
+makeExitCode e = ExitFailure e
+
+-- on Linux the exit code is right-shifted by 8 bits, causing exit codes to be
+-- rather large; older versions of GHC don't seem to handle that well in
+-- `exitWith`
+normalizeExitCode :: ExitCode -> ExitCode
+normalizeExitCode  ExitSuccess    = ExitSuccess
+normalizeExitCode (ExitFailure _) = ExitFailure 1
+
+-- we can't use the `process` library as it causes a dependency cycle with
+-- Cabal, so we reinvent the wheel here in a simplistic way; this will
+-- probably break with non-ASCII characters on Windows
+rawSystem :: String -> [String] -> IO ExitCode
+rawSystem cmd args  =
+  withCString (quoteCmdArgs (cmd : args)) $ \ c_command ->
+  makeExitCode . fromIntegral <$> c_system c_command
+
+-- handle the different quoting rules in CMD.EXE vs POSIX shells
+quoteCmdArgs :: [String] -> String
+quoteCmdArgs cmdArgs =
+#ifdef mingw32_HOST_OS
+  -- the arcane quoting rules require us to add an extra set of quotes
+  -- around the entire thing: see `help cmd` or look at
+  -- https://superuser.com/a/238813
+  "\"" ++ unwords (quote <$> cmdArgs) ++ "\""
+  where quote s = "\"" ++ replaceElem '"' "\"\"" s ++ "\""
+#else
+  unwords (quote <$> cmdArgs)
+  where quote s = "'" ++ replaceElem '\'' "'\\''" s ++ "'"
+#endif
+
+replaceElem :: Eq a => a -> [a] -> [a] -> [a]
+replaceElem match repl = concat . (replace <$>)
+  where replace c | c == match = repl
+                  | otherwise  = [c]
+
+foreign import ccall safe "stdlib.h system" c_system :: Ptr CChar -> IO CInt



More information about the ghc-commits mailing list