Added wc
equivalent improved du
. Fixes #71
This commit is contained in:
parent
c1a97ca50e
commit
c37e941a49
2 changed files with 105 additions and 11 deletions
|
@ -1,5 +1,6 @@
|
|||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
|
||||
-- | This module provides a large suite of utilities that resemble Unix
|
||||
-- utilities.
|
||||
|
@ -123,7 +124,6 @@ module Turtle.Prelude (
|
|||
, rm
|
||||
, rmdir
|
||||
, rmtree
|
||||
, du
|
||||
, testfile
|
||||
, testdir
|
||||
, date
|
||||
|
@ -169,6 +169,11 @@ module Turtle.Prelude (
|
|||
, limitWhile
|
||||
, cache
|
||||
|
||||
-- * Folds
|
||||
, countChars
|
||||
, countWords
|
||||
, countLines
|
||||
|
||||
-- * Permissions
|
||||
, Permissions
|
||||
, chmod
|
||||
|
@ -179,13 +184,27 @@ module Turtle.Prelude (
|
|||
, executable, nonexecutable
|
||||
, searchable, nonsearchable
|
||||
, ooo,roo,owo,oox,oos,rwo,rox,ros,owx,rwx,rws
|
||||
|
||||
-- * File size
|
||||
, du
|
||||
, Size
|
||||
, bytes
|
||||
, kilobytes
|
||||
, megabytes
|
||||
, gigabytes
|
||||
, terabytes
|
||||
, kibibytes
|
||||
, mebibytes
|
||||
, gibibytes
|
||||
, tebibytes
|
||||
) where
|
||||
|
||||
import Control.Applicative (Alternative(..), (<*), (*>))
|
||||
import Control.Concurrent.Async (Async, withAsync, wait, concurrently)
|
||||
import Control.Concurrent (threadDelay)
|
||||
import Control.Exception (bracket, throwIO)
|
||||
import Control.Foldl (FoldM(..), list)
|
||||
import Control.Foldl (Fold, FoldM(..), genericLength, handles, list, premap)
|
||||
import qualified Control.Foldl.Text
|
||||
import Control.Monad (liftM, msum, when)
|
||||
import Control.Monad.IO.Class (MonadIO(..))
|
||||
import Control.Monad.Managed (Managed, managed)
|
||||
|
@ -195,6 +214,7 @@ import Data.Bits ((.&.))
|
|||
import Data.IORef (newIORef, readIORef, writeIORef)
|
||||
import Data.Text (Text, pack, unpack)
|
||||
import Data.Time (NominalDiffTime, UTCTime, getCurrentTime)
|
||||
import Data.Traversable (traverse)
|
||||
import qualified Data.Text as Text
|
||||
import qualified Data.Text.IO as Text
|
||||
import qualified Filesystem
|
||||
|
@ -562,10 +582,6 @@ rmdir path = liftIO (Filesystem.removeDirectory path)
|
|||
rmtree :: MonadIO io => FilePath -> io ()
|
||||
rmtree path = liftIO (Filesystem.removeTree path)
|
||||
|
||||
-- | Get the size of a file or a directory in kilobytes
|
||||
du :: MonadIO io => FilePath -> io Integer
|
||||
du path = liftIO (Filesystem.getSize path)
|
||||
|
||||
-- | Check if a file exists
|
||||
testfile :: MonadIO io => FilePath -> io Bool
|
||||
testfile path = liftIO (Filesystem.isFile path)
|
||||
|
@ -985,3 +1001,81 @@ date = liftIO getCurrentTime
|
|||
-- | Get the time a file was last modified
|
||||
datefile :: MonadIO io => FilePath -> io UTCTime
|
||||
datefile path = liftIO (Filesystem.getModified path)
|
||||
|
||||
-- | Get the size of a file or a directory
|
||||
du :: MonadIO io => FilePath -> io Size
|
||||
du path = liftIO (fmap Size (Filesystem.getSize path))
|
||||
|
||||
{-| An abstract file size
|
||||
|
||||
Specify the units you want by using an accessor like `kilobytes`
|
||||
|
||||
The `Num` instance for `Size` interprets numeric literals as bytes
|
||||
-}
|
||||
newtype Size = Size { _bytes :: Integer } deriving (Num)
|
||||
|
||||
instance Show Size where
|
||||
show = show . _bytes
|
||||
|
||||
-- | Extract a size in bytes
|
||||
bytes :: Integral n => Size -> n
|
||||
bytes = fromInteger . _bytes
|
||||
|
||||
-- | @1 kilobyte = 1000 bytes@
|
||||
kilobytes :: Integral n => Size -> n
|
||||
kilobytes = (`div` 1000) . bytes
|
||||
|
||||
-- | @1 megabyte = 1000 kilobytes@
|
||||
megabytes :: Integral n => Size -> n
|
||||
megabytes = (`div` 1000) . kilobytes
|
||||
|
||||
-- | @1 gigabyte = 1000 megabytes@
|
||||
gigabytes :: Integral n => Size -> n
|
||||
gigabytes = (`div` 1000) . megabytes
|
||||
|
||||
-- | @1 terabyte = 1000 gigabytes@
|
||||
terabytes :: Integral n => Size -> n
|
||||
terabytes = (`div` 1000) . gigabytes
|
||||
|
||||
-- | @1 kibibyte = 1024 bytes@
|
||||
kibibytes :: Integral n => Size -> n
|
||||
kibibytes = (`div` 1024) . bytes
|
||||
|
||||
-- | @1 mebibyte = 1024 kibibytes@
|
||||
mebibytes :: Integral n => Size -> n
|
||||
mebibytes = (`div` 1024) . kibibytes
|
||||
|
||||
-- | @1 gibibyte = 1024 mebibytes@
|
||||
gibibytes :: Integral n => Size -> n
|
||||
gibibytes = (`div` 1024) . mebibytes
|
||||
|
||||
-- | @1 tebibyte = 1024 gibibytes@
|
||||
tebibytes :: Integral n => Size -> n
|
||||
tebibytes = (`div` 1024) . gibibytes
|
||||
|
||||
{-| Count the number of characters in the stream (like @wc -c@)
|
||||
|
||||
This uses the convention that the elements of the stream are implicitly
|
||||
ended by newlines that are one character wide
|
||||
-}
|
||||
countChars :: Integral n => Fold Text n
|
||||
countChars = Control.Foldl.Text.length + charsPerNewline * countLines
|
||||
|
||||
charsPerNewline :: Num a => a
|
||||
#ifdef mingw32_HOST_OS
|
||||
charsPerNewline = 2
|
||||
#else
|
||||
charsPerNewline = 1
|
||||
#endif
|
||||
|
||||
-- | Count the number of words in the stream (like @wc -w@)
|
||||
countWords :: Integral n => Fold Text n
|
||||
countWords = premap Text.words (handles traverse genericLength)
|
||||
|
||||
{-| Count the number of lines in the stream (like @wc -l@)
|
||||
|
||||
This uses the convention that each element of the stream represents one
|
||||
line
|
||||
-}
|
||||
countLines :: Integral n => Fold Text n
|
||||
countLines = genericLength
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Name: turtle
|
||||
Version: 1.1.1
|
||||
Version: 1.2.0
|
||||
Cabal-Version: >=1.10
|
||||
Build-Type: Simple
|
||||
License: BSD3
|
||||
|
@ -49,8 +49,8 @@ Library
|
|||
base >= 4.5 && < 5 ,
|
||||
async >= 2.0.0.0 && < 2.1,
|
||||
clock >= 0.4.1.2 && < 0.6,
|
||||
directory < 1.3,
|
||||
foldl < 1.2,
|
||||
directory >= 1.0.7 && < 1.3,
|
||||
foldl >= 1.1 && < 1.2,
|
||||
hostname < 1.1,
|
||||
managed < 1.1,
|
||||
process >= 1.0.1.1 && < 1.3,
|
||||
|
|
Loading…
Reference in a new issue