more OsPath conversion (542/749)

Sponsored-by: Luke T. Shumaker
This commit is contained in:
Joey Hess 2025-02-06 11:38:14 -04:00
parent 0d2b805806
commit 0811531b59
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
13 changed files with 127 additions and 116 deletions

View file

@ -144,8 +144,7 @@ noDaemonRunning :: Command -> Command
noDaemonRunning = addCheck NoDaemonRunning $ whenM (isJust <$> daemonpid) $ noDaemonRunning = addCheck NoDaemonRunning $ whenM (isJust <$> daemonpid) $
giveup "You cannot run this command while git-annex watch or git-annex assistant is running." giveup "You cannot run this command while git-annex watch or git-annex assistant is running."
where where
daemonpid = liftIO . checkDaemon . fromRawFilePath daemonpid = liftIO . checkDaemon =<< fromRepo gitAnnexPidFile
=<< fromRepo gitAnnexPidFile
dontCheck :: CommandCheck -> Command -> Command dontCheck :: CommandCheck -> Command -> Command
dontCheck check cmd = mutateCheck cmd $ \c -> filter (/= check) c dontCheck check cmd = mutateCheck cmd $ \c -> filter (/= check) c

View file

@ -39,12 +39,12 @@ seeker fast = AnnexedFileSeeker
, usesLocationLog = False , usesLocationLog = False
} }
start :: Bool -> SeekInput -> RawFilePath -> Key -> CommandStart start :: Bool -> SeekInput -> OsPath -> Key -> CommandStart
start fast si file key = start fast si file key =
starting "unannex" (mkActionItem (key, file)) si $ starting "unannex" (mkActionItem (key, file)) si $
perform fast file key perform fast file key
perform :: Bool -> RawFilePath -> Key -> CommandPerform perform :: Bool -> OsPath -> Key -> CommandPerform
perform fast file key = do perform fast file key = do
Annex.Queue.addCommand [] "rm" Annex.Queue.addCommand [] "rm"
[ Param "--cached" [ Param "--cached"
@ -52,7 +52,7 @@ perform fast file key = do
, Param "--quiet" , Param "--quiet"
, Param "--" , Param "--"
] ]
[fromRawFilePath file] [fromOsPath file]
isAnnexLink file >>= \case isAnnexLink file >>= \case
-- If the file is locked, it needs to be replaced with -- If the file is locked, it needs to be replaced with
-- the content from the annex. Note that it's possible -- the content from the annex. Note that it's possible
@ -73,9 +73,9 @@ perform fast file key = do
maybe noop Database.Keys.removeInodeCache maybe noop Database.Keys.removeInodeCache
=<< withTSDelta (liftIO . genInodeCache file) =<< withTSDelta (liftIO . genInodeCache file)
cleanup :: Bool -> RawFilePath -> Key -> CommandCleanup cleanup :: Bool -> OsPath -> Key -> CommandCleanup
cleanup fast file key = do cleanup fast file key = do
liftIO $ removeFile (fromRawFilePath file) liftIO $ removeFile file
src <- calcRepo (gitAnnexLocation key) src <- calcRepo (gitAnnexLocation key)
ifM (pure fast <||> Annex.getRead Annex.fast) ifM (pure fast <||> Annex.getRead Annex.fast)
( do ( do
@ -83,7 +83,7 @@ cleanup fast file key = do
-- already have other hard links pointing at it. This -- already have other hard links pointing at it. This
-- avoids unannexing (and uninit) ending up hard -- avoids unannexing (and uninit) ending up hard
-- linking files together, which would be surprising. -- linking files together, which would be surprising.
s <- liftIO $ R.getFileStatus src s <- liftIO $ R.getFileStatus (fromOsPath src)
if linkCount s > 1 if linkCount s > 1
then copyfrom src then copyfrom src
else hardlinkfrom src else hardlinkfrom src
@ -91,13 +91,14 @@ cleanup fast file key = do
) )
where where
copyfrom src = copyfrom src =
thawContent file `after` liftIO thawContent file `after`
(copyFileExternal CopyAllMetaData liftIO (copyFileExternal CopyAllMetaData src file)
(fromRawFilePath src)
(fromRawFilePath file))
hardlinkfrom src = hardlinkfrom src =
-- creating a hard link could fall; fall back to copying -- creating a hard link could fall; fall back to copying
ifM (liftIO $ catchBoolIO $ R.createLink src file >> return True) ifM (liftIO $ tryhardlink src file)
( return True ( return True
, copyfrom src , copyfrom src
) )
tryhardlink src dest = catchBoolIO $ do
R.createLink (fromOsPath src) (fromOsPath dest)
return True

View file

