add searchPathContents

And rename related functions for consistency.
This commit is contained in:
Joey Hess 2021-02-02 19:01:45 -04:00
parent aec2cf0abe
commit 1b63132ca3
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
18 changed files with 60 additions and 49 deletions

View file

@ -68,7 +68,7 @@ youtubeDl url workdir p = ifM ipAddressesUnlimited
youtubeDl' :: URLString -> FilePath -> MeterUpdate -> UrlOptions -> Annex (Either String (Maybe FilePath)) youtubeDl' :: URLString -> FilePath -> MeterUpdate -> UrlOptions -> Annex (Either String (Maybe FilePath))
youtubeDl' url workdir p uo youtubeDl' url workdir p uo
| supportedScheme uo url = ifM (liftIO $ inPath "youtube-dl") | supportedScheme uo url = ifM (liftIO $ inSearchPath "youtube-dl")
( runcmd >>= \case ( runcmd >>= \case
Right True -> workdirfiles >>= \case Right True -> workdirfiles >>= \case
(f:[]) -> return (Right (Just f)) (f:[]) -> return (Right (Just f))

View file

@ -49,7 +49,7 @@ import Control.Concurrent
{- This thread makes git commits at appropriate times. -} {- This thread makes git commits at appropriate times. -}
commitThread :: NamedThread commitThread :: NamedThread
commitThread = namedThread "Committer" $ do commitThread = namedThread "Committer" $ do
havelsof <- liftIO $ inPath "lsof" havelsof <- liftIO $ inSearchPath "lsof"
delayadd <- liftAnnex $ delayadd <- liftAnnex $
fmap Seconds . annexDelayAdd <$> Annex.getGitConfig fmap Seconds . annexDelayAdd <$> Annex.getGitConfig
msg <- liftAnnex Command.Sync.commitMsg msg <- liftAnnex Command.Sync.commitMsg

View file

@ -58,7 +58,7 @@ checkCanWatch
| canWatch = do | canWatch = do
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
liftIO Lsof.setup liftIO Lsof.setup
unlessM (liftIO (inPath "lsof") <||> Annex.getState Annex.force) unlessM (liftIO (inSearchPath "lsof") <||> Annex.getState Annex.force)
needLsof needLsof
#else #else
noop noop

View file

@ -34,7 +34,7 @@ awsConfigurator = page "Add an Amazon repository" (Just Configuration)
glacierConfigurator :: Widget -> Handler Html glacierConfigurator :: Widget -> Handler Html
glacierConfigurator a = do glacierConfigurator a = do
ifM (liftIO $ inPath "glacier") ifM (liftIO $ inSearchPath "glacier")
( awsConfigurator a ( awsConfigurator a
, awsConfigurator needglaciercli , awsConfigurator needglaciercli
) )

View file

@ -164,7 +164,7 @@ getFirstRepositoryR :: Handler Html
getFirstRepositoryR = postFirstRepositoryR getFirstRepositoryR = postFirstRepositoryR
postFirstRepositoryR :: Handler Html postFirstRepositoryR :: Handler Html
postFirstRepositoryR = page "Getting started" (Just Configuration) $ do postFirstRepositoryR = page "Getting started" (Just Configuration) $ do
unlessM (liftIO $ inPath "git") $ unlessM (liftIO $ inSearchPath "git") $
giveup "You need to install git in order to use git-annex!" giveup "You need to install git in order to use git-annex!"
androidspecial <- liftIO osAndroid androidspecial <- liftIO osAndroid
path <- liftIO . defaultRepositoryPath =<< liftH inFirstRun path <- liftIO . defaultRepositoryPath =<< liftH inFirstRun

View file

@ -134,7 +134,7 @@ openFileBrowser = do
let p = proc cmd [path] let p = proc cmd [path]
#endif #endif
#endif #endif
ifM (liftIO $ inPath cmd) ifM (liftIO $ inSearchPath cmd)
( do ( do
let run = void $ liftIO $ forkIO $ do let run = void $ liftIO $ forkIO $ do
withCreateProcess p $ \_ _ _ pid -> void $ withCreateProcess p $ \_ _ _ pid -> void $

View file

@ -41,7 +41,7 @@ genKeyModal :: Widget
genKeyModal = $(widgetFile "configurators/genkeymodal") genKeyModal = $(widgetFile "configurators/genkeymodal")
isGcryptInstalled :: IO Bool isGcryptInstalled :: IO Bool
isGcryptInstalled = inPath "git-remote-gcrypt" isGcryptInstalled = inSearchPath "git-remote-gcrypt"
whenGcryptInstalled :: Handler Html -> Handler Html whenGcryptInstalled :: Handler Html -> Handler Html
whenGcryptInstalled a = ifM (liftIO isGcryptInstalled) whenGcryptInstalled a = ifM (liftIO isGcryptInstalled)

View file

@ -97,7 +97,7 @@ searchCmd success failure cmdsparams = search cmdsparams
- the command. -} - the command. -}
findCmdPath :: ConfigKey -> String -> Test findCmdPath :: ConfigKey -> String -> Test
findCmdPath k command = do findCmdPath k command = do
ifM (inPath command) ifM (inSearchPath command)
( return $ Config k $ MaybeStringConfig $ Just command ( return $ Config k $ MaybeStringConfig $ Just command
, do , do
r <- getM find ["/usr/sbin", "/sbin", "/usr/local/sbin"] r <- getM find ["/usr/sbin", "/sbin", "/usr/local/sbin"]

View file

@ -79,7 +79,7 @@ autoStart o = do
f <- autoStartFile f <- autoStartFile
giveup $ "Nothing listed in " ++ f giveup $ "Nothing listed in " ++ f
program <- programPath program <- programPath
haveionice <- pure BuildInfo.ionice <&&> inPath "ionice" haveionice <- pure BuildInfo.ionice <&&> inSearchPath "ionice"
pids <- forM dirs $ \d -> do pids <- forM dirs $ \d -> do
putStrLn $ "git-annex autostart in " ++ d putStrLn $ "git-annex autostart in " ++ d
mpid <- catchMaybeIO $ go haveionice program d mpid <- catchMaybeIO $ go haveionice program d

View file

@ -64,7 +64,7 @@ runViewer :: FilePath -> [(String, [CommandParam])] -> Annex Bool
runViewer file [] = do runViewer file [] = do
showLongNote $ "left map in " ++ file showLongNote $ "left map in " ++ file
return True return True
runViewer file ((c, ps):rest) = ifM (liftIO $ inPath c) runViewer file ((c, ps):rest) = ifM (liftIO $ inSearchPath c)
( do ( do
showLongNote $ "running: " ++ c ++ unwords (toCommand ps) showLongNote $ "running: " ++ c ++ unwords (toCommand ps)
showOutput showOutput

View file

@ -291,7 +291,7 @@ downloadTorrentContent k u dest filenum p = do
checkDependencies :: Annex () checkDependencies :: Annex ()
checkDependencies = do checkDependencies = do
missing <- liftIO $ filterM (not <$$> inPath) deps missing <- liftIO $ filterM (not <$$> inSearchPath) deps
unless (null missing) $ unless (null missing) $
giveup $ "need to install additional software in order to download from bittorrent: " ++ unwords missing giveup $ "need to install additional software in order to download from bittorrent: " ++ unwords missing
where where

View file

@ -57,7 +57,7 @@ nonBatchCommandMaker = id
getBatchCommandMaker :: IO BatchCommandMaker getBatchCommandMaker :: IO BatchCommandMaker
getBatchCommandMaker = do getBatchCommandMaker = do
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
nicers <- filterM (inPath . fst) nicers <- filterM (inSearchPath . fst)
[ ("nice", []) [ ("nice", [])
, ("ionice", ["-c3"]) , ("ionice", ["-c3"])
, ("nocache", []) , ("nocache", [])

View file

@ -411,7 +411,7 @@ keyBlock public ls = unlines
- is returned. - is returned.
-} -}
testHarness :: FilePath -> GpgCmd -> IO a -> IO (Maybe a) testHarness :: FilePath -> GpgCmd -> IO a -> IO (Maybe a)
testHarness tmpdir cmd a = ifM (inPath (unGpgCmd cmd)) testHarness tmpdir cmd a = ifM (inSearchPath (unGpgCmd cmd))
( bracket (eitherToMaybe <$> tryNonAsync setup) cleanup go ( bracket (eitherToMaybe <$> tryNonAsync setup) cleanup go
, return Nothing , return Nothing
) )
@ -439,7 +439,7 @@ testHarness tmpdir cmd a = ifM (inPath (unGpgCmd cmd))
-- other daemons. Stop them when done. This only affects -- other daemons. Stop them when done. This only affects
-- daemons started for the GNUPGHOME that was used. -- daemons started for the GNUPGHOME that was used.
-- Older gpg may not support this, so ignore failure. -- Older gpg may not support this, so ignore failure.
stopgpgagent = whenM (inPath "gpgconf") $ stopgpgagent = whenM (inSearchPath "gpgconf") $
void $ boolSystem "gpgconf" [Param "--kill", Param "all"] void $ boolSystem "gpgconf" [Param "--kill", Param "all"]
go (Just _) = Just <$> a go (Just _) = Just <$> a

View file

@ -169,4 +169,4 @@ runWormHoleProcess p consumer =
ExitFailure _ -> False ExitFailure _ -> False
isInstalled :: IO Bool isInstalled :: IO Bool
isInstalled = inPath "wormhole" isInstalled = inSearchPath "wormhole"

View file

@ -18,11 +18,12 @@ module Utility.Path (
segmentPaths', segmentPaths',
runSegmentPaths, runSegmentPaths,
runSegmentPaths', runSegmentPaths',
inPath,
searchPath,
dotfile, dotfile,
splitShortExtensions, splitShortExtensions,
relPathDirToFileAbs, relPathDirToFileAbs,
inSearchPath,
searchPath,
searchPathContents,
) where ) where
import System.FilePath.ByteString import System.FilePath.ByteString
@ -35,6 +36,7 @@ import Prelude
import Utility.Monad import Utility.Monad
import Utility.SystemDirectory import Utility.SystemDirectory
import Utility.Exception
#ifdef mingw32_HOST_OS #ifdef mingw32_HOST_OS
import Data.Char import Data.Char
@ -136,33 +138,6 @@ runSegmentPaths c a paths = segmentPaths c paths <$> a paths
runSegmentPaths' :: (Maybe RawFilePath -> a -> r) -> (a -> RawFilePath) -> ([RawFilePath] -> IO [a]) -> [RawFilePath] -> IO [[r]] runSegmentPaths' :: (Maybe RawFilePath -> a -> r) -> (a -> RawFilePath) -> ([RawFilePath] -> IO [a]) -> [RawFilePath] -> IO [[r]]
runSegmentPaths' si c a paths = segmentPaths' si c paths <$> a paths runSegmentPaths' si c a paths = segmentPaths' si c paths <$> a paths
{- Checks if a command is available in PATH.
-
- The command may be fully-qualified, in which case, this succeeds as
- long as it exists. -}
inPath :: String -> IO Bool
inPath command = isJust <$> searchPath command
{- Finds a command in PATH and returns the full path to it.
-
- The command may be fully qualified already, in which case it will
- be returned if it exists.
-
- Note that this will find commands in PATH that are not executable.
-}
searchPath :: String -> IO (Maybe FilePath)
searchPath command
| P.isAbsolute command = check command
| otherwise = P.getSearchPath >>= getM indir
where
indir d = check $ d P.</> command
check f = firstM doesFileExist
#ifdef mingw32_HOST_OS
[f, f ++ ".exe"]
#else
[f]
#endif
{- Checks if a filename is a unix dotfile. All files inside dotdirs {- Checks if a filename is a unix dotfile. All files inside dotdirs
- count as dotfiles. -} - count as dotfiles. -}
dotfile :: RawFilePath -> Bool dotfile :: RawFilePath -> Bool
@ -213,3 +188,39 @@ relPathDirToFileAbs from to
#ifdef mingw32_HOST_OS #ifdef mingw32_HOST_OS
normdrive = map toLower . takeWhile (/= ':') . fromRawFilePath . takeDrive normdrive = map toLower . takeWhile (/= ':') . fromRawFilePath . takeDrive
#endif #endif
{- Checks if a command is available in PATH.
-
- The command may be fully-qualified, in which case, this succeeds as
- long as it exists. -}
inSearchPath :: String -> IO Bool
inSearchPath command = isJust <$> searchPath command
{- Finds a command in PATH and returns the full path to it.
-
- The command may be fully qualified already, in which case it will
- be returned if it exists.
-
- Note that this will find commands in PATH that are not executable.
-}
searchPath :: String -> IO (Maybe FilePath)
searchPath command
| P.isAbsolute command = check command
| otherwise = P.getSearchPath >>= getM indir
where
indir d = check $ d P.</> command
check f = firstM doesFileExist
#ifdef mingw32_HOST_OS
[f, f ++ ".exe"]
#else
[f]
#endif
{- Finds commands in PATH that match a predicate. Note that the predicate
- matches on the basename of the command, but the full path to it is
- returned. -}
searchPathContents :: (FilePath -> Bool) -> IO [FilePath]
searchPathContents p = concat <$> (P.getSearchPath >>= mapM go)
where
go d = map (d P.</>) . filter p
<$> catchDefaultIO [] (getDirectoryContents d)

View file

@ -46,11 +46,11 @@ findShellCommand f = do
[] -> defcmd [] -> defcmd
(c:ps) -> do (c:ps) -> do
let ps' = map Param ps ++ [File f] let ps' = map Param ps ++ [File f]
-- If the command is not inPath, -- If the command is not inSearchPath,
-- take the base of it, and run eg "sh" -- take the base of it, and run eg "sh"
-- which in some cases on windows will work -- which in some cases on windows will work
-- despite it not being inPath. -- despite it not being inSearchPath.
ok <- inPath c ok <- inSearchPath c
return (if ok then c else takeFileName c, ps') return (if ok then c else takeFileName c, ps')
_ -> defcmd _ -> defcmd
#endif #endif

View file

@ -71,7 +71,7 @@ mkSuCommand :: String -> [CommandParam] -> IO (Maybe SuCommand)
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
mkSuCommand cmd ps = do mkSuCommand cmd ps = do
pwd <- getCurrentDirectory pwd <- getCurrentDirectory
firstM (\(SuCommand _ p _) -> inPath p) =<< selectcmds pwd firstM (\(SuCommand _ p _) -> inSearchPath p) =<< selectcmds pwd
where where
selectcmds pwd = ifM (inx <||> (not <$> atconsole)) selectcmds pwd = ifM (inx <||> (not <$> atconsole))
( return (graphicalcmds pwd ++ consolecmds pwd) ( return (graphicalcmds pwd ++ consolecmds pwd)

View file

@ -191,4 +191,4 @@ varLibDir :: FilePath
varLibDir = "/var/lib" varLibDir = "/var/lib"
torIsInstalled :: IO Bool torIsInstalled :: IO Bool
torIsInstalled = inPath "tor" torIsInstalled = inSearchPath "tor"