Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 12 additions & 23 deletions src/Streamly/Coreutils/Cp.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module Streamly.Coreutils.Cp
( cp

-- * Cp options
, Cp
, CpOptions
, CpOverwrite (..)
-- , CpBackup
, cpOverwrite
Expand All @@ -25,6 +25,7 @@ import Control.Monad (when)
import Data.Function ((&))
import System.PosixCompat.Files (createLink)
import qualified Streamly.Internal.FileSystem.FileIO as File
import Streamly.FileSystem.Path (Path)
import qualified Streamly.FileSystem.Path as Path

import Streamly.Coreutils.FileTest
Expand All @@ -41,15 +42,6 @@ import Streamly.Coreutils.FileTest
-- Ideally, cp should not hard link as we have ln for hard linking, but it can
-- be useful when we need to hard link recursively.

-- Path vs FilePath:
--
-- Ideally, we want to use "Path" instead of "FilePath" in this module. However,
-- this change isn't very straightforward at the moment due to the dependence on
-- System.PosixCompat.Files.
--
-- Streamly.Coreutils.FileTest relies on System.PosixCompat.Files for most of
-- its APIs.

-- | Specify the overwrite behavior of copy.
data CpOverwrite =
OverwriteNever -- ^ Do not overwrite when destination file exists
Expand All @@ -68,13 +60,13 @@ data CpMethod =
| SymbolicLink
| CopyClone -- Use the cloning method if available on the platform

data Cp = Cp
data CpOptions = CpOptions
{ optOverwrite :: CpOverwrite
, optCopyMethod :: CpMethod
}

defaultOptions :: Cp
defaultOptions = Cp
defaultOptions :: CpOptions
defaultOptions = CpOptions
{ optOverwrite = OverwriteAlways
, optCopyMethod = CopyContents
}
Expand All @@ -83,32 +75,29 @@ defaultOptions = Cp
--
-- Default is 'OverwriteAlways'.
--
cpOverwrite :: CpOverwrite -> Cp -> Cp
cpOverwrite :: CpOverwrite -> CpOptions -> CpOptions
cpOverwrite opt options = options { optOverwrite = opt }

-- | Specify the copy method.
--
-- Default is 'CopyContents'.
--
cpMethod :: CpMethod -> Cp -> Cp
cpMethod :: CpMethod -> CpOptions -> CpOptions
cpMethod opt options = options { optCopyMethod = opt }

-- | Unconditionally copy the source to destination using the specified copy
-- method.
cpCopy :: CpMethod -> FilePath -> FilePath -> IO ()
cpCopy :: CpMethod -> Path -> Path -> IO ()
cpCopy method src dest =
case method of
CopyContents -> do
srcP <- Path.fromString src
destP <- Path.fromString dest
File.readChunks srcP & File.fromChunks destP
HardLink -> createLink src dest
CopyContents -> File.readChunks src & File.fromChunks dest
HardLink -> createLink (Path.toString src) (Path.toString dest)
SymbolicLink -> error "Unimplemented"
CopyClone -> error "Unimplemented"

-- | Determine whether source should be copied to destination based on the
-- specified overwrite behavior option.
cpShouldOverwrite :: CpOverwrite -> FilePath -> FilePath -> IO Bool
cpShouldOverwrite :: CpOverwrite -> Path -> Path -> IO Bool
cpShouldOverwrite option src dest =
case option of
OverwriteAlways -> return True
Expand All @@ -121,7 +110,7 @@ cpShouldOverwrite option src dest =
else return True

-- | @cp option-modifier source destination@. Copy a file or directory.
cp :: (Cp -> Cp) -> FilePath -> FilePath -> IO ()
cp :: (CpOptions -> CpOptions) -> Path -> Path -> IO ()
cp f src dest = do
let options = f defaultOptions
r <- cpShouldOverwrite (optOverwrite options) src dest
Expand Down
19 changes: 11 additions & 8 deletions src/Streamly/Coreutils/Directory.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,29 @@ import System.Directory
, setCurrentDirectory
)

import Streamly.FileSystem.Path (Path)
import qualified Streamly.FileSystem.Path as Path

-- | Get home directory of the current user.
home :: IO FilePath
home = getHomeDirectory
home :: IO Path
home = getHomeDirectory >>= Path.fromString

-- XXX Support -L and -P options? Move this to its own module.

-- | Get the current working directory of the process.
pwd :: IO FilePath
pwd = getCurrentDirectory
pwd :: IO Path
pwd = getCurrentDirectory >>= Path.fromString

-- XXX Set PWD env var? Move to its own module?
-- Support -L, -P options?

-- | Set the current working directory of the process.
cd :: FilePath -> IO ()
cd = setCurrentDirectory
cd :: Path -> IO ()
cd = setCurrentDirectory . Path.toString

-- | Run an IO action with the given working directory and restore the
-- original working directory afterwards, even if the given action fails
-- due to an exception.
--
withCd :: FilePath -> IO () -> IO ()
withCd = withCurrentDirectory
withCd :: Path -> IO () -> IO ()
withCd = withCurrentDirectory . Path.toString
7 changes: 5 additions & 2 deletions src/Streamly/Coreutils/Dirname.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ where

import System.FilePath (takeDirectory)

dirname :: FilePath -> FilePath
dirname = takeDirectory
import Streamly.FileSystem.Path (Path)
import qualified Streamly.FileSystem.Path as Path

dirname :: Path -> IO Path
dirname path = Path.fromString (takeDirectory (Path.toString path))
11 changes: 7 additions & 4 deletions src/Streamly/Coreutils/FileTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@
--
-- Example:
--
-- >>> _ <- test "a" doesItExist
-- >>> _ <- test "/usr/bin/ls" (isReadable `and_` size (> 4096))
-- >>> _ <- test "/usr/bin/ls" (modifyTimeComparedTo "reference.txt" (>))
-- >>> _ <- test [path|a|] doesItExist
-- >>> _ <- test [path|/usr/bin/ls|] (isReadable `and_` size (> 4096))
-- >>> _ <- test [path|/usr/bin/ls|] (modifyTimeComparedTo [path|reference.txt|] (>))

module Streamly.Coreutils.FileTest
(
Expand Down Expand Up @@ -254,13 +254,16 @@ import qualified Streamly.Coreutils.FileTest.Posix as FileTest
import qualified Streamly.Coreutils.FileTest.Windows as FileTest
#endif

import Streamly.FileSystem.Path (Path)
import Streamly.Coreutils.FileTest.Common
import Prelude hiding (and, or)

-- $setup
-- >>> :set -XQuasiQuotes
-- >>> import Prelude hiding (or, and)
-- >>> import Data.Time.Clock (NominalDiffTime)
-- >>> import Data.Time.Clock.POSIX (POSIXTime)
-- >>> import Streamly.FileSystem.Path (path)

-------------------------------------------------------------------------------
-- User and group ownerships
Expand Down Expand Up @@ -464,7 +467,7 @@ isExecutable = FileTest.isExecutable
--
-- The supplied file path is dereferenced if it is a symlink.
--
sameFileAs :: FilePath -> FileTest
sameFileAs :: Path -> FileTest
sameFileAs = FileTest.sameFileAs

-- | True if the supplied file descriptor refers to a terminal device.
Expand Down
Loading
Loading