broke up Utility
This commit is contained in:
parent
91366c896d
commit
23f2a12816
16 changed files with 126 additions and 112 deletions
|
@ -16,6 +16,7 @@ import Common.Annex
|
||||||
import Command
|
import Command
|
||||||
import Annex.Content
|
import Annex.Content
|
||||||
import Utility.FileMode
|
import Utility.FileMode
|
||||||
|
import Utility.TempFile
|
||||||
import Logs.Location
|
import Logs.Location
|
||||||
import qualified Annex
|
import qualified Annex
|
||||||
import qualified Git
|
import qualified Git
|
||||||
|
|
|
@ -15,7 +15,7 @@ module Common (
|
||||||
module System.Posix.IO,
|
module System.Posix.IO,
|
||||||
module System.Posix.Process,
|
module System.Posix.Process,
|
||||||
module System.Exit,
|
module System.Exit,
|
||||||
module Utility,
|
module Utility.Misc,
|
||||||
module Utility.Conditional,
|
module Utility.Conditional,
|
||||||
module Utility.SafeCommand,
|
module Utility.SafeCommand,
|
||||||
module Utility.Path,
|
module Utility.Path,
|
||||||
|
@ -40,7 +40,7 @@ import System.Posix.IO
|
||||||
import System.Posix.Process hiding (executeFile)
|
import System.Posix.Process hiding (executeFile)
|
||||||
import System.Exit
|
import System.Exit
|
||||||
|
|
||||||
import Utility
|
import Utility.Misc
|
||||||
import Utility.Conditional
|
import Utility.Conditional
|
||||||
import Utility.SafeCommand
|
import Utility.SafeCommand
|
||||||
import Utility.Path
|
import Utility.Path
|
||||||
|
|
1
Init.hs
1
Init.hs
|
@ -12,6 +12,7 @@ module Init (
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
|
import Utility.TempFile
|
||||||
import qualified Git
|
import qualified Git
|
||||||
import qualified Annex.Branch
|
import qualified Annex.Branch
|
||||||
import Annex.Version
|
import Annex.Version
|
||||||
|
|
|
@ -20,6 +20,7 @@ import qualified Annex
|
||||||
import Annex.UUID
|
import Annex.UUID
|
||||||
import qualified Annex.Content
|
import qualified Annex.Content
|
||||||
import qualified Utility.Url as Url
|
import qualified Utility.Url as Url
|
||||||
|
import Utility.TempFile
|
||||||
import Config
|
import Config
|
||||||
import Init
|
import Init
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ import qualified Data.Map as M
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
import Types.Remote
|
import Types.Remote
|
||||||
import qualified Git
|
import qualified Git
|
||||||
import Logs.UUID
|
|
||||||
import Config
|
import Config
|
||||||
import Annex.Content
|
import Annex.Content
|
||||||
import Remote.Helper.Special
|
import Remote.Helper.Special
|
||||||
|
|
|
@ -21,7 +21,6 @@ import Common.Annex
|
||||||
import Types.Remote
|
import Types.Remote
|
||||||
import Types.Key
|
import Types.Key
|
||||||
import qualified Git
|
import qualified Git
|
||||||
import Logs.UUID
|
|
||||||
import Config
|
import Config
|
||||||
import Remote.Helper.Special
|
import Remote.Helper.Special
|
||||||
import Remote.Helper.Encryptable
|
import Remote.Helper.Encryptable
|
||||||
|
|
|
@ -13,6 +13,7 @@ import qualified Git
|
||||||
import Config
|
import Config
|
||||||
import Logs.Web
|
import Logs.Web
|
||||||
import qualified Utility.Url as Url
|
import qualified Utility.Url as Url
|
||||||
|
import Utility.Monad
|
||||||
|
|
||||||
remote :: RemoteType Annex
|
remote :: RemoteType Annex
|
||||||
remote = RemoteType {
|
remote = RemoteType {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import qualified Git.LsFiles as LsFiles
|
||||||
import Backend
|
import Backend
|
||||||
import Annex.Version
|
import Annex.Version
|
||||||
import Utility.FileMode
|
import Utility.FileMode
|
||||||
|
import Utility.TempFile
|
||||||
import qualified Upgrade.V2
|
import qualified Upgrade.V2
|
||||||
|
|
||||||
-- v2 adds hashing of filenames of content and location log files.
|
-- v2 adds hashing of filenames of content and location log files.
|
||||||
|
|
|
@ -12,6 +12,7 @@ import qualified Git
|
||||||
import qualified Annex.Branch
|
import qualified Annex.Branch
|
||||||
import Logs.Location
|
import Logs.Location
|
||||||
import Annex.Content
|
import Annex.Content
|
||||||
|
import Utility.TempFile
|
||||||
|
|
||||||
olddir :: Git.Repo -> FilePath
|
olddir :: Git.Repo -> FilePath
|
||||||
olddir g
|
olddir g
|
||||||
|
|
106
Utility.hs
106
Utility.hs
|
@ -1,106 +0,0 @@
|
||||||
{- general purpose utility functions
|
|
||||||
-
|
|
||||||
- Copyright 2010-2011 Joey Hess <joey@kitenet.net>
|
|
||||||
-
|
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
|
||||||
-}
|
|
||||||
|
|
||||||
module Utility (
|
|
||||||
hGetContentsStrict,
|
|
||||||
readFileStrict,
|
|
||||||
readMaybe,
|
|
||||||
viaTmp,
|
|
||||||
withTempFile,
|
|
||||||
dirContents,
|
|
||||||
myHomeDir,
|
|
||||||
catchBool,
|
|
||||||
inPath,
|
|
||||||
firstM,
|
|
||||||
anyM
|
|
||||||
) where
|
|
||||||
|
|
||||||
import Control.Applicative
|
|
||||||
import IO (bracket)
|
|
||||||
import System.IO
|
|
||||||
import System.Posix.Process hiding (executeFile)
|
|
||||||
import System.Posix.User
|
|
||||||
import System.FilePath
|
|
||||||
import System.Directory
|
|
||||||
import Utility.Path
|
|
||||||
import Data.Maybe
|
|
||||||
import Control.Monad (liftM)
|
|
||||||
|
|
||||||
{- A version of hgetContents that is not lazy. Ensures file is
|
|
||||||
- all read before it gets closed. -}
|
|
||||||
hGetContentsStrict :: Handle -> IO String
|
|
||||||
hGetContentsStrict h = hGetContents h >>= \s -> length s `seq` return s
|
|
||||||
|
|
||||||
{- A version of readFile that is not lazy. -}
|
|
||||||
readFileStrict :: FilePath -> IO String
|
|
||||||
readFileStrict f = readFile f >>= \s -> length s `seq` return s
|
|
||||||
|
|
||||||
{- Attempts to read a value from a String. -}
|
|
||||||
readMaybe :: (Read a) => String -> Maybe a
|
|
||||||
readMaybe s = case reads s of
|
|
||||||
((x,_):_) -> Just x
|
|
||||||
_ -> Nothing
|
|
||||||
|
|
||||||
{- Runs an action like writeFile, writing to a tmp file first and
|
|
||||||
- then moving it into place. -}
|
|
||||||
viaTmp :: (FilePath -> String -> IO ()) -> FilePath -> String -> IO ()
|
|
||||||
viaTmp a file content = do
|
|
||||||
pid <- getProcessID
|
|
||||||
let tmpfile = file ++ ".tmp" ++ show pid
|
|
||||||
createDirectoryIfMissing True (parentDir file)
|
|
||||||
a tmpfile content
|
|
||||||
renameFile tmpfile file
|
|
||||||
|
|
||||||
{- Runs an action with a temp file, then removes the file. -}
|
|
||||||
withTempFile :: String -> (FilePath -> Handle -> IO a) -> IO a
|
|
||||||
withTempFile template a = bracket create remove use
|
|
||||||
where
|
|
||||||
create = do
|
|
||||||
tmpdir <- catch getTemporaryDirectory (const $ return ".")
|
|
||||||
openTempFile tmpdir template
|
|
||||||
remove (name, handle) = do
|
|
||||||
hClose handle
|
|
||||||
catchBool (removeFile name >> return True)
|
|
||||||
use (name, handle) = a name handle
|
|
||||||
|
|
||||||
{- Lists the contents of a directory.
|
|
||||||
- Unlike getDirectoryContents, paths are not relative to the directory. -}
|
|
||||||
dirContents :: FilePath -> IO [FilePath]
|
|
||||||
dirContents d = map (d </>) . filter notcruft <$> getDirectoryContents d
|
|
||||||
where
|
|
||||||
notcruft "." = False
|
|
||||||
notcruft ".." = False
|
|
||||||
notcruft _ = True
|
|
||||||
|
|
||||||
{- Current user's home directory. -}
|
|
||||||
myHomeDir :: IO FilePath
|
|
||||||
myHomeDir = homeDirectory <$> (getUserEntryForID =<< getEffectiveUserID)
|
|
||||||
|
|
||||||
{- Catches IO errors and returns a Bool -}
|
|
||||||
catchBool :: IO Bool -> IO Bool
|
|
||||||
catchBool = flip catch (const $ return False)
|
|
||||||
|
|
||||||
{- Return the first value from a list, if any, satisfying the given
|
|
||||||
- predicate -}
|
|
||||||
firstM :: (Monad m) => (a -> m Bool) -> [a] -> m (Maybe a)
|
|
||||||
firstM _ [] = return Nothing
|
|
||||||
firstM p (x:xs) = do
|
|
||||||
q <- p x
|
|
||||||
if q
|
|
||||||
then return (Just x)
|
|
||||||
else firstM p xs
|
|
||||||
|
|
||||||
{- Returns true if any value in the list satisfies the preducate,
|
|
||||||
- stopping once one is found. -}
|
|
||||||
anyM :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
|
|
||||||
anyM p = liftM isJust . firstM p
|
|
||||||
|
|
||||||
{- Checks if a command is available in PATH. -}
|
|
||||||
inPath :: String -> IO Bool
|
|
||||||
inPath command = getSearchPath >>= anyM indir
|
|
||||||
where
|
|
||||||
indir d = doesFileExist $ d </> command
|
|
29
Utility/Misc.hs
Normal file
29
Utility/Misc.hs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{- misc utility functions
|
||||||
|
-
|
||||||
|
- Copyright 2010-2011 Joey Hess <joey@kitenet.net>
|
||||||
|
-
|
||||||
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Utility.Misc where
|
||||||
|
|
||||||
|
import System.IO
|
||||||
|
|
||||||
|
{- A version of hgetContents that is not lazy. Ensures file is
|
||||||
|
- all read before it gets closed. -}
|
||||||
|
hGetContentsStrict :: Handle -> IO String
|
||||||
|
hGetContentsStrict h = hGetContents h >>= \s -> length s `seq` return s
|
||||||
|
|
||||||
|
{- A version of readFile that is not lazy. -}
|
||||||
|
readFileStrict :: FilePath -> IO String
|
||||||
|
readFileStrict f = readFile f >>= \s -> length s `seq` return s
|
||||||
|
|
||||||
|
{- Attempts to read a value from a String. -}
|
||||||
|
readMaybe :: (Read a) => String -> Maybe a
|
||||||
|
readMaybe s = case reads s of
|
||||||
|
((x,_):_) -> Just x
|
||||||
|
_ -> Nothing
|
||||||
|
|
||||||
|
{- Catches IO errors and returns a Bool -}
|
||||||
|
catchBool :: IO Bool -> IO Bool
|
||||||
|
catchBool = flip catch (const $ return False)
|
26
Utility/Monad.hs
Normal file
26
Utility/Monad.hs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{- monadic stuff
|
||||||
|
-
|
||||||
|
- Copyright 2010-2011 Joey Hess <joey@kitenet.net>
|
||||||
|
-
|
||||||
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Utility.Monad where
|
||||||
|
|
||||||
|
import Data.Maybe
|
||||||
|
import Control.Monad (liftM)
|
||||||
|
|
||||||
|
{- Return the first value from a list, if any, satisfying the given
|
||||||
|
- predicate -}
|
||||||
|
firstM :: (Monad m) => (a -> m Bool) -> [a] -> m (Maybe a)
|
||||||
|
firstM _ [] = return Nothing
|
||||||
|
firstM p (x:xs) = do
|
||||||
|
q <- p x
|
||||||
|
if q
|
||||||
|
then return (Just x)
|
||||||
|
else firstM p xs
|
||||||
|
|
||||||
|
{- Returns true if any value in the list satisfies the preducate,
|
||||||
|
- stopping once one is found. -}
|
||||||
|
anyM :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
|
||||||
|
anyM p = liftM isJust . firstM p
|
|
@ -14,6 +14,9 @@ import System.Directory
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
|
import System.Posix.User
|
||||||
|
|
||||||
|
import Utility.Monad
|
||||||
|
|
||||||
{- Returns the parent directory of a path. Parent of / is "" -}
|
{- Returns the parent directory of a path. Parent of / is "" -}
|
||||||
parentDir :: FilePath -> FilePath
|
parentDir :: FilePath -> FilePath
|
||||||
|
@ -112,3 +115,22 @@ preserveOrder (l:ls) new = found ++ preserveOrder ls rest
|
||||||
-}
|
-}
|
||||||
runPreserveOrder :: ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [FilePath]
|
runPreserveOrder :: ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [FilePath]
|
||||||
runPreserveOrder a files = preserveOrder files <$> a files
|
runPreserveOrder a files = preserveOrder files <$> a files
|
||||||
|
|
||||||
|
{- Lists the contents of a directory.
|
||||||
|
- Unlike getDirectoryContents, paths are not relative to the directory. -}
|
||||||
|
dirContents :: FilePath -> IO [FilePath]
|
||||||
|
dirContents d = map (d </>) . filter notcruft <$> getDirectoryContents d
|
||||||
|
where
|
||||||
|
notcruft "." = False
|
||||||
|
notcruft ".." = False
|
||||||
|
notcruft _ = True
|
||||||
|
|
||||||
|
{- Current user's home directory. -}
|
||||||
|
myHomeDir :: IO FilePath
|
||||||
|
myHomeDir = homeDirectory <$> (getUserEntryForID =<< getEffectiveUserID)
|
||||||
|
|
||||||
|
{- Checks if a command is available in PATH. -}
|
||||||
|
inPath :: String -> IO Bool
|
||||||
|
inPath command = getSearchPath >>= anyM indir
|
||||||
|
where
|
||||||
|
indir d = doesFileExist $ d </> command
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{- git-annex file copying with rsync
|
{- file copying with rsync
|
||||||
-
|
-
|
||||||
- Copyright 2010 Joey Hess <joey@kitenet.net>
|
- Copyright 2010 Joey Hess <joey@kitenet.net>
|
||||||
-
|
-
|
||||||
|
|
39
Utility/TempFile.hs
Normal file
39
Utility/TempFile.hs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{- temp file functions
|
||||||
|
-
|
||||||
|
- Copyright 2010-2011 Joey Hess <joey@kitenet.net>
|
||||||
|
-
|
||||||
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Utility.TempFile where
|
||||||
|
|
||||||
|
import IO (bracket)
|
||||||
|
import System.IO
|
||||||
|
import System.Posix.Process hiding (executeFile)
|
||||||
|
import System.Directory
|
||||||
|
|
||||||
|
import Utility.Misc
|
||||||
|
import Utility.Path
|
||||||
|
|
||||||
|
{- Runs an action like writeFile, writing to a temp file first and
|
||||||
|
- then moving it into place. The temp file is stored in the same
|
||||||
|
- directory as the final file to avoid cross-device renames. -}
|
||||||
|
viaTmp :: (FilePath -> String -> IO ()) -> FilePath -> String -> IO ()
|
||||||
|
viaTmp a file content = do
|
||||||
|
pid <- getProcessID
|
||||||
|
let tmpfile = file ++ ".tmp" ++ show pid
|
||||||
|
createDirectoryIfMissing True (parentDir file)
|
||||||
|
a tmpfile content
|
||||||
|
renameFile tmpfile file
|
||||||
|
|
||||||
|
{- Runs an action with a temp file, then removes the file. -}
|
||||||
|
withTempFile :: String -> (FilePath -> Handle -> IO a) -> IO a
|
||||||
|
withTempFile template a = bracket create remove use
|
||||||
|
where
|
||||||
|
create = do
|
||||||
|
tmpdir <- catch getTemporaryDirectory (const $ return ".")
|
||||||
|
openTempFile tmpdir template
|
||||||
|
remove (name, handle) = do
|
||||||
|
hClose handle
|
||||||
|
catchBool (removeFile name >> return True)
|
||||||
|
use (name, handle) = a name handle
|
|
@ -17,7 +17,7 @@ import Network.HTTP
|
||||||
import Network.URI
|
import Network.URI
|
||||||
|
|
||||||
import Utility.SafeCommand
|
import Utility.SafeCommand
|
||||||
import Utility
|
import Utility.Path
|
||||||
|
|
||||||
type URLString = String
|
type URLString = String
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue