module Debian.Changes
( ChangesFile(..)
, ChangedFileSpec(..)
, changesFileName
, ChangeLog(..)
, ChangeLogEntry(..)
, parseChangeLog
, parseEntries
, parseEntry
, parseChanges
) where
import Data.Either (partitionEithers)
import Data.List (intercalate, intersperse)
import Data.Monoid ((<>))
import Data.Text (Text, pack, unpack, strip)
import Debian.Arch (Arch, prettyArch)
import qualified Debian.Control.String as S
import Debian.Pretty (PP(..))
import Debian.Release
import Debian.URI()
import Debian.Version
import System.Posix.Types
import Text.Regex.TDFA hiding (empty)
import Text.PrettyPrint (Doc, text, hcat, render)
import Text.PrettyPrint.HughesPJClass (Pretty(pPrint))
data ChangesFile =
Changes { changeDir :: FilePath
, changePackage :: String
, changeVersion :: DebianVersion
, changeRelease :: ReleaseName
, changeArch :: Arch
, changeInfo :: S.Paragraph' Text
, changeEntry :: ChangeLogEntry
, changeFiles :: [ChangedFileSpec]
} deriving (Eq, Read, Show)
data ChangedFileSpec =
ChangedFileSpec { changedFileMD5sum :: String
, changedFileSHA1sum :: String
, changedFileSHA256sum :: String
, changedFileSize :: FileOffset
, changedFileSection :: SubSection
, changedFilePriority :: String
, changedFileName :: FilePath
} deriving (Eq, Read, Show)
data ChangeLogEntry =
Entry { logPackage :: String
, logVersion :: DebianVersion
, logDists :: [ReleaseName]
, logUrgency :: String
, logComments :: String
, logWho :: String
, logDate :: String
}
| WhiteSpace String
deriving (Eq, Read, Show)
newtype ChangeLog = ChangeLog [ChangeLogEntry] deriving (Eq, Read, Show)
changesFileName :: ChangesFile -> String
changesFileName = render . pPrint . PP
instance Pretty (PP ChangesFile) where
pPrint (PP changes) = text (changePackage changes ++ "_") <> prettyDebianVersion (changeVersion changes) <> text "_" <> prettyArch (changeArch changes) <> text ".changes"
instance Pretty (PP ChangedFileSpec) where
pPrint (PP file) =
text (changedFileMD5sum file <> " " <>
show (changedFileSize file) <> " " <>
sectionName (changedFileSection file) <> " " <>
changedFilePriority file <> " " <>
changedFileName file)
instance Pretty (PP ChangeLogEntry) where
pPrint (PP (Entry package ver dists urgency details who date)) =
hcat [ text package <> text " (" <> prettyDebianVersion ver <> text (") " <> intercalate " " (map releaseName' dists) ++ "; urgency=" ++ urgency)
, text "\n\n"
, text " " <> text (strip' details)
, text "\n\n"
, text (" -- " <> who <> " " <> date)
, text "\n" ]
pPrint (PP (WhiteSpace _)) = error "instance Pretty ChangeLogEntry"
instance Pretty (PP [ChangeLogEntry]) where
pPrint = hcat . intersperse (text "\n") . map (pPrint . PP) . unPP
strip' = unpack . strip . pack
instance Pretty (PP ChangeLog) where
pPrint (PP (ChangeLog xs)) = hcat (intersperse (text "\n") (map (pPrint . PP) xs))
_showHeader :: ChangeLogEntry -> Doc
_showHeader (Entry package ver dists urgency _ _ _) =
text (package <> " (") <> prettyDebianVersion ver <> text (") " <> intercalate " " (map releaseName' dists) <> "; urgency=" <> urgency <> "...")
_showHeader (WhiteSpace _) = error "_showHeader"
parseChangeLog :: String -> Either [[String]] ChangeLog
parseChangeLog s =
case partitionEithers (parseEntries s) of
([], xs) -> Right (ChangeLog xs)
(ss, _) -> Left ss
parseEntries :: String -> [Either [String] ChangeLogEntry]
parseEntries "" = []
parseEntries text =
case parseEntry text of
Left messages -> [Left messages]
Right (entry, text') -> Right entry : parseEntries text'
parseEntry :: String -> Either [String] (ChangeLogEntry, String)
parseEntry text =
case text =~ entryRE :: MatchResult String of
x | mrSubList x == [] -> Left ["Parse error in " ++ show text]
MR {mrAfter = after, mrSubList = [_, name, ver, dists, urgency, _, details, _, _, who, _, date, _]} ->
Right (Entry name
(parseDebianVersion' ver)
(map parseReleaseName . words $ dists)
urgency
(" " ++ unpack (strip (pack details)) ++ "\n")
(take (length who 2) who)
date,
after)
MR {mrBefore = _before, mrMatch = _matched, mrAfter = after, mrSubList = matches} ->
Left ["Internal error\n after=" ++ show after ++ "\n " ++ show (length matches) ++ " matches: " ++ show matches]
entryRE = bol ++ blankLines ++ headerRE ++ changeDetails ++ signature ++ blankLines
changeDetails = "((\n| \n| -\n|([^ ]| [^--]| -[^--])[^\n]*\n)*)"
signature = " -- ([ ]*([^ ]+ )* )([^\n]*)\n"
parseChanges :: Text -> Maybe ChangeLogEntry
parseChanges text =
case unpack text =~ changesRE :: MatchResult String of
MR {mrSubList = []} -> Nothing
MR {mrSubList = [_, name, ver, dists, urgency, _, details]} ->
Just $ Entry name
(parseDebianVersion' ver)
(map parseReleaseName . words $ dists)
urgency
details
"" ""
MR {mrSubList = x} -> error $ "Unexpected match: " ++ show x
where
changesRE = bol ++ blankLines ++ optWhite ++ headerRE ++ "(.*)$"
headerRE =
package ++ ver ++ dists ++ urgency
where
package = "([^ \t(]*)" ++ optWhite
ver = "\\(([^)]*)\\)" ++ optWhite
dists = "([^;]*);" ++ optWhite
urgency = "urgency=([^\n]*)\n" ++ blankLines
blankLines = blankLine ++ "*"
blankLine = "(" ++ optWhite ++ "\n)"
optWhite = "[ \t]*"
bol = "^"
_s1 = unlines
["haskell-regex-compat (0.92-3+seereason1~jaunty4) jaunty-seereason; urgency=low",
"",
" [ Joachim Breitner ]",
" * Adjust priority according to override file",
" * Depend on hscolour (Closes: #550769)",
"",
" [ Marco TĂșlio Gontijo e Silva ]",
" * debian/control: Use more sintetic name for Vcs-Darcs.",
" * Built from sid apt pool",
" * Build dependency changes:",
" cpphs: 1.9-1+seereason1~jaunty5 -> 1.9-1+seereason1~jaunty6",
" ghc6: 6.10.4-1+seereason5~jaunty1 -> 6.12.1-0+seereason1~jaunty1",
" ghc6-doc: 6.10.4-1+seereason5~jaunty1 -> 6.12.1-0+seereason1~jaunty1",
" ghc6-prof: 6.10.4-1+seereason5~jaunty1 -> 6.12.1-0+seereason1~jaunty1",
" haddock: 2.4.2-3+seereason3~jaunty1 -> 6.12.1-0+seereason1~jaunty1",
" haskell-devscripts: 0.6.18-21+seereason1~jaunty1 -> 0.6.18-23+seereason1~jaunty1",
" haskell-regex-base-doc: 0.93.1-5+seereason1~jaunty1 -> 0.93.1-5++1+seereason1~jaunty1",
" haskell-regex-posix-doc: 0.93.2-4+seereason1~jaunty1 -> 0.93.2-4+seereason1~jaunty2",
" libghc6-regex-base-dev: 0.93.1-5+seereason1~jaunty1 -> 0.93.1-5++1+seereason1~jaunty1",
" libghc6-regex-base-prof: 0.93.1-5+seereason1~jaunty1 -> 0.93.1-5++1+seereason1~jaunty1",
" libghc6-regex-posix-dev: 0.93.2-4+seereason1~jaunty1 -> 0.93.2-4+seereason1~jaunty2",
" libghc6-regex-posix-prof: 0.93.2-4+seereason1~jaunty1 -> 0.93.2-4+seereason1~jaunty2",
"",
" -- SeeReason Autobuilder <autobuilder@seereason.org> Fri, 25 Dec 2009 01:55:37 -0800",
"",
"haskell-regex-compat (0.92-3) unstable; urgency=low",
"",
" [ Joachim Breitner ]",
" * Adjust priority according to override file",
" * Depend on hscolour (Closes: #550769)",
"",
" [ Marco TĂșlio Gontijo e Silva ]",
" * debian/control: Use more sintetic name for Vcs-Darcs.",
"",
" -- Joachim Breitner <nomeata@debian.org> Mon, 20 Jul 2009 13:05:35 +0200",
"",
"haskell-regex-compat (0.92-2) unstable; urgency=low",
"",
" * Adopt package for the Debian Haskell Group",
" * Fix \"FTBFS with new dpkg-dev\" by adding comma to debian/control",
" (Closes: #536473)",
"",
" -- Joachim Breitner <nomeata@debian.org> Mon, 20 Jul 2009 12:05:40 +0200",
"",
"haskell-regex-compat (0.92-1.1) unstable; urgency=low",
"",
" * Rebuild for GHC 6.10.",
" * NMU with permission of the author.",
"",
" -- John Goerzen <jgoerzen@complete.org> Mon, 16 Mar 2009 10:12:04 -0500",
"",
"haskell-regex-compat (0.92-1) unstable; urgency=low",
"",
" * New upstream release",
" * debian/control:",
" - Bump Standards-Version. No changes needed.",
"",
" -- Arjan Oosting <arjan@debian.org> Sun, 18 Jan 2009 00:05:02 +0100",
"",
"haskell-regex-compat (0.91-1) unstable; urgency=low",
"",
" * Take over package from Ian, as I already maintain haskell-regex-base,",
" and move Ian to the Uploaders field.",
" * Packaging complete redone (based on my haskell-regex-base package).",
"",
" -- Arjan Oosting <arjan@debian.org> Sat, 19 Jan 2008 16:48:39 +0100",
"",
"haskell-regex-compat (0.71.0.1-1) unstable; urgency=low",
" ",
" * Initial release (used to be part of ghc6).",
" * Using \"Generic Haskell cabal library packaging files v9\".",
" ",
" -- Ian Lynagh (wibble) <igloo@debian.org> Wed, 21 Nov 2007 01:26:57 +0000"]