allow matching on files whose content is not present

Anything that needs to examine the file content will fail to match,
or fall back to other available information. But the intent is that the
matcher be checked for matchNeedsFileContent and only be used if it does
not, so the exact behavior doesn't much matter as it should never
happen.

The real point of this is to not need to provide a dummy content file
when matching.

This commit was sponsored by Martin D on Patreon.
This commit is contained in:
Joey Hess 2020-09-28 11:08:30 -04:00
parent 9e676f062f
commit 00dbe35fbc
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
11 changed files with 40 additions and 30 deletions

View file

@ -85,7 +85,7 @@ fileMatchInfo file = do
matchfile <- getTopFilePath <$> inRepo (toTopFilePath file) matchfile <- getTopFilePath <$> inRepo (toTopFilePath file)
return $ MatchingFile FileInfo return $ MatchingFile FileInfo
{ matchFile = matchfile { matchFile = matchfile
, currFile = file , contentFile = Just file
} }
matchAll :: FileMatcher Annex matchAll :: FileMatcher Annex

View file

@ -452,7 +452,7 @@ importKeys remote importtreeconfig importcontent importablecontents = do
matcher <- largematcher (fromRawFilePath f) matcher <- largematcher (fromRawFilePath f)
let mi = MatchingFile FileInfo let mi = MatchingFile FileInfo
{ matchFile = f { matchFile = f
, currFile = toRawFilePath tmpfile , contentFile = Just (toRawFilePath tmpfile)
} }
islargefile <- checkMatcher' matcher mi mempty islargefile <- checkMatcher' matcher mi mempty
if islargefile if islargefile

View file

@ -366,7 +366,7 @@ addAnnexedFile ci matcher file key mtmp = ifM (addUnlocked matcher mi)
where where
mi = case mtmp of mi = case mtmp of
Just tmp -> MatchingFile $ FileInfo Just tmp -> MatchingFile $ FileInfo
{ currFile = toRawFilePath tmp { contentFile = Just (toRawFilePath tmp)
, matchFile = toRawFilePath file , matchFile = toRawFilePath file
} }
-- Provide as much info as we can without access to the -- Provide as much info as we can without access to the

View file

@ -131,7 +131,7 @@ batchFilesMatching fmt a = do
matcher <- getMatcher matcher <- getMatcher
go $ \si f -> go $ \si f ->
let f' = toRawFilePath f let f' = toRawFilePath f
in ifM (matcher $ MatchingFile $ FileInfo f' f') in ifM (matcher $ MatchingFile $ FileInfo (Just f') f')
( a (si, f') ( a (si, f')
, return Nothing , return Nothing
) )

View file

@ -106,7 +106,7 @@ withPathContents a params = do
, return [(p, takeFileName p)] , return [(p, takeFileName p)]
) )
checkmatch matcher (f, relf) = matcher $ MatchingFile $ FileInfo checkmatch matcher (f, relf) = matcher $ MatchingFile $ FileInfo
{ currFile = toRawFilePath f { contentFile = Just (toRawFilePath f)
, matchFile = toRawFilePath relf , matchFile = toRawFilePath relf
} }
@ -280,7 +280,7 @@ seekFiltered prefilter a listfs = do
where where
process matcher v@(_si, f) = process matcher v@(_si, f) =
whenM (prefilter v) $ whenM (prefilter v) $
whenM (matcher $ MatchingFile $ FileInfo f f) $ whenM (matcher $ MatchingFile $ FileInfo (Just f) f) $
a v a v
data MatcherInfo = MatcherInfo data MatcherInfo = MatcherInfo
@ -358,7 +358,7 @@ seekFilteredKeys seeker listfs = do
-- checked later, to avoid a slow lookup here. -- checked later, to avoid a slow lookup here.
(not ((matcherNeedsKey mi || matcherNeedsLocationLog mi) (not ((matcherNeedsKey mi || matcherNeedsLocationLog mi)
&& not (matcherNeedsFileName mi))) && not (matcherNeedsFileName mi)))
(MatchingFile $ FileInfo f f) (MatchingFile $ FileInfo (Just f) f)
(liftIO $ ofeeder ((si, f), sha)) (liftIO $ ofeeder ((si, f), sha))
keyaction f mi content a = keyaction f mi content a =

