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:
parent
12660314f1
commit
ea775baccd
22 changed files with 159 additions and 163 deletions
|
@ -34,8 +34,10 @@ initMagicMime = catchMaybeIO $ do
|
||||||
m <- magicOpen [MagicMime]
|
m <- magicOpen [MagicMime]
|
||||||
liftIO $ getEnv "GIT_ANNEX_DIR" >>= \case
|
liftIO $ getEnv "GIT_ANNEX_DIR" >>= \case
|
||||||
Nothing -> magicLoadDefault m
|
Nothing -> magicLoadDefault m
|
||||||
Just d -> magicLoad m
|
Just d -> magicLoad m $ fromOsPath $
|
||||||
(d </> "magic" </> "magic.mgc")
|
toOsPath d
|
||||||
|
</> literalOsPath "magic"
|
||||||
|
</> literalOsPath "magic.mgc"
|
||||||
return m
|
return m
|
||||||
#else
|
#else
|
||||||
initMagicMime = return Nothing
|
initMagicMime = return Nothing
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
module Assistant.Install.AutoStart where
|
module Assistant.Install.AutoStart where
|
||||||
|
|
||||||
|
import Common
|
||||||
import Utility.FreeDesktop
|
import Utility.FreeDesktop
|
||||||
#ifdef darwin_HOST_OS
|
#ifdef darwin_HOST_OS
|
||||||
import Utility.OSX
|
import Utility.OSX
|
||||||
|
@ -18,11 +19,11 @@ import Utility.SystemDirectory
|
||||||
import Utility.FileSystemEncoding
|
import Utility.FileSystemEncoding
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
installAutoStart :: FilePath -> FilePath -> IO ()
|
installAutoStart :: String -> OsPath -> IO ()
|
||||||
installAutoStart command file = do
|
installAutoStart command file = do
|
||||||
#ifdef darwin_HOST_OS
|
#ifdef darwin_HOST_OS
|
||||||
createDirectoryIfMissing True (fromRawFilePath (parentDir (toRawFilePath file)))
|
createDirectoryIfMissing True (parentDir file)
|
||||||
writeFile file $ genOSXAutoStartFile osxAutoStartLabel command
|
writeFile (fromOsPath file) $ genOSXAutoStartFile osxAutoStartLabel command
|
||||||
["assistant", "--autostart"]
|
["assistant", "--autostart"]
|
||||||
#else
|
#else
|
||||||
writeDesktopMenuFile (fdoAutostart command) file
|
writeDesktopMenuFile (fdoAutostart command) file
|
||||||
|
|
|
@ -10,26 +10,24 @@
|
||||||
|
|
||||||
module Assistant.Install.Menu where
|
module Assistant.Install.Menu where
|
||||||
|
|
||||||
|
import Common
|
||||||
import Utility.FreeDesktop
|
import Utility.FreeDesktop
|
||||||
import Utility.FileSystemEncoding
|
import Utility.FileSystemEncoding
|
||||||
import Utility.Path
|
import Utility.Path
|
||||||
|
|
||||||
import System.IO
|
import System.IO
|
||||||
import Utility.SystemDirectory
|
import Utility.SystemDirectory
|
||||||
#ifndef darwin_HOST_OS
|
|
||||||
import System.FilePath
|
|
||||||
#endif
|
|
||||||
|
|
||||||
installMenu :: FilePath -> FilePath -> FilePath -> FilePath -> IO ()
|
installMenu :: String -> OsPath -> OsPath -> OsPath -> IO ()
|
||||||
#ifdef darwin_HOST_OS
|
#ifdef darwin_HOST_OS
|
||||||
installMenu _command _menufile _iconsrcdir _icondir = return ()
|
installMenu _command _menufile _iconsrcdir _icondir = return ()
|
||||||
#else
|
#else
|
||||||
installMenu command menufile iconsrcdir icondir = do
|
installMenu command menufile iconsrcdir icondir = do
|
||||||
writeDesktopMenuFile (fdoDesktopMenu command) menufile
|
writeDesktopMenuFile (fdoDesktopMenu command) menufile
|
||||||
installIcon (iconsrcdir </> "logo.svg") $
|
installIcon (iconsrcdir </> literalOsPath "logo.svg") $
|
||||||
iconFilePath (iconBaseName ++ ".svg") "scalable" icondir
|
iconFilePath (toOsPath (iconBaseName ++ ".svg")) "scalable" icondir
|
||||||
installIcon (iconsrcdir </> "logo_16x16.png") $
|
installIcon (iconsrcdir </> literalOsPath "logo_16x16.png") $
|
||||||
iconFilePath (iconBaseName ++ ".png") "16x16" icondir
|
iconFilePath (toOsPath (iconBaseName ++ ".png")) "16x16" icondir
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{- The command can be either just "git-annex", or the full path to use
|
{- The command can be either just "git-annex", or the full path to use
|
||||||
|
@ -43,11 +41,11 @@ fdoDesktopMenu command = genDesktopEntry
|
||||||
(Just iconBaseName)
|
(Just iconBaseName)
|
||||||
["Network", "FileTransfer"]
|
["Network", "FileTransfer"]
|
||||||
|
|
||||||
installIcon :: FilePath -> FilePath -> IO ()
|
installIcon :: OsPath -> OsPath -> IO ()
|
||||||
installIcon src dest = do
|
installIcon src dest = do
|
||||||
createDirectoryIfMissing True (fromRawFilePath (parentDir (toRawFilePath dest)))
|
createDirectoryIfMissing True (parentDir dest)
|
||||||
withBinaryFile src ReadMode $ \hin ->
|
withBinaryFile (fromOsPath src) ReadMode $ \hin ->
|
||||||
withBinaryFile dest WriteMode $ \hout ->
|
withBinaryFile (fromOsPath dest) WriteMode $ \hout ->
|
||||||
hGetContents hin >>= hPutStr hout
|
hGetContents hin >>= hPutStr hout
|
||||||
|
|
||||||
iconBaseName :: String
|
iconBaseName :: String
|
||||||
|
|
|
@ -11,12 +11,8 @@
|
||||||
|
|
||||||
module Build.DesktopFile where
|
module Build.DesktopFile where
|
||||||
|
|
||||||
import Utility.Exception
|
import Common
|
||||||
import Utility.FreeDesktop
|
import Utility.FreeDesktop
|
||||||
import Utility.Path
|
|
||||||
import Utility.Monad
|
|
||||||
import Utility.SystemDirectory
|
|
||||||
import Utility.FileSystemEncoding
|
|
||||||
import Config.Files
|
import Config.Files
|
||||||
import Utility.OSX
|
import Utility.OSX
|
||||||
import Assistant.Install.AutoStart
|
import Assistant.Install.AutoStart
|
||||||
|
@ -25,8 +21,6 @@ import Assistant.Install.Menu
|
||||||
import System.Environment
|
import System.Environment
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
import System.Posix.User
|
import System.Posix.User
|
||||||
import Data.Maybe
|
|
||||||
import Control.Applicative
|
|
||||||
import Prelude
|
import Prelude
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -42,10 +36,10 @@ systemwideInstall = isroot <||> (not <$> userdirset)
|
||||||
systemwideInstall = return False
|
systemwideInstall = return False
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inDestDir :: FilePath -> IO FilePath
|
inDestDir :: OsPath -> IO OsPath
|
||||||
inDestDir f = do
|
inDestDir f = do
|
||||||
destdir <- catchDefaultIO "" (getEnv "DESTDIR")
|
destdir <- catchDefaultIO "" (getEnv "DESTDIR")
|
||||||
return $ destdir ++ "/" ++ f
|
return $ toOsPath destdir <> literalOsPath "/" <> f
|
||||||
|
|
||||||
writeFDODesktop :: FilePath -> IO ()
|
writeFDODesktop :: FilePath -> IO ()
|
||||||
writeFDODesktop command = do
|
writeFDODesktop command = do
|
||||||
|
@ -54,7 +48,7 @@ writeFDODesktop command = do
|
||||||
datadir <- if systemwide then return systemDataDir else userDataDir
|
datadir <- if systemwide then return systemDataDir else userDataDir
|
||||||
menufile <- inDestDir (desktopMenuFilePath "git-annex" datadir)
|
menufile <- inDestDir (desktopMenuFilePath "git-annex" datadir)
|
||||||
icondir <- inDestDir (iconDir datadir)
|
icondir <- inDestDir (iconDir datadir)
|
||||||
installMenu command menufile "doc" icondir
|
installMenu command menufile (literalOsPath "doc") icondir
|
||||||
|
|
||||||
configdir <- if systemwide then return systemConfigDir else userConfigDir
|
configdir <- if systemwide then return systemConfigDir else userConfigDir
|
||||||
installAutoStart command
|
installAutoStart command
|
||||||
|
@ -78,8 +72,8 @@ install command = do
|
||||||
( return ()
|
( return ()
|
||||||
, do
|
, do
|
||||||
programfile <- inDestDir =<< programFile
|
programfile <- inDestDir =<< programFile
|
||||||
createDirectoryIfMissing True (fromRawFilePath (parentDir (toRawFilePath programfile)))
|
createDirectoryIfMissing True (parentDir programfile)
|
||||||
writeFile programfile command
|
writeFile (fromOsPath programfile) command
|
||||||
)
|
)
|
||||||
|
|
||||||
installUser :: FilePath -> IO ()
|
installUser :: FilePath -> IO ()
|
||||||
|
|
|
@ -9,28 +9,27 @@
|
||||||
|
|
||||||
module Config.Files where
|
module Config.Files where
|
||||||
|
|
||||||
|
import Common
|
||||||
import Utility.FreeDesktop
|
import Utility.FreeDesktop
|
||||||
import Utility.Exception
|
import Utility.Exception
|
||||||
|
|
||||||
import System.FilePath
|
|
||||||
|
|
||||||
{- ~/.config/git-annex/file -}
|
{- ~/.config/git-annex/file -}
|
||||||
userConfigFile :: FilePath -> IO FilePath
|
userConfigFile :: OsPath -> IO OsPath
|
||||||
userConfigFile file = do
|
userConfigFile file = do
|
||||||
dir <- userConfigDir
|
dir <- toOsPath <$> userConfigDir
|
||||||
return $ dir </> "git-annex" </> file
|
return $ dir </> literalOsPath "git-annex" </> file
|
||||||
|
|
||||||
autoStartFile :: IO FilePath
|
autoStartFile :: IO OsPath
|
||||||
autoStartFile = userConfigFile "autostart"
|
autoStartFile = userConfigFile (literalOsPath "autostart")
|
||||||
|
|
||||||
{- The path to git-annex is written here; which is useful when something
|
{- The path to git-annex is written here; which is useful when something
|
||||||
- has installed it to some awful non-PATH location. -}
|
- has installed it to some awful non-PATH location. -}
|
||||||
programFile :: IO FilePath
|
programFile :: IO OsPath
|
||||||
programFile = userConfigFile "program"
|
programFile = userConfigFile (literalOsPath "program")
|
||||||
|
|
||||||
{- A .noannex file in a git repository prevents git-annex from
|
{- A .noannex file in a git repository prevents git-annex from
|
||||||
- initializing that repository. The content of the file is returned. -}
|
- initializing that repository. The content of the file is returned. -}
|
||||||
noAnnexFileContent :: Maybe FilePath -> IO (Maybe String)
|
noAnnexFileContent :: Maybe OsPath -> IO (Maybe String)
|
||||||
noAnnexFileContent repoworktree = case repoworktree of
|
noAnnexFileContent repoworktree = case repoworktree of
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
Just wt -> catchMaybeIO (readFile (wt </> ".noannex"))
|
Just wt -> catchMaybeIO (readFile (fromOsPath (wt </> literalOsPath ".noannex")))
|
||||||
|
|
|
@ -14,38 +14,37 @@ import Config.Files
|
||||||
import Utility.Tmp
|
import Utility.Tmp
|
||||||
|
|
||||||
{- Returns anything listed in the autostart file (which may not exist). -}
|
{- Returns anything listed in the autostart file (which may not exist). -}
|
||||||
readAutoStartFile :: IO [FilePath]
|
readAutoStartFile :: IO [OsPath]
|
||||||
readAutoStartFile = do
|
readAutoStartFile = do
|
||||||
f <- autoStartFile
|
f <- autoStartFile
|
||||||
filter valid . nub . map dropTrailingPathSeparator . lines
|
filter valid . nub . map (dropTrailingPathSeparator . toOsPath) . lines
|
||||||
<$> catchDefaultIO "" (readFile f)
|
<$> catchDefaultIO "" (readFile (fromOsPath f))
|
||||||
where
|
where
|
||||||
-- Ignore any relative paths; some old buggy versions added eg "."
|
-- Ignore any relative paths; some old buggy versions added eg "."
|
||||||
valid = isAbsolute
|
valid = isAbsolute
|
||||||
|
|
||||||
modifyAutoStartFile :: ([FilePath] -> [FilePath]) -> IO ()
|
modifyAutoStartFile :: ([OsPath] -> [OsPath]) -> IO ()
|
||||||
modifyAutoStartFile func = do
|
modifyAutoStartFile func = do
|
||||||
dirs <- readAutoStartFile
|
dirs <- readAutoStartFile
|
||||||
let dirs' = nubBy equalFilePath $ func dirs
|
let dirs' = nubBy equalFilePath $ func dirs
|
||||||
when (dirs' /= dirs) $ do
|
when (dirs' /= dirs) $ do
|
||||||
f <- autoStartFile
|
f <- autoStartFile
|
||||||
createDirectoryIfMissing True $
|
createDirectoryIfMissing True (parentDir f)
|
||||||
fromRawFilePath (parentDir (toRawFilePath f))
|
|
||||||
viaTmp (writeFile . fromRawFilePath . fromOsPath)
|
viaTmp (writeFile . fromRawFilePath . fromOsPath)
|
||||||
(toOsPath (toRawFilePath f))
|
(toOsPath f)
|
||||||
(unlines dirs')
|
(unlines (map fromOsPath dirs'))
|
||||||
|
|
||||||
{- Adds a directory to the autostart file. If the directory is already
|
{- Adds a directory to the autostart file. If the directory is already
|
||||||
- present, it's moved to the top, so it will be used as the default
|
- present, it's moved to the top, so it will be used as the default
|
||||||
- when opening the webapp. -}
|
- when opening the webapp. -}
|
||||||
addAutoStartFile :: FilePath -> IO ()
|
addAutoStartFile :: OsPath -> IO ()
|
||||||
addAutoStartFile path = do
|
addAutoStartFile path = do
|
||||||
path' <- fromRawFilePath <$> absPath (toRawFilePath path)
|
path' <- absPath path
|
||||||
modifyAutoStartFile $ (:) path'
|
modifyAutoStartFile $ (:) path'
|
||||||
|
|
||||||
{- Removes a directory from the autostart file. -}
|
{- Removes a directory from the autostart file. -}
|
||||||
removeAutoStartFile :: FilePath -> IO ()
|
removeAutoStartFile :: OsPath -> IO ()
|
||||||
removeAutoStartFile path = do
|
removeAutoStartFile path = do
|
||||||
path' <- fromRawFilePath <$> absPath (toRawFilePath path)
|
path' <- absPath path
|
||||||
modifyAutoStartFile $
|
modifyAutoStartFile $
|
||||||
filter (not . equalFilePath path')
|
filter (not . equalFilePath path')
|
||||||
|
|
9
Git.hs
9
Git.hs
|
@ -86,7 +86,7 @@ repoWorkTree Repo { location = Local { worktree = Just d } } = Just d
|
||||||
repoWorkTree _ = Nothing
|
repoWorkTree _ = Nothing
|
||||||
|
|
||||||
{- Path to a local repository's .git directory. -}
|
{- Path to a local repository's .git directory. -}
|
||||||
localGitDir :: Repo -> RawFilePath
|
localGitDir :: Repo -> OsPath
|
||||||
localGitDir Repo { location = Local { gitdir = d } } = d
|
localGitDir Repo { location = Local { gitdir = d } } = d
|
||||||
localGitDir _ = giveup "unknown localGitDir"
|
localGitDir _ = giveup "unknown localGitDir"
|
||||||
|
|
||||||
|
@ -147,16 +147,17 @@ attributesLocal repo = localGitDir repo P.</> "info" P.</> "attributes"
|
||||||
|
|
||||||
{- Path to a given hook script in a repository, only if the hook exists
|
{- Path to a given hook script in a repository, only if the hook exists
|
||||||
- and is executable. -}
|
- and is executable. -}
|
||||||
hookPath :: String -> Repo -> IO (Maybe FilePath)
|
hookPath :: String -> Repo -> IO (Maybe OsPath)
|
||||||
hookPath script repo = do
|
hookPath script repo = do
|
||||||
let hook = fromRawFilePath (localGitDir repo) </> "hooks" </> script
|
let hook = localGitDir repo </> literalOsPath "hooks" </> toOsPath script
|
||||||
ifM (catchBoolIO $ isexecutable hook)
|
ifM (catchBoolIO $ isexecutable hook)
|
||||||
( return $ Just hook , return Nothing )
|
( return $ Just hook , return Nothing )
|
||||||
where
|
where
|
||||||
#if mingw32_HOST_OS
|
#if mingw32_HOST_OS
|
||||||
isexecutable f = doesFileExist f
|
isexecutable f = doesFileExist f
|
||||||
#else
|
#else
|
||||||
isexecutable f = isExecutable . fileMode <$> getSymbolicLinkStatus f
|
isexecutable f = isExecutable . fileMode
|
||||||
|
<$> getSymbolicLinkStatus (fromOsPath f)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{- Makes the path to a local Repo be relative to the cwd. -}
|
{- Makes the path to a local Repo be relative to the cwd. -}
|
||||||
|
|
|
@ -99,7 +99,7 @@ read' repo = go repo
|
||||||
global :: IO (Maybe Repo)
|
global :: IO (Maybe Repo)
|
||||||
global = do
|
global = do
|
||||||
home <- myHomeDir
|
home <- myHomeDir
|
||||||
ifM (doesFileExist $ home </> ".gitconfig")
|
ifM (doesFileExist $ toOsPath home </> literalOsPath ".gitconfig")
|
||||||
( Just <$> withCreateProcess p go
|
( Just <$> withCreateProcess p go
|
||||||
, return Nothing
|
, return Nothing
|
||||||
)
|
)
|
||||||
|
@ -153,22 +153,22 @@ store' k v repo = repo
|
||||||
-}
|
-}
|
||||||
updateLocation :: Repo -> IO Repo
|
updateLocation :: Repo -> IO Repo
|
||||||
updateLocation r@(Repo { location = LocalUnknown d }) = case isBare r of
|
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 dotgit Nothing
|
||||||
, updateLocation' r $ Local d Nothing
|
, updateLocation' r $ Local d Nothing
|
||||||
)
|
)
|
||||||
Just False -> mknonbare
|
Just False -> mknonbare
|
||||||
{- core.bare not in config, probably because safe.directory
|
{- core.bare not in config, probably because safe.directory
|
||||||
- did not allow reading the config -}
|
- did not allow reading the config -}
|
||||||
Nothing -> ifM (Git.Construct.isBareRepo (fromRawFilePath d))
|
Nothing -> ifM (Git.Construct.isBareRepo d)
|
||||||
( mkbare
|
( mkbare
|
||||||
, mknonbare
|
, mknonbare
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
dotgit = d P.</> ".git"
|
dotgit = d </> literalOsPath ".git"
|
||||||
-- git treats eg ~/foo as a bare git repository located in
|
-- git treats eg ~/foo as a bare git repository located in
|
||||||
-- ~/foo/.git if ~/foo/.git/config has core.bare=true
|
-- ~/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 dotgit Nothing
|
||||||
, updateLocation' r $ Local d Nothing
|
, updateLocation' r $ Local d Nothing
|
||||||
)
|
)
|
||||||
|
|
|
@ -176,43 +176,43 @@ fromRemoteLocation s knownurl repo = gen $ parseRemoteLocation s knownurl repo
|
||||||
fromRemotePath :: FilePath -> Repo -> IO Repo
|
fromRemotePath :: FilePath -> Repo -> IO Repo
|
||||||
fromRemotePath dir repo = do
|
fromRemotePath dir repo = do
|
||||||
dir' <- expandTilde dir
|
dir' <- expandTilde dir
|
||||||
fromPath $ repoPath repo P.</> toRawFilePath dir'
|
fromPath $ repoPath repo P.</> dir'
|
||||||
|
|
||||||
{- Git remotes can have a directory that is specified relative
|
{- Git remotes can have a directory that is specified relative
|
||||||
- to the user's home directory, or that contains tilde expansions.
|
- to the user's home directory, or that contains tilde expansions.
|
||||||
- This converts such a directory to an absolute path.
|
- This converts such a directory to an absolute path.
|
||||||
- Note that it has to run on the system where the remote is.
|
- Note that it has to run on the system where the remote is.
|
||||||
-}
|
-}
|
||||||
repoAbsPath :: RawFilePath -> IO RawFilePath
|
repoAbsPath :: OsPath -> IO OsPath
|
||||||
repoAbsPath d = do
|
repoAbsPath d = do
|
||||||
d' <- expandTilde (fromRawFilePath d)
|
d' <- expandTilde (fromOsPath d)
|
||||||
h <- myHomeDir
|
h <- myHomeDir
|
||||||
return $ toRawFilePath $ h </> d'
|
return $ toOsPath h </> d'
|
||||||
|
|
||||||
expandTilde :: FilePath -> IO FilePath
|
expandTilde :: FilePath -> IO OsPath
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
expandTilde = return
|
expandTilde = return . toOsPath
|
||||||
#else
|
#else
|
||||||
expandTilde p = expandt True p
|
expandTilde p = expandt True p
|
||||||
-- If unable to expand a tilde, eg due to a user not existing,
|
-- If unable to expand a tilde, eg due to a user not existing,
|
||||||
-- use the path as given.
|
-- use the path as given.
|
||||||
`catchNonAsync` (const (return p))
|
`catchNonAsync` (const (return (toOsPath p)))
|
||||||
where
|
where
|
||||||
expandt _ [] = return ""
|
expandt _ [] = return $ literalOsPath ""
|
||||||
expandt _ ('/':cs) = do
|
expandt _ ('/':cs) = do
|
||||||
v <- expandt True cs
|
v <- expandt True cs
|
||||||
return ('/':v)
|
return $ literalOsPath "/" <> v
|
||||||
expandt True ('~':'/':cs) = do
|
expandt True ('~':'/':cs) = do
|
||||||
h <- myHomeDir
|
h <- myHomeDir
|
||||||
return $ h </> cs
|
return $ toOsPath h </> toOsPath cs
|
||||||
expandt True "~" = myHomeDir
|
expandt True "~" = toOsPath <$> myHomeDir
|
||||||
expandt True ('~':cs) = do
|
expandt True ('~':cs) = do
|
||||||
let (name, rest) = findname "" cs
|
let (name, rest) = findname "" cs
|
||||||
u <- getUserEntryForName name
|
u <- getUserEntryForName name
|
||||||
return $ homeDirectory u </> rest
|
return $ toOsPath (homeDirectory u) </> toOsPath rest
|
||||||
expandt _ (c:cs) = do
|
expandt _ (c:cs) = do
|
||||||
v <- expandt False cs
|
v <- expandt False cs
|
||||||
return (c:v)
|
return $ toOsPath [c] <> v
|
||||||
findname n [] = (n, "")
|
findname n [] = (n, "")
|
||||||
findname n (c:cs)
|
findname n (c:cs)
|
||||||
| c == '/' = (n, 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
|
{- Checks if a git repository exists in a directory. Does not find
|
||||||
- git repositories in parent directories. -}
|
- git repositories in parent directories. -}
|
||||||
checkForRepo :: RawFilePath -> IO (Maybe RepoLocation)
|
checkForRepo :: OsPath -> IO (Maybe RepoLocation)
|
||||||
checkForRepo dir =
|
checkForRepo dir =
|
||||||
check isRepo $
|
check isRepo $
|
||||||
check (checkGitDirFile dir) $
|
check (checkGitDirFile dir) $
|
||||||
check (checkdir (isBareRepo dir')) $
|
check (checkdir (isBareRepo dir)) $
|
||||||
return Nothing
|
return Nothing
|
||||||
where
|
where
|
||||||
check test cont = maybe cont (return . Just) =<< test
|
check test cont = maybe cont (return . Just) =<< test
|
||||||
|
@ -234,23 +234,22 @@ checkForRepo dir =
|
||||||
, return Nothing
|
, return Nothing
|
||||||
)
|
)
|
||||||
isRepo = checkdir $
|
isRepo = checkdir $
|
||||||
doesFileExist (dir' </> ".git" </> "config")
|
doesFileExist (dir </> literalOsPath ".git" </> literalOsPath "config")
|
||||||
<||>
|
<||>
|
||||||
-- A git-worktree lacks .git/config, but has .git/gitdir.
|
-- A git-worktree lacks .git/config, but has .git/gitdir.
|
||||||
-- (Normally the .git is a file, not a symlink, but it can
|
-- (Normally the .git is a file, not a symlink, but it can
|
||||||
-- be converted to a symlink and git will still work;
|
-- be converted to a symlink and git will still work;
|
||||||
-- this handles that case.)
|
-- this handles that case.)
|
||||||
doesFileExist (dir' </> ".git" </> "gitdir")
|
doesFileExist (dir </> literalOsPath ".git" </> literalOsPath "gitdir")
|
||||||
dir' = fromRawFilePath dir
|
|
||||||
|
|
||||||
isBareRepo :: FilePath -> IO Bool
|
isBareRepo :: OsPath -> IO Bool
|
||||||
isBareRepo dir = doesFileExist (dir </> "config")
|
isBareRepo dir = doesFileExist (dir </> literalOsPath "config")
|
||||||
<&&> doesDirectoryExist (dir </> "objects")
|
<&&> doesDirectoryExist (dir </> literalOsPath "objects")
|
||||||
|
|
||||||
-- Check for a .git file.
|
-- Check for a .git file.
|
||||||
checkGitDirFile :: RawFilePath -> IO (Maybe RepoLocation)
|
checkGitDirFile :: OsPath -> IO (Maybe RepoLocation)
|
||||||
checkGitDirFile dir = adjustGitDirFile' $ Local
|
checkGitDirFile dir = adjustGitDirFile' $ Local
|
||||||
{ gitdir = dir P.</> ".git"
|
{ gitdir = dir </> literalOsPath ".git"
|
||||||
, worktree = Just dir
|
, worktree = Just dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ get = do
|
||||||
Just d -> do
|
Just d -> do
|
||||||
curr <- R.getCurrentDirectory
|
curr <- R.getCurrentDirectory
|
||||||
unless (d `dirContains` curr) $
|
unless (d `dirContains` curr) $
|
||||||
setCurrentDirectory (fromRawFilePath d)
|
setCurrentDirectory d
|
||||||
relPath $ addworktree wt r
|
relPath $ addworktree wt r
|
||||||
where
|
where
|
||||||
getpathenv s = do
|
getpathenv s = do
|
||||||
|
|
|
@ -32,13 +32,11 @@ import Common
|
||||||
import Git
|
import Git
|
||||||
import Git.Quote
|
import Git.Quote
|
||||||
|
|
||||||
import qualified System.FilePath.ByteString as P
|
|
||||||
import qualified System.FilePath.Posix.ByteString
|
|
||||||
import GHC.Generics
|
import GHC.Generics
|
||||||
import Control.DeepSeq
|
import Control.DeepSeq
|
||||||
|
|
||||||
{- A RawFilePath, relative to the top of the git repository. -}
|
{- A path relative to the top of the git repository. -}
|
||||||
newtype TopFilePath = TopFilePath { getTopFilePath :: RawFilePath }
|
newtype TopFilePath = TopFilePath { getTopFilePath :: OsPath }
|
||||||
deriving (Show, Eq, Ord, Generic)
|
deriving (Show, Eq, Ord, Generic)
|
||||||
|
|
||||||
instance NFData TopFilePath
|
instance NFData TopFilePath
|
||||||
|
@ -53,16 +51,16 @@ descBranchFilePath (BranchFilePath b f) =
|
||||||
UnquotedByteString (fromRef' b) <> ":" <> QuotedPath (getTopFilePath f)
|
UnquotedByteString (fromRef' b) <> ":" <> QuotedPath (getTopFilePath f)
|
||||||
|
|
||||||
{- Path to a TopFilePath, within the provided git repo. -}
|
{- Path to a TopFilePath, within the provided git repo. -}
|
||||||
fromTopFilePath :: TopFilePath -> Git.Repo -> RawFilePath
|
fromTopFilePath :: TopFilePath -> Git.Repo -> OsPath
|
||||||
fromTopFilePath p repo = P.combine (repoPath repo) (getTopFilePath p)
|
fromTopFilePath p repo = combine (repoPath repo) (getTopFilePath p)
|
||||||
|
|
||||||
{- The input FilePath can be absolute, or relative to the CWD. -}
|
{- 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
|
toTopFilePath file repo = TopFilePath <$> relPathDirToFile (repoPath repo) file
|
||||||
|
|
||||||
{- The input RawFilePath must already be relative to the top of the git
|
{- The input RawFilePath must already be relative to the top of the git
|
||||||
- repository -}
|
- repository -}
|
||||||
asTopFilePath :: RawFilePath -> TopFilePath
|
asTopFilePath :: OsPath -> TopFilePath
|
||||||
asTopFilePath file = TopFilePath file
|
asTopFilePath file = TopFilePath file
|
||||||
|
|
||||||
{- Git may use a different representation of a path when storing
|
{- Git may use a different representation of a path when storing
|
||||||
|
@ -72,25 +70,24 @@ asTopFilePath file = TopFilePath file
|
||||||
- despite Windows using '\'.
|
- despite Windows using '\'.
|
||||||
-
|
-
|
||||||
-}
|
-}
|
||||||
type InternalGitPath = RawFilePath
|
type InternalGitPath = OsPath
|
||||||
|
|
||||||
toInternalGitPath :: RawFilePath -> InternalGitPath
|
toInternalGitPath :: OsPath -> InternalGitPath
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
toInternalGitPath = id
|
toInternalGitPath = id
|
||||||
#else
|
#else
|
||||||
toInternalGitPath = encodeBS . replace "\\" "/" . decodeBS
|
toInternalGitPath = toOsPath . encodeBS . replace "\\" "/" . decodeBS . fromOsPath
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fromInternalGitPath :: InternalGitPath -> RawFilePath
|
fromInternalGitPath :: InternalGitPath -> OsPath
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
fromInternalGitPath = id
|
fromInternalGitPath = id
|
||||||
#else
|
#else
|
||||||
fromInternalGitPath = encodeBS . replace "/" "\\" . decodeBS
|
fromInternalGitPath = toOsPath . encodeBS . replace "/" "\\" . decodeBS . fromOsPath
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{- isAbsolute on Windows does not think "/foo" or "\foo" is absolute,
|
{- isAbsolute on Windows does not think "/foo" or "\foo" is absolute,
|
||||||
- so try posix paths.
|
- so try posix paths.
|
||||||
-}
|
-}
|
||||||
absoluteGitPath :: RawFilePath -> Bool
|
absoluteGitPath :: RawFilePath -> Bool
|
||||||
absoluteGitPath p = P.isAbsolute p ||
|
absoluteGitPath p = isAbsolute p || isAbsolute (toInternalGitPath p)
|
||||||
System.FilePath.Posix.ByteString.isAbsolute (toInternalGitPath p)
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ instance HashableBlob Builder where
|
||||||
{- Injects a blob into git. Unfortunately, the current git-hash-object
|
{- Injects a blob into git. Unfortunately, the current git-hash-object
|
||||||
- interface does not allow batch hashing without using temp files. -}
|
- interface does not allow batch hashing without using temp files. -}
|
||||||
hashBlob :: HashableBlob b => HashObjectHandle -> b -> IO Sha
|
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
|
hashableBlobToHandle tmph b
|
||||||
hClose tmph
|
hClose tmph
|
||||||
hashFile h (fromOsPath tmp)
|
hashFile h (fromOsPath tmp)
|
||||||
|
|
|
@ -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
|
- is run with a bundled bash, so should start with #!/bin/sh
|
||||||
-}
|
-}
|
||||||
hookWrite :: Hook -> Repo -> IO Bool
|
hookWrite :: Hook -> Repo -> IO Bool
|
||||||
hookWrite h r = ifM (doesFileExist (fromRawFilePath f))
|
hookWrite h r = ifM (doesFileExist f)
|
||||||
( expectedContent h r >>= \case
|
( expectedContent h r >>= \case
|
||||||
UnexpectedContent -> return False
|
UnexpectedContent -> return False
|
||||||
ExpectedContent -> return True
|
ExpectedContent -> return True
|
||||||
|
@ -81,7 +81,7 @@ hookUnWrite h r = ifM (doesFileExist f)
|
||||||
, return True
|
, return True
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
f = fromRawFilePath $ hookFile h r
|
f = hookFile h r
|
||||||
|
|
||||||
data ExpectedContent = UnexpectedContent | ExpectedContent | OldExpectedContent
|
data ExpectedContent = UnexpectedContent | ExpectedContent | OldExpectedContent
|
||||||
|
|
||||||
|
|
|
@ -113,8 +113,8 @@ exists ref = runBool
|
||||||
|
|
||||||
{- The file used to record a ref. (Git also stores some refs in a
|
{- The file used to record a ref. (Git also stores some refs in a
|
||||||
- packed-refs file.) -}
|
- packed-refs file.) -}
|
||||||
file :: Ref -> Repo -> FilePath
|
file :: Ref -> Repo -> OsPath
|
||||||
file ref repo = fromRawFilePath (localGitDir repo) </> fromRef ref
|
file ref repo = localGitDir repo </> toOsPath (fromRef' ref)
|
||||||
|
|
||||||
{- Checks if HEAD exists. It generally will, except for in a repository
|
{- Checks if HEAD exists. It generally will, except for in a repository
|
||||||
- that was just created. -}
|
- that was just created. -}
|
||||||
|
|
|
@ -137,7 +137,7 @@ mkTreeOutput fm ot s f = concat
|
||||||
, " "
|
, " "
|
||||||
, fromRef s
|
, fromRef s
|
||||||
, "\t"
|
, "\t"
|
||||||
, takeFileName (fromRawFilePath (getTopFilePath f))
|
, fromOsPath (takeFileName (getTopFilePath f))
|
||||||
, "\NUL"
|
, "\NUL"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
10
Git/Types.hs
10
Git/Types.hs
|
@ -9,6 +9,10 @@
|
||||||
|
|
||||||
module Git.Types where
|
module Git.Types where
|
||||||
|
|
||||||
|
import Utility.SafeCommand
|
||||||
|
import Utility.FileSystemEncoding
|
||||||
|
import Utility.OsPath
|
||||||
|
|
||||||
import Network.URI
|
import Network.URI
|
||||||
import Data.String
|
import Data.String
|
||||||
import Data.Default
|
import Data.Default
|
||||||
|
@ -16,8 +20,6 @@ import qualified Data.Map as M
|
||||||
import qualified Data.ByteString as S
|
import qualified Data.ByteString as S
|
||||||
import qualified Data.List.NonEmpty as NE
|
import qualified Data.List.NonEmpty as NE
|
||||||
import System.Posix.Types
|
import System.Posix.Types
|
||||||
import Utility.SafeCommand
|
|
||||||
import Utility.FileSystemEncoding
|
|
||||||
import qualified Data.Semigroup as Sem
|
import qualified Data.Semigroup as Sem
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
|
@ -32,8 +34,8 @@ import Prelude
|
||||||
- else known about it.
|
- else known about it.
|
||||||
-}
|
-}
|
||||||
data RepoLocation
|
data RepoLocation
|
||||||
= Local { gitdir :: RawFilePath, worktree :: Maybe RawFilePath }
|
= Local { gitdir :: OsPath, worktree :: Maybe OsPath }
|
||||||
| LocalUnknown RawFilePath
|
| LocalUnknown OsPath
|
||||||
| Url URI
|
| Url URI
|
||||||
| UnparseableUrl String
|
| UnparseableUrl String
|
||||||
| Unknown
|
| Unknown
|
||||||
|
|
|
@ -28,13 +28,12 @@ module Utility.FreeDesktop (
|
||||||
userDesktopDir
|
userDesktopDir
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Common
|
||||||
import Utility.Exception
|
import Utility.Exception
|
||||||
import Utility.UserInfo
|
import Utility.UserInfo
|
||||||
import Utility.Process
|
import Utility.Process
|
||||||
|
|
||||||
import System.Environment
|
import System.Environment
|
||||||
import System.FilePath
|
|
||||||
import System.Directory
|
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
|
@ -78,53 +77,53 @@ buildDesktopMenuFile d = unlines ("[Desktop Entry]" : map keyvalue d) ++ "\n"
|
||||||
where
|
where
|
||||||
keyvalue (k, v) = k ++ "=" ++ toString v
|
keyvalue (k, v) = k ++ "=" ++ toString v
|
||||||
|
|
||||||
writeDesktopMenuFile :: DesktopEntry -> String -> IO ()
|
writeDesktopMenuFile :: DesktopEntry -> OsPath -> IO ()
|
||||||
writeDesktopMenuFile d file = do
|
writeDesktopMenuFile d file = do
|
||||||
createDirectoryIfMissing True (takeDirectory file)
|
createDirectoryIfMissing True (takeDirectory file)
|
||||||
writeFile file $ buildDesktopMenuFile d
|
writeFile (fromOsPath file) $ buildDesktopMenuFile d
|
||||||
|
|
||||||
{- Path to use for a desktop menu file, in either the systemDataDir or
|
{- Path to use for a desktop menu file, in either the systemDataDir or
|
||||||
- the userDataDir -}
|
- the userDataDir -}
|
||||||
desktopMenuFilePath :: String -> FilePath -> FilePath
|
desktopMenuFilePath :: String -> OsPath -> OsPath
|
||||||
desktopMenuFilePath basename datadir =
|
desktopMenuFilePath basename datadir =
|
||||||
datadir </> "applications" </> desktopfile basename
|
datadir </> literalOsPath "applications" </> desktopfile basename
|
||||||
|
|
||||||
{- Path to use for a desktop autostart file, in either the systemDataDir
|
{- Path to use for a desktop autostart file, in either the systemDataDir
|
||||||
- or the userDataDir -}
|
- or the userDataDir -}
|
||||||
autoStartPath :: String -> FilePath -> FilePath
|
autoStartPath :: String -> OsPath -> OsPath
|
||||||
autoStartPath basename configdir =
|
autoStartPath basename configdir =
|
||||||
configdir </> "autostart" </> desktopfile basename
|
configdir </> literalOsPath "autostart" </> desktopfile basename
|
||||||
|
|
||||||
{- Base directory to install an icon file, in either the systemDataDir
|
{- Base directory to install an icon file, in either the systemDataDir
|
||||||
- or the userDatadir. -}
|
- or the userDatadir. -}
|
||||||
iconDir :: FilePath -> FilePath
|
iconDir :: OsPath -> OsPath
|
||||||
iconDir datadir = datadir </> "icons" </> "hicolor"
|
iconDir datadir = datadir </> literalOsPath "icons" </> literalOsPath "hicolor"
|
||||||
|
|
||||||
{- Filename of an icon, given the iconDir to use.
|
{- Filename of an icon, given the iconDir to use.
|
||||||
-
|
-
|
||||||
- The resolution is something like "48x48" or "scalable". -}
|
- The resolution is something like "48x48" or "scalable". -}
|
||||||
iconFilePath :: FilePath -> String -> FilePath -> FilePath
|
iconFilePath :: OsPath -> String -> OsPath -> OsPath
|
||||||
iconFilePath file resolution icondir =
|
iconFilePath file resolution icondir =
|
||||||
icondir </> resolution </> "apps" </> file
|
icondir </> toOsPath resolution </> literalOsPath "apps" </> file
|
||||||
|
|
||||||
desktopfile :: FilePath -> FilePath
|
desktopfile :: FilePath -> OsPath
|
||||||
desktopfile f = f ++ ".desktop"
|
desktopfile f = toOsPath $ f ++ ".desktop"
|
||||||
|
|
||||||
{- Directory used for installation of system wide data files.. -}
|
{- Directory used for installation of system wide data files.. -}
|
||||||
systemDataDir :: FilePath
|
systemDataDir :: OsPath
|
||||||
systemDataDir = "/usr/share"
|
systemDataDir = literalOsPath "/usr/share"
|
||||||
|
|
||||||
{- Directory used for installation of system wide config files. -}
|
{- Directory used for installation of system wide config files. -}
|
||||||
systemConfigDir :: FilePath
|
systemConfigDir :: OsPath
|
||||||
systemConfigDir = "/etc/xdg"
|
systemConfigDir = literalOsPath "/etc/xdg"
|
||||||
|
|
||||||
{- Directory for user data files. -}
|
{- Directory for user data files. -}
|
||||||
userDataDir :: IO FilePath
|
userDataDir :: IO OsPath
|
||||||
userDataDir = xdgEnvHome "DATA_HOME" ".local/share"
|
userDataDir = toOsPath <$> xdgEnvHome "DATA_HOME" ".local/share"
|
||||||
|
|
||||||
{- Directory for user config files. -}
|
{- Directory for user config files. -}
|
||||||
userConfigDir :: IO FilePath
|
userConfigDir :: IO OsPath
|
||||||
userConfigDir = xdgEnvHome "CONFIG_HOME" ".config"
|
userConfigDir = toOsPath <$> xdgEnvHome "CONFIG_HOME" ".config"
|
||||||
|
|
||||||
{- Directory for the user's Desktop, may be localized.
|
{- Directory for the user's Desktop, may be localized.
|
||||||
-
|
-
|
||||||
|
@ -142,6 +141,6 @@ userDesktopDir = maybe fallback return =<< (parse <$> xdg_user_dir)
|
||||||
|
|
||||||
xdgEnvHome :: String -> String -> IO String
|
xdgEnvHome :: String -> String -> IO String
|
||||||
xdgEnvHome envbase homedef = do
|
xdgEnvHome envbase homedef = do
|
||||||
home <- myHomeDir
|
home <- toOsPath <$> myHomeDir
|
||||||
catchDefaultIO (home </> homedef) $
|
catchDefaultIO (fromOsPath $ home </> toOsPath homedef) $
|
||||||
getEnv $ "XDG_" ++ envbase
|
getEnv ("XDG_" ++ envbase)
|
||||||
|
|
|
@ -14,20 +14,19 @@ module Utility.OSX (
|
||||||
genOSXAutoStartFile,
|
genOSXAutoStartFile,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Common
|
||||||
import Utility.UserInfo
|
import Utility.UserInfo
|
||||||
|
|
||||||
import System.FilePath
|
autoStartBase :: String -> OsPath
|
||||||
|
autoStartBase label = literalOsPath "Library" </> literalOsPath "LaunchAgents" </> literalOsPath (label ++ ".plist")
|
||||||
|
|
||||||
autoStartBase :: String -> FilePath
|
systemAutoStart :: String -> OsPath
|
||||||
autoStartBase label = "Library" </> "LaunchAgents" </> label ++ ".plist"
|
systemAutoStart label = literalOsPath "/" </> autoStartBase label
|
||||||
|
|
||||||
systemAutoStart :: String -> FilePath
|
userAutoStart :: String -> IO OsPath
|
||||||
systemAutoStart label = "/" </> autoStartBase label
|
|
||||||
|
|
||||||
userAutoStart :: String -> IO FilePath
|
|
||||||
userAutoStart label = do
|
userAutoStart label = do
|
||||||
home <- myHomeDir
|
home <- myHomeDir
|
||||||
return $ home </> autoStartBase label
|
return $ toOsPath home </> autoStartBase label
|
||||||
|
|
||||||
{- Generates an OSX autostart plist file with a given label, command, and
|
{- Generates an OSX autostart plist file with a given label, command, and
|
||||||
- params to run at boot or login. -}
|
- params to run at boot or login. -}
|
||||||
|
|
|
@ -21,11 +21,12 @@ import System.OsString as X hiding (length)
|
||||||
import qualified System.OsString
|
import qualified System.OsString
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import Utility.OsPath
|
import Utility.OsPath
|
||||||
|
import Prelude ((.), Int)
|
||||||
|
|
||||||
{- Avoid System.OsString.length, which returns the number of code points on
|
{- Avoid System.OsString.length, which returns the number of code points on
|
||||||
- windows. This is the number of bytes. -}
|
- windows. This is the number of bytes. -}
|
||||||
length :: System.OsString.OsString -> Int
|
length :: System.OsString.OsString -> Int
|
||||||
length = B.length . fromOsString
|
length = B.length . fromOsPath
|
||||||
#else
|
#else
|
||||||
import Data.ByteString as X hiding (length)
|
import Data.ByteString as X hiding (length)
|
||||||
import Data.ByteString (length)
|
import Data.ByteString (length)
|
||||||
|
|
|
@ -28,7 +28,6 @@ module Utility.Path (
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified System.FilePath.ByteString as PB
|
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
@ -70,9 +69,10 @@ simplifyPath path = dropTrailingPathSeparator $
|
||||||
|
|
||||||
norm c [] = reverse c
|
norm c [] = reverse c
|
||||||
norm c (p:ps)
|
norm c (p:ps)
|
||||||
| p' == ".." && not (null c) && dropTrailingPathSeparator (c !! 0) /= ".." =
|
| p' == dotdot && not (null c)
|
||||||
norm (drop 1 c) ps
|
&& dropTrailingPathSeparator (c !! 0) /= dotdot =
|
||||||
| p' == "." = norm c ps
|
norm (drop 1 c) ps
|
||||||
|
| p' == dot = norm c ps
|
||||||
| otherwise = norm (p:c) ps
|
| otherwise = norm (p:c) ps
|
||||||
where
|
where
|
||||||
p' = dropTrailingPathSeparator p
|
p' = dropTrailingPathSeparator p
|
||||||
|
@ -86,8 +86,8 @@ parentDir = takeDirectory . dropTrailingPathSeparator
|
||||||
upFrom :: OsPath -> Maybe OsPath
|
upFrom :: OsPath -> Maybe OsPath
|
||||||
upFrom dir
|
upFrom dir
|
||||||
| length dirs < 2 = Nothing
|
| length dirs < 2 = Nothing
|
||||||
| otherwise = Just $ joinDrive drive $ toOsPath $
|
| otherwise = Just $ joinDrive drive $
|
||||||
B.intercalate (B.singleton PB.pathSeparator) $ init dirs
|
OS.intercalate (OS.singleton pathSeparator) $ init dirs
|
||||||
where
|
where
|
||||||
-- on Unix, the drive will be "/" when the dir is absolute,
|
-- on Unix, the drive will be "/" when the dir is absolute,
|
||||||
-- otherwise ""
|
-- otherwise ""
|
||||||
|
@ -101,8 +101,8 @@ upFrom dir
|
||||||
dirContains :: OsPath -> OsPath -> Bool
|
dirContains :: OsPath -> OsPath -> Bool
|
||||||
dirContains a b = a == b
|
dirContains a b = a == b
|
||||||
|| a' == b'
|
|| a' == b'
|
||||||
|| (a'' `B.isPrefixOf` b' && avoiddotdotb)
|
|| (a'' `OS.isPrefixOf` b' && avoiddotdotb)
|
||||||
|| a' == "." && normalise ("." </> b') == b' && nodotdot b'
|
|| a' == dot && normalise (dot </> b') == b' && nodotdot b'
|
||||||
|| dotdotcontains
|
|| dotdotcontains
|
||||||
where
|
where
|
||||||
a' = norm a
|
a' = norm a
|
||||||
|
@ -124,7 +124,7 @@ dirContains a b = a == b
|
||||||
|
|
||||||
nodotdot p = all (not . isdotdot) (splitPath p)
|
nodotdot p = all (not . isdotdot) (splitPath p)
|
||||||
|
|
||||||
isdotdot s = dropTrailingPathSeparator s == ".."
|
isdotdot s = dropTrailingPathSeparator s == dotdot
|
||||||
|
|
||||||
{- This handles the case where a is ".." or "../.." etc,
|
{- This handles the case where a is ".." or "../.." etc,
|
||||||
- and b is "foo" or "../foo" etc. The rule is that when
|
- and b is "foo" or "../foo" etc. The rule is that when
|
||||||
|
@ -185,10 +185,10 @@ runSegmentPaths' si c a paths = segmentPaths' si c paths <$> a paths
|
||||||
- count as dotfiles. -}
|
- count as dotfiles. -}
|
||||||
dotfile :: OsPath -> Bool
|
dotfile :: OsPath -> Bool
|
||||||
dotfile file
|
dotfile file
|
||||||
| f == "." = False
|
| f == dot = False
|
||||||
| f == ".." = False
|
| f == dotdot = False
|
||||||
| f == "" = False
|
| f == literalOsPath "" = False
|
||||||
| otherwise = "." `OS.isPrefixOf` f || dotfile (takeDirectory file)
|
| otherwise = dot `OS.isPrefixOf` f || dotfile (takeDirectory file)
|
||||||
where
|
where
|
||||||
f = takeFileName file
|
f = takeFileName file
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ relPathDirToFileAbs from to
|
||||||
common = map fst $ takeWhile same $ zip pfrom pto
|
common = map fst $ takeWhile same $ zip pfrom pto
|
||||||
same (c,d) = c == d
|
same (c,d) = c == d
|
||||||
uncommon = drop numcommon pto
|
uncommon = drop numcommon pto
|
||||||
dotdots = replicate (length pfrom - numcommon) ".."
|
dotdots = replicate (length pfrom - numcommon) dotdot
|
||||||
numcommon = length common
|
numcommon = length common
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
normdrive = map toLower
|
normdrive = map toLower
|
||||||
|
@ -255,7 +255,7 @@ inSearchPath command = isJust <$> searchPath command
|
||||||
searchPath :: String -> IO (Maybe OsPath)
|
searchPath :: String -> IO (Maybe OsPath)
|
||||||
searchPath command
|
searchPath command
|
||||||
| isAbsolute command' = copyright $ check command'
|
| isAbsolute command' = copyright $ check command'
|
||||||
| otherwise = getSearchPath >>= getM indir . map toOsPath
|
| otherwise = getSearchPath >>= getM indir
|
||||||
where
|
where
|
||||||
command' = toOsPath command
|
command' = toOsPath command
|
||||||
indir d = check (d </> command')
|
indir d = check (d </> command')
|
||||||
|
@ -275,7 +275,14 @@ searchPath command
|
||||||
searchPathContents :: (OsPath -> Bool) -> IO [OsPath]
|
searchPathContents :: (OsPath -> Bool) -> IO [OsPath]
|
||||||
searchPathContents p =
|
searchPathContents p =
|
||||||
filterM doesFileExist
|
filterM doesFileExist
|
||||||
=<< (concat <$> (getSearchPath >>= mapM (go . toOsPath)))
|
=<< (concat <$> (getSearchPath >>= mapM go))
|
||||||
where
|
where
|
||||||
go d = map (d </>) . filter p
|
go d = map (d </>) . filter p
|
||||||
<$> catchDefaultIO [] (getDirectoryContents d)
|
<$> catchDefaultIO [] (getDirectoryContents d)
|
||||||
|
|
||||||
|
dot :: OsPath
|
||||||
|
dot = literalOsPath "."
|
||||||
|
|
||||||
|
dotdot :: OsPath
|
||||||
|
dotdot = literalOsPath ".."
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ module Utility.Path.AbsRel (
|
||||||
relHome,
|
relHome,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import System.FilePath.ByteString
|
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
|
@ -17,7 +17,6 @@ module Utility.Path.Tests (
|
||||||
prop_dirContains_regressionTest,
|
prop_dirContains_regressionTest,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import System.FilePath.ByteString
|
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
@ -25,8 +24,8 @@ import Data.Char
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
|
import Common
|
||||||
import Utility.Path
|
import Utility.Path
|
||||||
import Utility.FileSystemEncoding
|
|
||||||
import Utility.QuickCheck
|
import Utility.QuickCheck
|
||||||
|
|
||||||
prop_upFrom_basics :: TestableFilePath -> Bool
|
prop_upFrom_basics :: TestableFilePath -> Bool
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue