-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Shell programming, Haskell-style -- -- turtle is a reimplementation of the Unix command line -- environment in Haskell so that you can use Haskell as both a shell and -- a scripting language. -- -- Features include: -- -- -- -- Read Turtle.Tutorial for a detailed tutorial or -- Turtle.Prelude for a quick-start guide -- -- turtle is designed to be beginner-friendly, but as a result -- lacks certain features, like tracing commands. If you feel comfortable -- using turtle then you should also check out the -- Shelly library which provides similar functionality. @package turtle @version 1.3.4 -- | You can think of Shell as [] + IO + -- Managed. In fact, you can embed all three of them within a -- Shell: -- --
--   select ::        [a] -> Shell a
--   liftIO ::      IO a  -> Shell a
--   using  :: Managed a  -> Shell a
--   
-- -- Those three embeddings obey these laws: -- --
--   do { x <- select m; select (f x) } = select (do { x <- m; f x })
--   do { x <- liftIO m; liftIO (f x) } = liftIO (do { x <- m; f x })
--   do { x <- with   m; using  (f x) } = using  (do { x <- m; f x })
--   
--   select (return x) = return x
--   liftIO (return x) = return x
--   using  (return x) = return x
--   
-- -- ... and select obeys these additional laws: -- --
--   select xs <|> select ys = select (xs <|> ys)
--   select empty = empty
--   
-- -- You typically won't build Shells using the Shell -- constructor. Instead, use these functions to generate primitive -- Shells: -- -- -- -- Then use these classes to combine those primitive Shells into -- larger Shells: -- -- -- -- If you still insist on building your own Shell from scratch, -- then the Shell you build must satisfy this law: -- --
--   -- For every shell `s`:
--   _foldIO s (FoldM step begin done) = do
--       x  <- begin
--       x' <- _foldIO s (FoldM step (return x) return)
--       done x'
--   
-- -- ... which is a fancy way of saying that your Shell must call -- 'begin' exactly once when it begins and call 'done' -- exactly once when it ends. module Turtle.Shell -- | A (Shell a) is a protected stream of a's with side -- effects newtype Shell a Shell :: (forall r. FoldM IO a r -> IO r) -> Shell a [_foldIO] :: Shell a -> forall r. FoldM IO a r -> IO r -- | Use a FoldM IO to reduce the stream of -- a's produced by a Shell foldIO :: MonadIO io => Shell a -> FoldM IO a r -> io r -- | Use a Fold to reduce the stream of a's produced by a -- Shell fold :: MonadIO io => Shell a -> Fold a b -> io b -- | Run a Shell to completion, discarding any unused values sh :: MonadIO io => Shell a -> io () -- | Run a Shell to completion, printing any unused values view :: (MonadIO io, Show a) => Shell a -> io () -- | Convert a list to a Shell that emits each element of the list select :: Foldable f => f a -> Shell a -- | Lift a computation from the IO monad. liftIO :: MonadIO m => forall a. IO a -> m a using :: MonadManaged m => forall a. Managed a -> m a instance GHC.Base.Functor Turtle.Shell.Shell instance GHC.Base.Applicative Turtle.Shell.Shell instance GHC.Base.Monad Turtle.Shell.Shell instance GHC.Base.Alternative Turtle.Shell.Shell instance GHC.Base.MonadPlus Turtle.Shell.Shell instance Control.Monad.IO.Class.MonadIO Turtle.Shell.Shell instance Control.Monad.Managed.MonadManaged Turtle.Shell.Shell instance GHC.Base.Monoid a => GHC.Base.Monoid (Turtle.Shell.Shell a) instance GHC.Base.Monoid a => GHC.Num.Num (Turtle.Shell.Shell a) instance Data.String.IsString a => Data.String.IsString (Turtle.Shell.Shell a) -- | Use this module to either: -- -- -- -- Example usage: -- --
--   >>> :set -XOverloadedStrings
--   
--   >>> match ("can" <|> "cat") "cat"
--   ["cat"]
--   
--   >>> match ("can" <|> "cat") "dog"
--   []
--   
--   >>> match (decimal `sepBy` ",") "1,2,3"
--   [[1,2,3]]
--   
-- -- This pattern has unlimited backtracking, and will return as many -- solutions as possible: -- --
--   >>> match (prefix (star anyChar)) "123"
--   ["123","12","1",""]
--   
-- -- Use do notation to structure more complex patterns: -- --
--   >>> :{
--   let bit = ("0" *> pure False) <|> ("1" *> pure True) :: Pattern Bool;
--       portableBitMap = do
--           { "P1"
--           ; width  <- spaces1 *> decimal
--           ; height <- spaces1 *> decimal
--           ; count width (count height (spaces1 *> bit))
--           };
--   in  match (prefix portableBitMap) "P1\n2 2\n0 0\n1 0\n"
--   :}
--   [[[False,False],[True,False]]]
--   
module Turtle.Pattern -- | A fully backtracking pattern that parses an 'a' from some -- Text data Pattern a -- | Match a Pattern against a Text input, returning all -- possible solutions -- -- The Pattern must match the entire Text match :: Pattern a -> Text -> [a] -- | Match any character -- --
--   >>> match anyChar "1"
--   "1"
--   
--   >>> match anyChar ""
--   ""
--   
anyChar :: Pattern Char -- | Matches the end of input -- --
--   >>> match eof "1"
--   []
--   
--   >>> match eof ""
--   [()]
--   
eof :: Pattern () -- | Synonym for anyChar dot :: Pattern Char -- | Match any character that satisfies the given predicate -- --
--   >>> match (satisfy (== '1')) "1"
--   "1"
--   
--   >>> match (satisfy (== '2')) "1"
--   ""
--   
satisfy :: (Char -> Bool) -> Pattern Char -- | Match a specific character -- --
--   >>> match (char '1') "1"
--   "1"
--   
--   >>> match (char '2') "1"
--   ""
--   
char :: Char -> Pattern Char -- | Match any character except the given one -- --
--   >>> match (notChar '2') "1"
--   "1"
--   
--   >>> match (notChar '1') "1"
--   ""
--   
notChar :: Char -> Pattern Char -- | Match a specific string -- --
--   >>> match (text "123") "123"
--   ["123"]
--   
-- -- You can also omit the text function if you enable the -- OverloadedStrings extension: -- --
--   >>> match "123" "123"
--   ["123"]
--   
text :: Text -> Pattern Text -- | Match a specific string in a case-insensitive way -- -- This only handles ASCII strings -- --
--   >>> match (asciiCI "abc") "ABC"
--   ["ABC"]
--   
asciiCI :: Text -> Pattern Text -- | Match any one of the given characters -- --
--   >>> match (oneOf "1a") "1"
--   "1"
--   
--   >>> match (oneOf "2a") "1"
--   ""
--   
oneOf :: [Char] -> Pattern Char -- | Match anything other than the given characters -- --
--   >>> match (noneOf "2a") "1"
--   "1"
--   
--   >>> match (noneOf "1a") "1"
--   ""
--   
noneOf :: [Char] -> Pattern Char -- | Match a whitespace character -- --
--   >>> match space " "
--   " "
--   
--   >>> match space "1"
--   ""
--   
space :: Pattern Char -- | Match zero or more whitespace characters -- --
--   >>> match spaces "  "
--   ["  "]
--   
--   >>> match spaces ""
--   [""]
--   
spaces :: Pattern Text -- | Match one or more whitespace characters -- --
--   >>> match spaces1 "  "
--   ["  "]
--   
--   >>> match spaces1 ""
--   []
--   
spaces1 :: Pattern Text -- | Match the tab character ('t') -- --
--   >>> match tab "\t"
--   "\t"
--   
--   >>> match tab " "
--   ""
--   
tab :: Pattern Char -- | Match the newline character ('n') -- --
--   >>> match newline "\n"
--   "\n"
--   
--   >>> match newline " "
--   ""
--   
newline :: Pattern Char -- | Matches a carriage return ('r') followed by a newline -- ('n') -- --
--   >>> match crlf "\r\n"
--   ["\r\n"]
--   
--   >>> match crlf "\n\r"
--   []
--   
crlf :: Pattern Text -- | Match an uppercase letter -- --
--   >>> match upper "A"
--   "A"
--   
--   >>> match upper "a"
--   ""
--   
upper :: Pattern Char -- | Match a lowercase letter -- --
--   >>> match lower "a"
--   "a"
--   
--   >>> match lower "A"
--   ""
--   
lower :: Pattern Char -- | Match a letter or digit -- --
--   >>> match alphaNum "1"
--   "1"
--   
--   >>> match alphaNum "a"
--   "a"
--   
--   >>> match alphaNum "A"
--   "A"
--   
--   >>> match alphaNum "."
--   ""
--   
alphaNum :: Pattern Char -- | Match a letter -- --
--   >>> match letter "A"
--   "A"
--   
--   >>> match letter "a"
--   "a"
--   
--   >>> match letter "1"
--   ""
--   
letter :: Pattern Char -- | Match a digit -- --
--   >>> match digit "1"
--   "1"
--   
--   >>> match digit "a"
--   ""
--   
digit :: Pattern Char -- | Match a hexadecimal digit -- --
--   >>> match hexDigit "1"
--   "1"
--   
--   >>> match hexDigit "A"
--   "A"
--   
--   >>> match hexDigit "a"
--   "a"
--   
--   >>> match hexDigit "g"
--   ""
--   
hexDigit :: Pattern Char -- | Match an octal digit -- --
--   >>> match octDigit "1"
--   "1"
--   
--   >>> match octDigit "9"
--   ""
--   
octDigit :: Pattern Char -- | Match an unsigned decimal number -- --
--   >>> match decimal  "123"
--   [123]
--   
--   >>> match decimal "-123"
--   []
--   
decimal :: Num n => Pattern n -- | Transform a numeric parser to accept an optional leading '+' -- or '-' sign -- --
--   >>> match (signed decimal) "+123"
--   [123]
--   
--   >>> match (signed decimal) "-123"
--   [-123]
--   
--   >>> match (signed decimal)  "123"
--   [123]
--   
signed :: Num a => Pattern a -> Pattern a -- | Use this to match the prefix of a string -- --
--   >>> match         "A"  "ABC"
--   []
--   
--   >>> match (prefix "A") "ABC"
--   ["A"]
--   
prefix :: Pattern a -> Pattern a -- | Use this to match the suffix of a string -- --
--   >>> match         "C"  "ABC"
--   []
--   
--   >>> match (suffix "C") "ABC"
--   ["C"]
--   
suffix :: Pattern a -> Pattern a -- | Use this to match the interior of a string -- --
--   >>> match      "B"  "ABC"
--   []
--   
--   >>> match (has "B") "ABC"
--   ["B"]
--   
has :: Pattern a -> Pattern a -- | Match the entire string if it begins with the given pattern -- -- This returns the entire string, not just the matched prefix -- --
--   >>> match (begins  "A"             ) "ABC"
--   ["ABC"]
--   
--   >>> match (begins ("A" *> pure "1")) "ABC"
--   ["1BC"]
--   
begins :: Pattern Text -> Pattern Text -- | Match the entire string if it ends with the given pattern -- -- This returns the entire string, not just the matched prefix -- --
--   >>> match (ends  "C"             ) "ABC"
--   ["ABC"]
--   
--   >>> match (ends ("C" *> pure "1")) "ABC"
--   ["AB1"]
--   
ends :: Pattern Text -> Pattern Text -- | Match the entire string if it contains the given pattern -- -- This returns the entire string, not just the interior pattern -- --
--   >>> match (contains  "B"             ) "ABC"
--   ["ABC"]
--   
--   >>> match (contains ("B" *> pure "1")) "ABC"
--   ["A1C"]
--   
contains :: Pattern Text -> Pattern Text -- | (invert p) succeeds if p fails and fails if -- p succeeds -- --
--   >>> match (invert "A") "A"
--   []
--   
--   >>> match (invert "A") "B"
--   [()]
--   
invert :: Pattern a -> Pattern () -- | Match a Char, but return Text -- --
--   >>> match (once (char '1')) "1"
--   ["1"]
--   
--   >>> match (once (char '1')) ""
--   []
--   
once :: Pattern Char -> Pattern Text -- | Parse 0 or more occurrences of the given character -- --
--   >>> match (star anyChar) "123"
--   ["123"]
--   
--   >>> match (star anyChar) ""
--   [""]
--   
-- -- See also: chars star :: Pattern Char -> Pattern Text -- | Parse 1 or more occurrences of the given character -- --
--   >>> match (plus digit) "123"
--   ["123"]
--   
--   >>> match (plus digit) ""
--   []
--   
-- -- See also: chars1 plus :: Pattern Char -> Pattern Text -- | Patterns that match multiple times are greedy by default, meaning that -- they try to match as many times as possible. The selfless -- combinator makes a pattern match as few times as possible -- -- This only changes the order in which solutions are returned, by -- prioritizing less greedy solutions -- --
--   >>> match (prefix (selfless (some anyChar))) "123"
--   ["1","12","123"]
--   
--   >>> match (prefix           (some anyChar) ) "123"
--   ["123","12","1"]
--   
selfless :: Pattern a -> Pattern a -- | Apply the patterns in the list in order, until one of them succeeds -- --
--   >>> match (choice ["cat", "dog", "egg"]) "egg"
--   ["egg"]
--   
--   >>> match (choice ["cat", "dog", "egg"]) "cat"
--   ["cat"]
--   
--   >>> match (choice ["cat", "dog", "egg"]) "fan"
--   []
--   
choice :: [Pattern a] -> Pattern a -- | Apply the given pattern a fixed number of times, collecting the -- results -- --
--   >>> match (count 3 anyChar) "123"
--   ["123"]
--   
--   >>> match (count 4 anyChar) "123"
--   []
--   
count :: Int -> Pattern a -> Pattern [a] -- | Apply the given pattern at least the given number of times, collecting -- the results -- --
--   >>> match (lowerBounded 5 dot) "123"
--   []
--   
--   >>> match (lowerBounded 2 dot) "123"
--   ["123"]
--   
lowerBounded :: Int -> Pattern a -> Pattern [a] -- | Apply the given pattern 0 or more times, up to a given bound, -- collecting the results -- --
--   >>> match (upperBounded 5 dot) "123"
--   ["123"]
--   
--   >>> match (upperBounded 2 dot) "123"
--   []
--   
--   >>> match ((,) <$> upperBounded 2 dot <*> chars) "123"
--   [("12","3"),("1","23")]
--   
upperBounded :: Int -> Pattern a -> Pattern [a] -- | Apply the given pattern a number of times restricted by given lower -- and upper bounds, collecting the results -- --
--   >>> match (bounded 2 5 "cat") "catcatcat"
--   [["cat","cat","cat"]]
--   
--   >>> match (bounded 2 5 "cat") "cat"
--   []
--   
--   >>> match (bounded 2 5 "cat") "catcatcatcatcatcat"
--   []
--   
-- -- bounded could be implemented naively as follows: -- --
--   bounded m n p = do
--     x <- choice (map pure [m..n])
--     count x p
--   
bounded :: Int -> Int -> Pattern a -> Pattern [a] -- | Transform a parser to a succeed with an empty value instead of failing -- -- See also: optional -- --
--   >>> match (option "1" <> "2") "12"
--   ["12"]
--   
--   >>> match (option "1" <> "2") "2"
--   ["2"]
--   
option :: Monoid a => Pattern a -> Pattern a -- | (between open close p) matches 'p' in between -- 'open' and 'close' -- --
--   >>> match (between (char '(') (char ')') (star anyChar)) "(123)"
--   ["123"]
--   
--   >>> match (between (char '(') (char ')') (star anyChar)) "(123"
--   []
--   
between :: Pattern a -> Pattern b -> Pattern c -> Pattern c -- | Discard the pattern's result -- --
--   >>> match (skip anyChar) "1"
--   [()]
--   
--   >>> match (skip anyChar) ""
--   []
--   
skip :: Pattern a -> Pattern () -- | Restrict the pattern to consume no more than the given number of -- characters -- --
--   >>> match (within 2 decimal) "12"
--   [12]
--   
--   >>> match (within 2 decimal) "1"
--   [1]
--   
--   >>> match (within 2 decimal) "123"
--   []
--   
within :: Int -> Pattern a -> Pattern a -- | Require the pattern to consume exactly the given number of characters -- --
--   >>> match (fixed 2 decimal) "12"
--   [12]
--   
--   >>> match (fixed 2 decimal) "1"
--   []
--   
fixed :: Int -> Pattern a -> Pattern a -- | p sepBy sep matches zero or more occurrences of -- p separated by sep -- --
--   >>> match (decimal `sepBy` char ',') "1,2,3"
--   [[1,2,3]]
--   
--   >>> match (decimal `sepBy` char ',') ""
--   [[]]
--   
sepBy :: Pattern a -> Pattern b -> Pattern [a] -- | p sepBy1 sep matches one or more occurrences of -- p separated by sep -- --
--   >>> match (decimal `sepBy1` ",") "1,2,3"
--   [[1,2,3]]
--   
--   >>> match (decimal `sepBy1` ",") ""
--   []
--   
sepBy1 :: Pattern a -> Pattern b -> Pattern [a] -- | Like star dot or star anyChar, except more efficient chars :: Pattern Text -- | Like plus dot or plus anyChar, except more efficient chars1 :: Pattern Text instance GHC.Base.MonadPlus Turtle.Pattern.Pattern instance GHC.Base.Alternative Turtle.Pattern.Pattern instance GHC.Base.Monad Turtle.Pattern.Pattern instance GHC.Base.Applicative Turtle.Pattern.Pattern instance GHC.Base.Functor Turtle.Pattern.Pattern instance GHC.Base.Monoid a => GHC.Base.Monoid (Turtle.Pattern.Pattern a) instance GHC.Base.Monoid a => GHC.Num.Num (Turtle.Pattern.Pattern a) instance a ~ Data.Text.Internal.Text => Data.String.IsString (Turtle.Pattern.Pattern a) module Turtle.Line -- | A line of text (does not contain newlines). data Line -- | Convert a line to a text value. lineToText :: Line -> Text -- | Split text into lines. The inverse of linesToText. textToLines :: Text -> NonEmpty Line -- | Merge lines into a single text value. linesToText :: [Line] -> Text -- | Try to convert a text value into a line. Precondition (checked): the -- argument does not contain newlines. textToLine :: Text -> Maybe Line -- | Convert a text value into a line. Precondition (unchecked): the -- argument does not contain newlines. unsafeTextToLine :: Text -> Line -- | The NewlineForbidden exception is thrown when you construct a -- Line using an overloaded string literal or by calling -- fromString explicitly and the supplied string contains -- newlines. This is a programming error to do so: if you aren't sure -- that the input string is newline-free, do not rely on the -- IsString Line instance. -- -- When debugging, it might be useful to look for implicit invocations of -- fromString for Line: -- --
--   >>> sh (do { line <- "Hello\nWorld"; echo line })
--   *** Exception: NewlineForbidden
--   
-- -- In the above example, echo expects its argument to be a -- Line, thus line :: Line. Since we bind -- line in Shell, the string literal -- "Hello\nWorld" has type Shell Line. -- The IsString (Shell Line) instance -- delegates the construction of a Line to the IsString -- Line instance, where the exception is thrown. -- -- To fix the problem, use textToLines: -- --
--   >>> sh (do { line <- select (textToLines "Hello\nWorld"); echo line })
--   Hello
--   World
--   
data NewlineForbidden NewlineForbidden :: NewlineForbidden instance GHC.Base.Monoid Turtle.Line.Line instance GHC.Show.Show Turtle.Line.Line instance GHC.Classes.Ord Turtle.Line.Line instance GHC.Classes.Eq Turtle.Line.Line instance GHC.Show.Show Turtle.Line.NewlineForbidden instance GHC.Exception.Exception Turtle.Line.NewlineForbidden instance Data.String.IsString Turtle.Line.Line -- | Example usage of this module: -- --
--   -- options.hs
--   
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Turtle
--   
--   parser :: Parser (Text, Int)
--   parser = (,) <$> optText "name" 'n' "Your first name"
--                <*> optInt  "age"  'a' "Your current age"
--   
--   main = do
--       (name, age) <- options "Greeting script" parser
--       echo (format ("Hello there, "%s) name)
--       echo (format ("You are "%d%" years old") age)
--   
-- --
--   $ ./options --name John --age 42
--   Hello there, John
--   You are 42 years old
--   
-- --
--   $ ./options --help
--   Greeting script
--   
--   Usage: options (-n|--name NAME) (-a|--age AGE)
--   
--   Available options:
--    -h,--help                Show this help text
--    --name NAME              Your first name
--    --age AGE                Your current age
--   
-- -- See the Turtle.Tutorial module which contains more examples on -- how to use command-line parsing. module Turtle.Options -- | A Parser a is an option parser returning a value of type -- a. data Parser a :: * -> * -- | The name of a command-line argument -- -- This is used to infer the long name and metavariable for the command -- line flag. For example, an ArgName of "name" will -- create a --name flag with a NAME metavariable newtype ArgName ArgName :: Text -> ArgName [getArgName] :: ArgName -> Text -- | The name of a sub-command -- -- This is lower-cased to create a sub-command. For example, a -- CommandName of "Name" will parse name on the -- command line before parsing the remaining arguments using the -- command's subparser. newtype CommandName CommandName :: Text -> CommandName [getCommandName] :: CommandName -> Text -- | The short one-character abbreviation for a flag (i.e. -n) type ShortName = Char -- | A brief description of what your program does -- -- This description will appear in the header of the --help -- output newtype Description Description :: Doc -> Description [getDescription] :: Description -> Doc -- | A helpful message explaining what a flag does -- -- This will appear in the --help output newtype HelpMessage HelpMessage :: Text -> HelpMessage [getHelpMessage] :: HelpMessage -> Text -- | This parser returns True if the given flag is set and -- False if the flag is absent switch :: ArgName -> ShortName -> Optional HelpMessage -> Parser Bool -- | Parse a Text value as a flag-based option optText :: ArgName -> ShortName -> Optional HelpMessage -> Parser Text -- | Parse a Line value as a flag-based option optLine :: ArgName -> ShortName -> Optional HelpMessage -> Parser Line -- | Parse an Int as a flag-based option optInt :: ArgName -> ShortName -> Optional HelpMessage -> Parser Int -- | Parse an Integer as a flag-based option optInteger :: ArgName -> ShortName -> Optional HelpMessage -> Parser Integer -- | Parse a Double as a flag-based option optDouble :: ArgName -> ShortName -> Optional HelpMessage -> Parser Double -- | Parse a FilePath value as a flag-based option optPath :: ArgName -> ShortName -> Optional HelpMessage -> Parser FilePath -- | Parse any type that implements Read optRead :: Read a => ArgName -> ShortName -> Optional HelpMessage -> Parser a -- | Build a flag-based option parser for any type by providing a -- Text-parsing function opt :: (Text -> Maybe a) -> ArgName -> ShortName -> Optional HelpMessage -> Parser a -- | Parse a Text as a positional argument argText :: ArgName -> Optional HelpMessage -> Parser Text -- | Parse a Line as a positional argument argLine :: ArgName -> Optional HelpMessage -> Parser Line -- | Parse an Int as a positional argument argInt :: ArgName -> Optional HelpMessage -> Parser Int -- | Parse an Integer as a positional argument argInteger :: ArgName -> Optional HelpMessage -> Parser Integer -- | Parse a Double as a positional argument argDouble :: ArgName -> Optional HelpMessage -> Parser Double -- | Parse a FilePath as a positional argument argPath :: ArgName -> Optional HelpMessage -> Parser FilePath -- | Parse any type that implements Read as a positional argument argRead :: Read a => ArgName -> Optional HelpMessage -> Parser a -- | Build a positional argument parser for any type by providing a -- Text-parsing function arg :: (Text -> Maybe a) -> ArgName -> Optional HelpMessage -> Parser a -- | Create a sub-command that parses CommandName and then parses -- the rest of the command-line arguments -- -- The sub-command will have its own Description and help text subcommand :: CommandName -> Description -> Parser a -> Parser a -- | Create a named group of sub-commands subcommandGroup :: forall a. Description -> [(CommandName, Description, Parser a)] -> Parser a -- | Parse the given options from the command line options :: MonadIO io => Description -> Parser a -> io a instance Data.String.IsString Turtle.Options.HelpMessage instance Data.String.IsString Turtle.Options.Description instance Data.String.IsString Turtle.Options.CommandName instance Data.String.IsString Turtle.Options.ArgName -- | Minimalist implementation of type-safe formatted strings, borrowing -- heavily from the implementation of the formatting package. -- -- Example use of this module: -- --
--   >>> :set -XOverloadedStrings
--   
--   >>> import Turtle.Format
--   
--   >>> format ("This is a "%s%" string that takes "%d%" arguments") "format" 2
--   "This is a format string that takes 2 arguments"
--   
-- -- A Format string that takes no arguments has this type: -- --
--   "I take 0 arguments" :: Format r r
--   
--   format "I take 0 arguments" :: Text
--   
-- --
--   >>> format "I take 0 arguments"
--   "I take 0 arguments"
--   
-- -- A Format string that takes one argument has this type: -- --
--   "I take "%d%" arguments" :: Format r (Int -> r)
--   
--   format ("I take "%d%" argument") :: Int -> Text
--   
-- --
--   >>> format ("I take "%d%" argument") 1
--   "I take 1 argument"
--   
-- -- A Format string that takes two arguments has this type: -- --
--   "I "%s%" "%d%" arguments" :: Format r (Text -> Int -> r)
--   
--   format ("I "%s%" "%d%" arguments") :: Text -> Int -> Text
--   
-- --
--   >>> format ("I "%s%" "%d%" arguments") "take" 2
--   "I take 2 arguments"
--   
module Turtle.Format -- | A Format string data Format a b -- | Concatenate two Format strings (%) :: Format b c -> Format a b -> Format a c -- | Convert a Format string to a print function that takes zero or -- more typed arguments and returns a Text string format :: Format Text r -> r -- | Print a Format string to standard output (without a trailing -- newline) -- --
--   >>> printf ("Hello, "%s%"!\n") "world"
--   Hello, world!
--   
printf :: MonadIO io => Format (io ()) r -> r -- | Create your own format specifier makeFormat :: (a -> Text) -> Format r (a -> r) -- | Format any Showable value -- --
--   >>> format w True
--   "True"
--   
w :: Show a => Format r (a -> r) -- | Format an Integral value as a signed decimal -- --
--   >>> format d 25
--   "25"
--   
--   >>> format d (-25)
--   "-25"
--   
d :: Integral n => Format r (n -> r) -- | Format a Word value as an unsigned decimal -- --
--   >>> format u 25
--   "25"
--   
u :: Format r (Word -> r) -- | Format a Word value as an unsigned octal number -- --
--   >>> format o 25
--   "31"
--   
o :: Format r (Word -> r) -- | Format a Word value as an unsigned hexadecimal number -- (without a leading "0x") -- --
--   >>> format x 25
--   "19"
--   
x :: Format r (Word -> r) -- | Format a Double using decimal notation with 6 digits of -- precision -- --
--   >>> format f 25.1
--   "25.100000"
--   
f :: Format r (Double -> r) -- | Format a Double using scientific notation with 6 digits -- of precision -- --
--   >>> format e 25.1
--   "2.510000e1"
--   
e :: Format r (Double -> r) -- | Format a Double using decimal notation for small -- exponents and scientific notation for large exponents -- --
--   >>> format g 25.1
--   "25.100000"
--   
--   >>> format g 123456789
--   "1.234568e8"
--   
--   >>> format g 0.00000000001
--   "1.000000e-11"
--   
g :: Format r (Double -> r) -- | Format that inserts Text -- --
--   >>> format s "ABC"
--   "ABC"
--   
s :: Format r (Text -> r) -- | Format that inserts a Line -- --
--   >>> format l "ABC"
--   "ABC"
--   
l :: Format r (Line -> r) -- | Format a FilePath into Text fp :: Format r (FilePath -> r) -- | Format a UTCTime into Text utc :: Format r (UTCTime -> r) -- | Convert a Showable value to any type that implements -- IsString (such as Text) -- --
--   >>> repr (1,2)
--   "(1,2)"
--   
repr :: (Show a, IsString text) => a -> text instance Control.Category.Category Turtle.Format.Format instance a ~ b => Data.String.IsString (Turtle.Format.Format a b) -- | This module provides a large suite of utilities that resemble Unix -- utilities. -- -- Many of these commands are just existing Haskell commands renamed to -- match their Unix counterparts: -- --
--   >>> :set -XOverloadedStrings
--   
--   >>> cd "/tmp"
--   
--   >>> pwd
--   FilePath "/tmp"
--   
-- -- Some commands are Shells that emit streams of values. -- view prints all values in a Shell stream: -- --
--   >>> view (ls "/usr")
--   FilePath "/usr/lib"
--   FilePath "/usr/src"
--   FilePath "/usr/sbin"
--   FilePath "/usr/include"
--   FilePath "/usr/share"
--   FilePath "/usr/games"
--   FilePath "/usr/local"
--   FilePath "/usr/bin"
--   
--   >>> view (find (suffix "Browser.py") "/usr/lib")
--   FilePath "/usr/lib/python3.4/idlelib/ClassBrowser.py"
--   FilePath "/usr/lib/python3.4/idlelib/RemoteObjectBrowser.py"
--   FilePath "/usr/lib/python3.4/idlelib/PathBrowser.py"
--   FilePath "/usr/lib/python3.4/idlelib/ObjectBrowser.py"
--   
-- -- Use fold to reduce the output of a Shell stream: -- --
--   >>> import qualified Control.Foldl as Fold
--   
--   >>> fold (ls "/usr") Fold.length
--   8
--   
--   >>> fold (find (suffix "Browser.py") "/usr/lib") Fold.head
--   Just (FilePath "/usr/lib/python3.4/idlelib/ClassBrowser.py")
--   
-- -- Create files using output: -- --
--   >>> output "foo.txt" ("123" <|> "456" <|> "ABC")
--   
--   >>> realpath "foo.txt"
--   FilePath "/tmp/foo.txt"
--   
-- -- Read in files using input: -- --
--   >>> stdout (input "foo.txt")
--   123
--   456
--   ABC
--   
-- -- Format strings in a type safe way using format: -- --
--   >>> dir <- pwd
--   
--   >>> format ("I am in the "%fp%" directory") dir
--   "I am in the /tmp directory"
--   
-- -- Commands like grep, sed and find accept arbitrary -- Patterns -- --
--   >>> stdout (grep ("123" <|> "ABC") (input "foo.txt"))
--   123
--   ABC
--   
--   >>> let exclaim = fmap (<> "!") (plus digit)
--   
--   >>> stdout (sed exclaim (input "foo.txt"))
--   123!
--   456!
--   ABC
--   
-- -- Note that grep and find differ from their Unix -- counterparts by requiring that the Pattern matches the entire -- line or file name by default. However, you can optionally match the -- prefix, suffix, or interior of a line: -- --
--   >>> stdout (grep (has    "2") (input "foo.txt"))
--   123
--   
--   >>> stdout (grep (prefix "1") (input "foo.txt"))
--   123
--   
--   >>> stdout (grep (suffix "3") (input "foo.txt"))
--   123
--   
-- -- You can also build up more sophisticated Shell programs using -- sh in conjunction with do notation: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Turtle
--   
--   main = sh example
--   
--   example = do
--       -- Read in file names from "files1.txt" and "files2.txt"
--       file <- fmap fromText (input "files1.txt" <|> input "files2.txt")
--   
--       -- Stream each file to standard output only if the file exists
--       True <- liftIO (testfile file)
--       line <- input file
--       liftIO (echo line)
--   
-- -- See Turtle.Tutorial for an extended tutorial explaining how to -- use this library in greater detail. module Turtle.Prelude -- | Print exactly one line to stdout -- -- To print more than one line see printf, which also supports -- formatted output echo :: MonadIO io => Line -> io () -- | Print exactly one line to stderr err :: MonadIO io => Line -> io () -- | Read in a line from stdin -- -- Returns Nothing if at end of input readline :: MonadIO io => io (Maybe Line) -- | Read in the entire content of a text file. -- -- This computation throws IOError on failure. See “Classifying -- I/O errors” in the System.IO.Error documentation for -- information on why the failure occured. readTextFile :: FilePath -> IO Text -- | Replace the entire content of a text file with the provided -- Text. -- -- This computation throws IOError on failure. See “Classifying -- I/O errors” in the System.IO.Error documentation for -- information on why the failure occured. writeTextFile :: FilePath -> Text -> IO () -- | Get command line arguments in a list arguments :: MonadIO io => io [Text] -- | Set or modify an environment variable export :: MonadIO io => Text -> Text -> io () -- | Delete an environment variable unset :: MonadIO io => Text -> io () -- | Look up an environment variable need :: MonadIO io => Text -> io (Maybe Text) -- | Retrieve all environment variables env :: MonadIO io => io [(Text, Text)] -- | Change the current directory cd :: MonadIO io => FilePath -> io () -- | Get the current directory pwd :: MonadIO io => io FilePath -- | Get the home directory home :: MonadIO io => io FilePath -- | Canonicalize a path realpath :: MonadIO io => FilePath -> io FilePath -- | Move a file or directory -- -- Works if the two paths are on the same filesystem. If not, mv -- will still work when dealing with a regular file, but the operation -- will not be atomic mv :: MonadIO io => FilePath -> FilePath -> io () -- | Create a directory -- -- Fails if the directory is present mkdir :: MonadIO io => FilePath -> io () -- | Create a directory tree (equivalent to mkdir -p) -- -- Does not fail if the directory is present mktree :: MonadIO io => FilePath -> io () -- | Copy a file cp :: MonadIO io => FilePath -> FilePath -> io () -- | Copy a directory tree cptree :: MonadIO io => FilePath -> FilePath -> io () -- | Remove a file rm :: MonadIO io => FilePath -> io () -- | Remove a directory rmdir :: MonadIO io => FilePath -> io () -- | Remove a directory tree (equivalent to rm -r) -- -- Use at your own risk rmtree :: MonadIO io => FilePath -> io () -- | Check if a file exists testfile :: MonadIO io => FilePath -> io Bool -- | Check if a directory exists testdir :: MonadIO io => FilePath -> io Bool -- | Check if a path exists testpath :: MonadIO io => FilePath -> io Bool -- | Get the current time date :: MonadIO io => io UTCTime -- | Get the time a file was last modified datefile :: MonadIO io => FilePath -> io UTCTime -- | Touch a file, updating the access and modification times to the -- current time -- -- Creates an empty file if it does not exist touch :: MonadIO io => FilePath -> io () -- | Time how long a command takes in monotonic wall clock time -- -- Returns the duration alongside the return value time :: MonadIO io => io a -> io (a, NominalDiffTime) -- | Get the system's host name hostname :: MonadIO io => io Text -- | Show the full path of an executable file which :: MonadIO io => FilePath -> io (Maybe FilePath) -- | Show all matching executables in PATH, not just the first whichAll :: FilePath -> Shell FilePath -- | Sleep for the given duration -- -- A numeric literal argument is interpreted as seconds. In other words, -- (sleep 2.0) will sleep for two seconds. sleep :: MonadIO io => NominalDiffTime -> io () -- | Exit with the given exit code -- -- An exit code of 0 indicates success exit :: MonadIO io => ExitCode -> io a -- | Throw an exception using the provided Text message die :: MonadIO io => Text -> io a -- | Analogous to && in Bash -- -- Runs the second command only if the first one returns -- ExitSuccess (.&&.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode infixr 3 .&&. -- | Analogous to || in Bash -- -- Run the second command only if the first one returns -- ExitFailure (.||.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode infixr 2 .||. -- | Acquire a Managed read-only Handle from a -- FilePath readonly :: MonadManaged managed => FilePath -> managed Handle -- | Acquire a Managed write-only Handle from a -- FilePath writeonly :: MonadManaged managed => FilePath -> managed Handle -- | Acquire a Managed append-only Handle from a -- FilePath appendonly :: MonadManaged managed => FilePath -> managed Handle -- | Create a temporary file underneath the given directory -- -- Deletes the temporary file when done -- -- Note that this provides the Handle of the file in order to -- avoid a potential race condition from the file being moved or deleted -- before you have a chance to open the file. The mktempfile -- function provides a simpler API if you don't need to worry about that -- possibility. mktemp :: MonadManaged managed => FilePath -> Text -> managed (FilePath, Handle) -- | Create a temporary file underneath the given directory -- -- Deletes the temporary file when done mktempfile :: MonadManaged managed => FilePath -> Text -> managed FilePath -- | Create a temporary directory underneath the given directory -- -- Deletes the temporary directory when done mktempdir :: MonadManaged managed => FilePath -> Text -> managed FilePath -- | Fork a thread, acquiring an Async value fork :: MonadManaged managed => IO a -> managed (Async a) -- | Wait for an Async action to complete wait :: MonadIO io => Async a -> io a -- | Change the current directory. Once the current Shell is done, -- it returns back to the original directory. -- --
--   >>> :set -XOverloadedStrings
--   
--   >>> cd "/"
--   
--   >>> view (pushd "/tmp" >> pwd)
--   FilePath "/tmp"
--   
--   >>> pwd
--   FilePath "/"
--   
pushd :: MonadManaged managed => FilePath -> managed () -- | Read lines of Text from standard input stdin :: Shell Line -- | Read lines of Text from a file input :: FilePath -> Shell Line -- | Read lines of Text from a Handle inhandle :: Handle -> Shell Line -- | Stream lines of Text to standard output stdout :: MonadIO io => Shell Line -> io () -- | Stream lines of Text to a file output :: MonadIO io => FilePath -> Shell Line -> io () -- | Stream lines of Text to a Handle outhandle :: MonadIO io => Handle -> Shell Line -> io () -- | Stream lines of Text to append to a file append :: MonadIO io => FilePath -> Shell Line -> io () -- | Stream lines of Text to standard error stderr :: MonadIO io => Shell Line -> io () -- | Read in a stream's contents strictly strict :: MonadIO io => Shell Line -> io Text -- | Stream all immediate children of the given directory, excluding -- "." and ".." ls :: FilePath -> Shell FilePath -- | Stream all recursive descendents of the given directory -- -- This skips any directories that fail the supplied predicate -- --
--   lstree = lsif (\_ -> return True)
--   
lsif :: (FilePath -> IO Bool) -> FilePath -> Shell FilePath -- | Stream all recursive descendents of the given directory lstree :: FilePath -> Shell FilePath -- | Combine the output of multiple Shells, in order cat :: [Shell a] -> Shell a -- | Keep all lines that match the given Pattern grep :: Pattern a -> Shell Line -> Shell Line -- | Replace all occurrences of a Pattern with its Text -- result -- -- sed performs substitution on a line-by-line basis, meaning that -- substitutions may not span multiple lines. Additionally, substitutions -- may occur multiple times within the same line, like the behavior of -- s/.../.../g. -- -- Warning: Do not use a Pattern that matches the empty string, -- since it will match an infinite number of times. sed tries to -- detect such Patterns and die with an error message if -- they occur, but this detection is necessarily incomplete. sed :: Pattern Text -> Shell Line -> Shell Line -- | Make a `Shell Text -> Shell Text` function work on FilePaths -- instead. | Ignores any paths which cannot be decoded as valid -- Text. onFiles :: (Shell Text -> Shell Text) -> Shell FilePath -> Shell FilePath -- | Like sed, but operates in place on a FilePath (analogous -- to sed -i) inplace :: MonadIO io => Pattern Text -> FilePath -> io () -- | Search a directory recursively for all files matching the given -- Pattern find :: Pattern a -> FilePath -> Shell FilePath -- | A Stream of "y"s yes :: Shell Line -- | Number each element of a Shell (starting at 0) nl :: Num n => Shell a -> Shell (n, a) -- | Merge two Shells together, element-wise -- -- If one Shell is longer than the other, the excess elements are -- truncated paste :: Shell a -> Shell b -> Shell (a, b) -- | A Shell that endlessly emits () endless :: Shell () -- | Limit a Shell to a fixed number of values limit :: Int -> Shell a -> Shell a -- | Limit a Shell to values that satisfy the predicate -- -- This terminates the stream on the first value that does not satisfy -- the predicate limitWhile :: (a -> Bool) -> Shell a -> Shell a -- | Cache a Shell's output so that repeated runs of the script will -- reuse the result of previous runs. You must supply a FilePath -- where the cached result will be stored. -- -- The stored result is only reused if the Shell successfully ran -- to completion without any exceptions. Note: on some platforms Ctrl-C -- will flush standard input and signal end of file before killing the -- program, which may trick the program into "successfully" completing. cache :: (Read a, Show a) => FilePath -> Shell a -> Shell a -- | Run a list of IO actions in parallel using fork and wait. -- --
--   >>> view (parallel [(sleep 3) >> date, date, date])
--   2016-12-01 17:22:10.83296 UTC
--   2016-12-01 17:22:07.829876 UTC
--   2016-12-01 17:22:07.829963 UTC
--   
parallel :: [IO a] -> Shell a -- | Returns the result of a Shell that outputs a single line: -- --
--   main = do
--     Just directory <- single (inshell "pwd" empty)
--     print directory
--   
single :: MonadIO io => Shell a -> io (Maybe a) -- | 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 Line n -- | Count the number of words in the stream (like wc -w) countWords :: Integral n => Fold Line n -- | 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 Line n -- | Split a line into chunks delimited by the given Pattern cut :: Pattern a -> Text -> [Text] -- | Run a command using execvp, retrieving the exit code -- -- The command inherits stdout and stderr for the -- current process proc :: MonadIO io => Text -> [Text] -> Shell Line -> io ExitCode -- | Run a command line using the shell, retrieving the exit code -- -- This command is more powerful than proc, but highly vulnerable -- to code injection if you template the command line with untrusted -- input -- -- The command inherits stdout and stderr for the -- current process shell :: MonadIO io => Text -> Shell Line -> io ExitCode -- | This function is identical to proc except this throws -- ProcFailed for non-zero exit codes procs :: MonadIO io => Text -> [Text] -> Shell Line -> io () -- | This function is identical to shell except this throws -- ShellFailed for non-zero exit codes shells :: MonadIO io => Text -> Shell Line -> io () -- | Run a command using execvp, streaming stdout as -- lines of Text -- -- The command inherits stderr for the current process inproc :: Text -> [Text] -> Shell Line -> Shell Line -- | Run a command line using the shell, streaming stdout as lines -- of Text -- -- This command is more powerful than inproc, but highly -- vulnerable to code injection if you template the command line with -- untrusted input -- -- The command inherits stderr for the current process inshell :: Text -> Shell Line -> Shell Line -- | Run a command using the shell, streaming stdout and -- stderr as lines of Text. Lines from stdout -- are wrapped in Right and lines from stderr are wrapped -- in Left. This does not throw an exception if the command -- returns a non-zero exit code inprocWithErr :: Text -> [Text] -> Shell Line -> Shell (Either Line Line) -- | Run a command line using the shell, streaming stdout and -- stderr as lines of Text. Lines from stdout -- are wrapped in Right and lines from stderr are wrapped -- in Left. This does not throw an exception if the command -- returns a non-zero exit code -- -- This command is more powerful than inprocWithErr, but highly -- vulnerable to code injection if you template the command line with -- untrusted input inshellWithErr :: Text -> Shell Line -> Shell (Either Line Line) -- | Run a command using execvp, retrieving the exit code and -- stdout as a non-lazy blob of Text -- -- The command inherits stderr for the current process procStrict :: MonadIO io => Text -> [Text] -> Shell Line -> io (ExitCode, Text) -- | Run a command line using the shell, retrieving the exit code and -- stdout as a non-lazy blob of Text -- -- This command is more powerful than proc, but highly vulnerable -- to code injection if you template the command line with untrusted -- input -- -- The command inherits stderr for the current process shellStrict :: MonadIO io => Text -> Shell Line -> io (ExitCode, Text) -- | Run a command using execvp, retrieving the exit code, stdout, -- and stderr as a non-lazy blob of Text procStrictWithErr :: MonadIO io => Text -> [Text] -> Shell Line -> io (ExitCode, Text, Text) -- | Run a command line using the shell, retrieving the exit code, stdout, -- and stderr as a non-lazy blob of Text -- -- This command is more powerful than proc, but highly vulnerable -- to code injection if you template the command line with untrusted -- input shellStrictWithErr :: MonadIO io => Text -> Shell Line -> io (ExitCode, Text, Text) -- | system generalizes shell and proc by allowing you -- to supply your own custom CreateProcess. This is for advanced -- users who feel comfortable using the lower-level process API system :: MonadIO io => CreateProcess -> Shell Line -> io ExitCode -- | stream generalizes inproc and inshell by allowing -- you to supply your own custom CreateProcess. This is for -- advanced users who feel comfortable using the lower-level -- process API stream :: CreateProcess -> Shell Line -> Shell Line -- | streamWithErr generalizes inprocWithErr and -- inshellWithErr by allowing you to supply your own custom -- CreateProcess. This is for advanced users who feel -- comfortable using the lower-level process API streamWithErr :: CreateProcess -> Shell Line -> Shell (Either Line Line) -- | systemStrict generalizes shellStrict and -- procStrict by allowing you to supply your own custom -- CreateProcess. This is for advanced users who feel -- comfortable using the lower-level process API systemStrict :: MonadIO io => CreateProcess -> Shell Line -> io (ExitCode, Text) -- | systemStrictWithErr generalizes shellStrictWithErr and -- procStrictWithErr by allowing you to supply your own custom -- CreateProcess. This is for advanced users who feel -- comfortable using the lower-level process API systemStrictWithErr :: MonadIO io => CreateProcess -> Shell Line -> io (ExitCode, Text, Text) data Permissions :: * -- | Update a file or directory's user permissions -- --
--   chmod rwo        "foo.txt"  -- chmod u=rw foo.txt
--   chmod executable "foo.txt"  -- chmod u+x foo.txt
--   chmod nonwritable "foo.txt" -- chmod u-w foo.txt
--   
chmod :: MonadIO io => (Permissions -> Permissions) -> FilePath -> io Permissions -- | Get a file or directory's user permissions getmod :: MonadIO io => FilePath -> io Permissions -- | Set a file or directory's user permissions setmod :: MonadIO io => Permissions -> FilePath -> io () -- | Copy a file or directory's permissions (analogous to chmod -- --reference) copymod :: MonadIO io => FilePath -> FilePath -> io () -- |
--   +r
--   
readable :: Permissions -> Permissions -- |
--   -r
--   
nonreadable :: Permissions -> Permissions -- |
--   +w
--   
writable :: Permissions -> Permissions -- |
--   -w
--   
nonwritable :: Permissions -> Permissions -- |
--   +x
--   
executable :: Permissions -> Permissions -- |
--   -x
--   
nonexecutable :: Permissions -> Permissions -- |
--   +s
--   
searchable :: Permissions -> Permissions -- |
--   -s
--   
nonsearchable :: Permissions -> Permissions -- |
--   -r -w -x
--   
ooo :: Permissions -> Permissions -- |
--   +r -w -x
--   
roo :: Permissions -> Permissions -- |
--   -r +w -x
--   
owo :: Permissions -> Permissions -- |
--   -r -w +x
--   
oox :: Permissions -> Permissions -- |
--   -r -w +s
--   
oos :: Permissions -> Permissions -- |
--   +r +w -x
--   
rwo :: Permissions -> Permissions -- |
--   +r -w +x
--   
rox :: Permissions -> Permissions -- |
--   +r -w +s
--   
ros :: Permissions -> Permissions -- |
--   -r +w +x
--   
owx :: Permissions -> Permissions -- |
--   +r +w +x
--   
rwx :: Permissions -> Permissions -- |
--   +r +w +s
--   
rws :: Permissions -> Permissions -- | Get the size of a file or a directory du :: MonadIO io => FilePath -> io Size -- | 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 data Size -- | Format a Size using a human readable representation -- --
--   >>> format sz 42
--   "42 B"
--   
--   >>> format sz 2309
--   "2.309 KB"
--   
--   >>> format sz 949203
--   "949.203 KB"
--   
--   >>> format sz 1600000000
--   "1.600 GB"
--   
--   >>> format sz 999999999999999999
--   "999999.999 TB"
--   
sz :: Format r (Size -> r) -- | Extract a size in bytes bytes :: Integral n => Size -> n -- |
--   1 kilobyte = 1000 bytes
--   
kilobytes :: Integral n => Size -> n -- |
--   1 megabyte = 1000 kilobytes
--   
megabytes :: Integral n => Size -> n -- |
--   1 gigabyte = 1000 megabytes
--   
gigabytes :: Integral n => Size -> n -- |
--   1 terabyte = 1000 gigabytes
--   
terabytes :: Integral n => Size -> n -- |
--   1 kibibyte = 1024 bytes
--   
kibibytes :: Integral n => Size -> n -- |
--   1 mebibyte = 1024 kibibytes
--   
mebibytes :: Integral n => Size -> n -- |
--   1 gibibyte = 1024 mebibytes
--   
gibibytes :: Integral n => Size -> n -- |
--   1 tebibyte = 1024 gibibytes
--   
tebibytes :: Integral n => Size -> n -- | POSIX defines operations to get information, such as owner, -- permissions, size and access times, about a file. This information is -- represented by the FileStatus type. -- -- Note: see chmod. data FileStatus :: * -- | Get the status of a file stat :: MonadIO io => FilePath -> io FileStatus -- | Get the status of a file, but don't follow symbolic links lstat :: MonadIO io => FilePath -> io FileStatus -- | Size of the file in bytes. Does not follow symlinks fileSize :: FileStatus -> Size -- | Time of last access accessTime :: FileStatus -> POSIXTime -- | Time of last modification modificationTime :: FileStatus -> POSIXTime -- | Time of last status change (i.e. owner, group, link count, mode, etc.) statusChangeTime :: FileStatus -> POSIXTime -- | Checks if this file is a block device. isBlockDevice :: FileStatus -> Bool -- | Checks if this file is a character device. isCharacterDevice :: FileStatus -> Bool -- | Checks if this file is a named pipe device. isNamedPipe :: FileStatus -> Bool -- | Checks if this file is a regular file device. isRegularFile :: FileStatus -> Bool -- | Checks if this file is a directory device. isDirectory :: FileStatus -> Bool -- | Checks if this file is a symbolic link device. isSymbolicLink :: FileStatus -> Bool -- | Checks if this file is a socket device. isSocket :: FileStatus -> Bool data WithHeader a -- | The first line with the header Header :: a -> WithHeader a -- | Every other line: 1st element is header, 2nd element is original row Row :: a -> a -> WithHeader a header :: Shell a -> Shell (WithHeader a) data ProcFailed ProcFailed :: Text -> [Text] -> ExitCode -> ProcFailed [procCommand] :: ProcFailed -> Text [procArguments] :: ProcFailed -> [Text] [procExitCode] :: ProcFailed -> ExitCode data ShellFailed ShellFailed :: Text -> ExitCode -> ShellFailed [shellCommandLine] :: ShellFailed -> Text [shellExitCode] :: ShellFailed -> ExitCode instance GHC.Show.Show a => GHC.Show.Show (Turtle.Prelude.WithHeader a) instance GHC.Num.Num Turtle.Prelude.Size instance GHC.Classes.Ord Turtle.Prelude.Size instance GHC.Classes.Eq Turtle.Prelude.Size instance GHC.Show.Show Turtle.Prelude.ShellFailed instance GHC.Show.Show Turtle.Prelude.ProcFailed instance GHC.Exception.Exception Turtle.Prelude.ProcFailed instance GHC.Exception.Exception Turtle.Prelude.ShellFailed instance GHC.Show.Show Turtle.Prelude.Size -- | This module provides ByteString analogs of several utilities in -- Turtle.Prelude. The main difference is that the chunks of bytes -- read by these utilities are not necessarily aligned to line -- boundaries. module Turtle.Bytes -- | Read chunks of bytes from standard input -- -- The chunks are not necessarily aligned to line boundaries stdin :: Shell ByteString -- | Read chunks of bytes from a file -- -- The chunks are not necessarily aligned to line boundaries input :: FilePath -> Shell ByteString -- | Read chunks of bytes from a Handle -- -- The chunks are not necessarily aligned to line boundaries inhandle :: Handle -> Shell ByteString -- | Stream chunks of bytes to standard output -- -- The chunks are not necessarily aligned to line boundaries stdout :: MonadIO io => Shell ByteString -> io () -- | Stream chunks of bytes to a file -- -- The chunks do not need to be aligned to line boundaries output :: MonadIO io => FilePath -> Shell ByteString -> io () -- | Stream chunks of bytes to a Handle -- -- The chunks do not need to be aligned to line boundaries outhandle :: MonadIO io => Handle -> Shell ByteString -> io () -- | Append chunks of bytes to append to a file -- -- The chunks do not need to be aligned to line boundaries append :: MonadIO io => FilePath -> Shell ByteString -> io () -- | Stream chunks of bytes to standard error -- -- The chunks do not need to be aligned to line boundaries stderr :: MonadIO io => Shell ByteString -> io () -- | Read in a stream's contents strictly strict :: MonadIO io => Shell ByteString -> io ByteString -- | Run a command using execvp, retrieving the exit code -- -- The command inherits stdout and stderr for the -- current process proc :: MonadIO io => Text -> [Text] -> Shell ByteString -> io ExitCode -- | Run a command line using the shell, retrieving the exit code -- -- This command is more powerful than proc, but highly vulnerable -- to code injection if you template the command line with untrusted -- input -- -- The command inherits stdout and stderr for the -- current process shell :: MonadIO io => Text -> Shell ByteString -> io ExitCode -- | This function is identical to proc except this throws -- ProcFailed for non-zero exit codes procs :: MonadIO io => Text -> [Text] -> Shell ByteString -> io () -- | This function is identical to shell except this throws -- ShellFailed for non-zero exit codes shells :: MonadIO io => Text -> Shell ByteString -> io () -- | Run a command using execvp, streaming stdout as -- chunks of ByteString -- -- The command inherits stderr for the current process inproc :: Text -> [Text] -> Shell ByteString -> Shell ByteString -- | Run a command line using the shell, streaming stdout as -- chunks of ByteString -- -- This command is more powerful than inproc, but highly -- vulnerable to code injection if you template the command line with -- untrusted input -- -- The command inherits stderr for the current process inshell :: Text -> Shell ByteString -> Shell ByteString -- | Run a command using the shell, streaming stdout and -- stderr as chunks of ByteString. Chunks from -- stdout are wrapped in Right and chunks from -- stderr are wrapped in Left. This does not throw -- an exception if the command returns a non-zero exit code inprocWithErr :: Text -> [Text] -> Shell ByteString -> Shell (Either ByteString ByteString) -- | Run a command line using the shell, streaming stdout and -- stderr as chunks of ByteString. Chunks from -- stdout are wrapped in Right and chunks from -- stderr are wrapped in Left. This does not throw -- an exception if the command returns a non-zero exit code -- -- This command is more powerful than inprocWithErr, but highly -- vulnerable to code injection if you template the command line with -- untrusted input inshellWithErr :: Text -> Shell ByteString -> Shell (Either ByteString ByteString) -- | Run a command using execvp, retrieving the exit code and -- stdout as a non-lazy blob of Text -- -- The command inherits stderr for the current process procStrict :: MonadIO io => Text -> [Text] -> Shell ByteString -> io (ExitCode, ByteString) -- | Run a command line using the shell, retrieving the exit code and -- stdout as a non-lazy blob of Text -- -- This command is more powerful than proc, but highly vulnerable -- to code injection if you template the command line with untrusted -- input -- -- The command inherits stderr for the current process shellStrict :: MonadIO io => Text -> Shell ByteString -> io (ExitCode, ByteString) -- | Run a command using execvp, retrieving the exit code, stdout, -- and stderr as a non-lazy blob of Text procStrictWithErr :: MonadIO io => Text -> [Text] -> Shell ByteString -> io (ExitCode, ByteString, ByteString) -- | Run a command line using the shell, retrieving the exit code, stdout, -- and stderr as a non-lazy blob of Text -- -- This command is more powerful than proc, but highly vulnerable -- to code injection if you template the command line with untrusted -- input shellStrictWithErr :: MonadIO io => Text -> Shell ByteString -> io (ExitCode, ByteString, ByteString) -- | system generalizes shell and proc by allowing you -- to supply your own custom CreateProcess. This is for advanced -- users who feel comfortable using the lower-level process API system :: MonadIO io => CreateProcess -> Shell ByteString -> io ExitCode -- | stream generalizes inproc and inshell by allowing -- you to supply your own custom CreateProcess. This is for -- advanced users who feel comfortable using the lower-level -- process API stream :: CreateProcess -> Shell ByteString -> Shell ByteString -- | streamWithErr generalizes inprocWithErr and -- inshellWithErr by allowing you to supply your own custom -- CreateProcess. This is for advanced users who feel -- comfortable using the lower-level process API streamWithErr :: CreateProcess -> Shell ByteString -> Shell (Either ByteString ByteString) -- | systemStrict generalizes shellStrict and -- procStrict by allowing you to supply your own custom -- CreateProcess. This is for advanced users who feel -- comfortable using the lower-level process API systemStrict :: MonadIO io => CreateProcess -> Shell ByteString -> io (ExitCode, ByteString) -- | systemStrictWithErr generalizes shellStrictWithErr and -- procStrictWithErr by allowing you to supply your own custom -- CreateProcess. This is for advanced users who feel -- comfortable using the lower-level process API systemStrictWithErr :: MonadIO io => CreateProcess -> Shell ByteString -> io (ExitCode, ByteString, ByteString) -- | See Turtle.Tutorial to learn how to use this library or -- Turtle.Prelude for a quick-start guide. -- -- Here is the recommended way to import this library: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Turtle
--   import Prelude hiding (FilePath)
--   
-- -- This module re-exports the rest of the library and also re-exports -- useful modules from base: -- -- Turtle.Format provides type-safe string formatting -- -- Turtle.Pattern provides Patterns, which are like more -- powerful regular expressions -- -- Turtle.Shell provides a Shell abstraction for building -- streaming, exception-safe pipelines -- -- Turtle.Prelude provides a library of Unix-like utilities to get -- you started with basic shell-like programming within Haskell -- -- Control.Applicative provides two classes: -- -- -- -- Control.Monad provides two classes: -- -- -- -- Control.Monad.IO.Class provides one class: -- -- -- -- Data.Monoid provides one class: -- -- -- -- Control.Monad.Managed.Safe provides Managed resources -- -- Filesystem.Path.CurrentOS provides FilePath-manipulation -- utilities -- -- Additionally, you might also want to import the following modules -- qualified: -- -- module Turtle -- | Efficient representation of a left fold that preserves the fold's step -- function, initial accumulator, and extraction function -- -- This allows the Applicative instance to assemble derived folds -- that traverse the container only once -- -- A 'Fold a b' processes elements of type a and results in -- a value of type b. data Fold a b :: * -> * -> * -- | Fold step initial extract [Fold] :: Fold a b -- | Like Fold, but monadic. -- -- A 'FoldM m a b' processes elements of type a and results -- in a monadic value of type m b. data FoldM (m :: * -> *) a b :: (* -> *) -> * -> * -> * -- | FoldM step initial extract [FoldM] :: FoldM m a b -- | A space efficient, packed, unboxed Unicode text type. data Text :: * -- | This is the simplest representation of UTC. It consists of the day -- number, and a time offset from midnight. Note that if a day has a leap -- second added to it, it will have 86401 seconds. data UTCTime :: * -- | This is a length of time, as measured by UTC. Conversion functions -- will treat it as seconds. It has a precision of 10^-12 s. It ignores -- leap-seconds, so it's not necessarily a fixed amount of clock time. -- For instance, 23:00 UTC + 2 hours of NominalDiffTime = 01:00 UTC (+ 1 -- day), regardless of whether a leap-second intervened. data NominalDiffTime :: * -- | Haskell defines operations to read and write characters from and to -- files, represented by values of type Handle. Each value of -- this type is a handle: a record used by the Haskell run-time -- system to manage I/O with file system objects. A handle has at -- least the following properties: -- -- -- -- Most handles will also have a current I/O position indicating where -- the next input or output operation will occur. A handle is -- readable if it manages only input or both input and output; -- likewise, it is writable if it manages only output or both -- input and output. A handle is open when first allocated. Once -- it is closed it can no longer be used for either input or output, -- though an implementation cannot re-use its storage while references -- remain to it. Handles are in the Show and Eq classes. -- The string produced by showing a handle is system dependent; it should -- include enough information to identify the handle for debugging. A -- handle is equal according to == only to itself; no attempt is -- made to compare the internal state of different handles for equality. data Handle :: * -- | Defines the exit codes that a program can return. data ExitCode :: * -- | indicates successful termination; ExitSuccess :: ExitCode -- | indicates program failure with an exit code. The exact interpretation -- of the code is operating-system dependent. In particular, some values -- may be prohibited (e.g. 0 on a POSIX-compliant system). ExitFailure :: Int -> ExitCode -- | Class for string-like datastructures; used by the overloaded string -- extension (-XOverloadedStrings in GHC). class IsString a fromString :: IsString a => String -> a -- | & is a reverse application operator. This provides -- notational convenience. Its precedence is one higher than that of the -- forward application operator $, which allows & to be -- nested in $. (&) :: a -> (a -> b) -> b infixl 1 & -- | Use turtle if you want to write light-weight and maintainable -- shell scripts. -- -- turtle embeds shell scripting directly within Haskell for -- three main reasons: -- -- -- -- These features make Haskell ideal for scripting, particularly for -- replacing large and unwieldy Bash scripts. -- -- This tutorial introduces how to use the turtle library to -- write Haskell scripts. This assumes no prior knowledge of Haskell, but -- does assume prior knowledge of Bash or a similar shell scripting -- language. -- -- If you are already proficient with Haskell, then you can get quickly -- up to speed by reading the Quick Start guide at the top of -- Turtle.Prelude. -- -- If you are on Windows, the easiest way to follow along is to install -- Git for Windows and use the Git Bash program that it installs -- to get a fully featured Unix-like environment. -- -- For all operating systems, the recommended way to compile and run the -- following examples is to download the stack package -- management tool by following the instructions here: -- -- https://github.com/commercialhaskell/stack -- -- ... and then run the following instruction anywhere outside of a -- Haskell project: -- --
--   $ stack install turtle
--   
-- -- This tutorial will mostly focus on using Haskell as a scripting -- language. The first two lines of each script below contain boilerplate -- instructions so that stack will load and run the script. This -- helps ensure that a script will run on any computer that has a -- stack executable, as stack can install a Haskell -- compiler if one is not already present. If you are curious about how -- these two lines work, they are described here: -- -- -- https://github.com/commercialhaskell/stack/blob/master/doc/GUIDE.md#ghcrunghc -- -- If you want to make a Windows script independently executable outside -- of a Git Bash environment, you can either (A) compile the script into -- an executable or (B) run these two commands from a cmd shell -- with administrator privileges to make all *.hs scripts -- executable: -- --
--   assoc .hs=Haskell
--   ftype Haskell="C:\path\to\stack.exe" "%1" %*
--   
module Turtle.Tutorial