cabal-test-bin (empty) → 0.1.0
raw patch · 4 files changed
+206/−0 lines, 4 filesdep +basedep +directorydep +filepathsetup-changed
Dependencies added: base, directory, filepath, unix
Files
- LICENSE +30/−0
- Main.hs +137/−0
- Setup.hs +2/−0
- cabal-test-bin.cabal +37/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2015, Junji Hashimoto++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Junji Hashimoto nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Main.hs view
@@ -0,0 +1,137 @@+{-#LANGUAGE BangPatterns#-}++import Numeric+import Data.Word+import Data.List+import Data.Char (ord,isSpace)+import Data.Bits+import qualified Control.Exception as E+import Control.Applicative+import Control.Monad+import System.Posix.Files+import System.Posix.Types+import System.Directory+import System.FilePath+import System.Environment+import System.Exit+import System.IO++-- copy from https://github.com/haskell/cabal/blob/master/cabal-install/Distribution/Client/Sandbox.hs+sandboxBuildDir :: FilePath -> FilePath+sandboxBuildDir sandboxDir = "dist/dist-sandbox-" ++ showHex sandboxDirHash ""+ where+ sandboxDirHash = jenkins sandboxDir++ -- See http://en.wikipedia.org/wiki/Jenkins_hash_function+ jenkins :: String -> Word32+ jenkins str = loop_finish $ foldl' loop 0 str+ where+ loop :: Word32 -> Char -> Word32+ loop hash key_i' = hash'''+ where+ key_i = toEnum . ord $ key_i'+ hash' = hash + key_i+ hash'' = hash' + (shiftL hash' 10)+ hash''' = hash'' `xor` (shiftR hash'' 6)++ loop_finish :: Word32 -> Word32+ loop_finish hash = hash'''+ where+ hash' = hash + (shiftL hash 3)+ hash'' = hash' `xor` (shiftR hash' 11)+ hash''' = hash'' + (shiftL hash'' 15)++++-- copy from https://hackage.haskell.org/package/cab-0.2.14/docs/src/Distribution-Cab-Sandbox.html#getSandbox++configFile :: String+configFile = "cabal.sandbox.config"++pkgDbKey :: String+pkgDbKey = "package-db:"++pkgDbKeyLen :: Int+pkgDbKeyLen = length pkgDbKey++-- | Find a sandbox config file by tracing ancestor directories,+-- parse it and return the package db path+getSandbox :: IO (Maybe FilePath)+getSandbox = (Just <$> getPkgDb) `E.catch` handler+ where+ getPkgDb = getCurrentDirectory >>= getSandboxConfigFile >>= getPackageDbDir+ handler :: E.SomeException -> IO (Maybe String)+ handler _ = return Nothing++-- | Find a sandbox config file by tracing ancestor directories.+-- Exception is thrown if not found+getSandboxConfigFile :: FilePath -> IO FilePath+getSandboxConfigFile dir = do+ let cfile = dir </> configFile+ exist <- doesFileExist cfile+ if exist then+ return cfile+ else do+ let dir' = takeDirectory dir+ if dir == dir' then+ E.throwIO $ userError "sandbox config file not found"+ else+ getSandboxConfigFile dir'++-- | Extract a package db directory from the sandbox config file.+-- Exception is thrown if the sandbox config file is broken.+getPackageDbDir :: FilePath -> IO FilePath+getPackageDbDir sconf = do+ -- Be strict to ensure that an error can be caught.+ !path <- extractValue . parse <$> readFile sconf+ return path+ where+ parse = head . filter ("package-db:" `isPrefixOf`) . lines+ extractValue = fst . break isSpace . dropWhile isSpace . drop pkgDbKeyLen++type ProjectRootDir = FilePath+type BinaryName = FilePath+++getTimeStamp :: FilePath -> IO (Either E.SomeException EpochTime)+getTimeStamp path = do+ stat <- E.try $ getFileStatus path+ return $ fmap modificationTime stat++searchBinary :: ProjectRootDir -> BinaryName -> IO FilePath+searchBinary rdir name = do+ timeT <- getTimeStamp distTBin+ msdir <- getSandbox+ case msdir of+ Just sdir -> do+ let distS = sandboxBuildDir $ takeDirectory sdir+ let distSBin = rdir </> distS </> "build" </> name </> name+ timeS <- getTimeStamp distSBin+ case (timeS,timeT) of+ (Right s,Right t) -> return $ if t <= s then distSBin else distTBin+ (Right _,Left _) -> return distSBin+ (Left _,Right _) -> return distTBin+ _ -> errorHandler [distSBin,distTBin]+ Nothing -> do+ case timeT of+ (Right _) -> return distTBin+ _ -> errorHandler [distTBin]+ where+ distTBin = rdir </> "dist" </> "build" </> name </> name+ errorHandler paths = do+ forM_ paths $ \path -> do+ hPutStrLn stderr $ "Check:" ++ path+ hPutStrLn stderr $ "Can not find exe-file:" ++ name+ exitWith $ ExitFailure 2+ +main :: IO ()+main = do+ args <- getArgs+ case args of+ (dir:binName:[]) -> do+ binPath <- searchBinary dir binName+ putStrLn binPath+ exitWith $ ExitSuccess+ _ -> do+ hPutStrLn stderr "Usage: cabal-test-bin \"project's root directory\" \"executable-program-name\""+ exitWith $ ExitFailure 1
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ cabal-test-bin.cabal view
@@ -0,0 +1,37 @@+-- Initial cabal-temp-bin.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: cabal-test-bin+version: 0.1.0+synopsis: A program for finding temporary build file during cabal-test.+description: cabal-test-bin finds exe-file for "cabal install --enable-tests --run-tests" or "cabal test".+ When a project uses cabal-sandbox, + cabal-test-bin checks both <project root>/dist/dist-sandbox-<hash>/build/<exe-file>/<exe-file> + and <project root>/dist/build/<exe-file>/<exe-file>.+ +license: BSD3+license-file: LICENSE+author: Junji Hashimoto+maintainer: junji.hashimoto@gmail.com+-- copyright: +category: Testing+build-type: Simple+-- extra-source-files: +cabal-version: >=1.10++bug-reports: https://github.com/junjihashimoto/cabal-test-bin/issues++source-repository head+ type: git+ location: https://github.com/junjihashimoto/cabal-test-bin.git++executable cabal-test-bin+ main-is: Main.hs+ -- other-modules: + -- other-extensions: + build-depends: base >=4.7 && <4.8+ , directory+ , filepath+ , unix+ -- hs-source-dirs: + default-language: Haskell2010