{-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeApplications #-} -- | -- Module : Aura.Cache -- Copyright : (c) Colin Woodbury, 2012 - 2019 -- License : GPL3 -- Maintainer: Colin Woodbury -- -- Reading and searching the package cache. module Aura.Cache ( -- * Types Cache(..) , cacheContents -- * Misc. , defaultPackageCache , cacheMatches , pkgsInCache ) where import Aura.Settings import Aura.Types import BasePrelude import Data.Generics.Product (field) import qualified Data.Map.Strict as M import qualified Data.Set as S import Data.Set.NonEmpty (NESet) import qualified Data.Set.NonEmpty as NES import qualified Data.Text as T import Lens.Micro ((^.)) import System.Path (Absolute, Path, fromAbsoluteFilePath, toFilePath, ()) import System.Path.IO (getDirectoryContents) --- -- | Every package in the current cache, paired with its original filename. newtype Cache = Cache { _cache :: M.Map SimplePkg PackagePath } -- | The default location of the package cache: \/var\/cache\/pacman\/pkg\/ defaultPackageCache :: Path Absolute defaultPackageCache = fromAbsoluteFilePath "/var/cache/pacman/pkg/" -- SILENT DROPS PATHS THAT DON'T PARSE -- Maybe that's okay, since we don't know what non-package garbage files -- could be sitting in the cache. -- | Given every filepath contained in the package cache, form -- the `Cache` type. cache :: [PackagePath] -> Cache cache = Cache . M.fromList . mapMaybe (\p -> (,p) <$> simplepkg p) -- | Given a path to the package cache, yields its contents in a usable form. cacheContents :: Path Absolute -> IO Cache cacheContents pth = cache . map (PackagePath . (pth )) <$> getDirectoryContents pth -- | All packages from a given `S.Set` who have a copy in the cache. pkgsInCache :: Settings -> NESet PkgName -> IO (S.Set PkgName) pkgsInCache ss ps = do c <- cacheContents . either id id . cachePathOf $ commonConfigOf ss pure . S.filter (`NES.member` ps) . S.map (^. field @"name") . M.keysSet $ _cache c -- | Any entries (filepaths) in the cache that match a given `T.Text`. cacheMatches :: Settings -> T.Text -> IO [PackagePath] cacheMatches ss input = do c <- cacheContents . either id id . cachePathOf $ commonConfigOf ss pure . filter (T.isInfixOf input . T.pack . toFilePath . path) . M.elems $ _cache c