View file

@ -176,7 +176,7 @@ start o si file addunlockedmatcher = do
perform :: AddOptions -> RawFilePath -> AddUnlockedMatcher -> CommandPerform perform :: AddOptions -> RawFilePath -> AddUnlockedMatcher -> CommandPerform
perform o file addunlockedmatcher = withOtherTmp $ \tmpdir -> do perform o file addunlockedmatcher = withOtherTmp $ \tmpdir -> do
lockingfile <- not <$> addUnlocked addunlockedmatcher lockingfile <- not <$> addUnlocked addunlockedmatcher
(MatchingFile (FileInfo file file)) (MatchingFile (FileInfo (Just file) file))
let cfg = LockDownConfig let cfg = LockDownConfig
{ lockingFile = lockingfile { lockingFile = lockingfile
, hardlinkFileTmpDir = Just tmpdir , hardlinkFileTmpDir = Just tmpdir

View file

@ -223,7 +223,7 @@ startLocal o addunlockedmatcher largematcher mode (srcfile, destfile) =
stop stop
lockdown a = do lockdown a = do
let mi = MatchingFile $ FileInfo let mi = MatchingFile $ FileInfo
{ currFile = toRawFilePath srcfile { contentFile = Just (toRawFilePath srcfile)
, matchFile = toRawFilePath destfile , matchFile = toRawFilePath destfile
} }
lockingfile <- not <$> addUnlocked addunlockedmatcher mi lockingfile <- not <$> addUnlocked addunlockedmatcher mi

View file

@ -568,7 +568,7 @@ getDirStatInfo o dir = do
where where
initial = (emptyKeyInfo, emptyKeyInfo, emptyNumCopiesStats, M.empty) initial = (emptyKeyInfo, emptyKeyInfo, emptyNumCopiesStats, M.empty)
update matcher fast key file vs@(presentdata, referenceddata, numcopiesstats, repodata) = update matcher fast key file vs@(presentdata, referenceddata, numcopiesstats, repodata) =
ifM (matcher $ MatchingFile $ FileInfo file file) ifM (matcher $ MatchingFile $ FileInfo (Just file) file)
( do ( do
!presentdata' <- ifM (inAnnex key) !presentdata' <- ifM (inAnnex key)
( return $ addKey key presentdata ( return $ addKey key presentdata

View file

@ -133,7 +133,7 @@ send ups fs = do
(fs', cleanup) <- seekHelper id ww LsFiles.inRepo (fs', cleanup) <- seekHelper id ww LsFiles.inRepo
=<< workTreeItems ww fs =<< workTreeItems ww fs
matcher <- Limit.getMatcher matcher <- Limit.getMatcher
let addlist f o = whenM (matcher $ MatchingFile $ FileInfo f f) $ let addlist f o = whenM (matcher $ MatchingFile $ FileInfo (Just f) f) $
liftIO $ hPutStrLn h o liftIO $ hPutStrLn h o
forM_ fs' $ \(_, f) -> do forM_ fs' $ \(_, f) -> do
mk <- lookupKey f mk <- lookupKey f

View file

@ -155,9 +155,11 @@ matchMagic _limitname querymagic selectprovidedinfo (Just magic) glob =
where where
cglob = compileGlob glob CaseSensative -- memoized cglob = compileGlob glob CaseSensative -- memoized
go (MatchingKey _ _) = pure False go (MatchingKey _ _) = pure False
go (MatchingFile fi) = catchBoolIO $ go (MatchingFile fi) = case contentFile fi of
Just f -> catchBoolIO $
maybe False (matchGlob cglob) maybe False (matchGlob cglob)
<$> querymagic magic (fromRawFilePath (currFile fi)) <$> querymagic magic (fromRawFilePath f)
Nothing -> return False
go (MatchingInfo p) = go (MatchingInfo p) =
matchGlob cglob <$> getInfo (selectprovidedinfo p) matchGlob cglob <$> getInfo (selectprovidedinfo p)
matchMagic limitname _ _ Nothing _ = matchMagic limitname _ _ Nothing _ =
@ -184,12 +186,14 @@ addLocked = addLimit $ Right $ MatchFiles
matchLockStatus :: Bool -> MatchInfo -> Annex Bool matchLockStatus :: Bool -> MatchInfo -> Annex Bool
matchLockStatus _ (MatchingKey _ _) = pure False matchLockStatus _ (MatchingKey _ _) = pure False
matchLockStatus _ (MatchingInfo _) = pure False matchLockStatus _ (MatchingInfo _) = pure False
matchLockStatus wantlocked (MatchingFile fi) = liftIO $ do matchLockStatus wantlocked (MatchingFile fi) = case contentFile fi of
islocked <- isPointerFile (currFile fi) >>= \case Just f -> liftIO $ do
islocked <- isPointerFile f >>= \case
Just _key -> return False Just _key -> return False
Nothing -> isSymbolicLink Nothing -> isSymbolicLink
<$> getSymbolicLinkStatus (fromRawFilePath (currFile fi)) <$> getSymbolicLinkStatus (fromRawFilePath f)
return (islocked == wantlocked) return (islocked == wantlocked)
Nothing -> return False
{- Adds a limit to skip files not believed to be present {- Adds a limit to skip files not believed to be present
- in a specfied repository. Optionally on a prior date. -} - in a specfied repository. Optionally on a prior date. -}
@ -436,17 +440,20 @@ limitSize lb vs s = case readSize dataUnits s of
} }
where where
go sz _ (MatchingFile fi) = case lb of go sz _ (MatchingFile fi) = case lb of
LimitAnnexFiles -> lookupFileKey fi >>= \case LimitAnnexFiles -> goannexed sz fi
Just key -> checkkey sz key LimitDiskFiles -> case contentFile fi of
Nothing -> return False Just f -> do
LimitDiskFiles -> do
filesize <- liftIO $ catchMaybeIO $ filesize <- liftIO $ catchMaybeIO $
getFileSize (fromRawFilePath (currFile fi)) getFileSize (fromRawFilePath f)
return $ filesize `vs` Just sz return $ filesize `vs` Just sz
Nothing -> goannexed sz fi
go sz _ (MatchingKey key _) = checkkey sz key go sz _ (MatchingKey key _) = checkkey sz key
go sz _ (MatchingInfo p) = go sz _ (MatchingInfo p) =
getInfo (providedFileSize p) getInfo (providedFileSize p)
>>= \sz' -> return (Just sz' `vs` Just sz) >>= \sz' -> return (Just sz' `vs` Just sz)
goannexed sz fi = lookupFileKey fi >>= \case
Just key -> checkkey sz key
Nothing -> return False
checkkey sz key = return $ fromKey keySize key `vs` Just sz checkkey sz key = return $ fromKey keySize key `vs` Just sz
addMetaData :: String -> Annex () addMetaData :: String -> Annex ()
@ -506,7 +513,9 @@ addAccessedWithin duration = do
secs = fromIntegral (durationSeconds duration) secs = fromIntegral (durationSeconds duration)
lookupFileKey :: FileInfo -> Annex (Maybe Key) lookupFileKey :: FileInfo -> Annex (Maybe Key)
lookupFileKey = lookupKey . currFile lookupFileKey fi = case contentFile fi of
Just f -> lookupKey f
Nothing -> return Nothing
checkKey :: (Key -> Annex Bool) -> MatchInfo -> Annex Bool checkKey :: (Key -> Annex Bool) -> MatchInfo -> Annex Bool
checkKey a (MatchingFile fi) = lookupFileKey fi >>= maybe (return False) a checkKey a (MatchingFile fi) = lookupFileKey fi >>= maybe (return False) a

View file

@ -25,8 +25,9 @@ data MatchInfo
| MatchingInfo ProvidedInfo | MatchingInfo ProvidedInfo
data FileInfo = FileInfo data FileInfo = FileInfo
{ currFile :: RawFilePath { contentFile :: Maybe RawFilePath
-- ^ current path to the file, for operations that examine it -- ^ path to a file containing the content, for operations
-- that examine it
, matchFile :: RawFilePath , matchFile :: RawFilePath
-- ^ filepath to match on; may be relative to top of repo or cwd -- ^ filepath to match on; may be relative to top of repo or cwd
} }