Added wc equivalent improved du. Fixes #71

This commit is contained in:
Gabriel Gonzalez 2015-07-04 10:41:50 -07:00
parent c1a97ca50e
commit c37e941a49
2 changed files with 105 additions and 11 deletions

View file

@ -1,5 +1,6 @@
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- | This module provides a large suite of utilities that resemble Unix -- | This module provides a large suite of utilities that resemble Unix
-- utilities. -- utilities.
@ -123,7 +124,6 @@ module Turtle.Prelude (
, rm , rm
, rmdir , rmdir
, rmtree , rmtree
, du
, testfile , testfile
, testdir , testdir
, date , date
@ -169,6 +169,11 @@ module Turtle.Prelude (
, limitWhile , limitWhile
, cache , cache
-- * Folds
, countChars
, countWords
, countLines
-- * Permissions -- * Permissions
, Permissions , Permissions
, chmod , chmod
@ -179,13 +184,27 @@ module Turtle.Prelude (
, executable, nonexecutable , executable, nonexecutable
, searchable, nonsearchable , searchable, nonsearchable
, ooo,roo,owo,oox,oos,rwo,rox,ros,owx,rwx,rws , 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 ) where
import Control.Applicative (Alternative(..), (<*), (*>)) import Control.Applicative (Alternative(..), (<*), (*>))
import Control.Concurrent.Async (Async, withAsync, wait, concurrently) import Control.Concurrent.Async (Async, withAsync, wait, concurrently)
import Control.Concurrent (threadDelay) import Control.Concurrent (threadDelay)
import Control.Exception (bracket, throwIO) 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 (liftM, msum, when)
import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Managed (Managed, managed) import Control.Monad.Managed (Managed, managed)
@ -195,6 +214,7 @@ import Data.Bits ((.&.))
import Data.IORef (newIORef, readIORef, writeIORef) import Data.IORef (newIORef, readIORef, writeIORef)
import Data.Text (Text, pack, unpack) import Data.Text (Text, pack, unpack)
import Data.Time (NominalDiffTime, UTCTime, getCurrentTime) import Data.Time (NominalDiffTime, UTCTime, getCurrentTime)
import Data.Traversable (traverse)
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Text.IO as Text import qualified Data.Text.IO as Text
import qualified Filesystem import qualified Filesystem
@ -562,10 +582,6 @@ rmdir path = liftIO (Filesystem.removeDirectory path)
rmtree :: MonadIO io => FilePath -> io () rmtree :: MonadIO io => FilePath -> io ()
rmtree path = liftIO (Filesystem.removeTree path) 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 -- | Check if a file exists
testfile :: MonadIO io => FilePath -> io Bool testfile :: MonadIO io => FilePath -> io Bool
testfile path = liftIO (Filesystem.isFile path) testfile path = liftIO (Filesystem.isFile path)
@ -985,3 +1001,81 @@ date = liftIO getCurrentTime
-- | Get the time a file was last modified -- | Get the time a file was last modified
datefile :: MonadIO io => FilePath -> io UTCTime datefile :: MonadIO io => FilePath -> io UTCTime
datefile path = liftIO (Filesystem.getModified path) 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

View file

@ -1,5 +1,5 @@
Name: turtle Name: turtle
Version: 1.1.1 Version: 1.2.0
Cabal-Version: >=1.10 Cabal-Version: >=1.10
Build-Type: Simple Build-Type: Simple
License: BSD3 License: BSD3
@ -49,8 +49,8 @@ Library
base >= 4.5 && < 5 , base >= 4.5 && < 5 ,
async >= 2.0.0.0 && < 2.1, async >= 2.0.0.0 && < 2.1,
clock >= 0.4.1.2 && < 0.6, clock >= 0.4.1.2 && < 0.6,
directory < 1.3, directory >= 1.0.7 && < 1.3,
foldl < 1.2, foldl >= 1.1 && < 1.2,
hostname < 1.1, hostname < 1.1,
managed < 1.1, managed < 1.1,
process >= 1.0.1.1 && < 1.3, process >= 1.0.1.1 && < 1.3,