module FilenameDescr where import Data.Char import Data.Either import Data.List import BuildInfo import Utils import Tar -- We can't just compare plain filenames, because versions numbers of GHC -- and the libraries will vary. So we use FilenameDescr instead, which -- abstracts out the version numbers. type FilenameDescr = [FilenameDescrBit] data FilenameDescrBit = VersionOf String | HashOf String | FP String | Ways deriving (Show, Eq, Ord) normaliseDescr :: FilenameDescr -> FilenameDescr normaliseDescr [] = [] normaliseDescr [x] = [x] normaliseDescr (FP x1 : FP x2 : xs) = normaliseDescr (FP (x1 ++ x2) : xs) normaliseDescr (x : xs) = x : normaliseDescr xs -- Sanity check that the FilenameDescr matches the filename in the tar line checkContent :: BuildInfo -> (FilenameDescr, TarLine) -> Errors checkContent buildInfo (fd, tl) = let fn = tlFileName tl in case flattenFilenameDescr buildInfo fd of Right fn' -> if fn' == fn then [] else if all isAscii fn then ["checkContent: Can't happen: filename mismatch: " ++ show fn] else [] -- Ugly kludge; don't worry too much if filepaths -- containing non-ASCII chars have gone wrong Left errs -> errs flattenFilenameDescr :: BuildInfo -> FilenameDescr -> Either Errors FilePath flattenFilenameDescr buildInfo fd = case partitionEithers (map f fd) of ([], strs) -> Right (concat strs) (errs, _) -> Left (concat errs) where f (FP fp) = Right fp f (VersionOf thing) = case lookup thing (biThingVersionMap buildInfo) of Just v -> Right v Nothing -> Left ["Can't happen: thing has no version in mapping"] f (HashOf thing) = case lookup thing (biThingHashMap buildInfo) of Just v -> Right v Nothing -> Left ["Can't happen: thing has no hash in mapping"] f Ways = case biMaybeWays buildInfo of Just ways -> Right $ intercalate "-" ways Nothing -> Left ["Can't happen: No ways, but Ways is used"]