diff --git a/README.md b/README.md index 5f2e34c..40b2049 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/src/HpcCoverallsCmdLine.hs b/src/HpcCoverallsCmdLine.hs index 0aa4f9f..8d34c16 100644 --- a/src/HpcCoverallsCmdLine.hs +++ b/src/HpcCoverallsCmdLine.hs @@ -18,6 +18,7 @@ data HpcCoverallsArgs = CmdMain , optCurlVerbose :: Bool , optDontSend :: Bool , optCoverageMode :: CoverageMode + , optHpcDir :: Maybe String } deriving (Data, Show, Typeable) hpcCoverallsArgs :: HpcCoverallsArgs @@ -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" diff --git a/src/HpcCoverallsMain.hs b/src/HpcCoverallsMain.hs index 8d51112..32ca907 100644 --- a/src/HpcCoverallsMain.hs +++ b/src/HpcCoverallsMain.hs @@ -46,6 +46,7 @@ getConfig hca = Config (optCabalFile hca) (optServiceName hca) (optRepoToken hca) + (optHpcDir hca) <$> listToMaybe (argTestSuites hca) main :: IO () diff --git a/src/Trace/Hpc/Coveralls.hs b/src/Trace/Hpc/Coveralls.hs index c14ab24..f4ffa0d 100644 --- a/src/Trace/Hpc/Coveralls.hs +++ b/src/Trace/Hpc/Coveralls.hs @@ -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) @@ -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 diff --git a/src/Trace/Hpc/Coveralls/Cabal.hs b/src/Trace/Hpc/Coveralls/Cabal.hs index b303045..8acfdae 100644 --- a/src/Trace/Hpc/Coveralls/Cabal.hs +++ b/src/Trace/Hpc/Coveralls/Cabal.hs @@ -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 diff --git a/src/Trace/Hpc/Coveralls/Config.hs b/src/Trace/Hpc/Coveralls/Config.hs index 0daa895..9e58e7d 100644 --- a/src/Trace/Hpc/Coveralls/Config.hs +++ b/src/Trace/Hpc/Coveralls/Config.hs @@ -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] }