Skip to content

Commit

Permalink
Allow specifying the HPC data directory explicitly
Browse files Browse the repository at this point in the history
- Add functionality required to allow the user to specify the hpc data
  directory explicitly, rather than searching for it in the usual
  places. This is primarily motivated by the Nix package manager,
  where hpc output is usally written to some folder outside of the
  current directory (e.g. to
  /nix/store/HASH-my-lib-0.1.0.0/share/hpc).
  • Loading branch information
sevanspowell committed Aug 10, 2020
1 parent 04fe42c commit 1f9dc5e
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 24 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,40 @@ You will have to specify it for example when using Travis-pro as in the example
--service-name=travis-pro
```

#### --hpc-dir

This option allows you to manually specify the hpc data directory to use. The behaviour without this option is to attempt to find the hpc directory in the typical places in the current directory.
```bash
--hpc-dir=/dir/share/hpc
```

This directory should contain your hpc data (mix files and tix files) in the standard directory structure for hpc output, for example:

```bash
hpc
├── mix
│   ├── my-lib-0.1.0.0
│   │   └── my-lib-0.1.0.0-inplace
│   │   ├── My.Lib.A.mix
│   │   ├── My.Lib.B.mix
│   | └── My.Lib.C.mix
│   ├── my-lib-test
│   │   ├── SomeSpec.mix
│   │   ├── SomeOtherSpec.mix
│   └── Main.mix
│   └── my-lib-test2
│   ├── SomeSpec2.mix
│   ├── SomeOtherSpec2.mix
│   └── Main.mix
└── tix
├── my-lib-0.1.0.0
│   └── my-lib-0.1.0.0.tix
├── my-lib-test
│   └── my-lib-test.tix
└── my-lib-test2
└── my-lib-test2.tix
```

# Limitations

Because of the way hpc works, coverage data is only generated for modules that are referenced directly or indirectly by the test suites.
Expand Down
2 changes: 2 additions & 0 deletions src/HpcCoverallsCmdLine.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ data HpcCoverallsArgs = CmdMain
, optCurlVerbose :: Bool
, optDontSend :: Bool
, optCoverageMode :: CoverageMode
, optHpcDir :: Maybe String
} deriving (Data, Show, Typeable)

hpcCoverallsArgs :: HpcCoverallsArgs
Expand All @@ -30,6 +31,7 @@ hpcCoverallsArgs = CmdMain
, optCabalFile = Nothing &= explicit &= typ "FILE" &= name "cabal-file" &= help "Cabal file (ex.: module-name.cabal)"
, optServiceName = Nothing &= explicit &= typ "TOKEN" &= name "service-name" &= help "service-name (e.g. travis-pro)"
, optRepoToken = Nothing &= explicit &= typ "TOKEN" &= name "repo-token" &= help "Coveralls repo token"
, optHpcDir = Nothing &= explicit &= typDir &= name "hpc-dir" &= help "Explicitly use this hpc directory instead of trying to discover one"
, argTestSuites = [] &= typ "TEST-SUITES" &= args
} &= summary ("hpc-coveralls v" ++ versionString version ++ ", (C) Guillaume Nargeot 2014-2015")
&= program "hpc-coveralls"
Expand Down
1 change: 1 addition & 0 deletions src/HpcCoverallsMain.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ getConfig hca = Config
(optCabalFile hca)
(optServiceName hca)
(optRepoToken hca)
(optHpcDir hca)
<$> listToMaybe (argTestSuites hca)

main :: IO ()
Expand Down
41 changes: 28 additions & 13 deletions src/Trace/Hpc/Coveralls.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import Data.Digest.Pure.MD5
import Data.Function
import Data.List
import qualified Data.Map.Strict as M
import Data.Semigroup ((<>))
import System.Directory (doesDirectoryExist)
import System.Exit (exitFailure)
import Trace.Hpc.Coveralls.Config
import Trace.Hpc.Coveralls.GitInfo (GitInfo)
Expand Down Expand Up @@ -137,19 +139,32 @@ generateCoverallsFromTix :: String -- ^ CI name
-> Maybe String -- ^ Package name-version
-> IO Value -- ^ code coverage result in json format
generateCoverallsFromTix serviceName jobId gitInfo config mPkgNameVer = do
mHpcDir <- firstExistingDirectory hpcDirs
case mHpcDir of
Nothing -> putStrLn "Couldn't find the hpc data directory" >> dumpDirectory distDir >> ioFailure
Just hpcDir -> do
testSuitesCoverages <- mapM (readCoverageData mPkgNameVer hpcDir excludedDirPatterns) testSuiteNames
let coverageData = mergeCoverageData testSuitesCoverages
return $ toCoverallsJson serviceName jobId repoTokenM gitInfo converter coverageData
where excludedDirPatterns = excludedDirs config
testSuiteNames = testSuites config
repoTokenM = repoToken config
converter = case coverageMode config of
StrictlyFullLines -> strictConverter
AllowPartialLines -> looseConverter
hpcDir <- findHpcDataDir config
testSuitesCoverages <- mapM (readCoverageData mPkgNameVer hpcDir excludedDirPatterns) testSuiteNames
let coverageData = mergeCoverageData testSuitesCoverages
return $ toCoverallsJson serviceName jobId repoTokenM gitInfo converter coverageData
where excludedDirPatterns = excludedDirs config
testSuiteNames = testSuites config
repoTokenM = repoToken config
converter = case coverageMode config of
StrictlyFullLines -> strictConverter
AllowPartialLines -> looseConverter

findHpcDataDir :: Config -> IO FilePath
findHpcDataDir config = do
case hpcDirOverride config of
Nothing -> do
mHpcDir <- firstExistingDirectory hpcDirs
case mHpcDir of
Nothing -> putStrLn "Couldn't find the hpc data directory" >> dumpDirectory distDir >> ioFailure
Just hpcDir -> pure hpcDir
Just hpcDirOverride -> do
let hpcDir = hpcDirOverride <> "/"
doesExist <- doesDirectoryExist hpcDir
if doesExist == False
then putStrLn ("The hpc data directory override provided does not exist: " <> hpcDir) >> ioFailure
else pure hpcDir


ioFailure :: IO a
ioFailure = putStrLn ("You can get support at " ++ gitterUrl) >> exitFailure
Expand Down
15 changes: 10 additions & 5 deletions src/Trace/Hpc/Coveralls/Cabal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@ import System.Directory

getCabalFile :: FilePath -> IO (Maybe FilePath)
getCabalFile dir = do
files <- (filter isCabal <$> getDirectoryContents dir) >>= filterM doesFileExist
case files of
[file] -> return $ Just file
_ -> return Nothing
where isCabal filename = ".cabal" `isSuffixOf` filename && length filename > 6
cabalFilesInDir <- filter isCabal <$> getDirectoryContents dir
cabalFiles <- filterM doesFileExist (mkFullPath <$> cabalFilesInDir)
case cabalFiles of
[file] -> do
return $ Just file
_ -> do
return Nothing
where
isCabal filename = ".cabal" `isSuffixOf` filename && length filename > 6
mkFullPath = ((dir <> "/") <>)

getPackageNameVersion :: FilePath -> IO (Maybe String)
getPackageNameVersion file = do
Expand Down
13 changes: 7 additions & 6 deletions src/Trace/Hpc/Coveralls/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ module Trace.Hpc.Coveralls.Config where
import Trace.Hpc.Coveralls.Types (CoverageMode)

data Config = Config {
excludedDirs :: ![FilePath],
coverageMode :: !CoverageMode,
cabalFile :: !(Maybe FilePath),
serviceName :: !(Maybe String),
repoToken :: !(Maybe String),
testSuites :: ![String]
excludedDirs :: ![FilePath],
coverageMode :: !CoverageMode,
cabalFile :: !(Maybe FilePath),
serviceName :: !(Maybe String),
repoToken :: !(Maybe String),
hpcDirOverride :: !(Maybe String),
testSuites :: ![String]
}

0 comments on commit 1f9dc5e

Please sign in to comment.