Copyright | Isaac Jones Simon Marlow 2003-2004 |
---|---|
License | BSD3 portions Copyright (c) 2007, Galois Inc. |
Maintainer | cabal-devel@haskell.org |
Portability | portable |
Safe Haskell | None |
Language | Haskell2010 |
Distribution.Utils.Generic
Description
A large and somewhat miscellaneous collection of utility functions used
throughout the rest of the Cabal lib and in other tools that use the Cabal
lib like
cabal-install
. It has a very simple set of logging actions. It
has low level functions for running programs, a bunch of wrappers for
various directory and file functions that do extra logging.
Synopsis
- withFileContents :: FilePath -> ( String -> NoCallStackIO a) -> NoCallStackIO a
- writeFileAtomic :: FilePath -> ByteString -> NoCallStackIO ()
- fromUTF8BS :: ByteString -> String
- fromUTF8LBS :: ByteString -> String
- toUTF8BS :: String -> ByteString
- toUTF8LBS :: String -> ByteString
- validateUTF8 :: ByteString -> Maybe Int
- readUTF8File :: FilePath -> NoCallStackIO String
- withUTF8FileContents :: FilePath -> ( String -> IO a) -> IO a
- writeUTF8File :: FilePath -> String -> NoCallStackIO ()
- ignoreBOM :: String -> String
- normaliseLineEndings :: String -> String
- dropWhileEndLE :: (a -> Bool ) -> [a] -> [a]
- takeWhileEndLE :: (a -> Bool ) -> [a] -> [a]
- equating :: Eq a => (b -> a) -> b -> b -> Bool
- comparing :: Ord a => (b -> a) -> b -> b -> Ordering
- isInfixOf :: Eq a => [a] -> [a] -> Bool
- intercalate :: [a] -> [[a]] -> [a]
- lowercase :: String -> String
- isAscii :: Char -> Bool
- isAsciiAlpha :: Char -> Bool
- isAsciiAlphaNum :: Char -> Bool
- listUnion :: Ord a => [a] -> [a] -> [a]
- listUnionRight :: Ord a => [a] -> [a] -> [a]
- ordNub :: Ord a => [a] -> [a]
- ordNubBy :: Ord b => (a -> b) -> [a] -> [a]
- ordNubRight :: Ord a => [a] -> [a]
- safeHead :: [a] -> Maybe a
- safeTail :: [a] -> [a]
- safeLast :: [a] -> Maybe a
- safeInit :: [a] -> [a]
- unintersperse :: Char -> String -> [ String ]
- wrapText :: String -> String
- wrapLine :: Int -> [ String ] -> [[ String ]]
- unfoldrM :: Monad m => (b -> m ( Maybe (a, b))) -> b -> m [a]
- spanMaybe :: (a -> Maybe b) -> [a] -> ([b], [a])
- breakMaybe :: (a -> Maybe b) -> [a] -> ([a], Maybe (b, [a]))
- unsnoc :: [a] -> Maybe ([a], a)
- unsnocNE :: NonEmpty a -> ([a], a)
- isAbsoluteOnAnyPlatform :: FilePath -> Bool
- isRelativeOnAnyPlatform :: FilePath -> Bool
reading and writing files safely
withFileContents :: FilePath -> ( String -> NoCallStackIO a) -> NoCallStackIO a Source #
Gets the contents of a file, but guarantee that it gets closed.
The file is read lazily but if it is not fully consumed by the action then the remaining input is truncated and the file is closed.
writeFileAtomic :: FilePath -> ByteString -> NoCallStackIO () Source #
Writes a file atomically.
The file is either written successfully or an IO exception is raised and the original file is left unchanged.
On windows it is not possible to delete a file that is open by a process. This case will give an IO exception but the atomic property is not affected.
Unicode
Conversions
fromUTF8BS :: ByteString -> String Source #
Decode
String
from UTF8-encoded
ByteString
Invalid data in the UTF8 stream (this includes code-points
U+D800
through
U+DFFF
) will be decoded as the replacement character (
U+FFFD
).
fromUTF8LBS :: ByteString -> String Source #
Variant of
fromUTF8BS
for lazy
ByteString
s
toUTF8BS :: String -> ByteString Source #
Encode
String
to to UTF8-encoded
ByteString
Code-points in the
U+D800
-
U+DFFF
range will be encoded
as the replacement character (i.e.
U+FFFD
).
toUTF8LBS :: String -> ByteString Source #
Variant of
toUTF8BS
for lazy
ByteString
s
validateUTF8 :: ByteString -> Maybe Int Source #
Check that strict
ByteString
is valid UTF8. Returns 'Just offset' if it's not.
File I/O
readUTF8File :: FilePath -> NoCallStackIO String Source #
Reads a UTF8 encoded text file as a Unicode String
Reads lazily using ordinary
readFile
.
withUTF8FileContents :: FilePath -> ( String -> IO a) -> IO a Source #
Reads a UTF8 encoded text file as a Unicode String
Same behaviour as
withFileContents
.
writeUTF8File :: FilePath -> String -> NoCallStackIO () Source #
Writes a Unicode String as a UTF8 encoded text file.
Uses
writeFileAtomic
, so provides the same guarantees.
BOM
ignoreBOM :: String -> String Source #
Ignore a Unicode byte order mark (BOM) at the beginning of the input
Misc
normaliseLineEndings :: String -> String Source #
Fix different systems silly line ending conventions
generic utils
dropWhileEndLE :: (a -> Bool ) -> [a] -> [a] Source #
dropWhileEndLE p
is equivalent to
reverse . dropWhile p . reverse
, but
quite a bit faster. The difference between "Data.List.dropWhileEnd" and this
version is that the one in
Data.List
is strict in elements, but spine-lazy,
while this one is spine-strict but lazy in elements. That's what
LE
stands
for - "lazy in elements".
Example:
>>>
safeTail $ Data.List.dropWhileEnd (<3) [undefined, 5, 4, 3, 2, 1]
*** Exception: Prelude.undefined ...
>>>
safeTail $ dropWhileEndLE (<3) [undefined, 5, 4, 3, 2, 1]
[5,4,3]
>>>
take 3 $ Data.List.dropWhileEnd (<3) [5, 4, 3, 2, 1, undefined]
[5,4,3]
>>>
take 3 $ dropWhileEndLE (<3) [5, 4, 3, 2, 1, undefined]
*** Exception: Prelude.undefined ...
takeWhileEndLE :: (a -> Bool ) -> [a] -> [a] Source #
takeWhileEndLE p
is equivalent to
reverse . takeWhile p . reverse
, but
is usually faster (as well as being easier to read).
comparing :: Ord a => (b -> a) -> b -> b -> Ordering Source #
comparing p x y = compare (p x) (p y)
Useful combinator for use in conjunction with the
xxxBy
family
of functions from
Data.List
, for example:
... sortBy (comparing fst) ...
intercalate :: [a] -> [[a]] -> [a] Source #
intercalate
xs xss
is equivalent to
(
.
It inserts the list
concat
(
intersperse
xs xss))
xs
in between the lists in
xss
and concatenates the
result.
>>>
intercalate ", " ["Lorem", "ipsum", "dolor"]
"Lorem, ipsum, dolor"
isAsciiAlpha :: Char -> Bool Source #
Ascii letters.
isAsciiAlphaNum :: Char -> Bool Source #
Ascii letters and digits.
>>>
isAsciiAlphaNum 'a'
True
>>>
isAsciiAlphaNum 'ä'
False
listUnion :: Ord a => [a] -> [a] -> [a] Source #
Like "Data.List.union", but has
O(n log n)
complexity instead of
O(n^2)
.
listUnionRight :: Ord a => [a] -> [a] -> [a] Source #
A right-biased version of
listUnion
.
Example:
>>>
listUnion [1,2,3,4,3] [2,1,1]
[1,2,3,4,3]
>>>
listUnionRight [1,2,3,4,3] [2,1,1]
[4,3,2,1,1]
ordNubRight :: Ord a => [a] -> [a] Source #
A right-biased version of
ordNub
.
Example:
>>>
ordNub [1,2,1] :: [Int]
[1,2]
>>>
ordNubRight [1,2,1] :: [Int]
[2,1]
wrapText :: String -> String Source #
Wraps text to the default line width. Existing newlines are preserved.
wrapLine :: Int -> [ String ] -> [[ String ]] Source #
Wraps a list of words to a list of lines of words of a particular width.
unfoldrM :: Monad m => (b -> m ( Maybe (a, b))) -> b -> m [a] Source #
unfoldr
with monadic action.
>>>
take 5 $ unfoldrM (\b r -> Just (r + b, b + 1)) (1 :: Int) 2
[3,4,5,6,7]
Since: 2.2
breakMaybe :: (a -> Maybe b) -> [a] -> ([a], Maybe (b, [a])) Source #
unsnoc :: [a] -> Maybe ([a], a) Source #
The opposite of
snoc
, which is the reverse of
cons
Example:
>>>
unsnoc [1, 2, 3]
Just ([1,2],3)
>>>
unsnoc []
Nothing
Since: 3.2.0.0
FilePath stuff
isAbsoluteOnAnyPlatform :: FilePath -> Bool Source #
isAbsoluteOnAnyPlatform
and
isRelativeOnAnyPlatform
are like
isAbsolute
and
isRelative
but have
platform independent heuristics.
The System.FilePath exists in two versions, Windows and Posix. The two
versions don't agree on what is a relative path and we don't know if we're
given Windows or Posix paths.
This results in false positives when running on Posix and inspecting
Windows paths, like the hackage server does.
System.FilePath.Posix.isAbsolute "C:\hello" == False
System.FilePath.Windows.isAbsolute "/hello" == False
This means that we would treat paths that start with "/" to be absolute.
On Posix they are indeed absolute, while on Windows they are not.
The portable versions should be used when we might deal with paths that are from another OS than the host OS. For example, the Hackage Server deals with both Windows and Posix paths while performing the PackageDescription checks. In contrast, when we run 'cabal configure' we do expect the paths to be correct for our OS and we should not have to use the platform independent heuristics.
isRelativeOnAnyPlatform :: FilePath -> Bool Source #
isRelativeOnAnyPlatform = not . isAbsoluteOnAnyPlatform