more OsPath conversion

Git.Types now uses it, as does TopFilePath, making for plenty of new
compile errors needing fixing.

Sponsored-by: Brock Spratlen
This commit is contained in:
Joey Hess 2025-01-23 16:15:00 -04:00
parent 12660314f1
commit ea775baccd
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
22 changed files with 159 additions and 163 deletions

View file

@ -99,7 +99,7 @@ read' repo = go repo
global :: IO (Maybe Repo)
global = do
home <- myHomeDir
ifM (doesFileExist $ home </> ".gitconfig")
ifM (doesFileExist $ toOsPath home </> literalOsPath ".gitconfig")
( Just <$> withCreateProcess p go
, return Nothing
)
@ -153,22 +153,22 @@ store' k v repo = repo
-}
updateLocation :: Repo -> IO Repo
updateLocation r@(Repo { location = LocalUnknown d }) = case isBare r of
Just True -> ifM (doesDirectoryExist (fromRawFilePath dotgit))
Just True -> ifM (doesDirectoryExist dotgit)
( updateLocation' r $ Local dotgit Nothing
, updateLocation' r $ Local d Nothing
)
Just False -> mknonbare
{- core.bare not in config, probably because safe.directory
- did not allow reading the config -}
Nothing -> ifM (Git.Construct.isBareRepo (fromRawFilePath d))
Nothing -> ifM (Git.Construct.isBareRepo d)
( mkbare
, mknonbare
)
where
dotgit = d P.</> ".git"
dotgit = d </> literalOsPath ".git"
-- git treats eg ~/foo as a bare git repository located in
-- ~/foo/.git if ~/foo/.git/config has core.bare=true
mkbare = ifM (doesDirectoryExist (fromRawFilePath dotgit))
mkbare = ifM (doesDirectoryExist dotgit)
( updateLocation' r $ Local dotgit Nothing
, updateLocation' r $ Local d Nothing
)

View file

