-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | a distributed, interactive, smart revision control system -- -- Darcs is a free, open source revision control system. It is: -- --
-- englishNum 0 (Noun "watch") "" == "watches" -- englishNum 1 (Noun "watch") "" == "watch" -- englishNum 2 (Noun "watch") "" == "watches" --englishNum :: Countable n => Int -> n -> ShowS -- | Things that have a plural and singular spelling class Countable a plural :: Countable a => a -> ShowS singular :: Countable a => a -> ShowS -- | This only distinguishes between nouns with a final -ch, and nouns -- which do not. More irregular nouns will just need to have their own -- type -- --
-- plural (Noun "batch") "" == "batches" -- plural (Noun "bat") "" == "bats" -- plural (Noun "mouse") "" == "mouses" -- :-( --newtype Noun Noun :: String -> Noun data Pronoun It :: Pronoun -- |
-- singular This (Noun "batch") "" == "this batch" -- plural This (Noun "batch") "" == "these batches" --data This This :: Noun -> This -- | Given a list of things, combine them thusly: -- --
-- orClauses ["foo", "bar", "baz"] == "foo, bar or baz" --andClauses :: [String] -> String -- | Given a list of things, combine them thusly: -- --
-- orClauses ["foo", "bar", "baz"] == "foo, bar or baz" --orClauses :: [String] -> String -- | As intersperse, with a different separator for the last | -- interspersal. intersperseLast :: String -> String -> [String] -> String presentParticiple :: String -> String instance Countable This instance Countable Pronoun instance Countable Noun module Workaround -- | renameFile old new changes the name of an existing -- file system object from old to new. If the new -- object already exists, it is atomically replaced by the old -- object. Neither path may refer to an existing directory. A conformant -- implementation need not support renaming files in all situations (e.g. -- renaming across different physical devices), but the constraints must -- be documented. -- -- The operation may fail with: -- --
-- dropWhile isSpace == dropSpace --dropSpace :: ByteString -> ByteString -- | breakSpace returns the pair of ByteStrings when the argument is -- broken at the first whitespace byte. I.e. -- --
-- break isSpace == breakSpace --breakSpace :: ByteString -> (ByteString, ByteString) linesPS :: ByteString -> [ByteString] -- | This function acts exactly like the Prelude unlines function, -- or like Data.ByteString.Char8 unlines, but with one -- important difference: it will produce a string which may not end with -- a newline! That is: -- --
-- unlinesPS ["foo", "bar"] ---- -- evaluates to "foo\nbar", not "foo\nbar\n"! This point should hold true -- for linesPS as well. -- -- TODO: rename this function. unlinesPS :: [ByteString] -> ByteString hashPS :: ByteString -> Int32 breakFirstPS :: Char -> ByteString -> Maybe (ByteString, ByteString) breakLastPS :: Char -> ByteString -> Maybe (ByteString, ByteString) substrPS :: ByteString -> ByteString -> Maybe Int -- | readIntPS skips any whitespace at the beginning of its argument, and -- reads an Int from the beginning of the PackedString. If there is no -- integer at the beginning of the string, it returns Nothing, otherwise -- it just returns the int read, along with a B.ByteString containing the -- remainder of its input. readIntPS :: ByteString -> Maybe (Int, ByteString) isFunky :: ByteString -> Bool fromHex2PS :: ByteString -> ByteString fromPS2Hex :: ByteString -> ByteString -- | betweenLinesPS returns the B.ByteString between the two lines given, -- or Nothing if they do not appear. betweenLinesPS :: ByteString -> ByteString -> ByteString -> Maybe (ByteString) breakAfterNthNewline :: Int -> ByteString -> Maybe (ByteString, ByteString) breakBeforeNthNewline :: Int -> ByteString -> (ByteString, ByteString) -- | O(n) The intercalate function takes a ByteString -- and a list of ByteStrings and concatenates the list after -- interspersing the first argument between each element of the list. intercalate :: ByteString -> [ByteString] -> ByteString -- | Test if a ByteString is made of ascii characters isAscii :: ByteString -> Bool -- | Decode a ByteString to a String according to the current locale -- unsafePerformIO in the locale function is ratified by the fact that -- GHC 6.12 and above also supply locale conversion with functions with a -- pure type. Unrecognized byte sequences in the input are skipped. decodeLocale :: ByteString -> String -- | Encode a String to a ByteString according to the current locale encodeLocale :: String -> ByteString -- | Take a String that represents byte values and re-decode it -- acording to the current locale. decodeString :: String -> String module Darcs.Patch.TokenReplace tryTokInternal :: String -> ByteString -> ByteString -> ByteString -> Maybe [ByteString] forceTokReplace :: String -> String -> String -> ByteString -> Maybe ByteString -- | This module defines our parsing monad. In the past there have been -- lazy and strict parsers in this module. Currently we have only the -- strict variant and it is used for parsing patch files. module Darcs.Patch.ReadMonads class (Functor m, Applicative m, Alternative m, Monad m, MonadPlus m) => ParserM m parse :: ParserM m => m a -> ByteString -> Maybe (a, ByteString) -- | Takes exactly n bytes, or fails. take :: ParserM m => Int -> m ByteString -- | parseStrictly applies the parser functions to a string and -- checks that each parser produced a result as it goes. The strictness -- is in the ParserM instance for SM. parseStrictly :: SM a -> ByteString -> Maybe (a, ByteString) -- | Accepts only the specified character. Consumes a character, if -- available. char :: ParserM m => Char -> m () -- | Parse an integer and return it. Skips leading whitespaces and | uses -- the efficient ByteString readInt. int :: ParserM m => m Int -- | If p fails it returns x, otherwise it returns the -- result of p. option :: Alternative f => a -> f a -> f a -- | Attempts each option until one succeeds. choice :: Alternative f => [f a] -> f a -- | Discards spaces until a non-space character is encountered. Always -- succeeds. skipSpace :: ParserM m => m () -- | Discards any characters as long as p returns True. Always | -- succeeds. skipWhile :: ParserM m => (Char -> Bool) -> m () -- | Only succeeds if the characters in the input exactly match -- str. string :: ParserM m => ByteString -> m () -- | lexChar checks if the next space delimited token from the input -- stream matches a specific Char. Uses Maybe inside -- ParserM to handle failed matches, so that it always returns () -- on success. lexChar :: ParserM m => Char -> m () -- | lexString fetches the next whitespace delimited token from from -- the input and checks if it matches the ByteString input. Uses -- Maybe inside ParserM to handle failed matches, so that -- it always returns () on success. lexString :: ParserM m => ByteString -> m () -- | lexEof looks for optional spaces followed by the end of input. -- Uses Maybe inside ParserM to handle failed matches, so -- that it always returns () on success. lexEof :: ParserM m => m () -- | Equivalent to takeTill (==c), except that it is optimized for -- | the equality case. takeTillChar :: ParserM m => Char -> m ByteString -- | Like myLex except that it is in ParserM myLex' :: ParserM m => m ByteString -- | Accepts the next character and returns it. Only fails at end of input. anyChar :: ParserM m => m Char -- | Only succeeds at end of input, consumes no characters. endOfInput :: ParserM m => m () -- | Takes characters while p returns True. Always succeeds. takeTill :: ParserM m => (Char -> Bool) -> m ByteString -- | Ensure that a parser consumes input when producing a result Causes the -- initial state of the input stream to be held on to while the parser -- runs, so use with caution. checkConsumes :: ParserM m => m a -> m a -- | This is a highly optimized way to read lines that start with a -- particular character. To implement this efficiently we need access to -- the parser's internal state. If this is implemented in terms of the -- other primitives for the parser it requires us to consume one -- character at a time. That leads to (>>=) wasting -- significant time. linesStartingWith :: ParserM m => Char -> m [ByteString] -- | This is a highly optimized way to read lines that start with a -- particular character, and stops when it reaches a particular | -- character. See linesStartingWith for details on why this | -- defined here as a primitive. linesStartingWithEndingWith :: ParserM m => Char -> Char -> m [ByteString] instance Alternative SM instance Applicative SM instance Functor SM instance MonadPlus SM instance ParserM SM instance Monad SM module Printer -- | A Printable is either a String, a packed string, or a chunk of -- text with both representations. data Printable S :: !String -> Printable PS :: !ByteString -> Printable Both :: !String -> !ByteString -> Printable -- | a Doc is a bit of enriched text. Docs get concatanated -- using <>, which is right-associative. newtype Doc Doc :: (St -> Document) -> Doc unDoc :: Doc -> St -> Document type Printers = Handle -> Printers' -- | A set of printers to print different types of text to a handle. data Printers' Printers :: !(Color -> Printer) -> !Printer -> !Printer -> !Printer -> !Printer -> !(Color -> Doc -> Doc) -> !([Printable] -> [Printable]) -> Printers' colorP :: Printers' -> !(Color -> Printer) invisibleP :: Printers' -> !Printer hiddenP :: Printers' -> !Printer userchunkP :: Printers' -> !Printer defP :: Printers' -> !Printer lineColorT :: Printers' -> !(Color -> Doc -> Doc) lineColorS :: Printers' -> !([Printable] -> [Printable]) type Printer = Printable -> St -> Document data Color Blue :: Color Red :: Color Green :: Color Cyan :: Color Magenta :: Color -- | hputDoc puts a doc on the given handle using -- simplePrinters hPutDoc :: Handle -> Doc -> IO () hPutDocLn :: Handle -> Doc -> IO () -- | putDoc puts a doc on stdout using the simple printer -- simplePrinters. putDoc :: Doc -> IO () -- | putDocLn puts a doc, followed by a newline on stdout using -- simplePrinters putDocLn :: Doc -> IO () -- | hputDocWith puts a doc on the given handle using the given -- printer. hPutDocWith :: Printers -> Handle -> Doc -> IO () -- | hputDocLnWith puts a doc, followed by a newline on the given -- handle using the given printer. hPutDocLnWith :: Printers -> Handle -> Doc -> IO () -- | putDocWith puts a doc on stdout using the given printer. putDocWith :: Printers -> Doc -> IO () -- | putDocLnWith puts a doc, followed by a newline on stdout using -- the given printer. putDocLnWith :: Printers -> Doc -> IO () -- | renders a Doc into a String with control codes for the -- special features of the doc. renderString :: Doc -> String -- | renders a Doc into a String using a given set of -- printers. renderStringWith :: Printers' -> Doc -> String -- | renders a Doc into ByteString with control codes for the -- special features of the Doc. See also readerString. renderPS :: Doc -> ByteString -- | renders a doc into a ByteString using a given set of printers. renderPSWith :: Printers' -> Doc -> ByteString -- | renders a Doc into a list of PackedStrings, one for -- each line. renderPSs :: Doc -> [ByteString] -- | renders a Doc into a list of PackedStrings, one for -- each chunk of text that was added to the doc, using the given set of -- printers. renderPSsWith :: Printers' -> Doc -> [ByteString] lineColor :: Color -> Doc -> Doc prefix :: String -> Doc -> Doc insertBeforeLastline :: Doc -> Doc -> Doc -- | colorText creates a Doc containing colored text from a -- String colorText :: Color -> String -> Doc -- | invisibleText creates a Doc containing invisible text -- from a String invisibleText :: String -> Doc -- | hiddenText creates a Doc containing hidden text from a -- String hiddenText :: String -> Doc hiddenPrefix :: String -> Doc -> Doc -- | userchunk creates a Doc containing a user chunk from a -- String userchunk :: String -> Doc -- | text creates a Doc from a String, using -- printable. text :: String -> Doc -- | 'printable x' creates a Doc from any Printable. printable :: Printable -> Doc -- | wrapText n s is a Doc representing s -- line-wrapped at n characters wrapText :: Int -> String -> Doc -- | blueText creates a Doc containing blue text from a -- String blueText :: String -> Doc -- | blueText creates a Doc containing blue text from a -- String redText :: String -> Doc -- | blueText creates a Doc containing blue text from a -- String greenText :: String -> Doc -- | blueText creates a Doc containing blue text from a -- String magentaText :: String -> Doc -- | blueText creates a Doc containing blue text from a -- String cyanText :: String -> Doc -- | unsafeText creates a Doc from a String, using -- simplePrinter directly unsafeText :: String -> Doc -- | unsafeBoth builds a Doc from a String and a -- ByteString representing the same text, but does not check that -- they do. unsafeBoth :: String -> ByteString -> Doc -- | unsafeBothText builds a Doc from a String. The -- string is stored in the Doc as both a String and a ByteString. unsafeBothText :: String -> Doc -- | unsafeChar creates a Doc containing just one character. unsafeChar :: Char -> Doc -- | invisiblePS creates a Doc with invisible text from a -- ByteString invisiblePS :: ByteString -> Doc -- | packedString builds a Doc from a ByteString using -- printable packedString :: ByteString -> Doc -- | unsafePackedString builds a Doc from a ByteString -- using simplePrinter unsafePackedString :: ByteString -> Doc -- | userchunkPS creates a Doc representing a user chunk from -- a ByteString. userchunkPS :: ByteString -> Doc -- | simplePrinters is a Printers which uses the set -- 'simplePriners\'' on any handle. simplePrinters :: Printers -- | invisiblePrinter is the Printer for hidden text. It just -- replaces the document with empty. It's useful to have a printer -- that doesn't actually do anything because this allows you to have -- tunable policies, for example, only printing some text if it's to the -- terminal, but not if it's to a file or vice-versa. invisiblePrinter :: Printer -- | simplePrinter is the simplest Printer: it just -- concatenates together the pieces of the Doc simplePrinter :: Printer doc :: ([Printable] -> [Printable]) -> Doc -- | The empty Doc. empty :: Doc -- | '()' is the concatenation operator for Docs (<>) :: Doc -> Doc -> Doc -- | a <?> b is a b if a is -- not empty, else empty. (>) :: Doc -> Doc -> Doc -- | a <+> b is a followed by a space, then -- b. (<+>) :: Doc -> Doc -> Doc -- | a $$ b is a above b. ($$) :: Doc -> Doc -> Doc -- | vcat piles vertically a list of Docs. vcat :: [Doc] -> Doc -- | vsep piles vertically a list of Docs leaving a blank -- line between each. vsep :: [Doc] -> Doc -- | hcat concatenates (horizontally) a list of Docs hcat :: [Doc] -> Doc -- | Minimal Docs representing the common characters space, -- newline minus, plus, and backslash. minus :: Doc -- | Minimal Docs representing the common characters space, -- newline minus, plus, and backslash. newline :: Doc -- | Minimal Docs representing the common characters space, -- newline minus, plus, and backslash. plus :: Doc -- | Minimal Docs representing the common characters space, -- newline minus, plus, and backslash. space :: Doc -- | Minimal Docs representing the common characters space, -- newline minus, plus, and backslash. backslash :: Doc -- | lparen is the Doc that represents "(" lparen :: Doc -- | rparen is the Doc that represents ")" rparen :: Doc -- | parens doc returns a Doc with the content of -- doc put within a pair of parenthesis. parens :: Doc -> Doc errorDoc :: Doc -> a module Darcs.Bug _bug :: BugStuff -> String -> a _bugDoc :: BugStuff -> Doc -> a _impossible :: BugStuff -> a _fromJust :: BugStuff -> Maybe a -> a -- | Path resolving: -- --
-- /usr/repo/foo -- local file -- c:/src/darcs -- local file -- http://darcs.net/ -- URL -- peter@host:/path -- ssh -- droundy@host: -- ssh -- host:/path -- ssh ---- -- This means that single-letter hosts in ssh-paths do not work, unless a -- username is provided. -- -- Perhaps ssh-paths should use "ssh://user@host/path"-syntax -- instead? module Darcs.URL isFile :: String -> Bool isHttpUrl :: String -> Bool isSshUrl :: String -> Bool isRelative :: String -> Bool isAbsolute :: String -> Bool isSshNopath :: String -> Bool data SshFilePath sshRepo :: SshFilePath -> String sshUhost :: SshFilePath -> String sshFile :: SshFilePath -> String urlOf :: SshFilePath -> String -- | Gives the (user, host, dir) out of an ssh url splitSshUrl :: String -> SshFilePath module Darcs.Email makeEmail :: String -> [(String, String)] -> (Maybe Doc) -> Maybe String -> Doc -> (Maybe String) -> Doc readEmail :: ByteString -> ByteString -- | Formats an e-mail header by encoding any non-ascii characters using -- UTF-8 and Q-encoding, and folding lines at appropriate points. It -- doesn't do more than that, so the header name and header value should -- be well-formatted give or take line length and encoding. So no -- non-ASCII characters within quoted-string, quoted-pair, or atom; no -- semantically meaningful signs in names; no non-ASCII characters in the -- header name; etcetera. formatHeader :: String -> String -> ByteString -- | LCS stands for Longest Common Subsequence, and it is a relatively -- challenging problem to find an LCS efficiently. This module implements -- the algorithm described in: -- -- An O(ND) Difference Algorithm and its Variations, Eugene Myers, -- Algorithmica Vol. 1 No. 2, 1986, pp. 251-266; especially the variation -- described in section 4.2 and most refinements implemented in GNU diff -- (D is the edit-distance). -- -- There is currently no heuristic to reduce the running time and produce -- suboptimal output for large inputs with many differences. It behaves -- like GNU diff with the -d option in this regard. -- -- In the first step, a hash value for every line is calculated and -- collisions are marked with a special value. This reduces a string -- comparison to an int comparison for line tuples where at least one of -- the hash values is not equal to the special value. After that, lines -- which only exists in one of the files are removed and marked as -- changed which reduces the running time of the following difference -- algorithm. GNU diff additionally removes lines that appear very often -- in the other file in some cases. The last step tries to create longer -- changed regions and line up deletions in the first file to insertions -- in the second by shifting changed lines forward and backward. module Lcs -- | create a list of changes between a and b, each change has the form -- (starta, lima, startb, limb) which means that a[starta, lima) has to -- be replaced by b[startb, limb) getChanges :: [ByteString] -> [ByteString] -> [(Int, [ByteString], [ByteString])] -- | try to create nicer diffs by shifting around regions of changed lines shiftBoundaries :: BSTArray s -> BSTArray s -> PArray -> Int -> Int -> ST s () module Darcs.Witnesses.Ordered data (:>) a1 a2 x y (:>) :: (a1 x z) -> (a2 z y) -> :> a1 a2 x y data (:<) a1 a2 x y (:<) :: (a1 z y) -> (a2 x z) -> :< a1 a2 x y data (:\/:) a1 a2 x y (:\/:) :: (a1 z x) -> (a2 z y) -> :\/: a1 a2 x y data (:/\:) a1 a2 x y (:/\:) :: (a1 x z) -> (a2 y z) -> :/\: a1 a2 x y data (:||:) a1 a2 x y (:||:) :: (a1 x y) -> (a2 x y) -> :||: a1 a2 x y data FL a x z (:>:) :: a x y -> FL a y z -> FL a x z NilFL :: FL a x x data RL a x z (:<:) :: a y z -> RL a x y -> RL a x z NilRL :: RL a x x lengthFL :: FL a x z -> Int mapFL :: (forall w z. a w z -> b) -> FL a x y -> [b] mapFL_FL :: (forall w y. a w y -> b w y) -> FL a x z -> FL b x z spanFL :: (forall w y. a w y -> Bool) -> FL a x z -> (FL a :> FL a) x z foldlFL :: (forall w y. a -> b w y -> a) -> a -> FL b x z -> a allFL :: (forall x y. a x y -> Bool) -> FL a w z -> Bool anyFL :: (forall x y. a x y -> Bool) -> FL a w z -> Bool filterFL :: (forall x y. a x y -> Bool) -> FL a w z -> [Sealed2 a] splitAtFL :: Int -> FL a x z -> (FL a :> FL a) x z splitAtRL :: Int -> RL a x z -> (RL a :< RL a) x z bunchFL :: Int -> FL a x y -> FL (FL a) x y foldlRL :: (forall w y. a -> b w y -> a) -> a -> RL b x z -> a lengthRL :: RL a x z -> Int isShorterThanRL :: RL a x y -> Int -> Bool mapRL :: (forall w z. a w z -> b) -> RL a x y -> [b] mapRL_RL :: (forall w y. a w y -> b w y) -> RL a x z -> RL b x z zipWithFL :: (forall x y. a -> p x y -> q x y) -> [a] -> FL p w z -> FL q w z filterFLFL :: (forall x y. p x y -> EqCheck x y) -> FL p w z -> FL p w z filterRL :: (forall x y. p x y -> Bool) -> RL p a b -> [Sealed2 p] reverseFL :: FL a x z -> RL a x z reverseRL :: RL a x z -> FL a x z (+>+) :: FL a x y -> FL a y z -> FL a x z (+<+) :: RL a y z -> RL a x y -> RL a x z nullFL :: FL a x z -> Bool concatFL :: FL (FL a) x z -> FL a x z concatRL :: RL (RL a) x z -> RL a x z consRLSealed :: a y z -> FlippedSeal (RL a) y -> FlippedSeal (RL a) z nullRL :: RL a x z -> Bool toFL :: [FreeLeft a] -> Sealed (FL a x) dropWhileFL :: (forall x y. a x y -> Bool) -> FL a r v -> FlippedSeal (FL a) v dropWhileRL :: (forall x y. a x y -> Bool) -> RL a r v -> Sealed (RL a r) spanFL_M :: Monad m => (forall w y. a w y -> m Bool) -> FL a x z -> m ((FL a :> FL a) x z) -- | Check that two FLs are equal element by element. This differs -- from the MyEq instance for FL which uses commutation. eqFL :: MyEq a => FL a x y -> FL a x z -> EqCheck y z eqFLRev :: MyEq a => FL a x z -> FL a y z -> EqCheck x y eqFLUnsafe :: MyEq a => FL a x y -> FL a z w -> Bool instance (Show2 a, Show2 b) => Show1 ((:>) a b x) instance Show2 a => Show2 (RL a) instance Show2 a => Show1 (RL a x) instance Show2 a => Show (RL a x z) instance Show2 a => Show2 (FL a) instance Show2 a => Show1 (FL a x) instance Show2 a => Show (FL a x z) instance (Show2 a, Show2 b) => Show2 (a :\/: b) instance (Show2 a, Show2 b) => Show ((:\/:) a b x y) instance (Show2 a, Show2 b) => Show2 (a :> b) instance (MyEq a, MyEq b) => Eq ((:<) a b x y) instance (MyEq a, MyEq b) => MyEq (a :< b) instance (MyEq a, MyEq b) => Eq ((:>) a b x y) instance (MyEq a, MyEq b) => MyEq (a :> b) instance (Show2 a, Show2 b) => Show ((:>) a b x y) module Darcs.Patch.Commute -- | Things that can commute. class Commute p commute :: Commute p => (p :> p) x y -> Maybe ((p :> p) x y) commuteFL :: Commute p => (p :> FL p) x y -> Maybe ((FL p :> p) x y) commuteFLorComplain :: Commute p => (p :> FL p) x y -> Either (Sealed2 p) ((FL p :> p) x y) commuteRL :: Commute p => (RL p :> p) x y -> Maybe ((p :> RL p) x y) commuteRLFL :: Commute p => (RL p :> FL p) x y -> Maybe ((FL p :> RL p) x y) -- | Swaps the ordered pair type so that commute can be called directly. toFwdCommute :: (Commute p, Commute q, Monad m) => ((p :< q) x y -> m ((q :< p) x y)) -> (q :> p) x y -> m ((p :> q) x y) -- | Swaps the ordered pair type from the order expected by commute to the -- reverse order. toRevCommute :: (Commute p, Commute q, Monad m) => ((p :> q) x y -> m ((q :> p) x y)) -> (q :< p) x y -> m ((p :< q) x y) instance Commute p => Commute (RL p) instance Commute p => Commute (FL p) module Darcs.Patch.Invert class Invert p invert :: Invert p => p x y -> p y x invertFL :: Invert p => FL p x y -> RL p y x invertRL :: Invert p => RL p x y -> FL p y x module Darcs.Patch.Permutations -- | removeFL x xs removes x from xs if -- x can be commuted to its head. Otherwise it returns -- Nothing removeFL :: (MyEq p, Commute p) => p x y -> FL p x z -> Maybe (FL p y z) -- | removeRL is like removeFL except with RL removeRL :: (MyEq p, Commute p) => p y z -> RL p x z -> Maybe (RL p x y) removeCommon :: (MyEq p, Commute p) => (FL p :\/: FL p) x y -> (FL p :\/: FL p) x y commuteWhatWeCanFL :: Commute p => (p :> FL p) x y -> (FL p :> (p :> FL p)) x y commuteWhatWeCanRL :: Commute p => (RL p :> p) x y -> (RL p :> (p :> RL p)) x y genCommuteWhatWeCanRL :: (forall a b. (p :> p) a b -> Maybe ((p :> p) a b)) -> (RL p :> p) x y -> (RL p :> (p :> RL p)) x y -- | split an FL into left and right lists according -- to a predicate p, using commutation as necessary. If a patch -- does satisfy the predicate but cannot be commuted past one that does -- not satisfy the predicate, it goes in the middle list; to sum -- up, we have: all p left and all (not.p) right, while -- midddle is mixed. partitionFL :: Commute p => (forall u v. p u v -> Bool) -> FL p x y -> ((FL p :> (FL p :> FL p)) x y) -- | split an RL into left and right lists according -- to a predicate, using commutation as necessary. If a patch does -- satisfy the predicate but cannot be commuted past one that does not -- satisfy the predicate, it goes in the left list. partitionRL :: Commute p => (forall u v. p u v -> Bool) -> RL p x y -> (RL p :> RL p) x y -- | This is a minor variant of headPermutationsFL with each -- permutation is simply returned as a FL simpleHeadPermutationsFL :: Commute p => FL p x y -> [FL p x y] -- | headPermutationsRL is like headPermutationsFL, except -- that we operate on an RL (in other words, we are pushing things -- to the end of a patch sequence instead of to the beginning). headPermutationsRL :: Commute p => RL p x y -> [RL p x y] -- | headPermutationsFL p:>:ps returns all the -- permutations of the list in which one element of ps is -- commuted past p -- -- Suppose we have a sequence of patches -- --
-- X h a y s-t-c k ---- -- Suppose furthermore that the patch c depends on t, -- which in turn depends on s. This function will return -- --
-- X :> h a y s t c k -- h :> X a y s t c k -- a :> X h y s t c k -- y :> X h a s t c k -- s :> X h a y t c k -- k :> X h a y s t c --headPermutationsFL :: Commute p => FL p x y -> [(p :> FL p) x y] -- | removeSubsequenceFL ab abc returns Just c' -- where all the patches in ab have been commuted out of it, if -- possible. If this is not possible for any reason (the set of patches -- ab is not actually a subset of abc, or they can't be -- commuted out) we return Nothing. removeSubsequenceFL :: (MyEq p, Commute p) => FL p a b -> FL p a c -> Maybe (FL p b c) -- | removeSubsequenceRL is like removeSubsequenceFL except -- that it works on RL removeSubsequenceRL :: (MyEq p, Commute p) => RL p ab abc -> RL p a abc -> Maybe (RL p a ab) -- | Partition a list into the patches that commute with the given patch -- and those that don't (including dependencies) partitionConflictingFL :: (Commute p1, Invert p1) => CommuteFn p1 p2 -> FL p1 x y -> p2 x z -> (FL p1 :> FL p1) x y -- | CommuteFn is the basis of a general framework for building up -- commutation operations between different patch types in a generic -- manner. Unfortunately type classes are not well suited to the problem -- because of the multiple possible routes by which the commuter for (FL -- p1, FL p2) can be built out of the commuter for (p1, p2) - and more -- complicated problems when we start building multiple constructors on -- top of each other. The type class resolution machinery really can't -- cope with selecting some route, because it doesn't know that all -- possible routes should be equivalent. type CommuteFn p1 p2 = forall x y. (p1 :> p2) x y -> Maybe ((p2 :> p1) x y) -- | Build a commuter between a patch and itself using the operation from -- the type class. selfCommuter :: Commute p => CommuteFn p p commuterIdFL :: CommuteFn p1 p2 -> CommuteFn p1 (FL p2) commuterFLId :: CommuteFn p1 p2 -> CommuteFn (FL p1) p2 commuterIdRL :: CommuteFn p1 p2 -> CommuteFn p1 (RL p2) instance (Commute p, Invert p) => Invert (RL p) instance (MyEq p, Commute p) => MyEq (RL p) instance (Invert p, Commute p) => Invert (FL p) instance (MyEq p, Commute p) => MyEq (FL p) module Darcs.Patch.Bracketed -- | This type exists for legacy support of on-disk format patch formats. -- It is a wrapper type that explicitly tracks the nesting of braces and -- parens in the on-disk representation of such patches. It is used as an -- intermediate form when reading such patches normally, and also for -- round-tripping such patches when checking the hash in bundles. It -- shouldn't be used for anything else. data Bracketed p x y Singleton :: p x y -> Bracketed p x y Braced :: BracketedFL p x y -> Bracketed p x y Parens :: BracketedFL p x y -> Bracketed p x y mapBracketed :: (forall a b. p a b -> q a b) -> Bracketed p x y -> Bracketed q x y unBracketed :: Bracketed p x y -> FL p x y type BracketedFL p x y = FL (Bracketed p) x y mapBracketedFL_FL :: (forall a b. p a b -> q a b) -> BracketedFL p x y -> BracketedFL q x y unBracketedFL :: BracketedFL p x y -> FL p x y instance PatchListFormat (Bracketed p) module Darcs.Patch.Merge -- | Things that can always be merged class Commute p => Merge p merge :: Merge p => (p :\/: p) x y -> (p :/\: p) x y mergeFL :: Merge p => (p :\/: FL p) x y -> (FL p :/\: p) x y instance Merge p => Merge (RL p) instance Merge p => Merge (FL p) module Darcs.Patch.Inspect class PatchInspect p listTouchedFiles :: PatchInspect p => p x y -> [FilePath] hunkMatches :: PatchInspect p => (ByteString -> Bool) -> p x y -> Bool instance PatchInspect p => PatchInspect (RL p) instance PatchInspect p => PatchInspect (FL p) module Darcs.Witnesses.WZipper data FZipper a x z FZipper :: RL a x y -> FL a y z -> FZipper a x z focus :: FZipper a x y -> Maybe (Sealed2 a) leftmost :: FZipper p x y -> Bool left :: FZipper p x y -> FZipper p x y rightmost :: FZipper p x y -> Bool right :: FZipper p x y -> FZipper p x y -- | See clowns jokers :: FZipper a x y -> FlippedSeal (FL a) y -- | "Clowns to the left of me, jokers to the right. Here I am, stuck in -- the middle of you" -- http://en.wikipedia.org/wiki/Stuck_in_the_Middle clowns :: FZipper a x y -> Sealed ((RL a) x) flToZipper :: FL a x y -> FZipper a x y lengthFZ :: FZipper a x y -> Int nullFZ :: FZipper a x y -> Bool toEnd :: FZipper p x y -> FZipper p x y toStart :: FZipper p x y -> FZipper p x y -- | FileName is an abstract type intended to facilitate the input and -- output of unicode filenames. module Darcs.Patch.FileName data FileName fp2fn :: FilePath -> FileName fn2fp :: FileName -> FilePath fn2ps :: FileName -> ByteString ps2fn :: ByteString -> FileName niceps2fn :: ByteString -> FileName fn2niceps :: FileName -> ByteString breakOnDir :: FileName -> Maybe (FileName, FileName) normPath :: FileName -> FileName ownName :: FileName -> FileName superName :: FileName -> FileName movedirfilename :: FileName -> FileName -> FileName -> FileName -- | encodeWhite translates whitespace in filenames to a -- darcs-specific format (numerical representation according to -- ord surrounded by backslashes). Note that backslashes are also -- escaped since they are used in the encoding. -- --
-- encodeWhite "hello there" == "hello\32\there" -- encodeWhite "hello\there" == "hello\92\there" --encodeWhite :: FilePath -> String -- | decodeWhite interprets the Darcs-specific "encoded" filenames -- produced by encodeWhite -- --
-- decodeWhite "hello\32\there" == "hello there" -- decodeWhite "hello\92\there" == "hello\there" -- decodeWhite "hello\there" == error "malformed filename" --decodeWhite :: String -> FilePath (///) :: FileName -> FileName -> FileName -- | Split a file path at the slashes breakup :: String -> [String] isParentOrEqOf :: FileName -> FileName -> Bool instance Eq FileName instance Ord FileName instance Show FileName -- | Various abstractions for dealing with paths. module Darcs.RepoPath data AbsolutePath -- | Take an absolute path and a string representing a (possibly relative) -- path and combine them into an absolute path. If the second argument is -- already absolute, then the first argument gets ignored. This function -- also takes care that the result is converted to Posix convention and -- normalized. Also, parent directories ("..") at the front of the string -- argument get canceled out against trailing directory parts of the -- absolute path argument. -- -- Regarding the last point, someone more familiar with how these -- functions are used should verify that this is indeed necessary or at -- least useful. makeAbsolute :: AbsolutePath -> FilePath -> AbsolutePath -- | Interpret a possibly relative path wrt the current working directory. ioAbsolute :: FilePath -> IO AbsolutePath -- | The root directory as an absolute path. rootDirectory :: AbsolutePath -- | This is for situations where a string (e.g. a command line argument) -- may take the value "-" to mean stdin or stdout (which one depends on -- context) instead of a normal file path. data AbsolutePathOrStd makeAbsoluteOrStd :: AbsolutePath -> String -> AbsolutePathOrStd ioAbsoluteOrStd :: String -> IO AbsolutePathOrStd -- | Execute either the first or the second argument action, depending on -- whether the given path is an AbsolutePath or stdin/stdout. useAbsoluteOrStd :: (AbsolutePath -> a) -> a -> AbsolutePathOrStd -> a stdOut :: AbsolutePathOrStd data AbsoluteOrRemotePath ioAbsoluteOrRemote :: String -> IO AbsoluteOrRemotePath isRemote :: AbsoluteOrRemotePath -> Bool -- | Paths which are relative to the local darcs repository and normalized. -- Note: These are understood not to have the dot in front. data SubPath -- | Make the second path relative to the first, if possible makeSubPathOf :: AbsolutePath -> AbsolutePath -> Maybe SubPath simpleSubPath :: FilePath -> Maybe SubPath sp2fn :: SubPath -> FileName class FilePathOrURL a toPath :: FilePathOrURL a => a -> String class FilePathOrURL a => FilePathLike a toFilePath :: FilePathLike a => a -> FilePath getCurrentDirectory :: IO AbsolutePath setCurrentDirectory :: FilePathLike p => p -> IO () instance Eq SubPath instance Ord SubPath instance Eq AbsolutePath instance Ord AbsolutePath instance Eq AbsolutePathOrStd instance Ord AbsolutePathOrStd instance Eq AbsoluteOrRemotePath instance Ord AbsoluteOrRemotePath instance Show AbsoluteOrRemotePath instance Show AbsolutePathOrStd instance Show SubPath instance Show AbsolutePath instance CharLike c => FilePathLike [c] instance CharLike Char instance FilePathLike SubPath instance FilePathLike AbsolutePath instance FilePathLike FileName instance FilePathOrURL FileName instance FilePathOrURL AbsoluteOrRemotePath instance CharLike c => FilePathOrURL [c] instance FilePathOrURL SubPath instance FilePathOrURL AbsolutePath -- | Various utility functions that do not belong anywhere else. module Darcs.Utils -- | Given two shell commands as arguments, execute the former. The latter -- is then executed if the former failed because the executable wasn't -- found (code 127), wasn't executable (code 126) or some other exception -- occurred. Other failures (such as the user holding ^C) do not cause -- the second command to be tried. ortryrunning :: IO ExitCode -> IO ExitCode -> IO ExitCode nubsort :: Ord a => [a] -> [a] breakCommand :: String -> (String, [String]) showHexLen :: (Integral a, Show a) => Int -> a -> String maybeGetEnv :: String -> IO (Maybe String) -- | Format a path for screen output, so that the user sees where the path -- begins and ends. Could (should?) also warn about unprintable -- characters here. formatPath :: String -> String -- | The firstJustIO is a slight modification to firstJustM: the entries in -- the list must be IO monad operations and the firstJustIO will silently -- turn any monad call that throws an exception into Nothing, basically -- causing it to be ignored. firstJustIO :: [IO (Maybe a)] -> IO (Maybe a) -- | Ask the user to press Enter askEnter :: String -> IO () -- | Ask the user for a line of input. askUser :: String -> IO String -- | askUserListItem prompt xs enumerates xs on the -- screen, allowing the user to choose one of the items askUserListItem :: String -> [String] -> IO String data PromptConfig PromptConfig :: String -> [Char] -> [Char] -> Maybe Char -> [Char] -> PromptConfig pPrompt :: PromptConfig -> String pBasicCharacters :: PromptConfig -> [Char] -- | only shown on help pAdvancedCharacters :: PromptConfig -> [Char] pDefault :: PromptConfig -> Maybe Char pHelp :: PromptConfig -> [Char] -- | Prompt the user for a yes or no promptYorn :: [Char] -> IO Bool promptChar :: PromptConfig -> IO Char getViewer :: IO String -- | editFile f lets the user edit a file which could but does not -- need to already exist. This function returns the exit code from the -- text editor and a flag indicating if the user made any changes. editFile :: FilePathLike p => p -> IO (ExitCode, Bool) runEditor :: FilePath -> IO ExitCode stripCr :: String -> String environmentHelpEditor :: ([String], [String]) environmentHelpPager :: ([String], [String]) catchall :: IO a -> IO a -> IO a clarifyErrors :: IO a -> String -> IO a prettyException :: SomeException -> String prettyError :: IOError -> String addToErrorLoc :: IOException -> String -> IOException getFileStatus :: FilePath -> IO (Maybe FileStatus) withCurrentDirectory :: FilePathLike p => p -> IO a -> IO a withUMask :: String -> IO a -> IO a -- | In some environments, darcs requires that certain global GHC library -- variables that control the encoding used in internal translations are -- set to specific values. -- -- setDarcsEncoding enforces those settings, and should be -- called before the first time any darcs operation is run, and again if -- anything else might have set those encodings to different values. -- -- Note that it isn't thread-safe and has a global effect on your -- program. -- -- The current behaviour of this function is as follows, though this may -- change in future: -- -- Encodings are only set on GHC 7.4 and up, on any non-Windows platform. -- -- Two encodings are set, both to GHC.IO.Encoding.char8: -- GHC.IO.Encoding.setFileSystemEncoding and -- GHC.IO.Encoding.setForeignEncoding. setDarcsEncodings :: IO () getSystemEncoding :: IO String -- | isUTF8 checks if an encoding is UTF-8 (or ascii, since it is -- a subset of UTF-8). isUTF8Locale :: String -> Bool -- | Same as filterPath, but for ordinary FilePaths (as -- opposed to AnchoredPath). filterFilePaths :: [FilePath] -> AnchoredPath -> t -> Bool -- | Construct a filter from a list of AnchoredPaths, that will accept any -- path that is either a parent or a child of any of the listed paths, -- and discard everything else. filterPaths :: [AnchoredPath] -> AnchoredPath -> t -> Bool treeHas :: (MonadError e m, Functor m, Monad m) => Tree m -> FilePath -> m Bool treeHasDir :: (MonadError e m, Functor m, Monad m) => Tree m -> FilePath -> m Bool treeHasFile :: (MonadError e m, Functor m, Monad m) => Tree m -> FilePath -> m Bool treeHasAnycase :: (MonadError e m, Functor m, Monad m) => Tree m -> FilePath -> m Bool module Darcs.Compat stdoutIsAPipe :: IO Bool mkStdoutTemp :: String -> IO String canonFilename :: FilePath -> IO FilePath maybeRelink :: String -> String -> IO Bool atomicCreate :: FilePath -> IO () sloppyAtomicCreate :: FilePath -> IO () module Darcs.Flags -- | The DarcsFlag type is a list of all flags that can ever be -- passed to darcs, or to one of its commands. data DarcsFlag Help :: DarcsFlag ListOptions :: DarcsFlag NoTest :: DarcsFlag Test :: DarcsFlag OnlyChangesToFiles :: DarcsFlag ChangesToAllFiles :: DarcsFlag LeaveTestDir :: DarcsFlag NoLeaveTestDir :: DarcsFlag Timings :: DarcsFlag Debug :: DarcsFlag DebugVerbose :: DarcsFlag DebugHTTP :: DarcsFlag Verbose :: DarcsFlag NormalVerbosity :: DarcsFlag Quiet :: DarcsFlag Target :: String -> DarcsFlag Cc :: String -> DarcsFlag Output :: AbsolutePathOrStd -> DarcsFlag OutputAutoName :: AbsolutePath -> DarcsFlag Subject :: String -> DarcsFlag InReplyTo :: String -> DarcsFlag Charset :: String -> DarcsFlag SendmailCmd :: String -> DarcsFlag Author :: String -> DarcsFlag PatchName :: String -> DarcsFlag OnePatch :: String -> DarcsFlag SeveralPatch :: String -> DarcsFlag AfterPatch :: String -> DarcsFlag UpToPatch :: String -> DarcsFlag TagName :: String -> DarcsFlag LastN :: Int -> DarcsFlag MaxCount :: Int -> DarcsFlag PatchIndexRange :: Int -> Int -> DarcsFlag NumberPatches :: DarcsFlag OneTag :: String -> DarcsFlag AfterTag :: String -> DarcsFlag UpToTag :: String -> DarcsFlag GenContext :: DarcsFlag Context :: AbsolutePath -> DarcsFlag Count :: DarcsFlag LogFile :: AbsolutePath -> DarcsFlag RmLogFile :: DarcsFlag DontRmLogFile :: DarcsFlag DistName :: String -> DarcsFlag All :: DarcsFlag Recursive :: DarcsFlag NoRecursive :: DarcsFlag Reorder :: DarcsFlag RestrictPaths :: DarcsFlag DontRestrictPaths :: DarcsFlag AskDeps :: DarcsFlag NoAskDeps :: DarcsFlag IgnoreTimes :: DarcsFlag DontIgnoreTimes :: DarcsFlag LookForAdds :: DarcsFlag NoLookForAdds :: DarcsFlag AnyOrder :: DarcsFlag CreatorHash :: String -> DarcsFlag Intersection :: DarcsFlag Union :: DarcsFlag Complement :: DarcsFlag Sign :: DarcsFlag SignAs :: String -> DarcsFlag NoSign :: DarcsFlag SignSSL :: String -> DarcsFlag HappyForwarding :: DarcsFlag NoHappyForwarding :: DarcsFlag Verify :: AbsolutePath -> DarcsFlag VerifySSL :: AbsolutePath -> DarcsFlag RemoteDarcsOpt :: String -> DarcsFlag EditDescription :: DarcsFlag NoEditDescription :: DarcsFlag Toks :: String -> DarcsFlag EditLongComment :: DarcsFlag NoEditLongComment :: DarcsFlag PromptLongComment :: DarcsFlag KeepDate :: DarcsFlag NoKeepDate :: DarcsFlag AllowConflicts :: DarcsFlag MarkConflicts :: DarcsFlag NoAllowConflicts :: DarcsFlag SkipConflicts :: DarcsFlag Boring :: DarcsFlag SkipBoring :: DarcsFlag AllowCaseOnly :: DarcsFlag DontAllowCaseOnly :: DarcsFlag AllowWindowsReserved :: DarcsFlag DontAllowWindowsReserved :: DarcsFlag DontGrabDeps :: DarcsFlag DontPromptForDependencies :: DarcsFlag PromptForDependencies :: DarcsFlag Compress :: DarcsFlag NoCompress :: DarcsFlag UnCompress :: DarcsFlag WorkRepoDir :: String -> DarcsFlag WorkRepoUrl :: String -> DarcsFlag RemoteRepo :: String -> DarcsFlag NewRepo :: String -> DarcsFlag Reply :: String -> DarcsFlag ApplyAs :: String -> DarcsFlag MachineReadable :: DarcsFlag HumanReadable :: DarcsFlag Pipe :: DarcsFlag Interactive :: DarcsFlag DiffCmd :: String -> DarcsFlag ExternalMerge :: String -> DarcsFlag Summary :: DarcsFlag NoSummary :: DarcsFlag PauseForGui :: DarcsFlag NoPauseForGui :: DarcsFlag Unified :: DarcsFlag NonUnified :: DarcsFlag Reverse :: DarcsFlag Forward :: DarcsFlag Complete :: DarcsFlag Lazy :: DarcsFlag FixFilePath :: AbsolutePath -> AbsolutePath -> DarcsFlag DiffFlags :: String -> DarcsFlag XMLOutput :: DarcsFlag ForceReplace :: DarcsFlag OnePattern :: PatchMatch -> DarcsFlag SeveralPattern :: PatchMatch -> DarcsFlag AfterPattern :: PatchMatch -> DarcsFlag UpToPattern :: PatchMatch -> DarcsFlag NonApply :: DarcsFlag NonVerify :: DarcsFlag NonForce :: DarcsFlag DryRun :: DarcsFlag SetDefault :: Bool -> DarcsFlag NoSetDefault :: Bool -> DarcsFlag Disable :: DarcsFlag SetScriptsExecutable :: DarcsFlag DontSetScriptsExecutable :: DarcsFlag Bisect :: DarcsFlag UseHashedInventory :: DarcsFlag UseFormat2 :: DarcsFlag UseNoWorkingDir :: DarcsFlag UseWorkingDir :: DarcsFlag NoUpdateWorking :: DarcsFlag Sibling :: AbsolutePath -> DarcsFlag Relink :: DarcsFlag OptimizePristine :: DarcsFlag OptimizeHTTP :: DarcsFlag UpgradeFormat :: DarcsFlag Files :: DarcsFlag NoFiles :: DarcsFlag Directories :: DarcsFlag NoDirectories :: DarcsFlag Pending :: DarcsFlag NoPending :: DarcsFlag PosthookCmd :: String -> DarcsFlag NoPosthook :: DarcsFlag AskPosthook :: DarcsFlag RunPosthook :: DarcsFlag PrehookCmd :: String -> DarcsFlag NoPrehook :: DarcsFlag AskPrehook :: DarcsFlag RunPrehook :: DarcsFlag UMask :: String -> DarcsFlag StoreInMemory :: DarcsFlag ApplyOnDisk :: DarcsFlag NoHTTPPipelining :: DarcsFlag Packs :: DarcsFlag NoPacks :: DarcsFlag NoCache :: DarcsFlag AllowUnrelatedRepos :: DarcsFlag Check :: DarcsFlag Repair :: DarcsFlag JustThisRepo :: DarcsFlag NullFlag :: DarcsFlag RecordRollback :: DarcsFlag NoRecordRollback :: DarcsFlag NoAmendUnrecord :: DarcsFlag AmendUnrecord :: DarcsFlag data Compression NoCompression :: Compression GzipCompression :: Compression data UseIndex UseIndex :: UseIndex IgnoreIndex :: UseIndex data ScanKnown -- | Just files already known to darcs ScanKnown :: ScanKnown -- | All files, i.e. look for new ones ScanAll :: ScanKnown -- | All files, even boring ones ScanBoring :: ScanKnown data RemoteDarcs RemoteDarcs :: String -> RemoteDarcs DefaultRemoteDarcs :: RemoteDarcs compression :: [DarcsFlag] -> Compression remoteDarcs :: [DarcsFlag] -> RemoteDarcs diffingOpts :: [DarcsFlag] -> (UseIndex, ScanKnown) wantExternalMerge :: [DarcsFlag] -> Maybe String wantGuiPause :: [DarcsFlag] -> Bool isInteractive :: [DarcsFlag] -> Bool maxCount :: [DarcsFlag] -> Maybe Int willIgnoreTimes :: [DarcsFlag] -> Bool willRemoveLogFile :: [DarcsFlag] -> Bool isUnified :: [DarcsFlag] -> Bool isNotUnified :: [DarcsFlag] -> Bool doHappyForwarding :: [DarcsFlag] -> Bool includeBoring :: [DarcsFlag] -> Bool doAllowCaseOnly :: [DarcsFlag] -> Bool doAllowWindowsReserved :: [DarcsFlag] -> Bool doReverse :: [DarcsFlag] -> Bool usePacks :: [DarcsFlag] -> Bool showChangesOnlyToFiles :: [DarcsFlag] -> Bool rollbackInWorkingDir :: [DarcsFlag] -> Bool removeFromAmended :: [DarcsFlag] -> Bool -- | Set flags to a default value, but only one has not already been -- provided defaultFlag :: [DarcsFlag] -> DarcsFlag -> [DarcsFlag] -> [DarcsFlag] instance Eq DarcsFlag instance Show DarcsFlag module Darcs.Ssh copySSH :: RemoteDarcs -> SshFilePath -> FilePath -> IO () data SSHCmd SSH :: SSHCmd SCP :: SSHCmd SFTP :: SSHCmd -- | Return the command and arguments needed to run an ssh command First -- try the appropriate darcs environment variable and SSH_PORT defaulting -- to ssh and no specified port. getSSH :: SSHCmd -> IO (String, [String]) environmentHelpSsh :: ([String], [String]) environmentHelpScp :: ([String], [String]) environmentHelpSshPort :: ([String], [String]) remoteDarcs :: RemoteDarcs -> String module Darcs.Lock withLock :: String -> IO a -> IO a -- | Tries to perform some task if it can obtain the lock, Otherwise, just -- gives up without doing the task withLockCanFail :: String -> IO a -> IO (Either () a) -- | withTemp safely creates an empty file (not open for writing) -- and returns its name. -- -- The temp file operations are rather similar to the locking operations, -- in that they both should always try to clean up, so exitWith causes -- trouble. withTemp :: (String -> IO a) -> IO a -- | withOpenTemp creates a temporary file, and opens it. Both of -- them run their argument and then delete the file. Also, both of them -- (to my knowledge) are not susceptible to race conditions on the -- temporary file (as long as you never delete the temporary file; that -- would reintroduce a race condition). withOpenTemp :: ((Handle, String) -> IO a) -> IO a withStdoutTemp :: (String -> IO a) -> IO a -- | withTempDir creates an empty directory and then removes it when -- it is no longer needed. withTempDir creates a temporary directory. The -- location of that directory is determined by the contents of -- _darcsprefstmpdir, if it exists, otherwise by -- $DARCS_TMPDIR, and if that doesn't exist then whatever your -- operating system considers to be a a temporary directory (e.g. -- $TMPDIR under Unix, $TEMP under Windows). -- -- If none of those exist it creates the temporary directory in the -- current directory, unless the current directory is under a _darcs -- directory, in which case the temporary directory in the parent of the -- highest _darcs directory to avoid accidentally corrupting darcs's -- internals. This should not fail, but if it does indeed fail, we go -- ahead and use the current directory anyway. If -- $DARCS_KEEP_TMPDIR variable is set temporary directory is not -- removed, this can be useful for debugging. withTempDir :: String -> (AbsolutePath -> IO a) -> IO a -- | withPermDir is like withTempDir, except that it doesn't -- delete the directory afterwards. withPermDir :: String -> (AbsolutePath -> IO a) -> IO a withDelayedDir :: String -> (AbsolutePath -> IO a) -> IO a withNamedTemp :: String -> (String -> IO a) -> IO a writeToFile :: FilePathLike p => p -> (Handle -> IO ()) -> IO () appendToFile :: FilePathLike p => p -> (Handle -> IO ()) -> IO () writeBinFile :: FilePathLike p => p -> String -> IO () -- | Writes a file. Differs from writeBinFile in that it writes the string -- encoded with the current locale instead of what GHC thinks is right. writeLocaleFile :: FilePathLike p => p -> String -> IO () writeDocBinFile :: FilePathLike p => p -> Doc -> IO () appendBinFile :: FilePathLike p => p -> String -> IO () appendDocBinFile :: FilePathLike p => p -> Doc -> IO () readBinFile :: FilePathLike p => p -> IO String -- | Reads a file. Differs from readBinFile in that it interprets the file -- in the current locale instead of as ISO-8859-1. readLocaleFile :: FilePathLike p => p -> IO String readDocBinFile :: FilePathLike p => p -> IO Doc writeAtomicFilePS :: FilePathLike p => p -> ByteString -> IO () gzWriteAtomicFilePS :: FilePathLike p => p -> ByteString -> IO () gzWriteAtomicFilePSs :: FilePathLike p => p -> [ByteString] -> IO () gzWriteDocFile :: FilePathLike p => p -> Doc -> IO () rmRecursive :: FilePath -> IO () removeFileMayNotExist :: FilePathLike p => p -> IO () canonFilename :: FilePath -> IO FilePath maybeRelink :: String -> String -> IO Bool worldReadableTemp :: String -> IO String tempdirLoc :: IO FilePath editText :: String -> ByteString -> IO ByteString environmentHelpTmpdir :: ([String], [String]) environmentHelpKeepTmpdir :: ([String], [String]) module Darcs.Patch.Read class ReadPatch p readPatch' :: (ReadPatch p, ParserM m) => m (Sealed (p x)) readPatch :: ReadPatch p => ByteString -> Maybe (Sealed (p x)) readPatchPartial :: ReadPatch p => ByteString -> Maybe (Sealed (p x), ByteString) bracketedFL :: ParserM m => (forall y. m (Sealed (p y))) -> Char -> Char -> m (Sealed (FL p x)) peekfor :: ParserM m => ByteString -> m a -> m a -> m a readFileName :: FileNameFormat -> ByteString -> FileName instance (ReadPatch p, PatchListFormat p) => ReadPatch (RL p) instance (ReadPatch p, PatchListFormat p) => ReadPatch (FL p) instance ReadPatch p => ReadPatch (Bracketed p) module Darcs.Patch.SummaryData data SummDetail SummAddDir :: FileName -> SummDetail SummRmDir :: FileName -> SummDetail SummFile :: SummOp -> FileName -> Int -> Int -> Int -> SummDetail SummMv :: FileName -> FileName -> SummDetail SummNone :: SummDetail data SummOp SummAdd :: SummOp SummRm :: SummOp SummMod :: SummOp instance Ord SummOp instance Eq SummOp instance Ord SummDetail instance Eq SummDetail module Crypt.SHA256 sha256sum :: ByteString -> String -- | |A parser for commandlines, returns an arg list and expands format -- strings given in a translation table. Additionally the commandline can -- end with %< specifying that the command expects input on -- stdin. -- -- Some tests for the parser. -- --
-- formatTable = [('s',"<insert subject here>"), -- ('a',"<insert author here>")] -- -- testParser :: (Show a, Eq a) => Parser a -> String -> a -> a -- testParser p s ok = case parse p "" s of -- Left e -> error $ "Parser failed with: " ++ (show e) -- Right res -> if res == ok -- then res -- else error $ "Parser failed: got " -- ++ (show res) ++ ", expected " -- ++ (show ok) -- -- testCases = [("a b",(["a","b"], False)), -- ("a b %<",(["a","b"], True)), -- ("a b %< ",(["a","b"], True)), -- ("\"arg0 contains spaces \\\"quotes\\\"\" b", -- (["arg0 contains spaces \"quotes\"","b"],False)), -- ("a %s %<",(["a","<insert subject here>"], True))] -- -- runTests = map (uncurry $ testParser (commandline formatTable)) testCases --module CommandLine -- | parse a commandline returning a list of strings (intended to be used -- as argv) and a bool value which specifies if the command expects input -- on stdin format specifiers with a mapping in ftable are accepted and -- replaced by the given strings. E.g. if the ftable is -- [(s,Some subject)], then %s is replaced by -- Some subject parseCmd :: FTable -> String -> Either ParseError ([String], Bool) -- | for every mapping (c,s), add a mapping with uppercase c and the -- urlencoded string s addUrlencoded :: FTable -> FTable module URL copyUrl :: String -> FilePath -> Cachable -> IO () copyUrlFirst :: String -> FilePath -> Cachable -> IO () setDebugHTTP :: IO () disableHTTPPipelining :: IO () maxPipelineLength :: IO Int waitUrl :: String -> IO () data Cachable Cachable :: Cachable Uncachable :: Cachable MaxAge :: !CInt -> Cachable environmentHelpProxy :: ([String], [String]) environmentHelpProxyPassword :: ([String], [String]) -- | Data type to represent a connection error. The following are the codes -- from libcurl which map to each of the constructors: * 6 -> -- CouldNotResolveHost : The remote host was not resolved. * 7 -> -- CouldNotConnectToServer : Failed to connect() to host or proxy. * 28 -- -> OperationTimeout: the specified time-out period was reached. data ConnectionError CouldNotResolveHost :: ConnectionError CouldNotConnectToServer :: ConnectionError OperationTimeout :: ConnectionError module Darcs.External backupByRenaming :: FilePath -> IO () backupByCopying :: FilePath -> IO () copyFileOrUrl :: RemoteDarcs -> FilePath -> FilePath -> Cachable -> IO () speculateFileOrUrl :: String -> FilePath -> IO () copyLocal :: String -> FilePath -> IO () cloneFile :: FilePath -> FilePath -> IO () cloneTree :: FilePath -> FilePath -> IO () cloneTreeExcept :: [FilePath] -> FilePath -> FilePath -> IO () -- | fetchFile fileOrUrl cache returns the content of its argument -- (either a file or an URL). If it has to download an url, then it will -- use a cache as required by its second argument. -- -- We always use default remote darcs, since it is not fatal if the -- remote darcs does not exist or is too old -- anything that supports -- transfer-mode should do, and if not, we will fall back to SFTP or SCP. fetchFilePS :: String -> Cachable -> IO ByteString -- | fetchFileLazyPS fileOrUrl cache lazily reads the content of -- its argument (either a file or an URL). Warning: this function may -- constitute a fd leak; make sure to force consumption of file contents -- to avoid that. See fetchFilePS for details. fetchFileLazyPS :: String -> Cachable -> IO ByteString gzFetchFilePS :: String -> Cachable -> IO ByteString sendEmail :: String -> String -> String -> String -> String -> String -> IO () generateEmail :: Handle -> String -> String -> String -> String -> Doc -> IO () -- | Send an email, optionally containing a patch bundle (more precisely, -- its description and the bundle itself) sendEmailDoc :: String -> String -> String -> String -> String -> Maybe (Doc, Doc) -> Doc -> IO () resendEmail :: String -> String -> ByteString -> IO () signString :: [DarcsFlag] -> Doc -> IO Doc verifyPS :: [DarcsFlag] -> ByteString -> IO (Maybe ByteString) execDocPipe :: String -> [String] -> Doc -> IO Doc execPipeIgnoreError :: String -> [String] -> Doc -> IO Doc getTermNColors :: IO Int pipeDoc :: String -> [String] -> Doc -> IO ExitCode pipeDocSSH :: SshFilePath -> [String] -> Doc -> IO ExitCode -- | Run a command on a remote location without passing it any input or -- reading its output. Return its ExitCode execSSH :: SshFilePath -> String -> IO ExitCode maybeURLCmd :: String -> String -> IO (Maybe (String)) data Cachable Cachable :: Cachable Uncachable :: Cachable MaxAge :: !CInt -> Cachable viewDoc :: Doc -> IO () viewDocWith :: Printers -> Doc -> IO () haveSendmail :: IO Bool sendmailPath :: IO String diffProgram :: IO String -- | Get the name of the darcs executable (as supplied by -- getProgName) darcsProgram :: IO String module Darcs.ColorPrinter errorDoc :: Doc -> a traceDoc :: Doc -> a -> a assertDoc :: Maybe Doc -> a -> a -- | fancyPrinters h returns a set of printers suitable for -- outputting to h fancyPrinters :: Printers instance Show Doc module Darcs.MonadProgress class Monad m => MonadProgress m runProgressActions :: MonadProgress m => String -> [ProgressAction m ()] -> m () -- | a monadic action, annotated with a progress message that could be -- printed out while running the action, and a message that could be -- printed out on error. Actually printing out these messages is optional -- to allow non-IO monads to just run the action. data ProgressAction m a ProgressAction :: m a -> Doc -> Doc -> ProgressAction m a paAction :: ProgressAction m a -> m a paMessage :: ProgressAction m a -> Doc paOnError :: ProgressAction m a -> Doc -- | run a list of ProgressActions without any feedback messages silentlyRunProgressActions :: Monad m => String -> [ProgressAction m ()] -> m () instance (Functor m, Monad m) => MonadProgress (TreeMonad m) instance MonadProgress IO module Darcs.Patch.ApplyMonad class (Functor m, Monad m, Functor (ApplyMonadBase m), Monad (ApplyMonadBase m), ToTree state) => ApplyMonad m (state :: (* -> *) -> *) where type family ApplyMonadBase m :: * -> * mReadFilePSs f = linesPS `fmap` mReadFilePS f mCreateFile f = mModifyFilePS f $ \ _ -> return empty mModifyFilePSs f j = mModifyFilePS f (fmap unlinesPS . j . linesPS) mChangePref _ _ _ = return () nestedApply :: ApplyMonad m state => m x -> state (ApplyMonadBase m) -> m (x, state (ApplyMonadBase m)) liftApply :: ApplyMonad m state => (state (ApplyMonadBase m) -> (ApplyMonadBase m) x) -> state (ApplyMonadBase m) -> m (x, state (ApplyMonadBase m)) getApplyState :: ApplyMonad m state => m (state (ApplyMonadBase m)) putApplyState :: ApplyMonad m state => state m -> m () editFile :: (ApplyMonad m state, state ~ ObjectMap) => UUID -> (ByteString -> ByteString) -> m () editDirectory :: (ApplyMonad m state, state ~ ObjectMap) => UUID -> (DirContent -> DirContent) -> m () mDoesDirectoryExist :: (ApplyMonad m state, state ~ Tree) => FileName -> m Bool mDoesFileExist :: (ApplyMonad m state, state ~ Tree) => FileName -> m Bool mReadFilePS :: (ApplyMonad m state, state ~ Tree) => FileName -> m ByteString mReadFilePSs :: (ApplyMonad m state, state ~ Tree) => FileName -> m [ByteString] mCreateDirectory :: (ApplyMonad m state, state ~ Tree) => FileName -> m () mRemoveDirectory :: (ApplyMonad m state, state ~ Tree) => FileName -> m () mCreateFile :: (ApplyMonad m state, state ~ Tree) => FileName -> m () mRemoveFile :: (ApplyMonad m state, state ~ Tree) => FileName -> m () mRename :: (ApplyMonad m state, state ~ Tree) => FileName -> FileName -> m () mModifyFilePS :: (ApplyMonad m state, state ~ Tree) => FileName -> (ByteString -> m ByteString) -> m () mModifyFilePSs :: (ApplyMonad m state, state ~ Tree) => FileName -> ([ByteString] -> m [ByteString]) -> m () mChangePref :: (ApplyMonad m state, state ~ Tree) => String -> String -> String -> m () class (Functor m, Monad m, ApplyMonad (ApplyMonadOver m state) state) => ApplyMonadTrans m (state :: (* -> *) -> *) where type family ApplyMonadOver m state :: * -> * runApplyMonad :: ApplyMonadTrans m state => (ApplyMonadOver m state) x -> state m -> m (x, state m) -- | withFileNames takes a maybe list of existing rename-pairs, a list of -- filenames and an action, and returns the resulting triple of affected -- files, updated filename list and new rename details. If the -- rename-pairs are not present, a new list is generated from the -- filesnames. withFileNames :: (Maybe [OrigFileNameOf]) -> [FileName] -> FilePathMonad a -> FilePathMonadState withFiles :: [(FileName, ByteString)] -> RestrictedApply a -> [(FileName, ByteString)] class ToTree s toTree :: ToTree s => s m -> Tree m instance MonadProgress RestrictedApply instance ApplyMonad RestrictedApply Tree instance MonadProgress FilePathMonad instance ApplyMonad FilePathMonad Tree instance (Functor m, Monad m) => ApplyMonad (TreeMonad m) Tree instance (Functor m, Monad m) => ApplyMonadTrans m Tree instance ToTree Tree module Darcs.Patch.Apply class Apply p where type family ApplyState p :: (* -> *) -> * apply :: (Apply p, ApplyMonad m (ApplyState p)) => p x y -> m () applyToFilePaths :: (Apply p, ApplyState p ~ Tree) => p x y -> Maybe [(FilePath, FilePath)] -> [FilePath] -> ([FilePath], [FilePath], [(FilePath, FilePath)]) -- | Apply a patch to a Tree, yielding a new Tree. applyToTree :: (Apply p, Functor m, Monad m, ApplyState p ~ Tree) => p x y -> Tree m -> m (Tree m) applyToState :: (Apply p, ApplyMonadTrans m (ApplyState p)) => p x y -> (ApplyState p) m -> m ((ApplyState p) m) effectOnFilePaths :: (Apply p, ApplyState p ~ Tree) => p x y -> [FilePath] -> [FilePath] instance Apply p => Apply (RL p) instance Apply p => Apply (FL p) module Darcs.Patch.Repair -- | Repair and RepairToFL deal with repairing old patches -- that were were written out due to bugs or that we no longer wish to -- support. Repair is implemented by collections of patches (FL, -- Named, PatchInfoAnd) that might need repairing. class Repair p applyAndTryToFix :: (Repair p, ApplyMonad m (ApplyState p)) => p x y -> m (Maybe (String, p x y)) -- | RepairToFL is implemented by single patches that can be -- repaired (Prim, Patch, RealPatch) There is a default so that patch -- types with no current legacy problems don't need to have an -- implementation. class Apply p => RepairToFL p where applyAndTryToFixFL p = do { apply p; return Nothing } applyAndTryToFixFL :: (RepairToFL p, ApplyMonad m (ApplyState p)) => p x y -> m (Maybe (String, FL p x y)) mapMaybeSnd :: (a -> b) -> Maybe (c, a) -> Maybe (c, b) class Check p where isInconsistent _ = Nothing isInconsistent :: Check p => p x y -> Maybe Doc instance RepairToFL p => Repair (FL p) instance Check p => Check (RL p) instance Check p => Check (FL p) module Darcs.Repository.Format -- | RepoFormat is the representation of the format of a -- repository. Each sublist corresponds to a line in the format file. -- Each line is decomposed into words. newtype RepoFormat RF :: [[ByteString]] -> RepoFormat data RepoProperty Darcs1_0 :: RepoProperty Darcs2 :: RepoProperty HashedInventory :: RepoProperty NoWorkingDir :: RepoProperty -- | identifyRepoFormat URL identifies the format of the -- repository at the given address. Fails if we weren't able to identify -- the format. identifyRepoFormat :: String -> IO RepoFormat -- | tryIdentifyRepoFormat URL identifies the format of the -- repository at the given address. Return Left reason if it -- fails, where reason explains why we weren't able to identify -- the format. tryIdentifyRepoFormat :: String -> IO (Either String RepoFormat) createRepoFormat :: [DarcsFlag] -> RepoFormat -- | writeRepoFormat writes the repo format to the given file. writeRepoFormat :: RepoFormat -> FilePath -> IO () -- | writeProblem form tells if we can write to a repo in format -- form. It returns Nothing if there's no problem -- writing to such a repository. writeProblem :: RepoFormat -> Maybe String -- | readProblem form tells if we can read from a repo in format -- form. It returns Nothing if there's no problem -- reading from such a repository. readProblem :: RepoFormat -> Maybe String -- | readfromAndWritetoProblem form tells if we can read from and -- write to a repo in format form. It returns Nothing -- if there's no problem reading and writing to such a repository. readfromAndWritetoProblem :: RepoFormat -> RepoFormat -> Maybe String formatHas :: RepoProperty -> RepoFormat -> Bool instance Show RepoFormat instance Show RepoProperty module Darcs.Repository.Motd -- | Fetch and return the message of the day for a given repository. getMotd :: String -> IO ByteString -- | Display the message of the day for a given repository, unless either -- the XMLOutput or the Quiet flags are passed in showMotd :: [DarcsFlag] -> String -> IO () -- | This module is used by the push and put commands to apply the a bundle -- to a remote repository. By remote I do not necessarily mean a -- repository on another machine, it is just not the repository we're -- located in. module Darcs.RemoteApply remoteApply :: [DarcsFlag] -> String -> Doc -> IO ExitCode applyAs :: [DarcsFlag] -> Maybe String module SHA1 sha1PS :: ByteString -> String module Darcs.Patch.Info -- | A PatchInfo value contains the metadata of a patch. The date, name, -- author and log fields are UTF-8 encoded text in darcs 2.4 and later, -- and just sequences of bytes (decoded with whatever is the locale when -- displayed) in earlier darcs. -- -- The members with names that start with '_' are not supposed to be used -- directly in code that does not care how the patch info is stored. data PatchInfo PatchInfo :: !ByteString -> !ByteString -> !ByteString -> ![ByteString] -> !Bool -> PatchInfo _piDate :: PatchInfo -> !ByteString _piName :: PatchInfo -> !ByteString _piAuthor :: PatchInfo -> !ByteString _piLog :: PatchInfo -> ![ByteString] isInverted :: PatchInfo -> !Bool patchinfo :: String -> String -> String -> [String] -> IO PatchInfo invertName :: PatchInfo -> PatchInfo idpatchinfo :: PatchInfo -- | addJunk adds a line that contains a random number to make the patch -- unique. addJunk :: PatchInfo -> IO PatchInfo makePatchname :: PatchInfo -> String -- | This makes darcs-1 (non-hashed repos) filenames, and is also generally -- used in both in hashed and non-hashed repo code for making patch -- hashes. -- -- The name consists of three segments: -- --
-- [Document the foo interface -- John Doe <john.doe@example.com>**20110615084241 -- Ignore-this: 85b94f67d377c4ab671101266ef9c229 -- Nobody knows what a 'foo' is, so describe it. -- ] ---- -- See showPatchInfo for the inverse operation. readPatchInfo :: ParserM m => m (PatchInfo) -- | Get the name, including an UNDO: prefix if the patch is -- inverted. justName :: PatchInfo -> String -- | Returns the author of a patch. justAuthor :: PatchInfo -> String justLog :: PatchInfo -> String repopatchinfo :: String -> PatchInfo -> RepoPatchInfo data RepoPatchInfo humanFriendly :: PatchInfo -> Doc toXml :: PatchInfo -> Doc piDate :: PatchInfo -> CalendarTime setPiDate :: String -> PatchInfo -> PatchInfo piDateString :: PatchInfo -> String piDateBytestring :: PatchInfo -> ByteString -- | Returns the name of the patch. Unlike justName, it does not -- preprend UNDO: to the name if the patch is inverted. piName :: PatchInfo -> String piRename :: PatchInfo -> String -> PatchInfo -- | Returns the author of a patch. piAuthor :: PatchInfo -> String -- | Get the tag name, if the patch is a tag patch. piTag :: PatchInfo -> Maybe String -- | Get the log message of a patch. piLog :: PatchInfo -> [String] -- | Patch is stored between square brackets. -- --
-- [ <patch name> -- <patch author>*<patch date> -- <patch log (may be empty)> (indented one) -- <can have multiple lines in patch log,> -- <as long as they're preceded by a space> -- <and don't end with a square bracket.> -- ] ---- -- note that below I assume the name has no newline in it. See -- readPatchInfo for the inverse operation. showPatchInfo :: PatchInfo -> Doc isTag :: PatchInfo -> Bool readPatchInfos :: ByteString -> [PatchInfo] escapeXML :: String -> Doc instance Eq PatchInfo instance Ord PatchInfo instance Show PatchInfo instance HTML RepoPatchInfo module Darcs.Patch.Show class ShowPatchBasic p showPatch :: ShowPatchBasic p => p x y -> Doc class ShowPatchBasic p => ShowPatch p where showNicely = showPatch showContextPatch p = return $ showPatch p description = showPatch thing _ = "patch" things x = plural (Noun $ thing x) "" showNicely :: ShowPatch p => p x y -> Doc showContextPatch :: (ShowPatch p, Monad m, ApplyMonadTrans m (ApplyState p), ApplyMonad m (ApplyState p)) => p x y -> m Doc description :: ShowPatch p => p x y -> Doc summary :: ShowPatch p => p x y -> Doc summaryFL :: ShowPatch p => FL p x y -> Doc thing :: ShowPatch p => p x y -> String things :: ShowPatch p => p x y -> String showNamedPrefix :: PatchInfo -> [PatchInfo] -> Doc writePatch :: ShowPatchBasic p => FilePath -> p x y -> IO () gzWritePatch :: ShowPatchBasic p => FilePath -> p x y -> IO () formatFileName :: FileNameFormat -> FileName -> Doc module Darcs.Patch.Patchy class (MyEq p, Apply p, Commute p, PatchInspect p, ShowPatch p, ReadPatch p, Invert p) => Patchy p class Apply p where type family ApplyState p :: (* -> *) -> * apply :: (Apply p, ApplyMonad m (ApplyState p)) => p x y -> m () -- | Things that can commute. class Commute p commute :: Commute p => (p :> p) x y -> Maybe ((p :> p) x y) class Invert p invert :: Invert p => p x y -> p y x class PatchInspect p listTouchedFiles :: PatchInspect p => p x y -> [FilePath] hunkMatches :: PatchInspect p => (ByteString -> Bool) -> p x y -> Bool class ReadPatch p readPatch' :: (ReadPatch p, ParserM m) => m (Sealed (p x)) showPatch :: ShowPatchBasic p => p x y -> Doc class ShowPatchBasic p => ShowPatch p where showNicely = showPatch showContextPatch p = return $ showPatch p description = showPatch thing _ = "patch" things x = plural (Noun $ thing x) "" showNicely :: ShowPatch p => p x y -> Doc showContextPatch :: (ShowPatch p, Monad m, ApplyMonadTrans m (ApplyState p), ApplyMonad m (ApplyState p)) => p x y -> m Doc description :: ShowPatch p => p x y -> Doc summary :: ShowPatch p => p x y -> Doc summaryFL :: ShowPatch p => FL p x y -> Doc thing :: ShowPatch p => p x y -> String things :: ShowPatch p => p x y -> String module Darcs.Patch.FileHunk data FileHunk x y FileHunk :: !FileName -> !Int -> [ByteString] -> [ByteString] -> FileHunk x y class IsHunk p isHunk :: IsHunk p => p x y -> Maybe (FileHunk x y) showFileHunk :: FileNameFormat -> FileHunk x y -> Doc module Darcs.Patch.Prim.Class class PrimConstruct prim addfile :: PrimConstruct prim => FilePath -> prim x y rmfile :: PrimConstruct prim => FilePath -> prim x y adddir :: PrimConstruct prim => FilePath -> prim x y rmdir :: PrimConstruct prim => FilePath -> prim x y move :: PrimConstruct prim => FilePath -> FilePath -> prim x y changepref :: PrimConstruct prim => String -> String -> String -> prim x y hunk :: PrimConstruct prim => FilePath -> Int -> [ByteString] -> [ByteString] -> prim x y tokreplace :: PrimConstruct prim => FilePath -> String -> String -> String -> prim x y binary :: PrimConstruct prim => FilePath -> ByteString -> ByteString -> prim x y primFromHunk :: PrimConstruct prim => FileHunk x y -> prim x y anIdentity :: PrimConstruct prim => prim x x class PrimCanonize prim tryToShrink :: PrimCanonize prim => FL prim x y -> FL prim x y tryShrinkingInverse :: PrimCanonize prim => FL prim x y -> Maybe (FL prim x y) sortCoalesceFL :: PrimCanonize prim => FL prim x y -> FL prim x y canonize :: PrimCanonize prim => prim x y -> FL prim x y canonizeFL :: PrimCanonize prim => FL prim x y -> FL prim x y join :: PrimCanonize prim => (prim :> prim) x y -> Maybe (FL prim x y) class PrimClassify prim primIsAddfile :: PrimClassify prim => prim x y -> Bool primIsRmfile :: PrimClassify prim => prim x y -> Bool primIsAdddir :: PrimClassify prim => prim x y -> Bool primIsRmdir :: PrimClassify prim => prim x y -> Bool primIsMove :: PrimClassify prim => prim x y -> Bool primIsHunk :: PrimClassify prim => prim x y -> Bool primIsTokReplace :: PrimClassify prim => prim x y -> Bool primIsBinary :: PrimClassify prim => prim x y -> Bool primIsSetpref :: PrimClassify prim => prim x y -> Bool is_filepatch :: PrimClassify prim => prim x y -> Maybe FileName class PrimDetails prim summarizePrim :: PrimDetails prim => prim x y -> [SummDetail] class PrimShow prim showPrim :: PrimShow prim => FileNameFormat -> prim a b -> Doc showPrimFL :: PrimShow prim => FileNameFormat -> FL prim a b -> Doc class PrimRead prim readPrim :: (PrimRead prim, ParserM m) => FileNameFormat -> m (Sealed (prim x)) class PrimApply prim applyPrimFL :: (PrimApply prim, ApplyMonad m (ApplyState prim)) => FL prim x y -> m () class (Patchy prim, PatchListFormat prim, IsHunk prim, RepairToFL prim, PrimConstruct prim, PrimCanonize prim, PrimClassify prim, PrimDetails prim, PrimShow prim, PrimRead prim, PrimApply prim) => PrimPatch prim class PrimPatch (PrimOf p) => PrimPatchBase p where type family PrimOf (p :: * -> * -> *) :: * -> * -> * class FromPrim p fromPrim :: FromPrim p => PrimOf p x y -> p x y class FromPrims p fromPrims :: FromPrims p => FL (PrimOf p) x y -> p x y joinPatches :: FromPrims p => FL p x y -> p x y class FromPrim p => ToFromPrim p toPrim :: ToFromPrim p => p x y -> Maybe (PrimOf p x y) instance FromPrim p => FromPrims (RL p) instance FromPrim p => FromPrims (FL p) instance FromPrim p => FromPrim (FL p) instance PrimPatchBase p => PrimPatchBase (RL p) instance PrimPatchBase p => PrimPatchBase (FL p) module Darcs.Patch.Prim showPrim :: PrimShow prim => FileNameFormat -> prim a b -> Doc showPrimFL :: PrimShow prim => FileNameFormat -> FL prim a b -> Doc primIsAddfile :: PrimClassify prim => prim x y -> Bool primIsHunk :: PrimClassify prim => prim x y -> Bool primIsBinary :: PrimClassify prim => prim x y -> Bool primIsSetpref :: PrimClassify prim => prim x y -> Bool primIsAdddir :: PrimClassify prim => prim x y -> Bool is_filepatch :: PrimClassify prim => prim x y -> Maybe FileName -- | It can sometimes be handy to have a canonical representation of a -- given patch. We achieve this by defining a canonical form for each -- patch type, and a function canonize which takes a patch and -- puts it into canonical form. This routine is used by the diff function -- to create an optimal patch (based on an LCS algorithm) from a simple -- hunk describing the old and new version of a file. canonize :: PrimCanonize prim => prim x y -> FL prim x y tryToShrink :: PrimCanonize prim => FL prim x y -> FL prim x y -- | sortCoalesceFL ps coalesces as many patches in -- ps as possible, sorting the results in some standard order. sortCoalesceFL :: PrimCanonize prim => FL prim x y -> FL prim x y join :: PrimCanonize prim => (prim :> prim) x y -> Maybe (FL prim x y) -- | canonizeFL ps puts a sequence of primitive patches -- into canonical form. Even if the patches are just hunk patches, this -- is not necessarily the same set of results as you would get if you -- applied the sequence to a specific tree and recalculated a diff. -- -- Note that this process does not preserve the commutation behaviour of -- the patches and is therefore not appropriate for use when working with -- already recorded patches (unless doing amend-record or the like). canonizeFL :: PrimCanonize prim => FL prim x y -> FL prim x y tryShrinkingInverse :: PrimCanonize prim => FL prim x y -> Maybe (FL prim x y) summarizePrim :: PrimDetails prim => prim x y -> [SummDetail] applyPrimFL :: (PrimApply prim, ApplyMonad m (ApplyState prim)) => FL prim x y -> m () readPrim :: (PrimRead prim, ParserM m) => FileNameFormat -> m (Sealed (prim x)) class FromPrim p fromPrim :: FromPrim p => PrimOf p x y -> p x y class FromPrims p fromPrims :: FromPrims p => FL (PrimOf p) x y -> p x y joinPatches :: FromPrims p => FL p x y -> p x y class FromPrim p => ToFromPrim p toPrim :: ToFromPrim p => p x y -> Maybe (PrimOf p x y) class (Patchy prim, PatchListFormat prim, IsHunk prim, RepairToFL prim, PrimConstruct prim, PrimCanonize prim, PrimClassify prim, PrimDetails prim, PrimShow prim, PrimRead prim, PrimApply prim) => PrimPatch prim class PrimPatch (PrimOf p) => PrimPatchBase p where type family PrimOf (p :: * -> * -> *) :: * -> * -> * class PrimConstruct prim addfile :: PrimConstruct prim => FilePath -> prim x y rmfile :: PrimConstruct prim => FilePath -> prim x y adddir :: PrimConstruct prim => FilePath -> prim x y rmdir :: PrimConstruct prim => FilePath -> prim x y move :: PrimConstruct prim => FilePath -> FilePath -> prim x y changepref :: PrimConstruct prim => String -> String -> String -> prim x y hunk :: PrimConstruct prim => FilePath -> Int -> [ByteString] -> [ByteString] -> prim x y tokreplace :: PrimConstruct prim => FilePath -> String -> String -> String -> prim x y binary :: PrimConstruct prim => FilePath -> ByteString -> ByteString -> prim x y primFromHunk :: PrimConstruct prim => FileHunk x y -> prim x y anIdentity :: PrimConstruct prim => prim x x module Darcs.Patch.V1.Core data Patch prim x y PP :: prim x y -> Patch prim x y Merger :: FL (Patch prim) x y -> RL (Patch prim) x b -> Patch prim c b -> Patch prim c d -> Patch prim x y Regrem :: FL (Patch prim) x y -> RL (Patch prim) x b -> Patch prim c b -> Patch prim c a -> Patch prim y x isMerger :: Patch prim a b -> Bool mergerUndo :: Patch prim x y -> FL (Patch prim) x y instance Check (Patch prim) instance PatchListFormat (Patch prim) instance FromPrim (Patch prim) instance PrimPatch prim => PrimPatchBase (Patch prim) module Darcs.Patch.V1.Show showPatch_ :: PrimPatch prim => Patch prim a b -> Doc instance PrimPatch prim => Show2 (Patch prim) instance PrimPatch prim => Show1 (Patch prim x) instance PrimPatch prim => Show (Patch prim x y) module Darcs.Patch.Effect -- | Patches whose concrete effect which can be expressed as a list of -- primitive patches. -- -- A minimal definition would be either of effect or -- effectRL. class Effect p where effect = reverseRL . effectRL effectRL = reverseFL . effect effect :: Effect p => p x y -> FL (PrimOf p) x y effectRL :: Effect p => p x y -> RL (PrimOf p) x y instance Effect p => Effect (RL p) instance Effect p => Effect (FL p) module Darcs.Patch.Conflict class (Effect p, PatchInspect (PrimOf p)) => Conflict p where listConflictedFiles p = nubsort $ concatMap (unseal listTouchedFiles) $ concat $ resolveConflicts p conflictedEffect x = case listConflictedFiles x of { [] -> mapFL (IsC Okay) $ effect x _ -> mapFL (IsC Conflicted) $ effect x } listConflictedFiles :: Conflict p => p x y -> [FilePath] resolveConflicts :: Conflict p => p x y -> [[Sealed (FL (PrimOf p) y)]] conflictedEffect :: Conflict p => p x y -> [IsConflictedPrim (PrimOf p)] class CommuteNoConflicts p commuteNoConflicts :: CommuteNoConflicts p => (p :> p) x y -> Maybe ((p :> p) x y) data IsConflictedPrim prim IsC :: !ConflictState -> !(prim x y) -> IsConflictedPrim prim data ConflictState Okay :: ConflictState Conflicted :: ConflictState Duplicated :: ConflictState instance Eq ConflictState instance Ord ConflictState instance Show ConflictState instance Read ConflictState instance CommuteNoConflicts p => CommuteNoConflicts (RL p) instance (CommuteNoConflicts p, Conflict p) => Conflict (RL p) instance CommuteNoConflicts p => CommuteNoConflicts (FL p) instance (CommuteNoConflicts p, Conflict p) => Conflict (FL p) module Darcs.Patch.Summary plainSummary :: (Conflict e, Effect e, PrimPatchBase e) => e x y -> Doc plainSummaryPrim :: PrimDetails prim => prim x y -> Doc plainSummaryPrims :: PrimDetails prim => FL prim x y -> Doc xmlSummary :: (Effect p, Conflict p, PrimPatchBase p) => p x y -> Doc instance Ord SummChunk instance Eq SummChunk module Darcs.Patch.ConflictMarking mangleUnravelled :: PrimPatch prim => [Sealed (FL prim x)] -> Sealed (FL prim x) module Darcs.Patch.V1.Commute merge :: Merge p => (p :\/: p) x y -> (p :/\: p) x y merger :: PrimPatch prim => String -> Patch prim x y -> Patch prim x z -> Sealed (Patch prim y) unravel :: PrimPatch prim => Patch prim x y -> [Sealed (FL prim x)] publicUnravel :: PrimPatch prim => Patch prim x y -> [Sealed (FL prim y)] instance MyEq prim => Eq (Patch prim x y) instance MyEq prim => MyEq (Patch prim) instance Invert prim => Invert (Patch prim) instance IsHunk prim => IsHunk (Patch prim) instance PrimPatch prim => Effect (Patch prim) instance PrimPatch prim => Conflict (Patch prim) instance PrimPatch prim => CommuteNoConflicts (Patch prim) instance PrimPatch prim => PatchInspect (Patch prim) instance PrimPatch prim => Commute (Patch prim) instance PrimPatch prim => Merge (Patch prim) instance MonadPlus Perhaps instance Monad Perhaps module Darcs.Patch.V1.Apply instance PrimPatch prim => RepairToFL (Patch prim) instance PrimPatch prim => Apply (Patch prim) module Darcs.Patch.V1.Read instance PrimPatch prim => ReadPatch (Patch prim) module Darcs.Patch.Prim.V1.Core data Prim x y Move :: !FileName -> !FileName -> Prim x y DP :: !FileName -> !(DirPatchType x y) -> Prim x y FP :: !FileName -> !(FilePatchType x y) -> Prim x y ChangePref :: !String -> !String -> !String -> Prim x y data DirPatchType x y RmDir :: DirPatchType x y AddDir :: DirPatchType x y data FilePatchType x y RmFile :: FilePatchType x y AddFile :: FilePatchType x y Hunk :: !Int -> [ByteString] -> [ByteString] -> FilePatchType x y TokReplace :: !String -> !String -> !String -> FilePatchType x y Binary :: ByteString -> ByteString -> FilePatchType x y isIdentity :: Prim x y -> EqCheck x y -- | comparePrim p1 p2 is used to provide an arbitrary -- ordering between p1 and p2. Basically, identical -- patches are equal and Move < DP < FP < ChangePref. -- Everything else is compared in dictionary order of its arguments. comparePrim :: Prim x y -> Prim w z -> Ordering instance Eq (FilePatchType x y) instance Ord (FilePatchType x y) instance Eq (DirPatchType x y) instance Ord (DirPatchType x y) instance Eq (Prim x y) instance MyEq Prim instance PatchInspect Prim instance Invert Prim instance IsHunk Prim instance PrimConstruct Prim instance PrimClassify Prim instance MyEq DirPatchType instance MyEq FilePatchType module Darcs.Patch.Prim.V1.Commute data Perhaps a Unknown :: Perhaps a Failed :: Perhaps a Succeeded :: a -> Perhaps a subcommutes :: [(String, WrappedCommuteFunction)] newtype WrappedCommuteFunction WrappedCommuteFunction :: CommuteFunction -> WrappedCommuteFunction runWrappedCommuteFunction :: WrappedCommuteFunction -> CommuteFunction instance Commute Prim instance MonadPlus Perhaps instance Monad Perhaps module Darcs.Patch.Prim.V1.Details instance PrimDetails Prim module Darcs.Patch.Prim.V1.Read instance PrimRead Prim instance ReadPatch Prim module Darcs.Patch.Prim.V3.Core data Prim x y BinaryHunk :: !UUID -> Hunk x y -> Prim x y TextHunk :: !UUID -> Hunk x y -> Prim x y Manifest :: !UUID -> Location -> Prim x y Demanifest :: !UUID -> Location -> Prim x y Move :: !UUID -> Location -> Location -> Prim x y Identity :: Prim x x data Hunk x y Hunk :: !Int -> ByteString -> ByteString -> Hunk x y newtype UUID UUID :: ByteString -> UUID type Location = (UUID, ByteString) data Object (m :: * -> *) Directory :: DirContent -> Object Blob :: (m ByteString) -> !Hash -> Object touches :: Prim x y -> [UUID] hunkEdit :: Hunk x y -> ByteString -> ByteString instance Eq (Prim x y) instance MyEq Prim instance PatchInspect Prim instance Invert Prim instance IsHunk Prim instance PrimConstruct Prim instance PrimClassify Prim instance MyEq Hunk module Darcs.Patch.Prim.V3.Apply data ObjectMap (m :: * -> *) ObjectMap :: (UUID -> m (Maybe (Object m))) -> (UUID -> Object m -> m (ObjectMap m)) -> m [UUID] -> ObjectMap getObject :: ObjectMap -> UUID -> m (Maybe (Object m)) putObject :: ObjectMap -> UUID -> Object m -> m (ObjectMap m) listObjects :: ObjectMap -> m [UUID] instance (Functor m, Monad m) => ApplyMonadTrans m ObjectMap instance (Functor m, Monad m) => ApplyMonad (StateT (ObjectMap m) m) ObjectMap instance ToTree ObjectMap instance PrimApply Prim instance RepairToFL Prim instance Apply Prim module Darcs.Patch.Prim.V3.Coalesce instance PrimCanonize Prim module Darcs.Patch.Prim.V3.Commute class Monad m => CommuteMonad m commuteFail :: CommuteMonad m => m a instance Commute' Prim instance Commute Prim instance CommuteMonad Maybe module Darcs.Patch.Prim.V3.Details instance PrimDetails Prim module Darcs.Patch.Prim.V3.Read instance ReadPatch Prim instance PrimRead Prim module Darcs.Patch.Dummy data DummyPatch x y instance Patchy DummyPatch instance Apply DummyPatch instance Commute DummyPatch instance ShowPatch DummyPatch instance ShowPatchBasic DummyPatch instance ReadPatch DummyPatch instance PatchInspect DummyPatch instance Invert DummyPatch instance MyEq DummyPatch instance PatchListFormat DummyPatch instance IsHunk DummyPatch module Darcs.Patch.Bracketed.Instances instance ShowPatchBasic p => ShowPatchBasic (Bracketed p) module Darcs.Patch.Viewing showContextHunk :: ApplyMonad m Tree => FileHunk x y -> m Doc showContextSeries :: (Apply p, ShowPatch p, IsHunk p, ApplyMonadTrans m (ApplyState p), ApplyMonad m (ApplyState p)) => FL p x y -> m Doc instance (Apply p, IsHunk p, PatchListFormat p, ShowPatch p) => ShowPatch (RL p) instance (PatchListFormat p, ShowPatchBasic p) => ShowPatchBasic (RL p) instance (Apply p, IsHunk p, PatchListFormat p, ShowPatch p) => ShowPatch (FL p) instance (PatchListFormat p, ShowPatchBasic p) => ShowPatchBasic (FL p) module Darcs.Patch.Split -- | A splitter is something that can take a patch and (possibly) render it -- as text in some format of its own choosing. This text can then be -- presented to the user for editing, and the result given to the -- splitter for parsing. If the parse succeeds, the result is a list of -- patches that could replace the original patch in any context. -- Typically this list will contain the changed version of the patch, -- along with fixup pieces to ensure that the overall effect of the list -- is the same as the original patch. The individual elements of the list -- can then be offered separately to the user, allowing them to accept -- some and reject others. -- -- There's no immediate application for a splitter for anything other -- than Prim (you shouldn't go editing named patches, you'll break them!) -- However you might want to compose splitters for FilePatchType to make -- splitters for Prim etc, and the generality doesn't cost anything. data Splitter p Splitter :: (forall x y. p x y -> Maybe (ByteString, ByteString -> Maybe (FL p x y))) -> (forall x y. FL p x y -> FL p x y) -> Splitter p applySplitter :: Splitter p -> forall x y. p x y -> Maybe (ByteString, ByteString -> Maybe (FL p x y)) canonizeSplit :: Splitter p -> forall x y. FL p x y -> FL p x y -- | This generic splitter just lets the user edit the printed -- representation of the patch Should not be used expect for testing and -- experimentation. rawSplitter :: (ShowPatch p, ReadPatch p, Invert p) => Splitter p -- | Never splits. In other code we normally pass around Maybe Splitter -- instead of using this as the default, because it saves clients that -- don't care about splitting from having to import this module just to -- get noSplitter. noSplitter :: Splitter p -- | Split a primitive hunk patch up by allowing the user to edit both the -- before and after lines, then insert fixup patches to clean up the -- mess. primSplitter :: PrimPatch p => Splitter p reversePrimSplitter :: PrimPatch prim => Splitter prim module Darcs.Patch.Named -- | The Named type adds a patch info about a patch, that is a -- name. -- -- NamedP info deps p represents patch p with name -- info. deps is a list of dependencies added at the -- named patch level, compared with the unnamed level (ie, dependencies -- added with darcs record --ask-deps). data Named p x y NamedP :: !PatchInfo -> ![PatchInfo] -> !(FL p x y) -> Named p x y infopatch :: Patchy p => PatchInfo -> FL p x y -> Named p x y adddeps :: Named p x y -> [PatchInfo] -> Named p x y namepatch :: Patchy p => String -> String -> String -> [String] -> FL p x y -> IO (Named p x y) anonymous :: Patchy p => FL p x y -> IO (Named p x y) getdeps :: Named p x y -> [PatchInfo] patch2patchinfo :: Named p x y -> PatchInfo patchname :: Named p x y -> String patchcontents :: Named p x y -> FL p x y fmapNamed :: (forall a b. p a b -> q a b) -> Named p x y -> Named q x y fmapFL_Named :: (FL p x y -> FL q x y) -> Named p x y -> Named q x y instance (PatchListFormat p, ShowPatch p) => Show2 (Named p) instance (PatchListFormat p, ShowPatch p) => Show1 (Named p x) instance (PatchListFormat p, ShowPatch p) => Show (Named p x y) instance (Apply p, CommuteNoConflicts p, Conflict p, IsHunk p, PatchListFormat p, PrimPatchBase p, ShowPatch p) => ShowPatch (Named p) instance (PatchListFormat p, ShowPatchBasic p) => ShowPatchBasic (Named p) instance Check p => Check (Named p) instance (CommuteNoConflicts p, Conflict p) => Conflict (Named p) instance PatchInspect p => PatchInspect (Named p) instance Merge p => Merge (Named p) instance Commute p => Commute (Named p) instance (Commute p, Invert p) => Invert (Named p) instance (Commute p, MyEq p) => MyEq (Named p) instance RepairToFL p => Repair (Named p) instance Apply p => Apply (Named p) instance (ReadPatch p, PatchListFormat p) => ReadPatch (Named p) instance PatchListFormat (Named p) instance IsHunk (Named p) instance Effect p => Effect (Named p) instance PrimPatchBase p => PrimPatchBase (Named p) module Darcs.Patch.Patchy.Instances instance (IsHunk p, PatchListFormat p, Patchy p) => Patchy (RL p) instance (IsHunk p, PatchListFormat p, Patchy p) => Patchy (FL p) module Darcs.Patch.RepoPatch class (Patchy p, Merge p, Effect p, IsHunk p, FromPrim p, Conflict p, CommuteNoConflicts p, Check p, RepairToFL p, PatchListFormat p, PrimPatchBase p, Patchy (PrimOf p), IsHunk (PrimOf p)) => RepoPatch p module Darcs.Patch class (Patchy p, Merge p, Effect p, IsHunk p, FromPrim p, Conflict p, CommuteNoConflicts p, Check p, RepairToFL p, PatchListFormat p, PrimPatchBase p, Patchy (PrimOf p), IsHunk (PrimOf p)) => RepoPatch p -- | The Named type adds a patch info about a patch, that is a -- name. -- -- NamedP info deps p represents patch p with name -- info. deps is a list of dependencies added at the -- named patch level, compared with the unnamed level (ie, dependencies -- added with darcs record --ask-deps). data Named p x y class (MyEq p, Apply p, Commute p, PatchInspect p, ShowPatch p, ReadPatch p, Invert p) => Patchy p joinPatches :: FromPrims p => FL p x y -> p x y fromPrim :: FromPrim p => PrimOf p x y -> p x y fromPrims :: FromPrims p => FL (PrimOf p) x y -> p x y rmfile :: PrimConstruct prim => FilePath -> prim x y addfile :: PrimConstruct prim => FilePath -> prim x y rmdir :: PrimConstruct prim => FilePath -> prim x y adddir :: PrimConstruct prim => FilePath -> prim x y move :: PrimConstruct prim => FilePath -> FilePath -> prim x y hunk :: PrimConstruct prim => FilePath -> Int -> [ByteString] -> [ByteString] -> prim x y tokreplace :: PrimConstruct prim => FilePath -> String -> String -> String -> prim x y namepatch :: Patchy p => String -> String -> String -> [String] -> FL p x y -> IO (Named p x y) anonymous :: Patchy p => FL p x y -> IO (Named p x y) binary :: PrimConstruct prim => FilePath -> ByteString -> ByteString -> prim x y description :: ShowPatch p => p x y -> Doc -- | showContextPatch is used to add context to a patch, as diff -u does. -- Thus, it differs from showPatch only for hunks. It is used for -- instance before putting it into a bundle. As this unified context is -- not included in patch representation, this requires access to the -- tree. showContextPatch :: (ShowPatch p, Monad m, ApplyMonadTrans m (ApplyState p), ApplyMonad m (ApplyState p)) => p x y -> m Doc showPatch :: ShowPatchBasic p => p x y -> Doc showNicely :: ShowPatch p => p x y -> Doc infopatch :: Patchy p => PatchInfo -> FL p x y -> Named p x y changepref :: PrimConstruct prim => String -> String -> String -> prim x y thing :: ShowPatch p => p x y -> String things :: ShowPatch p => p x y -> String primIsAddfile :: PrimClassify prim => prim x y -> Bool primIsHunk :: PrimClassify prim => prim x y -> Bool primIsSetpref :: PrimClassify prim => prim x y -> Bool merge :: Merge p => (p :\/: p) x y -> (p :/\: p) x y commute :: Commute p => (p :> p) x y -> Maybe ((p :> p) x y) listTouchedFiles :: PatchInspect p => p x y -> [FilePath] hunkMatches :: PatchInspect p => (ByteString -> Bool) -> p x y -> Bool forceTokReplace :: String -> String -> String -> ByteString -> Maybe ByteString class (Patchy prim, PatchListFormat prim, IsHunk prim, RepairToFL prim, PrimConstruct prim, PrimCanonize prim, PrimClassify prim, PrimDetails prim, PrimShow prim, PrimRead prim, PrimApply prim) => PrimPatch prim resolveConflicts :: Conflict p => p x y -> [[Sealed (FL (PrimOf p) y)]] -- | Patches whose concrete effect which can be expressed as a list of -- primitive patches. -- -- A minimal definition would be either of effect or -- effectRL. class Effect p where effect = reverseRL . effectRL effectRL = reverseFL . effect effect :: Effect p => p x y -> FL (PrimOf p) x y primIsBinary :: PrimClassify prim => prim x y -> Bool gzWritePatch :: ShowPatchBasic p => FilePath -> p x y -> IO () writePatch :: ShowPatchBasic p => FilePath -> p x y -> IO () primIsAdddir :: PrimClassify prim => prim x y -> Bool invert :: Invert p => p x y -> p y x invertFL :: Invert p => FL p x y -> RL p y x invertRL :: Invert p => RL p x y -> FL p y x commuteFLorComplain :: Commute p => (p :> FL p) x y -> Either (Sealed2 p) ((FL p :> p) x y) commuteRL :: Commute p => (RL p :> p) x y -> Maybe ((p :> RL p) x y) readPatch :: ReadPatch p => ByteString -> Maybe (Sealed (p x)) readPatchPartial :: ReadPatch p => ByteString -> Maybe (Sealed (p x), ByteString) -- | It can sometimes be handy to have a canonical representation of a -- given patch. We achieve this by defining a canonical form for each -- patch type, and a function canonize which takes a patch and -- puts it into canonical form. This routine is used by the diff function -- to create an optimal patch (based on an LCS algorithm) from a simple -- hunk describing the old and new version of a file. canonize :: PrimCanonize prim => prim x y -> FL prim x y -- | sortCoalesceFL ps coalesces as many patches in -- ps as possible, sorting the results in some standard order. sortCoalesceFL :: PrimCanonize prim => FL prim x y -> FL prim x y tryToShrink :: PrimCanonize prim => FL prim x y -> FL prim x y patchname :: Named p x y -> String patchcontents :: Named p x y -> FL p x y applyToFilePaths :: (Apply p, ApplyState p ~ Tree) => p x y -> Maybe [(FilePath, FilePath)] -> [FilePath] -> ([FilePath], [FilePath], [(FilePath, FilePath)]) apply :: (Apply p, ApplyMonad m (ApplyState p)) => p x y -> m () -- | Apply a patch to a Tree, yielding a new Tree. applyToTree :: (Apply p, Functor m, Monad m, ApplyState p ~ Tree) => p x y -> Tree m -> m (Tree m) effectOnFilePaths :: (Apply p, ApplyState p ~ Tree) => p x y -> [FilePath] -> [FilePath] patch2patchinfo :: Named p x y -> PatchInfo summary :: ShowPatch p => p x y -> Doc summaryFL :: ShowPatch p => FL p x y -> Doc plainSummary :: (Conflict e, Effect e, PrimPatchBase e) => e x y -> Doc xmlSummary :: (Effect p, Conflict p, PrimPatchBase p) => p x y -> Doc plainSummaryPrims :: PrimDetails prim => FL prim x y -> Doc adddeps :: Named p x y -> [PatchInfo] -> Named p x y getdeps :: Named p x y -> [PatchInfo] listConflictedFiles :: Conflict p => p x y -> [FilePath] isInconsistent :: Check p => p x y -> Maybe Doc instance (CommuteNoConflicts p, Conflict p, IsHunk p, PatchListFormat p, PrimPatchBase p, Patchy p, ApplyState p ~ Tree) => Patchy (Named p) module Darcs.Patch.PatchInfoAnd -- | Hopefully p C (x y) is Either -- String (p C (x y)) in a form adapted to darcs patches. -- The C (x y) represents the type witness for the -- patch that should be there. The Hopefully type just tells -- whether we expect the patch to be hashed or not, and -- SimpleHopefully does the real work of emulating Either. -- Hopefully sh represents an expected unhashed patch, and -- Hashed hash sh represents an expected hashed patch with its -- hash. data Hopefully a x y -- | PatchInfoAnd p a b represents a hope we have to get a -- patch through its info. We're not sure we have the patch, but we know -- its info. data PatchInfoAnd p a b -- | WPatchInfo a b represents the info of a patch, marked -- with the patch's witnesses. data WPatchInfo a b unWPatchInfo :: WPatchInfo a b -> PatchInfo compareWPatchInfo :: WPatchInfo a b -> WPatchInfo c d -> EqCheck (a, b) (c, d) -- | piap i p creates a PatchInfoAnd containing p with info -- i. piap :: PatchInfo -> Named p a b -> PatchInfoAnd p a b -- | n2pia creates a PatchInfoAnd representing a Named -- patch. n2pia :: Named p x y -> PatchInfoAnd p x y patchInfoAndPatch :: PatchInfo -> Hopefully (Named p) a b -> PatchInfoAnd p a b fmapPIAP :: (forall a b. p a b -> q a b) -> PatchInfoAnd p x y -> PatchInfoAnd q x y fmapFL_PIAP :: (FL p x y -> FL q x y) -> PatchInfoAnd p x y -> PatchInfoAnd q x y -- | conscientiously er hp tries to extract a patch from a -- PatchInfoAnd. If it fails, it applies the error handling -- function er to a description of the patch info component of -- hp. conscientiously :: (Doc -> Doc) -> PatchInfoAnd p a b -> Named p a b -- | hopefully hp tries to get a patch from a -- PatchInfoAnd value. If it fails, it outputs an error "failed to -- read patch: <description of the patch>". We get the description -- of the patch from the info part of hp hopefully :: PatchInfoAnd p a b -> Named p a b info :: PatchInfoAnd p a b -> PatchInfo winfo :: PatchInfoAnd p a b -> WPatchInfo a b -- | hopefullyM is a version of hopefully which calls -- fail in a monad instead of erroring. hopefullyM :: Monad m => PatchInfoAnd p a b -> m (Named p a b) createHashed :: String -> (String -> IO (Sealed (a x))) -> IO (Sealed (Hopefully a x)) extractHash :: PatchInfoAnd p a b -> Either (Named p a b) String actually :: a x y -> Hopefully a x y unavailable :: String -> Hopefully a x y patchDesc :: PatchInfoAnd p x y -> String instance (RepoPatch p, ApplyState p ~ Tree) => Patchy (PatchInfoAnd p) instance IsHunk (PatchInfoAnd p) instance Effect p => Effect (PatchInfoAnd p) instance (ReadPatch p, PatchListFormat p) => ReadPatch (PatchInfoAnd p) instance RepairToFL p => Repair (PatchInfoAnd p) instance Apply p => Apply (PatchInfoAnd p) instance PatchInspect p => PatchInspect (PatchInfoAnd p) instance Merge p => Merge (PatchInfoAnd p) instance Commute p => Commute (PatchInfoAnd p) instance (Apply p, Conflict p, CommuteNoConflicts p, IsHunk p, PatchListFormat p, PrimPatchBase p, ShowPatch p, ApplyState p ~ Tree) => ShowPatch (PatchInfoAnd p) instance (PatchListFormat p, ShowPatchBasic p) => ShowPatchBasic (PatchInfoAnd p) instance PatchListFormat (PatchInfoAnd p) instance (Commute p, Invert p) => Invert (PatchInfoAnd p) instance (Commute p, MyEq p) => MyEq (PatchInfoAnd p) instance MyEq WPatchInfo instance PrimPatchBase p => PrimPatchBase (PatchInfoAnd p) module Darcs.Annotate annotate :: (Apply p, ApplyState p ~ Tree) => FL (PatchInfoAnd p) x y -> FileName -> ByteString -> Annotated annotateDirectory :: (Apply p, ApplyState p ~ Tree) => FL (PatchInfoAnd p) x y -> FileName -> [FileName] -> Annotated format :: ByteString -> Annotated -> String machineFormat :: ByteString -> Annotated -> String instance Show FileOrDirectory instance Eq FileOrDirectory instance Show Annotated instance ApplyMonad AnnotatedM Tree module Darcs.Patch.Set data PatchSet p start y PatchSet :: RL (PatchInfoAnd p) x y -> RL (Tagged p) start x -> PatchSet p start y data Tagged p x z Tagged :: PatchInfoAnd p y z -> Maybe String -> RL (PatchInfoAnd p) x y -> Tagged p x z type SealedPatchSet p start = Sealed ((PatchSet p) start) data Origin -- | Runs a progress action for each tag and patch in a given PatchSet, -- using the passed progress message. Does not alter the PatchSet. progressPatchSet :: String -> PatchSet p start x -> PatchSet p start x -- | tags returns the PatchInfos corresponding to the tags of a given -- PatchSet. tags :: PatchSet p start x -> [PatchInfo] -- | appendPSFL takes a PatchSet and a FL of patches that follow -- the PatchSet, and concatenates the patches into the PatchSet. appendPSFL :: PatchSet p start x -> FL (PatchInfoAnd p) x y -> PatchSet p start y -- | newset2RL takes a PatchSet and returns an equivalent, linear RL of -- patches. newset2RL :: PatchSet p start x -> RL (PatchInfoAnd p) start x -- | newset2FL takes a PatchSet and returns an equivalent, linear FL of -- patches. newset2FL :: PatchSet p start x -> FL (PatchInfoAnd p) start x module Darcs.ProgressPatches -- | Evaluate an RL list and report progress. progressRL :: String -> RL a x y -> RL a x y -- | Evaluate an FL list and report progress. progressFL :: String -> FL a x y -> FL a x y -- | Evaluate an RL list and report progress. In addition to -- printing the number of patches we got, show the name of the last tag -- we got. progressRLShowTags :: String -> RL (PatchInfoAnd p) x y -> RL (PatchInfoAnd p) x y module Darcs.CommandsAux -- | A convenience function to call from all darcs command functions before -- applying any patches. It checks for malicious paths in patches, and -- prints an error message and fails if it finds one. checkPaths :: Patchy p => [DarcsFlag] -> FL p x y -> IO () -- | Filter out patches that contains some malicious file path maliciousPatches :: Patchy p => [Sealed2 p] -> [Sealed2 p] hasMaliciousPath :: Patchy p => p x y -> Bool -- | What is a malicious path? -- -- A spoofed path is a malicious path. -- --
-- x1 x2 x3 [c1 c2 y] ---- -- and that in our example x1 fails to commute past c1, -- this function would commute down to -- --
-- x1 [c1'' c2'' y''] x2' x3' ---- -- and return [x1 c1'' c2'' y''] commuteOrAddToCtxRL :: (Patchy p, ToFromPrim p) => RL p x y -> Non p y -> Non p x -- | commuteOrRemFromCtxFL attempts to remove a FL of patches from a Non, -- returning Nothing if any of the individual removes fail. commuteOrRemFromCtxFL :: (Patchy p, ToFromPrim p) => FL p x y -> Non p x -> Maybe (Non p y) remNons :: (Nonable p, Effect p, Patchy p, ToFromPrim p, PrimPatchBase p, MyEq (PrimOf p)) => [Non p x] -> Non p x -> Non p x -- | (*>) attemts to modify a Non by commuting it past a given patch. (*>) :: (Patchy p, ToFromPrim p) => Non p x -> p x y -> Maybe (Non p y) -- | (>*) attempts to modify a Non, by commuting a given patch past it. (>*) :: (Patchy p, ToFromPrim p) => p x y -> Non p y -> Maybe (Non p x) -- | (*>>) attempts to modify a Non by commuting it past a given WL -- of patches. (*>>) :: (WL l, Patchy p, ToFromPrim p, PrimPatchBase p) => Non p x -> l (PrimOf p) x y -> Maybe (Non p y) -- | (>>*) attempts to modify a Non by commuting a given WL of -- patches past it. (>>*) :: (WL l, Patchy p, ToFromPrim p) => l (PrimOf p) x y -> Non p y -> Maybe (Non p x) instance WL RL instance WL FL instance (Commute p, MyEq p, MyEq (PrimOf p)) => Eq (Non p x) instance (Show2 p, Show2 (PrimOf p)) => Show1 (Non p) instance (Show2 p, Show2 (PrimOf p)) => Show (Non p x) module Darcs.Patch.V2.Real -- | RealPatch is used to represents prim patches that are -- duplicates of, or conflict with, another prim patch in the repository. -- -- Normal prim: A primitive patch -- -- Duplicate x: This patch has no effect since x is -- already present in the repository. -- --
-- Etacilpud x: invert (Duplicate x) ---- -- Conflictor ix xx x: ix is the set of patches: * that -- conflict with x and also conflict with another patch in the -- repository. * that conflict with a patch that conflict with x -- -- xx is the sequence of patches that conflict *only* with -- x -- -- x is the original, conflicting patch. -- -- ix and x are stored as Non objects, which -- include any necessary context to uniquely define the patch that is -- referred to. -- -- The intuition is that a Conflictor should have the effect of inverting -- any patches that x conflicts with, that haven't already been -- undone by another Conflictor in the repository. Therefore, the effect -- of a Conflictor is invert xx. -- -- InvConflictor ix xx x: like invert (Conflictor ix xx -- x) data RealPatch prim x y Duplicate :: Non (RealPatch prim) x -> RealPatch prim x x Etacilpud :: Non (RealPatch prim) x -> RealPatch prim x x Normal :: prim x y -> RealPatch prim x y Conflictor :: [Non (RealPatch prim) x] -> FL prim x y -> Non (RealPatch prim) x -> RealPatch prim y x InvConflictor :: [Non (RealPatch prim) x] -> FL prim x y -> Non (RealPatch prim) x -> RealPatch prim x y prim2real :: prim x y -> RealPatch prim x y -- | This is used for unit-testing and for internal sanity checks isConsistent :: PrimPatch prim => RealPatch prim x y -> Maybe Doc -- | isForward p is True if p is either -- an InvConflictor or Etacilpud. isForward :: PrimPatch prim => RealPatch prim s y -> Maybe Doc -- | isDuplicate p is True if p is either -- a Duplicate or Etacilpud patch. isDuplicate :: RealPatch prim s y -> Bool -- | mergeUnravelled is used when converting from Darcs V1 patches -- (Mergers) to Darcs V2 patches (Conflictors). mergeUnravelled :: PrimPatch prim => [Sealed ((FL prim) x)] -> Maybe (FlippedSeal (RealPatch prim) x) instance IsHunk prim => IsHunk (RealPatch prim) instance PrimPatch prim => Effect (RealPatch prim) instance PrimPatch prim => Nonable (RealPatch prim) instance PrimPatch prim => Show2 (RealPatch prim) instance PrimPatch prim => Show (RealPatch prim x y) instance PrimPatch prim => ReadPatch (RealPatch prim) instance PrimPatch prim => ShowPatch (RealPatch prim) instance PrimPatch prim => ShowPatchBasic (RealPatch prim) instance PatchListFormat (RealPatch prim) instance PrimPatch prim => RepairToFL (RealPatch prim) instance PrimPatch prim => Apply (RealPatch prim) instance PatchInspect prim => PatchInspect (RealPatch prim) instance PrimPatch prim => Merge (RealPatch prim) instance PrimPatch prim => Commute (RealPatch prim) instance Invert prim => Invert (RealPatch prim) instance PrimPatch prim => MyEq (RealPatch prim) instance ToFromPrim (RealPatch prim) instance FromPrim (RealPatch prim) instance PrimPatch prim => Check (RealPatch prim) instance PrimPatch prim => CommuteNoConflicts (RealPatch prim) instance PrimPatch prim => Conflict (RealPatch prim) instance PrimPatch prim => Patchy (RealPatch prim) instance PrimPatch prim => PrimPatchBase (RealPatch prim) module Darcs.Patch.V2 -- | RealPatch is used to represents prim patches that are -- duplicates of, or conflict with, another prim patch in the repository. -- -- Normal prim: A primitive patch -- -- Duplicate x: This patch has no effect since x is -- already present in the repository. -- --
-- Etacilpud x: invert (Duplicate x) ---- -- Conflictor ix xx x: ix is the set of patches: * that -- conflict with x and also conflict with another patch in the -- repository. * that conflict with a patch that conflict with x -- -- xx is the sequence of patches that conflict *only* with -- x -- -- x is the original, conflicting patch. -- -- ix and x are stored as Non objects, which -- include any necessary context to uniquely define the patch that is -- referred to. -- -- The intuition is that a Conflictor should have the effect of inverting -- any patches that x conflicts with, that haven't already been -- undone by another Conflictor in the repository. Therefore, the effect -- of a Conflictor is invert xx. -- -- InvConflictor ix xx x: like invert (Conflictor ix xx -- x) data RealPatch prim x y prim2real :: prim x y -> RealPatch prim x y instance PrimPatch prim => RepoPatch (RealPatch prim) module Darcs.Patch.Bundle -- | hashBundle creates a SHA1 string of a given a FL of named patches. -- This allows us to ensure that the patches in a received patchBundle -- have not been modified in transit. hashBundle :: (PatchListFormat p, ShowPatchBasic p) => FL (Named p) x y -> String -- | In makeBundle2, it is presumed that the two patch sequences are -- identical, but that they may be lazily generated. If two different -- patch sequences are passed, a bundle with a mismatched hash will be -- generated, which is not the end of the world, but isn't very useful -- either. makeBundle2 :: (ApplyState p ~ Tree, RepoPatch p) => Maybe (Tree IO) -> RL (PatchInfoAnd p) start x -> FL (Named p) x y -> FL (Named p) x y -> IO Doc makeBundleN :: (ApplyState p ~ Tree, RepoPatch p) => Maybe (Tree IO) -> PatchSet p start x -> FL (Named p) x y -> IO Doc scanBundle :: RepoPatch p => ByteString -> Either String (SealedPatchSet p Origin) contextPatches :: RepoPatch p => PatchSet p Origin x -> (PatchSet p :> (RL (PatchInfoAnd p))) Origin x scanContext :: RepoPatch p => ByteString -> PatchSet p Origin x -- | patchFilename maps a patch description string to a safe (lowercased, -- spaces removed and ascii-only characters) patch filename. patchFilename :: String -> String -- | getContext parses a context list, returning a tuple containing the -- list, and remaining ByteString input. getContext :: ByteString -> ([PatchInfo], ByteString) parseBundle :: RepoPatch p => ByteString -> Either String (Sealed ((PatchSet p :> FL (PatchInfoAnd p)) Origin)) module Darcs.Repository.Cache -- | cacheHash computes the cache hash (i.e. filename) of a packed -- string. cacheHash :: ByteString -> String okayHash :: String -> Bool takeHash :: ByteString -> Maybe (String, ByteString) newtype Cache Ca :: [CacheLoc] -> Cache data CacheType Repo :: CacheType Directory :: CacheType data CacheLoc Cache :: !CacheType -> !WritableOrNot -> !String -> CacheLoc cacheType :: CacheLoc -> !CacheType cacheWritable :: CacheLoc -> !WritableOrNot cacheSource :: CacheLoc -> !String data WritableOrNot Writable :: WritableOrNot NotWritable :: WritableOrNot data HashedDir HashedPristineDir :: HashedDir HashedPatchesDir :: HashedDir HashedInventoriesDir :: HashedDir hashedDir :: HashedDir -> String unionCaches :: Cache -> Cache -> Cache -- | unionRemoteCaches merges caches. It tries to do better than just -- blindly copying remote cache entries: -- --