@ -18,7 +18,6 @@ import qualified Annex
import qualified Git.LsFiles as LsFiles import qualified Git.LsFiles as LsFiles
import qualified Git.Command as Git import qualified Git.Command as Git
import qualified Git.Branch import qualified Git.Branch
import qualified Utility.RawFilePath as R
cmd :: Command cmd :: Command
cmd = notBareRepo $ withAnnexOptions [jsonOptions] $ cmd = notBareRepo $ withAnnexOptions [jsonOptions] $
@ -30,7 +29,7 @@ seek :: CmdParams -> CommandSeek
seek ps = do seek ps = do
-- Safety first; avoid any undo that would touch files that are not -- Safety first; avoid any undo that would touch files that are not
-- in the index. -- in the index.
(fs, cleanup) <- inRepo $ LsFiles.notInRepo [] False (map toRawFilePath ps) (fs, cleanup) <- inRepo $ LsFiles.notInRepo [] False (map toOsPath ps)
unless (null fs) $ do unless (null fs) $ do
qp <- coreQuotePath <$> Annex.getGitConfig qp <- coreQuotePath <$> Annex.getGitConfig
giveup $ decodeBS $ quote qp $ giveup $ decodeBS $ quote qp $
@ -48,19 +47,20 @@ seek ps = do
start :: FilePath -> CommandStart start :: FilePath -> CommandStart
start p = starting "undo" ai si $ start p = starting "undo" ai si $
perform p perform p'
where where
ai = ActionItemOther (Just (QuotedPath (toRawFilePath p))) p' = toOsPath p
ai = ActionItemOther (Just (QuotedPath p'))
si = SeekInput [p] si = SeekInput [p]
perform :: FilePath -> CommandPerform perform :: OsPath -> CommandPerform
perform p = do perform p = do
g <- gitRepo g <- gitRepo
-- Get the reversed diff that needs to be applied to undo. -- Get the reversed diff that needs to be applied to undo.
(diff, cleanup) <- inRepo $ (diff, cleanup) <- inRepo $
diffLog [Param "-R", Param "--", Param p] diffLog [Param "-R", Param "--", Param (fromOsPath p)]
top <- inRepo $ toTopFilePath $ toRawFilePath p top <- inRepo $ toTopFilePath p
let diff' = filter (`isDiffOf` top) diff let diff' = filter (`isDiffOf` top) diff
liftIO $ streamUpdateIndex g (map stageDiffTreeItem diff') liftIO $ streamUpdateIndex g (map stageDiffTreeItem diff')
@ -73,10 +73,10 @@ perform p = do
forM_ removals $ \di -> do forM_ removals $ \di -> do
f <- mkrel di f <- mkrel di
liftIO $ removeWhenExistsWith R.removeLink f liftIO $ removeWhenExistsWith removeFile f
forM_ adds $ \di -> do forM_ adds $ \di -> do
f <- fromRawFilePath <$> mkrel di f <- fromOsPath <$> mkrel di
inRepo $ Git.run [Param "checkout", Param "--", File f] inRepo $ Git.run [Param "checkout", Param "--", File f]
next $ liftIO cleanup next $ liftIO cleanup

View file

@ -73,7 +73,7 @@ checkCanUninit recordok =
when (b == Just Annex.Branch.name) $ giveup $ when (b == Just Annex.Branch.name) $ giveup $
"cannot uninit when the " ++ Git.fromRef Annex.Branch.name ++ " branch is checked out" "cannot uninit when the " ++ Git.fromRef Annex.Branch.name ++ " branch is checked out"
top <- fromRepo Git.repoPath top <- fromRepo Git.repoPath
currdir <- liftIO R.getCurrentDirectory currdir <- liftIO getCurrentDirectory
whenM ((/=) <$> liftIO (absPath top) <*> liftIO (absPath currdir)) $ whenM ((/=) <$> liftIO (absPath top) <*> liftIO (absPath currdir)) $
giveup "can only run uninit from the top of the git repository" giveup "can only run uninit from the top of the git repository"
@ -87,14 +87,14 @@ checkCanUninit recordok =
{- git annex symlinks that are not checked into git could be left by an {- git annex symlinks that are not checked into git could be left by an
- interrupted add. -} - interrupted add. -}
startCheckIncomplete :: Annex () -> RawFilePath -> Key -> CommandStart startCheckIncomplete :: Annex () -> OsPath -> Key -> CommandStart
startCheckIncomplete recordnotok file key = startCheckIncomplete recordnotok file key =
starting "uninit check" (mkActionItem (file, key)) (SeekInput []) $ do starting "uninit check" (mkActionItem (file, key)) (SeekInput []) $ do
recordnotok recordnotok
giveup $ unlines err giveup $ unlines err
where where
err = err =
[ fromRawFilePath file ++ " points to annexed content, but is not checked into git." [ fromOsPath file ++ " points to annexed content, but is not checked into git."
, "Perhaps this was left behind by an interrupted git annex add?" , "Perhaps this was left behind by an interrupted git annex add?"
, "Not continuing with uninit; either delete or git annex add the file and retry." , "Not continuing with uninit; either delete or git annex add the file and retry."
] ]
@ -109,11 +109,11 @@ removeAnnexDir recordok = do
prepareRemoveAnnexDir annexdir prepareRemoveAnnexDir annexdir
if null leftovers if null leftovers
then do then do
liftIO $ removeDirectoryRecursive (fromRawFilePath annexdir) liftIO $ removeDirectoryRecursive annexdir
next recordok next recordok
else giveup $ unlines else giveup $ unlines
[ "Not fully uninitialized" [ "Not fully uninitialized"
, "Some annexed data is still left in " ++ fromRawFilePath annexobjectdir , "Some annexed data is still left in " ++ fromOsPath annexobjectdir
, "This may include deleted files, or old versions of modified files." , "This may include deleted files, or old versions of modified files."
, "" , ""
, "If you don't care about preserving the data, just delete the" , "If you don't care about preserving the data, just delete the"
@ -134,12 +134,12 @@ removeAnnexDir recordok = do
- -
- Also closes sqlite databases that might be in the directory, - Also closes sqlite databases that might be in the directory,
- to avoid later failure to write any cached changes to them. -} - to avoid later failure to write any cached changes to them. -}
prepareRemoveAnnexDir :: RawFilePath -> Annex () prepareRemoveAnnexDir :: OsPath -> Annex ()
prepareRemoveAnnexDir annexdir = do prepareRemoveAnnexDir annexdir = do
Database.Keys.closeDb Database.Keys.closeDb
liftIO $ prepareRemoveAnnexDir' annexdir liftIO $ prepareRemoveAnnexDir' annexdir
prepareRemoveAnnexDir' :: RawFilePath -> IO () prepareRemoveAnnexDir' :: OsPath -> IO ()
prepareRemoveAnnexDir' annexdir = prepareRemoveAnnexDir' annexdir =
emptyWhenDoesNotExist (dirTreeRecursiveSkipping (const False) annexdir) emptyWhenDoesNotExist (dirTreeRecursiveSkipping (const False) annexdir)
>>= mapM_ (void . tryIO . allowWrite) >>= mapM_ (void . tryIO . allowWrite)
@ -159,7 +159,7 @@ removeUnannexed = go []
, go (k:c) ks , go (k:c) ks
) )
enoughlinks f = catchBoolIO $ do enoughlinks f = catchBoolIO $ do
s <- R.getFileStatus f s <- R.getFileStatus (fromOsPath f)
return $ linkCount s > 1 return $ linkCount s > 1
completeUnitialize :: CommandStart completeUnitialize :: CommandStart

View file