@ -176,43 +176,43 @@ fromRemoteLocation s knownurl repo = gen $ parseRemoteLocation s knownurl repo
fromRemotePath :: FilePath -> Repo -> IO Repo
fromRemotePath dir repo = do
dir' <- expandTilde dir
fromPath $ repoPath repo P.</> toRawFilePath dir'
fromPath $ repoPath repo P.</> dir'
{- Git remotes can have a directory that is specified relative
- to the user's home directory, or that contains tilde expansions.
- This converts such a directory to an absolute path.
- Note that it has to run on the system where the remote is.
-}
repoAbsPath :: RawFilePath -> IO RawFilePath
repoAbsPath :: OsPath -> IO OsPath
repoAbsPath d = do
d' <- expandTilde (fromRawFilePath d)
d' <- expandTilde (fromOsPath d)
h <- myHomeDir
return $ toRawFilePath $ h </> d'
return $ toOsPath h </> d'
expandTilde :: FilePath -> IO FilePath
expandTilde :: FilePath -> IO OsPath
#ifdef mingw32_HOST_OS
expandTilde = return
expandTilde = return . toOsPath
#else
expandTilde p = expandt True p
-- If unable to expand a tilde, eg due to a user not existing,
-- use the path as given.
`catchNonAsync` (const (return p))
`catchNonAsync` (const (return (toOsPath p)))
where
expandt _ [] = return ""
expandt _ [] = return $ literalOsPath ""
expandt _ ('/':cs) = do
v <- expandt True cs
return ('/':v)
return $ literalOsPath "/" <> v
expandt True ('~':'/':cs) = do
h <- myHomeDir
return $ h </> cs
expandt True "~" = myHomeDir
return $ toOsPath h </> toOsPath cs
expandt True "~" = toOsPath <$> myHomeDir
expandt True ('~':cs) = do
let (name, rest) = findname "" cs
u <- getUserEntryForName name
return $ homeDirectory u </> rest
return $ toOsPath (homeDirectory u) </> toOsPath rest
expandt _ (c:cs) = do
v <- expandt False cs
return (c:v)
return $ toOsPath [c] <> v
findname n [] = (n, "")
findname n (c:cs)
| c == '/' = (n, cs)
@ -221,11 +221,11 @@ expandTilde p = expandt True p
{- Checks if a git repository exists in a directory. Does not find
- git repositories in parent directories. -}
checkForRepo :: RawFilePath -> IO (Maybe RepoLocation)
checkForRepo :: OsPath -> IO (Maybe RepoLocation)
checkForRepo dir =
check isRepo $
check (checkGitDirFile dir) $
check (checkdir (isBareRepo dir')) $
check (checkdir (isBareRepo dir)) $
return Nothing
where
check test cont = maybe cont (return . Just) =<< test
@ -234,23 +234,22 @@ checkForRepo dir =
, return Nothing
)
isRepo = checkdir $
doesFileExist (dir' </> ".git" </> "config")
doesFileExist (dir </> literalOsPath ".git" </> literalOsPath "config")
<||>
-- A git-worktree lacks .git/config, but has .git/gitdir.
-- (Normally the .git is a file, not a symlink, but it can
-- be converted to a symlink and git will still work;
-- this handles that case.)
doesFileExist (dir' </> ".git" </> "gitdir")
dir' = fromRawFilePath dir
doesFileExist (dir </> literalOsPath ".git" </> literalOsPath "gitdir")
isBareRepo :: FilePath -> IO Bool
isBareRepo dir = doesFileExist (dir </> "config")
<&&> doesDirectoryExist (dir </> "objects")
isBareRepo :: OsPath -> IO Bool
isBareRepo dir = doesFileExist (dir </> literalOsPath "config")
<&&> doesDirectoryExist (dir </> literalOsPath "objects")
-- Check for a .git file.
checkGitDirFile :: RawFilePath -> IO (Maybe RepoLocation)
checkGitDirFile :: OsPath -> IO (Maybe RepoLocation)
checkGitDirFile dir = adjustGitDirFile' $ Local
{ gitdir = dir P.</> ".git"
{ gitdir = dir </> literalOsPath ".git"
, worktree = Just dir
}

View file

@ -51,7 +51,7 @@ get = do
Just d -> do
curr <- R.getCurrentDirectory
unless (d `dirContains` curr) $
setCurrentDirectory (fromRawFilePath d)
setCurrentDirectory d
relPath $ addworktree wt r
where
getpathenv s = do

View file

@ -32,13 +32,11 @@ import Common
import Git
import Git.Quote
import qualified System.FilePath.ByteString as P
import qualified System.FilePath.Posix.ByteString
import GHC.Generics
import Control.DeepSeq
{- A RawFilePath, relative to the top of the git repository. -}
newtype TopFilePath = TopFilePath { getTopFilePath :: RawFilePath }
{- A path relative to the top of the git repository. -}
newtype TopFilePath = TopFilePath { getTopFilePath :: OsPath }
deriving (Show, Eq, Ord, Generic)
instance NFData TopFilePath
@ -53,16 +51,16 @@ descBranchFilePath (BranchFilePath b f) =
UnquotedByteString (fromRef' b) <> ":" <> QuotedPath (getTopFilePath f)
{- Path to a TopFilePath, within the provided git repo. -}
fromTopFilePath :: TopFilePath -> Git.Repo -> RawFilePath
fromTopFilePath p repo = P.combine (repoPath repo) (getTopFilePath p)
fromTopFilePath :: TopFilePath -> Git.Repo -> OsPath
fromTopFilePath p repo = combine (repoPath repo) (getTopFilePath p)
{- The input FilePath can be absolute, or relative to the CWD. -}
toTopFilePath :: RawFilePath -> Git.Repo -> IO TopFilePath
toTopFilePath :: OsPath -> Git.Repo -> IO TopFilePath
toTopFilePath file repo = TopFilePath <$> relPathDirToFile (repoPath repo) file
{- The input RawFilePath must already be relative to the top of the git
- repository -}
asTopFilePath :: RawFilePath -> TopFilePath
asTopFilePath :: OsPath -> TopFilePath
asTopFilePath file = TopFilePath file
{- Git may use a different representation of a path when storing
@ -72,25 +70,24 @@ asTopFilePath file = TopFilePath file
- despite Windows using '\'.
-
-}
type InternalGitPath = RawFilePath
type InternalGitPath = OsPath
toInternalGitPath :: RawFilePath -> InternalGitPath
toInternalGitPath :: OsPath -> InternalGitPath
#ifndef mingw32_HOST_OS
toInternalGitPath = id
#else
toInternalGitPath = encodeBS . replace "\\" "/" . decodeBS
toInternalGitPath = toOsPath . encodeBS . replace "\\" "/" . decodeBS . fromOsPath
#endif
fromInternalGitPath :: InternalGitPath -> RawFilePath
fromInternalGitPath :: InternalGitPath -> OsPath
#ifndef mingw32_HOST_OS
fromInternalGitPath = id
#else
fromInternalGitPath = encodeBS . replace "/" "\\" . decodeBS
fromInternalGitPath = toOsPath . encodeBS . replace "/" "\\" . decodeBS . fromOsPath
#endif
{- isAbsolute on Windows does not think "/foo" or "\foo" is absolute,
- so try posix paths.
-}
absoluteGitPath :: RawFilePath -> Bool
absoluteGitPath p = P.isAbsolute p ||
System.FilePath.Posix.ByteString.isAbsolute (toInternalGitPath p)
absoluteGitPath p = isAbsolute p || isAbsolute (toInternalGitPath p)

View file

@ -83,7 +83,7 @@ instance HashableBlob Builder where
{- Injects a blob into git. Unfortunately, the current git-hash-object
- interface does not allow batch hashing without using temp files. -}
hashBlob :: HashableBlob b => HashObjectHandle -> b -> IO Sha
hashBlob h b = withTmpFile (toOsPath "hash") $ \tmp tmph -> do
hashBlob h b = withTmpFile (literalOsPath "hash") $ \tmp tmph -> do
hashableBlobToHandle tmph b
hClose tmph
hashFile h (fromOsPath tmp)

View file

@ -50,7 +50,7 @@ hookFile h r = localGitDir r P.</> "hooks" P.</> hookName h
- is run with a bundled bash, so should start with #!/bin/sh
-}
hookWrite :: Hook -> Repo -> IO Bool
hookWrite h r = ifM (doesFileExist (fromRawFilePath f))
hookWrite h r = ifM (doesFileExist f)
( expectedContent h r >>= \case
UnexpectedContent -> return False
ExpectedContent -> return True
@ -81,7 +81,7 @@ hookUnWrite h r = ifM (doesFileExist f)
, return True
)
where
f = fromRawFilePath $ hookFile h r
f = hookFile h r
data ExpectedContent = UnexpectedContent | ExpectedContent | OldExpectedContent

View file

@ -113,8 +113,8 @@ exists ref = runBool
{- The file used to record a ref. (Git also stores some refs in a
- packed-refs file.) -}
file :: Ref -> Repo -> FilePath
file ref repo = fromRawFilePath (localGitDir repo) </> fromRef ref
file :: Ref -> Repo -> OsPath
file ref repo = localGitDir repo </> toOsPath (fromRef' ref)
{- Checks if HEAD exists. It generally will, except for in a repository
- that was just created. -}

View file

@ -137,7 +137,7 @@ mkTreeOutput fm ot s f = concat
, " "
, fromRef s
, "\t"
, takeFileName (fromRawFilePath (getTopFilePath f))
, fromOsPath (takeFileName (getTopFilePath f))
, "\NUL"
]

View file

@ -9,6 +9,10 @@
module Git.Types where
import Utility.SafeCommand
import Utility.FileSystemEncoding
import Utility.OsPath
import Network.URI
import Data.String
import Data.Default
@ -16,8 +20,6 @@ import qualified Data.Map as M
import qualified Data.ByteString as S
import qualified Data.List.NonEmpty as NE
import System.Posix.Types
import Utility.SafeCommand
import Utility.FileSystemEncoding
import qualified Data.Semigroup as Sem
import Prelude
@ -32,8 +34,8 @@ import Prelude
- else known about it.
-}
data RepoLocation
= Local { gitdir :: RawFilePath, worktree :: Maybe RawFilePath }
| LocalUnknown RawFilePath
= Local { gitdir :: OsPath, worktree :: Maybe OsPath }
| LocalUnknown OsPath
| Url URI
| UnparseableUrl String
| Unknown