Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 641e23c3ef | |||
| 82ea75cc88 | |||
| abf043be14 | |||
| 10adc4be27 | |||
| a176e4970b | |||
| 08de2ebefb | |||
| d15d7761c1 | |||
| 7e924d3386 | |||
| 21fccc9ca9 | |||
| 79dbcd8b55 |
@@ -9,8 +9,10 @@ matrix:
|
|||||||
include:
|
include:
|
||||||
- env: CABALVER=1.22 GHCVER=7.8.4
|
- env: CABALVER=1.22 GHCVER=7.8.4
|
||||||
addons: {apt: {packages: [cabal-install-1.22,ghc-7.8.4], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [cabal-install-1.22,ghc-7.8.4], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=1.22 GHCVER=7.10.2
|
- env: CABALVER=1.24 GHCVER=7.10.2
|
||||||
addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [cabal-install-1.24,ghc-7.10.2], sources: [hvr-ghc]}}
|
||||||
|
- env: CABALVER=1.24 GHCVER=8.0.1
|
||||||
|
addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=head GHCVER=head
|
- env: CABALVER=head GHCVER=head
|
||||||
addons: {apt: {packages: [cabal-install-head,ghc-head], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [cabal-install-head,ghc-head], sources: [hvr-ghc]}}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
0.7.3:
|
||||||
|
* don't expose HPath.Internal
|
||||||
0.7.2:
|
0.7.2:
|
||||||
* fix tests, so they work with the sdist tarball too
|
* fix tests, so they work with the sdist tarball too
|
||||||
* added the following function to HPath.IO: createSymlink
|
* added the following function to HPath.IO: createSymlink
|
||||||
|
|||||||
23
README.md
23
README.md
@@ -62,3 +62,26 @@ Note: this library was written for __posix__ systems and it will probably not su
|
|||||||
* has a custom versions of `openFd` which allows more control over the flags than its unix package counterpart
|
* has a custom versions of `openFd` which allows more control over the flags than its unix package counterpart
|
||||||
* adds a `getDirectoryContents'` version that works on Fd
|
* adds a `getDirectoryContents'` version that works on Fd
|
||||||
|
|
||||||
|
## Examples in ghci
|
||||||
|
|
||||||
|
Start ghci via `cabal repl`:
|
||||||
|
|
||||||
|
```hs
|
||||||
|
-- enable OverloadedStrings
|
||||||
|
:set -XOverloadedStrings
|
||||||
|
-- import HPath.IO
|
||||||
|
import HPath.IO
|
||||||
|
-- parse an absolute path
|
||||||
|
abspath <- parseAbs "/home"
|
||||||
|
-- parse a relative path (e.g. user users home directory)
|
||||||
|
relpath <- parseRel "jule"
|
||||||
|
-- concatenate paths
|
||||||
|
let newpath = abspath </> relpath
|
||||||
|
-- get file type
|
||||||
|
getFileType newpath
|
||||||
|
-- return all contents of that directory
|
||||||
|
getDirsFiles newpath
|
||||||
|
-- return all contents of the parent directory
|
||||||
|
getDirsFiles (dirname newpath)
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
{-# LANGUAGE ForeignFunctionInterface #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE TupleSections #-}
|
|
||||||
{-# LANGUAGE ViewPatterns #-}
|
|
||||||
|
|
||||||
{-# OPTIONS_GHC -Wall #-}
|
|
||||||
import Control.Applicative
|
|
||||||
import Control.Monad
|
|
||||||
import System.Directory
|
|
||||||
import System.FilePath ((</>))
|
|
||||||
import System.Posix.ByteString.FilePath
|
|
||||||
import System.Posix.Directory.ByteString as PosixBS
|
|
||||||
import System.Posix.Directory.Traversals
|
|
||||||
import qualified System.Posix.FilePath as PosixBS
|
|
||||||
import System.Posix.Files.ByteString
|
|
||||||
|
|
||||||
import Control.Exception
|
|
||||||
import qualified Data.ByteString.Char8 as BS
|
|
||||||
|
|
||||||
import System.Environment (getArgs, withArgs)
|
|
||||||
import System.IO.Error
|
|
||||||
import System.IO.Unsafe
|
|
||||||
import System.Process (system)
|
|
||||||
import Criterion.Main
|
|
||||||
|
|
||||||
|
|
||||||
-- | Based on code from 'Real World Haskell', at
|
|
||||||
-- http://book.realworldhaskell.org/read/io-case-study-a-library-for-searching-the-filesystem.html#id620419
|
|
||||||
listFilesRecursive :: FilePath -> IO [FilePath]
|
|
||||||
listFilesRecursive topdir = do
|
|
||||||
names <- System.Directory.getDirectoryContents topdir
|
|
||||||
let properNames = filter (`notElem` [".", ".."]) names
|
|
||||||
paths <- forM properNames $ \name -> do
|
|
||||||
let path = topdir </> name
|
|
||||||
isDir <- doesDirectoryExist path
|
|
||||||
if isDir
|
|
||||||
then listFilesRecursive path
|
|
||||||
else return [path]
|
|
||||||
return (topdir : concat paths)
|
|
||||||
|
|
||||||
----------------------------------------------------------
|
|
||||||
|
|
||||||
getDirectoryContentsBS :: RawFilePath -> IO [RawFilePath]
|
|
||||||
getDirectoryContentsBS path =
|
|
||||||
modifyIOError ((`ioeSetFileName` (BS.unpack path)) .
|
|
||||||
(`ioeSetLocation` "getDirectoryContentsBS")) $ do
|
|
||||||
bracket
|
|
||||||
(PosixBS.openDirStream path)
|
|
||||||
PosixBS.closeDirStream
|
|
||||||
loop
|
|
||||||
where
|
|
||||||
loop dirp = do
|
|
||||||
e <- PosixBS.readDirStream dirp
|
|
||||||
if BS.null e then return [] else do
|
|
||||||
es <- loop dirp
|
|
||||||
return (e:es)
|
|
||||||
|
|
||||||
|
|
||||||
-- | similar to 'listFilesRecursive, but uses RawFilePaths
|
|
||||||
listFilesRecursiveBS :: RawFilePath -> IO [RawFilePath]
|
|
||||||
listFilesRecursiveBS topdir = do
|
|
||||||
names <- getDirectoryContentsBS topdir
|
|
||||||
let properNames = filter (`notElem` [".", ".."]) names
|
|
||||||
paths <- forM properNames $ \name -> unsafeInterleaveIO $ do
|
|
||||||
let path = PosixBS.combine topdir name
|
|
||||||
isDir <- isDirectory <$> getFileStatus path
|
|
||||||
if isDir
|
|
||||||
then listFilesRecursiveBS path
|
|
||||||
else return [path]
|
|
||||||
return (topdir : concat paths)
|
|
||||||
----------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
benchTraverse :: RawFilePath -> IO ()
|
|
||||||
benchTraverse = traverseDirectory (\() p -> BS.putStrLn p) ()
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
args <- getArgs
|
|
||||||
let (d,otherArgs) = case args of
|
|
||||||
[] -> ("/usr/local",[])
|
|
||||||
x:xs -> (x,xs)
|
|
||||||
withArgs otherArgs $ defaultMain
|
|
||||||
[ bench "traverse (FilePath)" $ nfIO $ listFilesRecursive d >>= mapM_ putStrLn
|
|
||||||
, bench "traverse (RawFilePath)" $ nfIO $ listFilesRecursiveBS (BS.pack d) >>= mapM_ BS.putStrLn
|
|
||||||
, bench "allDirectoryContents" $ nfIO $ allDirectoryContents (BS.pack d) >>= mapM_ BS.putStrLn
|
|
||||||
, bench "allDirectoryContents'" $ nfIO $ allDirectoryContents' (BS.pack d) >>= mapM_ BS.putStrLn
|
|
||||||
, bench "traverseDirectory" $ nfIO $ benchTraverse (BS.pack d)
|
|
||||||
, bench "unix find" $ nfIO $ void $ system ("find " ++ d)
|
|
||||||
]
|
|
||||||
22
hpath.cabal
22
hpath.cabal
@@ -1,5 +1,5 @@
|
|||||||
name: hpath
|
name: hpath
|
||||||
version: 0.7.2
|
version: 0.7.3
|
||||||
synopsis: Support for well-typed paths
|
synopsis: Support for well-typed paths
|
||||||
description: Support for well-typed paths, utilizing ByteString under the hood.
|
description: Support for well-typed paths, utilizing ByteString under the hood.
|
||||||
license: GPL-2
|
license: GPL-2
|
||||||
@@ -12,7 +12,6 @@ build-type: Simple
|
|||||||
cabal-version: >=1.14
|
cabal-version: >=1.14
|
||||||
extra-source-files: README.md
|
extra-source-files: README.md
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
benchmarks/*.hs
|
|
||||||
cbits/dirutils.h
|
cbits/dirutils.h
|
||||||
doctests-hpath.hs
|
doctests-hpath.hs
|
||||||
doctests-posix.hs
|
doctests-posix.hs
|
||||||
@@ -26,11 +25,11 @@ library
|
|||||||
HPath.IO,
|
HPath.IO,
|
||||||
HPath.IO.Errors,
|
HPath.IO.Errors,
|
||||||
HPath.IO.Utils,
|
HPath.IO.Utils,
|
||||||
HPath.Internal,
|
|
||||||
System.Posix.Directory.Foreign,
|
System.Posix.Directory.Foreign,
|
||||||
System.Posix.Directory.Traversals,
|
System.Posix.Directory.Traversals,
|
||||||
System.Posix.FD,
|
System.Posix.FD,
|
||||||
System.Posix.FilePath
|
System.Posix.FilePath
|
||||||
|
other-modules: HPath.Internal
|
||||||
build-depends: base >= 4.2 && <5
|
build-depends: base >= 4.2 && <5
|
||||||
, bytestring >= 0.9.2.0
|
, bytestring >= 0.9.2.0
|
||||||
, deepseq
|
, deepseq
|
||||||
@@ -103,23 +102,6 @@ test-suite spec
|
|||||||
, unix-bytestring
|
, unix-bytestring
|
||||||
, utf8-string
|
, utf8-string
|
||||||
|
|
||||||
benchmark bench.hs
|
|
||||||
default-language: Haskell2010
|
|
||||||
type: exitcode-stdio-1.0
|
|
||||||
hs-source-dirs: benchmarks
|
|
||||||
main-is: Bench.hs
|
|
||||||
|
|
||||||
build-depends:
|
|
||||||
base,
|
|
||||||
hpath,
|
|
||||||
bytestring,
|
|
||||||
unix,
|
|
||||||
directory >= 1.1 && < 1.3,
|
|
||||||
filepath >= 1.2 && < 1.5,
|
|
||||||
process >= 1.0 && < 1.3,
|
|
||||||
criterion >= 0.6 && < 1.2
|
|
||||||
ghc-options: -O2
|
|
||||||
|
|
||||||
source-repository head
|
source-repository head
|
||||||
type: git
|
type: git
|
||||||
location: https://github.com/hasufell/hpath
|
location: https://github.com/hasufell/hpath
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ module HPath
|
|||||||
,Fn
|
,Fn
|
||||||
,PathParseException
|
,PathParseException
|
||||||
,PathException
|
,PathException
|
||||||
|
,RelC
|
||||||
-- * PatternSynonyms/ViewPatterns
|
-- * PatternSynonyms/ViewPatterns
|
||||||
,pattern Path
|
,pattern Path
|
||||||
-- * Path Parsing
|
-- * Path Parsing
|
||||||
@@ -89,12 +90,17 @@ data PathException = RootDirHasNoBasename
|
|||||||
deriving (Show,Typeable)
|
deriving (Show,Typeable)
|
||||||
instance Exception PathException
|
instance Exception PathException
|
||||||
|
|
||||||
|
class RelC m
|
||||||
|
|
||||||
instance RelC Rel
|
instance RelC Rel
|
||||||
instance RelC Fn
|
instance RelC Fn
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- PatternSynonyms
|
-- PatternSynonyms
|
||||||
|
|
||||||
|
#if __GLASGOW_HASKELL__ >= 710
|
||||||
|
pattern Path :: ByteString -> Path a
|
||||||
|
#endif
|
||||||
pattern Path x <- (MkPath x)
|
pattern Path x <- (MkPath x)
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
-- | Internal types and functions.
|
-- | Internal types and functions.
|
||||||
|
|
||||||
module HPath.Internal
|
module HPath.Internal
|
||||||
(Path(..)
|
(Path(..))
|
||||||
,RelC)
|
|
||||||
where
|
where
|
||||||
|
|
||||||
import Control.DeepSeq (NFData (..))
|
import Control.DeepSeq (NFData (..))
|
||||||
@@ -13,7 +12,7 @@ import Data.Data
|
|||||||
|
|
||||||
-- | Path of some base and type.
|
-- | Path of some base and type.
|
||||||
--
|
--
|
||||||
-- Internally is a string. The string can be of two formats only:
|
-- Internally is a ByteString. The ByteString can be of two formats only:
|
||||||
--
|
--
|
||||||
-- 1. without trailing path separator: @file.txt@, @foo\/bar.txt@, @\/foo\/bar.txt@
|
-- 1. without trailing path separator: @file.txt@, @foo\/bar.txt@, @\/foo\/bar.txt@
|
||||||
-- 2. with trailing path separator: @foo\/@, @\/foo\/bar\/@
|
-- 2. with trailing path separator: @foo\/@, @\/foo\/bar\/@
|
||||||
@@ -23,7 +22,7 @@ import Data.Data
|
|||||||
data Path b = MkPath ByteString
|
data Path b = MkPath ByteString
|
||||||
deriving (Typeable)
|
deriving (Typeable)
|
||||||
|
|
||||||
-- | String equality.
|
-- | ByteString equality.
|
||||||
--
|
--
|
||||||
-- The following property holds:
|
-- The following property holds:
|
||||||
--
|
--
|
||||||
@@ -31,7 +30,7 @@ data Path b = MkPath ByteString
|
|||||||
instance Eq (Path b) where
|
instance Eq (Path b) where
|
||||||
(==) (MkPath x) (MkPath y) = x == y
|
(==) (MkPath x) (MkPath y) = x == y
|
||||||
|
|
||||||
-- | String ordering.
|
-- | ByteString ordering.
|
||||||
--
|
--
|
||||||
-- The following property holds:
|
-- The following property holds:
|
||||||
--
|
--
|
||||||
@@ -39,7 +38,7 @@ instance Eq (Path b) where
|
|||||||
instance Ord (Path b) where
|
instance Ord (Path b) where
|
||||||
compare (MkPath x) (MkPath y) = compare x y
|
compare (MkPath x) (MkPath y) = compare x y
|
||||||
|
|
||||||
-- | Same as 'Path.toFilePath'.
|
-- | Same as 'HPath.toFilePath'.
|
||||||
--
|
--
|
||||||
-- The following property holds:
|
-- The following property holds:
|
||||||
--
|
--
|
||||||
@@ -50,6 +49,3 @@ instance Show (Path b) where
|
|||||||
instance NFData (Path b) where
|
instance NFData (Path b) where
|
||||||
rnf (MkPath x) = rnf x
|
rnf (MkPath x) = rnf x
|
||||||
|
|
||||||
|
|
||||||
class RelC m
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user