@ -40,7 +40,7 @@ seek ps = withFilesInGitAnnex ww seeker =<< workTreeItems ww ps
, usesLocationLog = False , usesLocationLog = False
} }
start :: SeekInput -> RawFilePath -> Key -> CommandStart start :: SeekInput -> OsPath -> Key -> CommandStart
start si file key = ifM (isJust <$> isAnnexLink file) start si file key = ifM (isJust <$> isAnnexLink file)
( starting "unlock" ai si $ perform file key ( starting "unlock" ai si $ perform file key
, stop , stop
@ -48,9 +48,9 @@ start si file key = ifM (isJust <$> isAnnexLink file)
where where
ai = mkActionItem (key, AssociatedFile (Just file)) ai = mkActionItem (key, AssociatedFile (Just file))
perform :: RawFilePath -> Key -> CommandPerform perform :: OsPath -> Key -> CommandPerform
perform dest key = do perform dest key = do
destmode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus dest destmode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus (fromOsPath dest)
destic <- replaceWorkTreeFile dest $ \tmp -> do destic <- replaceWorkTreeFile dest $ \tmp -> do
ifM (inAnnex key) ifM (inAnnex key)
( do ( do
@ -64,7 +64,7 @@ perform dest key = do
withTSDelta (liftIO . genInodeCache tmp) withTSDelta (liftIO . genInodeCache tmp)
next $ cleanup dest destic key destmode next $ cleanup dest destic key destmode
cleanup :: RawFilePath -> Maybe InodeCache -> Key -> Maybe FileMode -> CommandCleanup cleanup :: OsPath -> Maybe InodeCache -> Key -> Maybe FileMode -> CommandCleanup
cleanup dest destic key destmode = do cleanup dest destic key destmode = do
stagePointerFile dest destmode =<< hashPointerFile key stagePointerFile dest destmode =<< hashPointerFile key
maybe noop (restagePointerFile (Restage True) dest) destic maybe noop (restagePointerFile (Restage True) dest) destic

View file

@ -119,7 +119,7 @@ check fileprefix msg a c = do
maybeAddJSONField maybeAddJSONField
((if null fileprefix then "unused" else fileprefix) ++ "-list") ((if null fileprefix then "unused" else fileprefix) ++ "-list")
(M.fromList $ map (\(n, k) -> (T.pack (show n), serializeKey k)) unusedlist) (M.fromList $ map (\(n, k) -> (T.pack (show n), serializeKey k)) unusedlist)
updateUnusedLog (toRawFilePath fileprefix) (M.fromList unusedlist) updateUnusedLog (toOsPath fileprefix) (M.fromList unusedlist)
return $ c + length l return $ c + length l
number :: Int -> [a] -> [(Int, a)] number :: Int -> [a] -> [(Int, a)]
@ -194,7 +194,7 @@ excludeReferenced refspec ks = runbloomfilter withKeysReferencedM ks
{- Given an initial value, accumulates the value over each key {- Given an initial value, accumulates the value over each key
- referenced by files in the working tree. -} - referenced by files in the working tree. -}
withKeysReferenced :: v -> (Key -> RawFilePath -> v -> Annex v) -> Annex v withKeysReferenced :: v -> (Key -> OsPath -> v -> Annex v) -> Annex v
withKeysReferenced initial = withKeysReferenced' Nothing initial withKeysReferenced initial = withKeysReferenced' Nothing initial
{- Runs an action on each referenced key in the working tree. -} {- Runs an action on each referenced key in the working tree. -}
@ -204,10 +204,10 @@ withKeysReferencedM a = withKeysReferenced' Nothing () calla
calla k _ _ = a k calla k _ _ = a k
{- Folds an action over keys and files referenced in a particular directory. -} {- Folds an action over keys and files referenced in a particular directory. -}
withKeysFilesReferencedIn :: FilePath -> v -> (Key -> RawFilePath -> v -> Annex v) -> Annex v withKeysFilesReferencedIn :: OsPath -> v -> (Key -> OsPath -> v -> Annex v) -> Annex v
withKeysFilesReferencedIn = withKeysReferenced' . Just withKeysFilesReferencedIn = withKeysReferenced' . Just
withKeysReferenced' :: Maybe FilePath -> v -> (Key -> RawFilePath -> v -> Annex v) -> Annex v withKeysReferenced' :: Maybe OsPath -> v -> (Key -> OsPath -> v -> Annex v) -> Annex v
withKeysReferenced' mdir initial a = do withKeysReferenced' mdir initial a = do
(files, clean) <- getfiles (files, clean) <- getfiles
r <- go initial files r <- go initial files
@ -221,7 +221,7 @@ withKeysReferenced' mdir initial a = do
top <- fromRepo Git.repoPath top <- fromRepo Git.repoPath
inRepo $ LsFiles.allFiles [] [top] inRepo $ LsFiles.allFiles [] [top]
) )
Just dir -> inRepo $ LsFiles.inRepo [] [toRawFilePath dir] Just dir -> inRepo $ LsFiles.inRepo [] [dir]
go v [] = return v go v [] = return v
go v (f:fs) = do go v (f:fs) = do
mk <- lookupKey f mk <- lookupKey f
@ -308,9 +308,9 @@ data UnusedMaps = UnusedMaps
withUnusedMaps :: (UnusedMaps -> Int -> CommandStart) -> CmdParams -> CommandSeek withUnusedMaps :: (UnusedMaps -> Int -> CommandStart) -> CmdParams -> CommandSeek
withUnusedMaps a params = do withUnusedMaps a params = do
unused <- readUnusedMap "" unused <- readUnusedMap (literalOsPath "")
unusedbad <- readUnusedMap "bad" unusedbad <- readUnusedMap (literalOsPath "bad")
unusedtmp <- readUnusedMap "tmp" unusedtmp <- readUnusedMap (literalOsPath "tmp")
let m = unused `M.union` unusedbad `M.union` unusedtmp let m = unused `M.union` unusedbad `M.union` unusedtmp
let unusedmaps = UnusedMaps unused unusedbad unusedtmp let unusedmaps = UnusedMaps unused unusedbad unusedtmp
commandActions $ map (a unusedmaps) $ concatMap (unusedSpec m) params commandActions $ map (a unusedmaps) $ concatMap (unusedSpec m) params

View file

@ -34,7 +34,6 @@ import Types.NumCopies
import Remote import Remote
import Git.Types (fromConfigKey, fromConfigValue) import Git.Types (fromConfigKey, fromConfigValue)
import Utility.DataUnits import Utility.DataUnits
import qualified Utility.RawFilePath as R
import qualified Utility.FileIO as F import qualified Utility.FileIO as F
cmd :: Command cmd :: Command
@ -47,30 +46,35 @@ seek = withNothing (commandAction start)
start :: CommandStart start :: CommandStart
start = do start = do
f <- fromRepo gitAnnexTmpCfgFile f <- fromRepo gitAnnexTmpCfgFile
let f' = fromRawFilePath f
createAnnexDirectory $ parentDir f createAnnexDirectory $ parentDir f
cfg <- getCfg cfg <- getCfg
descs <- uuidDescriptions descs <- uuidDescriptions
liftIO $ writeFile f' $ genCfg cfg descs liftIO $ writeFile (fromOsPath f) $ genCfg cfg descs
vicfg cfg f' vicfg cfg f
stop stop
vicfg :: Cfg -> FilePath -> Annex () vicfg :: Cfg -> OsPath -> Annex ()
vicfg curcfg f = do vicfg curcfg f = do
vi <- liftIO $ catchDefaultIO "vi" $ getEnv "EDITOR" vi <- liftIO $ catchDefaultIO "vi" $ getEnv "EDITOR"
-- Allow EDITOR to be processed by the shell, so it can contain options. unlessM (liftIO $ boolSystem "sh" (shparams vi)) $
unlessM (liftIO $ boolSystem "sh" [Param "-c", Param $ unwords [vi, shellEscape f]]) $
giveup $ vi ++ " exited nonzero; aborting" giveup $ vi ++ " exited nonzero; aborting"
r <- liftIO $ parseCfg (defCfg curcfg) r <- liftIO $ parseCfg (defCfg curcfg)
. map decodeBS . map decodeBS
. fileLines' . fileLines'
<$> F.readFile' (toOsPath (toRawFilePath f)) <$> F.readFile' f
liftIO $ removeWhenExistsWith R.removeLink (toRawFilePath f) liftIO $ removeWhenExistsWith removeFile f
case r of case r of
Left s -> do Left s -> do
liftIO $ writeFile f s liftIO $ writeFile (fromOsPath f) s
vicfg curcfg f vicfg curcfg f
Right newcfg -> setCfg curcfg newcfg Right newcfg -> setCfg curcfg newcfg
where
-- Allow EDITOR to be processed by the shell,
-- so it can contain options.
shparams editor =
[ Param "-c"
, Param $ unwords [editor, shellEscape (fromOsPath f)]
]
data Cfg = Cfg data Cfg = Cfg
{ cfgTrustMap :: M.Map UUID (Down TrustLevel) { cfgTrustMap :: M.Map UUID (Down TrustLevel)

View file

@ -24,8 +24,6 @@ import Logs.View
import Types.AdjustedBranch import Types.AdjustedBranch
import Annex.AdjustedBranch.Name import Annex.AdjustedBranch.Name
import qualified System.FilePath.ByteString as P
cmd :: Command cmd :: Command
cmd = notBareRepo $ cmd = notBareRepo $
command "view" SectionMetaData "enter a view branch" command "view" SectionMetaData "enter a view branch"
@ -120,13 +118,12 @@ checkoutViewBranch view madj mkbranch = do
forM_ l (removeemptydir top) forM_ l (removeemptydir top)
liftIO $ void cleanup liftIO $ void cleanup
unlessM (liftIO $ doesDirectoryExist here) $ do unlessM (liftIO $ doesDirectoryExist here) $ do
showLongNote $ UnquotedString $ cwdmissing (fromRawFilePath top) showLongNote $ UnquotedString $ cwdmissing (fromOsPath top)
return ok return ok
where where
removeemptydir top d = do removeemptydir top d = do
p <- inRepo $ toTopFilePath d p <- inRepo $ toTopFilePath d
liftIO $ tryIO $ removeDirectory $ liftIO $ tryIO $ removeDirectory $ top </> getTopFilePath p
fromRawFilePath $ (top P.</> getTopFilePath p)
cwdmissing top = unlines cwdmissing top = unlines
[ "This view does not include the subdirectory you are currently in." [ "This view does not include the subdirectory you are currently in."
, "Perhaps you should: cd " ++ top , "Perhaps you should: cd " ++ top

View file

@ -124,7 +124,7 @@ findHistorical key = do
display key (descBranchFilePath (BranchFilePath r tf)) display key (descBranchFilePath (BranchFilePath r tf))
return True return True
searchLog :: Key -> [CommandParam] -> (S.ByteString -> [RawFilePath] -> Annex Bool) -> Annex Bool searchLog :: Key -> [CommandParam] -> (S.ByteString -> [OsPath] -> Annex Bool) -> Annex Bool
searchLog key ps a = do searchLog key ps a = do
(output, cleanup) <- Annex.inRepo $ Git.Command.pipeNullSplit ps' (output, cleanup) <- Annex.inRepo $ Git.Command.pipeNullSplit ps'
found <- case output of found <- case output of
@ -154,7 +154,7 @@ searchLog key ps a = do
-- so a regexp is used. Since annex pointer files -- so a regexp is used. Since annex pointer files
-- may contain a newline followed by perhaps something -- may contain a newline followed by perhaps something
-- else, that is also matched. -- else, that is also matched.
, Param ("-G" ++ escapeRegexp (fromRawFilePath (keyFile key)) ++ "($|\n)") , Param ("-G" ++ escapeRegexp (fromOsPath (keyFile key)) ++ "($|\n)")
-- Skip commits where the file was deleted, -- Skip commits where the file was deleted,
-- only find those where it was added or modified. -- only find those where it was added or modified.
, Param "--diff-filter=ACMRTUX" , Param "--diff-filter=ACMRTUX"

View file

@ -107,6 +107,9 @@ instance FromConfigValue S.ByteString where
instance FromConfigValue String where instance FromConfigValue String where
fromConfigValue = decodeBS . fromConfigValue fromConfigValue = decodeBS . fromConfigValue
instance FromConfigValue OsPath where
fromConfigValue v = toOsPath (fromConfigValue v :: S.ByteString)
instance Show ConfigValue where instance Show ConfigValue where
show = fromConfigValue show = fromConfigValue

View file

@ -66,6 +66,7 @@ import qualified Utility.Tmp.Dir
import qualified Utility.Metered import qualified Utility.Metered
import qualified Utility.HumanTime import qualified Utility.HumanTime
import qualified Command.Uninit import qualified Command.Uninit
import qualified Utility.OsString as OS
-- Run a process. The output and stderr is captured, and is only -- Run a process. The output and stderr is captured, and is only
-- displayed if the process does not return the expected value. -- displayed if the process does not return the expected value.
@ -123,13 +124,14 @@ git_annex'' expectedret expectedtranscript command params environ faildesc = do
let params' = if debug let params' = if debug
then "--debug":params then "--debug":params
else params else params
testProcess pp (command:params') environ expectedret expectedtranscript faildesc testProcess (fromOsPath pp) (command:params') environ
expectedret expectedtranscript faildesc
{- Runs git-annex and returns its standard output. -} {- Runs git-annex and returns its standard output. -}
git_annex_output :: String -> [String] -> IO String git_annex_output :: String -> [String] -> IO String
git_annex_output command params = do git_annex_output command params = do
pp <- Annex.Path.programPath pp <- Annex.Path.programPath
Utility.Process.readProcess pp (command:params) Utility.Process.readProcess (fromOsPath pp) (command:params)
git_annex_expectoutput :: String -> [String] -> [String] -> Assertion git_annex_expectoutput :: String -> [String] -> [String] -> Assertion
git_annex_expectoutput command params expected = do git_annex_expectoutput command params expected = do
@ -159,7 +161,7 @@ with_ssh_origin cloner a = cloner $ do
let v = Git.Types.ConfigValue (toRawFilePath "/dev/null") let v = Git.Types.ConfigValue (toRawFilePath "/dev/null")
origindir <- absPath . Git.Types.fromConfigValue origindir <- absPath . Git.Types.fromConfigValue
=<< annexeval (Config.getConfig k v) =<< annexeval (Config.getConfig k v)
let originurl = "localhost:" ++ fromRawFilePath origindir let originurl = "localhost:" ++ fromOsPath origindir
git "config" [config, originurl] "git config failed" git "config" [config, originurl] "git config failed"
a a
where where
@ -170,7 +172,7 @@ intmpclonerepo a = withtmpclonerepo $ \r -> intopdir r a
checkRepo :: Types.Annex a -> FilePath -> IO a checkRepo :: Types.Annex a -> FilePath -> IO a
checkRepo getval d = do checkRepo getval d = do
s <- Annex.new =<< Git.Construct.fromPath (toRawFilePath d) s <- Annex.new =<< Git.Construct.fromPath (toOsPath d)
Annex.eval s $ Annex.eval s $
getval `finally` Annex.Action.stopCoProcesses getval `finally` Annex.Action.stopCoProcesses
@ -218,7 +220,7 @@ inpath path a = do
-- any type of error and change back to currdir before -- any type of error and change back to currdir before
-- rethrowing. -- rethrowing.
r <- bracket_ r <- bracket_
(setCurrentDirectory path) (setCurrentDirectory (toOsPath path))
(setCurrentDirectory currdir) (setCurrentDirectory currdir)
(tryNonAsync a) (tryNonAsync a)
case r of case r of
@ -295,17 +297,18 @@ configrepo dir = intopdir dir $ do
ensuredir :: FilePath -> IO () ensuredir :: FilePath -> IO ()
ensuredir d = do ensuredir d = do
e <- doesDirectoryExist d let d' = toOsPath d
e <- doesDirectoryExist d'
unless e $ unless e $
createDirectory d createDirectory d'
{- This is the only place in the test suite that can use setEnv. {- This is the only place in the test suite that can use setEnv.
- Using it elsewhere can conflict with tasty's use of getEnv, which can - Using it elsewhere can conflict with tasty's use of getEnv, which can
- happen concurrently with a test case running, and would be a problem - happen concurrently with a test case running, and would be a problem
- since setEnv is not thread safe. This is run before tasty. -} - since setEnv is not thread safe. This is run before tasty. -}
setTestEnv :: IO a -> IO a setTestEnv :: IO a -> IO a
setTestEnv a = Utility.Tmp.Dir.withTmpDir (toOsPath "testhome") $ \tmphome -> do setTestEnv a = Utility.Tmp.Dir.withTmpDir (literalOsPath "testhome") $ \tmphome -> do
tmphomeabs <- fromRawFilePath <$> absPath (toRawFilePath tmphome) tmphomeabs <- fromOsPath <$> absPath tmphome
{- Prevent global git configs from affecting the test suite. -} {- Prevent global git configs from affecting the test suite. -}
Utility.Env.Set.setEnv "HOME" tmphomeabs True Utility.Env.Set.setEnv "HOME" tmphomeabs True
Utility.Env.Set.setEnv "XDG_CONFIG_HOME" tmphomeabs True Utility.Env.Set.setEnv "XDG_CONFIG_HOME" tmphomeabs True
@ -313,9 +316,11 @@ setTestEnv a = Utility.Tmp.Dir.withTmpDir (toOsPath "testhome") $ \tmphome -> do
-- Ensure that the same git-annex binary that is running -- Ensure that the same git-annex binary that is running
-- git-annex test is at the front of the PATH. -- git-annex test is at the front of the PATH.
p <- Utility.Env.getEnvDefault "PATH" ""
pp <- Annex.Path.programPath pp <- Annex.Path.programPath
Utility.Env.Set.setEnv "PATH" (takeDirectory pp ++ [searchPathSeparator] ++ p) True p <- Utility.Env.getEnvDefault "PATH" ""
let p' = fromOsPath $
takeDirectory pp <> OS.singleton searchPathSeparator <> toOsPath p
Utility.Env.Set.setEnv "PATH" p' True
-- Avoid git complaining if it cannot determine the user's -- Avoid git complaining if it cannot determine the user's
-- email address, or exploding if it doesn't know the user's name. -- email address, or exploding if it doesn't know the user's name.
@ -332,34 +337,34 @@ setTestEnv a = Utility.Tmp.Dir.withTmpDir (toOsPath "testhome") $ \tmphome -> do
-- Record top directory. -- Record top directory.
currdir <- getCurrentDirectory currdir <- getCurrentDirectory
Utility.Env.Set.setEnv "TOPDIR" currdir True Utility.Env.Set.setEnv "TOPDIR" (fromOsPath currdir) True
a a
removeDirectoryForCleanup :: FilePath -> IO () removeDirectoryForCleanup :: FilePath -> IO ()
removeDirectoryForCleanup = removePathForcibly removeDirectoryForCleanup = removePathForcibly . toOsPath
cleanup :: FilePath -> IO () cleanup :: FilePath -> IO ()
cleanup dir = whenM (doesDirectoryExist dir) $ do cleanup dir = whenM (doesDirectoryExist (toOsPath dir)) $ do
Command.Uninit.prepareRemoveAnnexDir' (toRawFilePath dir) Command.Uninit.prepareRemoveAnnexDir' (toOsPath dir)
-- This can fail if files in the directory are still open by a -- This can fail if files in the directory are still open by a
-- subprocess. -- subprocess.
void $ tryIO $ removeDirectoryForCleanup dir void $ tryIO $ removeDirectoryForCleanup dir
finalCleanup :: IO () finalCleanup :: IO ()
finalCleanup = whenM (doesDirectoryExist tmpdir) $ do finalCleanup = whenM (doesDirectoryExist (toOsPath tmpdir)) $ do
Command.Uninit.prepareRemoveAnnexDir' (toRawFilePath tmpdir) Command.Uninit.prepareRemoveAnnexDir' (toOsPath tmpdir)
catchIO (removeDirectoryForCleanup tmpdir) $ \e -> do catchIO (removeDirectoryForCleanup tmpdir) $ \e -> do
print e print e
putStrLn "sleeping 10 seconds and will retry directory cleanup" putStrLn "sleeping 10 seconds and will retry directory cleanup"
Utility.ThreadScheduler.threadDelaySeconds $ Utility.ThreadScheduler.threadDelaySeconds $
Utility.ThreadScheduler.Seconds 10 Utility.ThreadScheduler.Seconds 10
whenM (doesDirectoryExist tmpdir) $ whenM (doesDirectoryExist (toOsPath tmpdir)) $
removeDirectoryForCleanup tmpdir removeDirectoryForCleanup tmpdir
checklink :: FilePath -> Assertion checklink :: FilePath -> Assertion
checklink f = ifM (annexeval Config.crippledFileSystem) checklink f = ifM (annexeval Config.crippledFileSystem)
( (isJust <$> annexeval (Annex.Link.getAnnexLinkTarget (toRawFilePath f))) ( (isJust <$> annexeval (Annex.Link.getAnnexLinkTarget (toOsPath f)))
@? f ++ " is not a (crippled) symlink" @? f ++ " is not a (crippled) symlink"
, do , do
s <- R.getSymbolicLinkStatus (toRawFilePath f) s <- R.getSymbolicLinkStatus (toRawFilePath f)
@ -417,7 +422,7 @@ checkdangling f = ifM (annexeval Config.crippledFileSystem)
checklocationlog :: FilePath -> Bool -> Assertion checklocationlog :: FilePath -> Bool -> Assertion
checklocationlog f expected = do checklocationlog f expected = do
thisuuid <- annexeval Annex.UUID.getUUID thisuuid <- annexeval Annex.UUID.getUUID
r <- annexeval $ Annex.WorkTree.lookupKey (toRawFilePath f) r <- annexeval $ Annex.WorkTree.lookupKey (toOsPath f)
case r of case r of
Just k -> do Just k -> do
uuids <- annexeval $ Remote.keyLocations k uuids <- annexeval $ Remote.keyLocations k
@ -428,11 +433,11 @@ checklocationlog f expected = do
checkbackend :: FilePath -> Types.Backend -> Assertion checkbackend :: FilePath -> Types.Backend -> Assertion
checkbackend file expected = do checkbackend file expected = do
b <- annexeval $ maybe (return Nothing) (Backend.getBackend file) b <- annexeval $ maybe (return Nothing) (Backend.getBackend file)
=<< Annex.WorkTree.lookupKey (toRawFilePath file) =<< Annex.WorkTree.lookupKey (toOsPath file)
assertEqual ("backend for " ++ file) (Just expected) b assertEqual ("backend for " ++ file) (Just expected) b
checkispointerfile :: FilePath -> Assertion checkispointerfile :: FilePath -> Assertion
checkispointerfile f = unlessM (isJust <$> Annex.Link.isPointerFile (toRawFilePath f)) $ checkispointerfile f = unlessM (isJust <$> Annex.Link.isPointerFile (toOsPath f)) $
assertFailure $ f ++ " is not a pointer file" assertFailure $ f ++ " is not a pointer file"
inlocationlog :: FilePath -> Assertion inlocationlog :: FilePath -> Assertion
@ -501,7 +506,7 @@ unannexed = runchecks [checkregularfile, checkcontent, checkwritable]
unannexed_in_git :: FilePath -> Assertion unannexed_in_git :: FilePath -> Assertion
unannexed_in_git f = do unannexed_in_git f = do
unannexed f unannexed f
r <- annexeval $ Annex.WorkTree.lookupKey (toRawFilePath f) r <- annexeval $ Annex.WorkTree.lookupKey (toOsPath f)
case r of case r of
Just _k -> assertFailure $ f ++ " is annexed in git" Just _k -> assertFailure $ f ++ " is annexed in git"
Nothing -> return () Nothing -> return ()
@ -585,10 +590,10 @@ newmainrepodir = go (0 :: Int)
where where
go n = do go n = do
let d = "main" ++ show n let d = "main" ++ show n
ifM (doesDirectoryExist d) ifM (doesDirectoryExist (toOsPath d))
( go $ n + 1 ( go $ n + 1
, do , do
createDirectory d createDirectory (toOsPath d)
return d return d
) )
@ -597,7 +602,7 @@ tmprepodir = go (0 :: Int)
where where
go n = do go n = do
let d = "tmprepo" ++ show n let d = "tmprepo" ++ show n
ifM (doesDirectoryExist d) ifM (doesDirectoryExist (toOsPath d))
( go $ n + 1 ( go $ n + 1
, return d , return d
) )
@ -637,9 +642,9 @@ writecontent :: FilePath -> String -> IO ()
writecontent f c = go (10000000 :: Integer) writecontent f c = go (10000000 :: Integer)
where where
go ticsleft = do go ticsleft = do
oldmtime <- catchMaybeIO $ getModificationTime f oldmtime <- catchMaybeIO $ getModificationTime (toOsPath f)
writeFile f c writeFile f c
newmtime <- getModificationTime f newmtime <- getModificationTime (toOsPath f)
if Just newmtime == oldmtime if Just newmtime == oldmtime
then do then do
threadDelay 100000 threadDelay 100000
@ -679,8 +684,8 @@ getKey b f = case Types.Backend.genKey b of
Nothing -> error "internal" Nothing -> error "internal"
where where
ks = Types.KeySource.KeySource ks = Types.KeySource.KeySource
{ Types.KeySource.keyFilename = toRawFilePath f { Types.KeySource.keyFilename = toOsPath f
, Types.KeySource.contentLocation = toRawFilePath f , Types.KeySource.contentLocation = toOsPath f
, Types.KeySource.inodeCache = Nothing , Types.KeySource.inodeCache = Nothing
} }
@ -799,7 +804,7 @@ parallelTestRunner' numjobs opts mkts
go Nothing = summarizeresults $ withConcurrentOutput $ do go Nothing = summarizeresults $ withConcurrentOutput $ do
ensuredir tmpdir ensuredir tmpdir
crippledfilesystem <- fst <$> Annex.Init.probeCrippledFileSystem' crippledfilesystem <- fst <$> Annex.Init.probeCrippledFileSystem'
(toRawFilePath tmpdir) (toOsPath tmpdir)
Nothing Nothing False Nothing Nothing False
adjustedbranchok <- Annex.AdjustedBranch.isGitVersionSupported adjustedbranchok <- Annex.AdjustedBranch.isGitVersionSupported
let ts = mkts numparts crippledfilesystem adjustedbranchok opts let ts = mkts numparts crippledfilesystem adjustedbranchok opts
@ -809,13 +814,13 @@ parallelTestRunner' numjobs opts mkts
mapM_ (hPutStrLn stderr) warnings mapM_ (hPutStrLn stderr) warnings
environ <- Utility.Env.getEnvironment environ <- Utility.Env.getEnvironment
args <- getArgs args <- getArgs
pp <- Annex.Path.programPath pp <- fromOsPath <$> Annex.Path.programPath
termcolor <- hSupportsANSIColor stdout termcolor <- hSupportsANSIColor stdout
let ps = if useColor (lookupOption tastyopts) termcolor let ps = if useColor (lookupOption tastyopts) termcolor
then "--color=always":args then "--color=always":args
else "--color=never":args else "--color=never":args
let runone n = do let runone n = do
let subdir = tmpdir </> show n let subdir = fromOsPath $ toOsPath tmpdir </> toOsPath (show n)
ensuredir subdir ensuredir subdir
let p = (proc pp ps) let p = (proc pp ps)
{ env = Just ((subenv, show (n, crippledfilesystem, adjustedbranchok)):environ) { env = Just ((subenv, show (n, crippledfilesystem, adjustedbranchok)):environ)

View file

@ -55,7 +55,7 @@ upgrade automatic
- run for an entire year and so predate the v9 upgrade. -} - run for an entire year and so predate the v9 upgrade. -}
assistantrunning = do assistantrunning = do
pidfile <- fromRepo gitAnnexPidFile pidfile <- fromRepo gitAnnexPidFile
isJust <$> liftIO (checkDaemon (fromOsPath pidfile)) isJust <$> liftIO (checkDaemon pidfile)
unsafeupgrade = unsafeupgrade =
[ "Not upgrading from v9 to v10, because there may be git-annex" [ "Not upgrading from v9 to v10, because there may be git-annex"

View file

@ -5,6 +5,7 @@
- License: BSD-2-clause - License: BSD-2-clause
-} -}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
module Utility.Daemon ( module Utility.Daemon (
@ -25,6 +26,7 @@ import Utility.OpenFd
#else #else
import System.Win32.Process (terminateProcessById) import System.Win32.Process (terminateProcessById)
import Utility.LockFile import Utility.LockFile
import qualified Utility.OsString as OS
#endif #endif
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
@ -42,7 +44,7 @@ import System.Posix hiding (getEnv, getEnvironment)
- Instead, it runs the cmd with provided params, in the background, - Instead, it runs the cmd with provided params, in the background,
- which the caller should arrange to run this again. - which the caller should arrange to run this again.
-} -}
daemonize :: String -> [CommandParam] -> IO Fd -> Maybe FilePath -> Bool -> IO () -> IO () daemonize :: String -> [CommandParam] -> IO Fd -> Maybe OsPath -> Bool -> IO () -> IO ()
daemonize cmd params openlogfd pidfile changedirectory a = do daemonize cmd params openlogfd pidfile changedirectory a = do
maybe noop checkalreadyrunning pidfile maybe noop checkalreadyrunning pidfile
getEnv envvar >>= \case getEnv envvar >>= \case
@ -70,10 +72,10 @@ daemonize cmd params openlogfd pidfile changedirectory a = do
{- To run an action that is normally daemonized in the foreground. -} {- To run an action that is normally daemonized in the foreground. -}
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
foreground :: IO Fd -> Maybe FilePath -> IO () -> IO () foreground :: IO Fd -> Maybe OsPath -> IO () -> IO ()
foreground openlogfd pidfile a = do foreground openlogfd pidfile a = do
#else #else
foreground :: Maybe FilePath -> IO () -> IO () foreground :: Maybe OsPath -> IO () -> IO ()
foreground pidfile a = do foreground pidfile a = do
#endif #endif
maybe noop lockPidFile pidfile maybe noop lockPidFile pidfile
@ -93,12 +95,12 @@ foreground pidfile a = do
- -
- Writes the pid to the file, fully atomically. - Writes the pid to the file, fully atomically.
- Fails if the pid file is already locked by another process. -} - Fails if the pid file is already locked by another process. -}
lockPidFile :: FilePath -> IO () lockPidFile :: OsPath -> IO ()
lockPidFile pidfile = do lockPidFile pidfile = do
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
fd <- openFdWithMode (toRawFilePath pidfile) ReadWrite (Just stdFileMode) defaultFileFlags fd <- openFdWithMode (fromOsPath pidfile) ReadWrite (Just stdFileMode) defaultFileFlags
locked <- catchMaybeIO $ setLock fd (WriteLock, AbsoluteSeek, 0, 0) locked <- catchMaybeIO $ setLock fd (WriteLock, AbsoluteSeek, 0, 0)
fd' <- openFdWithMode (toRawFilePath newfile) ReadWrite (Just stdFileMode) defaultFileFlags fd' <- openFdWithMode (fromOsPath newfile) ReadWrite (Just stdFileMode) defaultFileFlags
{ trunc = True } { trunc = True }
locked' <- catchMaybeIO $ setLock fd' (WriteLock, AbsoluteSeek, 0, 0) locked' <- catchMaybeIO $ setLock fd' (WriteLock, AbsoluteSeek, 0, 0)
case (locked, locked') of case (locked, locked') of
@ -107,17 +109,17 @@ lockPidFile pidfile = do
_ -> do _ -> do
_ <- fdWrite fd' =<< show <$> getPID _ <- fdWrite fd' =<< show <$> getPID
closeFd fd closeFd fd
rename newfile pidfile renameFile newfile pidfile
where where
newfile = pidfile ++ ".new" newfile = pidfile <> literalOsPath ".new"
#else #else
{- Not atomic on Windows, oh well. -} {- Not atomic on Windows, oh well. -}
unlessM (isNothing <$> checkDaemon pidfile) unlessM (isNothing <$> checkDaemon pidfile)
alreadyRunning alreadyRunning
pid <- getPID pid <- getPID
writeFile pidfile (show pid) writeFile (fromOsPath pidfile) (show pid)
lckfile <- winLockFile pid pidfile lckfile <- winLockFile pid pidfile
writeFile (fromRawFilePath lckfile) "" writeFile (fromOsPath lckfile) ""
void $ lockExclusive lckfile void $ lockExclusive lckfile
#endif #endif
@ -128,17 +130,17 @@ alreadyRunning = giveup "Daemon is already running."
- is locked by the same process that is listed in the pid file. - is locked by the same process that is listed in the pid file.
- -
- If it's running, returns its pid. -} - If it's running, returns its pid. -}
checkDaemon :: FilePath -> IO (Maybe PID) checkDaemon :: OsPath -> IO (Maybe PID)
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
checkDaemon pidfile = bracket setup cleanup go checkDaemon pidfile = bracket setup cleanup go
where where
setup = catchMaybeIO $ setup = catchMaybeIO $
openFdWithMode (toRawFilePath pidfile) ReadOnly (Just stdFileMode) defaultFileFlags openFdWithMode (fromOsPath pidfile) ReadOnly (Just stdFileMode) defaultFileFlags
cleanup (Just fd) = closeFd fd cleanup (Just fd) = closeFd fd
cleanup Nothing = return () cleanup Nothing = return ()
go (Just fd) = catchDefaultIO Nothing $ do go (Just fd) = catchDefaultIO Nothing $ do
locked <- getLock fd (ReadLock, AbsoluteSeek, 0, 0) locked <- getLock fd (ReadLock, AbsoluteSeek, 0, 0)
p <- readish <$> readFile pidfile p <- readish <$> readFile (fromOsPath pidfile)
return (check locked p) return (check locked p)
go Nothing = return Nothing go Nothing = return Nothing
@ -147,16 +149,16 @@ checkDaemon pidfile = bracket setup cleanup go
check (Just (pid, _)) (Just pid') check (Just (pid, _)) (Just pid')
| pid == pid' = Just pid | pid == pid' = Just pid
| otherwise = giveup $ | otherwise = giveup $
"stale pid in " ++ pidfile ++ "stale pid in " ++ fromOsPath pidfile ++
" (got " ++ show pid' ++ " (got " ++ show pid' ++
"; expected " ++ show pid ++ " )" "; expected " ++ show pid ++ " )"
#else #else
checkDaemon pidfile = maybe (return Nothing) (check . readish) checkDaemon pidfile = maybe (return Nothing) (check . readish)
=<< catchMaybeIO (readFile pidfile) =<< catchMaybeIO (readFile (fromOsPath pidfile))
where where
check Nothing = return Nothing check Nothing = return Nothing
check (Just pid) = do check (Just pid) = do
v <- lockShared =<< winLockFile pid pidfile v <- lockShared =<< winLockFile pid (fromOsPath pidfile)
case v of case v of
Just h -> do Just h -> do
dropLock h dropLock h
@ -165,7 +167,7 @@ checkDaemon pidfile = maybe (return Nothing) (check . readish)
#endif #endif
{- Stops the daemon, safely. -} {- Stops the daemon, safely. -}
stopDaemon :: FilePath -> IO () stopDaemon :: OsPath -> IO ()
stopDaemon pidfile = go =<< checkDaemon pidfile stopDaemon pidfile = go =<< checkDaemon pidfile
where where
go Nothing = noop go Nothing = noop
@ -181,14 +183,14 @@ stopDaemon pidfile = go =<< checkDaemon pidfile
- when eg, restarting the daemon. - when eg, restarting the daemon.
-} -}
#ifdef mingw32_HOST_OS #ifdef mingw32_HOST_OS
winLockFile :: PID -> FilePath -> IO RawFilePath winLockFile :: PID -> OsPath -> IO OsPath
winLockFile pid pidfile = do winLockFile pid pidfile = do
cleanstale cleanstale
return $ toRawFilePath $ prefix ++ show pid ++ suffix return $ prefix <> toOsPath (show pid) <> suffix
where where
prefix = pidfile ++ "." prefix = pidfile <> literalOsPath "."
suffix = ".lck" suffix = literalOsPath ".lck"
cleanstale = mapM_ (void . tryIO . removeFile) =<< cleanstale = mapM_ (void . tryIO . removeFile) =<<
(filter iswinlockfile . map fromRawFilePath <$> dirContents (parentDir (toRawFilePath pidfile))) (filter iswinlockfile <$> dirContents (parentDir pidfile))
iswinlockfile f = suffix `isSuffixOf` f && prefix `isPrefixOf` f iswinlockfile f = suffix `OS.isSuffixOf` f && prefix `OS.isPrefixOf` f
#endif #endif