summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CheckDir.hs48
1 files changed, 40 insertions, 8 deletions
diff --git a/lib/CheckDir.hs b/lib/CheckDir.hs
index 2a35c12..7280887 100644
--- a/lib/CheckDir.hs
+++ b/lib/CheckDir.hs
@@ -10,7 +10,7 @@ module CheckDir (recursiveCheckDir) where
import CheckMap (MapResult (mapresultProvides),
loadAndLintMap, mapresultDepends)
-import Control.Monad (void)
+import Control.Monad ( void, foldM )
import Control.Monad.Extra (mapMaybeM)
import Data.Aeson (ToJSON, (.=))
import qualified Data.Aeson as A
@@ -25,8 +25,11 @@ import Paths (normalise, normaliseWithFrag)
import System.FilePath (splitPath, (</>))
import qualified System.FilePath as FP
import System.FilePath.Posix (takeDirectory)
-import Types (Dep (LocalMap), Level)
+import Types (Dep (LocalMap, Local), Level)
import Util (PrettyPrint (prettyprint))
+import Data.Foldable (fold)
+import Data.Functor ((<&>))
+import System.Directory.Extra (doesFileExist)
-- based on the startling observation that Data.Map has lower complexity
@@ -41,6 +44,7 @@ listFromSet = map fst . M.toList
data DirResult = DirResult
{ dirresultMaps :: Map FilePath MapResult
, dirresultDeps :: [MissingDep]
+ , dirresultMissingAssets :: [MissingAsset]
} deriving (Generic)
data MissingDep = MissingDep
@@ -48,12 +52,22 @@ data MissingDep = MissingDep
, neededBy :: [FilePath]
} deriving (Generic, ToJSON)
+newtype MissingAsset = MissingAsset MissingDep
+
instance ToJSON DirResult where
toJSON res = A.object
[ "missingDeps" .= dirresultDeps res
+ , "missingAssets" .= dirresultMissingAssets res
, "mapLints" .= dirresultMaps res
]
+instance ToJSON MissingAsset where
+ toJSON (MissingAsset md) = A.object
+ [ "asset" .= entrypoint md
+ , "neededBy" .= neededBy md
+ ]
+
+
instance PrettyPrint (Level, DirResult) where
prettyprint (level, res) = prettyMapLints <> prettyMissingDeps
where
@@ -79,12 +93,15 @@ instance Semigroup DirResult where
a <> b = DirResult
{ dirresultMaps = dirresultMaps a <> dirresultMaps b
, dirresultDeps = dirresultDeps a <> dirresultDeps b
+ , dirresultMissingAssets =
+ dirresultMissingAssets a <> dirresultMissingAssets b
}
instance Monoid DirResult where
mempty = DirResult
{ dirresultMaps = mempty
- , dirresultDeps = []
+ , dirresultDeps = mempty
+ , dirresultMissingAssets = mempty
}
@@ -95,7 +112,10 @@ instance Monoid DirResult where
recursiveCheckDir :: FilePath -> FilePath -> IO DirResult
recursiveCheckDir prefix root = do
linted <- recursiveCheckDir' prefix [root] mempty mempty
- pure $ linted <> mempty { dirresultDeps = missingDeps linted }
+ mAssets <- missingAssets prefix linted
+ pure $ linted <> mempty { dirresultDeps = missingDeps linted
+ , dirresultMissingAssets = mAssets
+ }
-- | Given a (partially) completed DirResult, check which local
@@ -123,6 +143,20 @@ missingDeps res =
-- each map file is an entrypoint by itself
trivial = mapKeys T.pack $ void (dirresultMaps res)
+-- | Checks if all assets found (contained in the map's lints)
+-- actually exist where they should exist
+missingAssets :: FilePath -> DirResult -> IO [MissingAsset]
+missingAssets prefix res =
+ mapM (fmap (fmap (fmap MissingAsset)) missingOfMap) (M.toList . dirresultMaps $ res) <&> fold
+ where missingOfMap (path, mapres) = mapMaybeM
+ (\case Local relpath ->
+ let asset = normalise (takeDirectory path) relpath
+ in doesFileExist (prefix </> asset) <&>
+ \case True -> Nothing
+ False -> Just $ MissingDep (T.pack asset) [path]
+ _ -> pure Nothing)
+ (mapresultDepends mapres)
+
-- | The less-nice function for checking an entire repository.
--
@@ -145,7 +179,7 @@ recursiveCheckDir' prefix paths done acc = do
(\(m,res) ->
let ps = mapMaybe
(\case {LocalMap p -> Just p; _ -> Nothing})
- (mapresultDepends $ res)
+ (mapresultDepends res)
in map (FP.normalise . normalise (takeDirectory m)) ps
)
lints
@@ -160,9 +194,7 @@ recursiveCheckDir' prefix paths done acc = do
let knowns = M.union done $ setFromList paths
-- Monoids!
- let acc' = acc <> DirResult
- { dirresultMaps = M.fromList lints
- , dirresultDeps = [] }
+ let acc' = acc <> mempty { dirresultMaps = M.fromList lints }
-- Tail recursion!
case unknowns of
[] -> pure acc'