|
| 1 | +import Test.Cabal.Prelude |
| 2 | +import System.Directory |
| 3 | + |
| 4 | +-- Test that extra-prog-path in the global cabal config (~/.cabal/config) |
| 5 | +-- overrides the path for pkg-config while resolving a dependency on zlib. |
| 6 | +-- Specifically, this test emulates the scenario on Windows where pkg-config |
| 7 | +-- doesn't exist natively and must be provided via extra-prog-path. |
| 8 | +main = cabalTest $ do |
| 9 | + env <- getTestEnv |
| 10 | + let |
| 11 | + testDir = testCurrentDir env |
| 12 | + tmpDir = testTmpDir env |
| 13 | + -- Scripts is where we put a bad pkg-config |
| 14 | + scripts = tmpDir </> "scripts" |
| 15 | + -- Scripts-Winpath contains a mock pkg-config that returns good results. |
| 16 | + -- We add this to PATH on Windows before executing the test so we can tell |
| 17 | + -- apart when Cabal uses the override or not. |
| 18 | + scripts_winpath = tmpDir </> "scripts-winpath" |
| 19 | + |
| 20 | + ------------------------- |
| 21 | + -- Workaround for the fact that, on Windows, Cabal will only look for |
| 22 | + -- .exe files to satisfy executable dependencies. So we have to create a |
| 23 | + -- shim pkg-config.exe file in 'script'. This is a thin wrapper (which is |
| 24 | + -- explicitly added to Git) that calls whatever is defined in the .shim |
| 25 | + -- file. In our case, we rewrite the .shim file as below so that the |
| 26 | + -- pkg-config script is executed using sh. |
| 27 | + when isWindows $ do |
| 28 | + mb_sh <- fmap takeDirectory <$> liftIO (findExecutable "sh") |
| 29 | + case mb_sh of |
| 30 | + Nothing -> skip "no sh" |
| 31 | + Just sh -> do |
| 32 | + let escape = concatMap (\c -> case c of '\\' -> "\\\\\\\\"; x -> [x]) |
| 33 | + void $ shell "sed" [ "-i", "-e", "s/FINDSH/" <> escape sh <> "/g", escape (scripts </> "pkg-config.shim"), escape (scripts_winpath </> "pkg-config.shim") ] |
| 34 | + void $ shell "sed" [ "-i", "-e", "s/SCRIPTSDIR/" <> escape scripts <> "/g", escape (scripts </> "pkg-config.shim") ] |
| 35 | + void $ shell "sed" [ "-i", "-e", "s/SCRIPTSWINPATHDIR/" <> escape scripts_winpath <> "/g", escape (scripts_winpath </> "pkg-config.shim") ] |
| 36 | + |
| 37 | + -- End of Windows workaround |
| 38 | + ------------------------------ |
| 39 | + |
| 40 | + -- On Windows, we want it to find the "scripts/pkg-config" (which will |
| 41 | + -- return exit code 1), instead of what we add to the path |
| 42 | + -- ("scripts-winpath/pkg-config", which will return exit code 0). This is |
| 43 | + -- because Windows doesn't have a system pkg-config by default. If we didn't |
| 44 | + -- add a known-to-be-good mock pkg-config in the path, we wouldn't be able |
| 45 | + -- to tell apart from Cabal logs whether it wasn't able to find pkg-config |
| 46 | + -- at all (test fail) or whether the override worked and it found the bad |
| 47 | + -- one but couldn't query it (test success). |
| 48 | + -- |
| 49 | + -- On other systems, we want it to find "scripts/pkg-config" (exit code 1) |
| 50 | + -- instead of the system pkg-config (success). |
| 51 | + let wrap_test = if isWindows then addToPath scripts_winpath else id |
| 52 | + |
| 53 | + -- Add global config override in ~/.cabal/config (in the test environment). |
| 54 | + liftIO $ appendFile (testUserCabalConfigFile env) $ |
| 55 | + "\nextra-prog-path: " ++ scripts |
| 56 | + liftIO $ putStrLn $ testUserCabalConfigFile env |
| 57 | + |
| 58 | + -- On correct behaviour, cabal should fail because it found our exit-code-1 |
| 59 | + -- pkg-config through the global extra-prog-path. |
| 60 | + fails $ wrap_test $ cabal "v2-build" [] |
0 commit comments