Skip to content

Commit 5a4a8ef

Browse files
committed
cabal-doctest: Cache doctest executables
1 parent 1f07492 commit 5a4a8ef

File tree

5 files changed

+55
-26
lines changed

5 files changed

+55
-26
lines changed

doctest.cabal

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ library:
6565
ghc-paths: ">= 0.1.0.9"
6666
Cabal:
6767
transformers:
68-
temporary:
6968

7069
flags:
7170
cabal-doctest:

src/Cabal.hs

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ module Cabal (externalCommand) where
33

44
import Imports
55

6+
import System.IO
67
import System.Environment
78
import System.Exit (exitWith)
9+
import System.Directory
810
import System.FilePath
9-
import System.IO.Temp (withSystemTempDirectory)
1011
import System.Process
1112

1213
import qualified Info
@@ -19,30 +20,46 @@ externalCommand args = do
1920
Just cabal -> run cabal (drop 1 args)
2021

2122
run :: String -> [String] -> IO ()
22-
run cabal args = withSystemTempDirectory "doctest" $ \ dir -> do
23-
let
24-
doctest = dir </> "doctest"
25-
script = dir </> "init-ghci"
23+
run cabal args = do
2624

2725
Paths{..} <- paths cabal
2826

29-
callProcess cabal [
30-
"install" , "doctest-" <> Info.version
31-
, "--flag", "-cabal-doctest"
32-
, "--ignore-project"
33-
, "--installdir", dir
34-
, "--install-method=symlink"
35-
, "--with-compiler", ghc
36-
, "--with-hc-pkg", ghcPkg
37-
]
38-
39-
callProcess (dir </> "doctest") ["--version"]
27+
let
28+
doctest = cache </> "doctest" <> "-" <> Info.version
29+
script = cache </> "init-ghci-" <> Info.version
30+
31+
doesFileExist doctest >>= \ case
32+
True -> pass
33+
False -> callProcess cabal [
34+
"install" , "doctest-" <> Info.version
35+
, "--flag", "-cabal-doctest"
36+
, "--ignore-project"
37+
, "--installdir", cache
38+
, "--program-suffix", "-" <> Info.version
39+
, "--install-method=copy"
40+
, "--with-compiler", ghc
41+
, "--with-hc-pkg", ghcPkg
42+
]
43+
44+
doesFileExist script >>= \ case
45+
True -> pass
46+
False -> writeFileAtomically script ":seti -w -Wdefault"
47+
48+
callProcess doctest ["--version"]
49+
4050
callProcess cabal ("build" : "--only-dependencies" : args)
41-
writeFile script ":seti -w -Wdefault"
51+
4252
spawnProcess cabal ("repl"
4353
: "--build-depends=QuickCheck"
4454
: "--build-depends=template-haskell"
4555
: ("--repl-options=-ghci-script=" <> script)
4656
: "--with-compiler" : doctest
4757
: "--with-hc-pkg" : ghcPkg
4858
: args) >>= waitForProcess >>= exitWith
59+
60+
writeFileAtomically :: FilePath -> String -> IO ()
61+
writeFileAtomically name contents = do
62+
(tmp, h) <- openTempFile (takeDirectory name) (takeFileName name)
63+
hPutStr h contents
64+
hClose h
65+
renameFile tmp name

src/Cabal/Paths.hs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Data.Version hiding (parseVersion)
1212
import qualified Data.Version as Version
1313
import System.Exit hiding (die)
1414
import System.Directory
15+
import System.FilePath
1516
import System.IO
1617
import System.Process
1718
import Text.ParserCombinators.ReadP
@@ -20,10 +21,12 @@ import qualified Distribution.Simple.GHC as GHC
2021
import Distribution.Verbosity
2122
import Distribution.Simple.Program.Db
2223
import Distribution.Simple.Program.Types
24+
import Distribution.Simple.Compiler
2325

2426
data Paths = Paths {
2527
ghc :: FilePath
2628
, ghcPkg :: FilePath
29+
, cache :: FilePath
2730
} deriving (Eq, Show)
2831

2932
paths :: FilePath -> IO Paths
@@ -40,22 +43,31 @@ paths cabal = do
4043
values <- parseFields <$> readProcess cabal ["path", "-v0"] ""
4144

4245
let
43-
compiler_path :: String
44-
compiler_path = "compiler-path"
46+
getPath :: String -> String -> IO FilePath
47+
getPath subject key = case lookup key values of
48+
Nothing -> die $ "Cannot determine the path to " <> subject <> ". Running 'cabal path' did not return a value for '" <> key <> "'."
49+
Just path -> canonicalizePath path
4550

46-
ghc <- case lookup compiler_path values of
47-
Nothing -> die $ "Cannot determine the path to 'ghc'. Running 'cabal path' did not return a value for '" <> compiler_path <> "'."
48-
Just path -> canonicalizePath path
51+
ghc <- getPath "'ghc'" "compiler-path"
52+
53+
(compiler, _, programs) <- GHC.configure silent (Just ghc) Nothing emptyProgramDb
4954

50-
(_, _, programs) <- GHC.configure silent (Just ghc) Nothing emptyProgramDb
5155

5256
ghcPkg <- case programPath <$> List.find (programId >>> (== "ghc-pkg")) (configuredPrograms programs) of
5357
Nothing -> die $ "Cannot determine the path to 'ghc-pkg' from '" <> ghc <> "'."
5458
Just path -> return path
5559

60+
abi <- strip <$> readProcess ghcPkg ["--no-user-package-db", "field", "base", "abi", "--simple-output"] ""
61+
62+
cache_home <- getPath "Cabal's cache directory" "cache-home"
63+
let cache = cache_home </> "doctest" </> showCompilerId compiler <> "-" <> abi
64+
65+
createDirectoryIfMissing True cache
66+
5667
return Paths {
5768
ghc
5869
, ghcPkg
70+
, cache
5971
}
6072
where
6173
parseFields :: String -> [(String, FilePath)]

test/Cabal/PathsSpec.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ spec = do
1616

1717
it "returns the path to 'ghc-pkg'" $ do
1818
(paths "cabal" >>= doesFileExist . ghcPkg) `shouldReturn` True
19+
20+
it "returns the path to Cabal's cache directory" $ do
21+
(paths "cabal" >>= doesDirectoryExist . cache) `shouldReturn` True

0 commit comments

Comments
 (0)