packages feed

debian-build 0.5.0.2 → 0.6.0.0

raw patch · 7 files changed

+347/−284 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Debian.Package.Data.Source: ChangesAll :: ChangesType
- Debian.Package.Data.Source: ChangesArch :: String -> ChangesType
- Debian.Package.Data.Source: ChangesSource :: ChangesType
- Debian.Package.Data.Source: data ChangesType
- Debian.Package.Data.Source: data DebianVersion
- Debian.Package.Data.Source: data HaskellPackage
- Debian.Package.Data.Source: data Source
- Debian.Package.Data.Source: deriveHackageVersion :: Source -> HackageVersion
- Debian.Package.Data.Source: hackage :: HaskellPackage -> Hackage
- Debian.Package.Data.Source: haskellPackageDefault :: NameRule -> String -> HackageVersion -> Maybe String -> HaskellPackage
- Debian.Package.Data.Source: haskellPackageFromPackage :: String -> Source -> HaskellPackage
- Debian.Package.Data.Source: instance Eq ChangesType
- Debian.Package.Data.Source: instance Read DebianVersion
- Debian.Package.Data.Source: instance Show ChangesType
- Debian.Package.Data.Source: instance Show DebianVersion
- Debian.Package.Data.Source: instance Show HaskellPackage
- Debian.Package.Data.Source: instance Show Source
- Debian.Package.Data.Source: isBinaryChanges :: ChangesType -> Bool
- Debian.Package.Data.Source: isNative :: Source -> Bool
- Debian.Package.Data.Source: isNative' :: DebianVersion -> Bool
- Debian.Package.Data.Source: isSourceChanges :: ChangesType -> Bool
- Debian.Package.Data.Source: mkSource :: String -> DebianVersion -> Source
- Debian.Package.Data.Source: nativeArchiveName :: Source -> String
- Debian.Package.Data.Source: origArchiveName :: Source -> FilePath
- Debian.Package.Data.Source: origVersion :: Source -> Version
- Debian.Package.Data.Source: origVersion' :: DebianVersion -> Version
- Debian.Package.Data.Source: package :: HaskellPackage -> Source
- Debian.Package.Data.Source: parseChangeLog :: String -> Maybe Source
- Debian.Package.Data.Source: readDebianVersion :: String -> Maybe DebianVersion
- Debian.Package.Data.Source: sourceDirName :: Source -> FilePath
- Debian.Package.Data.Source: sourceName :: Source -> String
- Debian.Package.Data.Source: takeChangesType :: FilePath -> Maybe ChangesType
- Debian.Package.Data.Source: version :: Source -> DebianVersion
- Debian.Package.Data.Source: versionFromHackageVersion :: HackageVersion -> Maybe String -> DebianVersion
+ Debian.Package.Build.Command: dpkgParseControl :: FilePath -> Trace Control
+ Debian.Package.Build.Command: instance Eq BuildMode
+ Debian.Package.Build.Command: instance Show BuildMode
+ Debian.Package.Build.Command: modeListFromControl :: Control -> [BuildMode]
+ Debian.Package.Data.Packages: Control :: String -> [String] -> [String] -> Control
+ Debian.Package.Data.Packages: PackageAll :: PackageType
+ Debian.Package.Data.Packages: PackageArch :: (Maybe String) -> PackageType
+ Debian.Package.Data.Packages: PackageSource :: PackageType
+ Debian.Package.Data.Packages: controlAll :: Control -> [String]
+ Debian.Package.Data.Packages: controlArch :: Control -> [String]
+ Debian.Package.Data.Packages: controlSource :: Control -> String
+ Debian.Package.Data.Packages: data Control
+ Debian.Package.Data.Packages: data DebianVersion
+ Debian.Package.Data.Packages: data HaskellPackage
+ Debian.Package.Data.Packages: data PackageType
+ Debian.Package.Data.Packages: data Source
+ Debian.Package.Data.Packages: deriveHackageVersion :: Source -> HackageVersion
+ Debian.Package.Data.Packages: hackage :: HaskellPackage -> Hackage
+ Debian.Package.Data.Packages: haskellPackageDefault :: NameRule -> String -> HackageVersion -> Maybe String -> HaskellPackage
+ Debian.Package.Data.Packages: haskellPackageFromPackage :: String -> Source -> HaskellPackage
+ Debian.Package.Data.Packages: instance Eq Control
+ Debian.Package.Data.Packages: instance Eq PackageType
+ Debian.Package.Data.Packages: instance Read DebianVersion
+ Debian.Package.Data.Packages: instance Show Control
+ Debian.Package.Data.Packages: instance Show DebianVersion
+ Debian.Package.Data.Packages: instance Show HaskellPackage
+ Debian.Package.Data.Packages: instance Show PackageType
+ Debian.Package.Data.Packages: instance Show Source
+ Debian.Package.Data.Packages: isBinaryPackage :: PackageType -> Bool
+ Debian.Package.Data.Packages: isNative :: Source -> Bool
+ Debian.Package.Data.Packages: isNative' :: DebianVersion -> Bool
+ Debian.Package.Data.Packages: isSourcePackage :: PackageType -> Bool
+ Debian.Package.Data.Packages: mkSource :: String -> DebianVersion -> Source
+ Debian.Package.Data.Packages: nativeArchiveName :: Source -> String
+ Debian.Package.Data.Packages: origArchiveName :: Source -> FilePath
+ Debian.Package.Data.Packages: origVersion :: Source -> Version
+ Debian.Package.Data.Packages: origVersion' :: DebianVersion -> Version
+ Debian.Package.Data.Packages: package :: HaskellPackage -> Source
+ Debian.Package.Data.Packages: parseChangeLog :: String -> Maybe Source
+ Debian.Package.Data.Packages: parseControl :: String -> Maybe Control
+ Debian.Package.Data.Packages: parseControlEntry :: [String] -> Maybe (PackageType, String)
+ Debian.Package.Data.Packages: readDebianVersion :: String -> Maybe DebianVersion
+ Debian.Package.Data.Packages: sourceDirName :: Source -> FilePath
+ Debian.Package.Data.Packages: sourceName :: Source -> String
+ Debian.Package.Data.Packages: takeChangesType :: FilePath -> Maybe PackageType
+ Debian.Package.Data.Packages: version :: Source -> DebianVersion
+ Debian.Package.Data.Packages: versionFromHackageVersion :: HackageVersion -> Maybe String -> DebianVersion
- Debian.Package.Build.Command: rebuild :: FilePath -> BuildMode -> [String] -> Trace ()
+ Debian.Package.Build.Command: rebuild :: FilePath -> [BuildMode] -> [String] -> Trace ()
- Debian.Package.Build.Sequence: findDebianChanges :: Build [(FilePath, ChangesType)]
+ Debian.Package.Build.Sequence: findDebianChanges :: Build [(FilePath, PackageType)]

Files

debian-build.cabal view
@@ -1,5 +1,5 @@ name:                debian-build-version:             0.5.0.2+version:             0.6.0.0 synopsis:            Debian package build sequence tools description:         This package provides build sequence functions                      for debian package, and includes on-the-fly@@ -17,7 +17,7 @@ library   exposed-modules:                      Debian.Package.Data.Hackage-                     Debian.Package.Data.Source+                     Debian.Package.Data.Packages                      Debian.Package.Data                      Debian.Package.Build.Monad                      Debian.Package.Build.Cabal@@ -41,6 +41,7 @@  executable odebuild   build-depends:       base <5+                     , filepath                      , debian-build    main-is: odebuild.hs
mains/odebuild.hs view
@@ -1,11 +1,12 @@ import System.Environment (getProgName, getArgs)+import System.FilePath ((</>)) import Control.Monad (void, when) import Data.List (stripPrefix) -import Debian.Package.Data (Source, Hackage, isBinaryChanges)+import Debian.Package.Data (Source, Hackage, isBinaryPackage) import Debian.Package.Build   (BuildMode (Dep, Indep, Src), buildPackage, debi', pwd,-   defaultConfig, Build, runBuild, liftTrace,+   defaultConfig, Build, runBuild, liftTrace, dpkgParseControl, modeListFromControl,    removeBuildDir, findDebianChanges, genSources, removeGhcLibrary)  @@ -18,7 +19,7 @@ install' :: Build () install' =  do   ps <- findDebianChanges-  let cs = [c | (c, t) <- ps, isBinaryChanges t ]+  let cs = [c | (c, t) <- ps, isBinaryPackage t ]   liftTrace $ do     when (null cs) $ fail "No .changes files found!"     mapM_ (\c -> debi' [c]) cs@@ -49,7 +50,8 @@ build :: Maybe String -> [String] -> Build (Source, Maybe Hackage) build mayRev opts = do   ((_, dir), src, mayH) <- source mayRev-  liftTrace $ sequence_ [buildPackage dir m opts | m <- defualtModes]+  ctrl <- liftTrace . dpkgParseControl $ dir </> "debian" </> "control"+  liftTrace $ sequence_ [buildPackage dir m opts | m <- modeListFromControl ctrl]   return (src, mayH)  install :: Maybe String -> [String] -> Build ()
src/Debian/Package/Build/Command.hs view
@@ -17,13 +17,14 @@         , unpackInDir, unpack, packInDir', packInDir -       , cabalDebian', cabalDebian, packageVersion, dpkgParseChangeLog+       , cabalDebian', cabalDebian, packageVersion+       , dpkgParseChangeLog, dpkgParseControl         , debuild, debi', debi         , BuildMode (..) -       , buildPackage, rebuild+       , modeListFromControl, buildPackage, rebuild         , removeGhcLibrary @@ -45,7 +46,8 @@  import Debian.Package.Data   (Hackage, ghcLibraryBinPackages, ghcLibraryPackages, ghcLibraryDocPackage,-   Source, parseChangeLog, DebianVersion, readDebianVersion, origVersion')+   Source, parseChangeLog, DebianVersion, readDebianVersion, origVersion',+   Control (..), parseControl) import Debian.Package.Build.Monad (Trace, traceCommand, traceOut, putLog, bracketTrace_)  @@ -181,7 +183,15 @@   maybe (fail $ "parseChangeLog: failed: " ++ str) return     $ parseChangeLog str +-- | Read debian control file+dpkgParseControl :: FilePath -> Trace Control+dpkgParseControl cpath =  do+  putLog $ unwords ["Reading", cpath, "."]+  str <- lift $ readFile cpath+  maybe (fail $ "parseControl: failed: " ++ str) return+    $ parseControl str + run :: String -> [String] -> Trace () run cmd = rawSystem' . (cmd :) @@ -202,7 +212,15 @@  -- | Build mode, all or binary only data BuildMode = All | Bin | Src | Dep | Indep+               deriving (Eq, Show) +-- | Infer all build mode list from debian control file data+modeListFromControl :: Control -> [BuildMode]+modeListFromControl c =+  Src+  :  [ Dep   | not . null $ controlArch c ]+  ++ [ Indep | not . null $ controlAll  c ]+ -- | Build package using /debuild/ under specified directory buildPackage :: FilePath -> BuildMode -> [String] -> Trace () buildPackage dir mode opts = do@@ -214,10 +232,10 @@   debuild dir $ ["-uc", "-us"] ++ modeOpt mode ++ opts  -- | Clean and build package using /debuild/ under specified directory-rebuild :: FilePath -> BuildMode -> [String] -> Trace ()-rebuild dir mode opts = do+rebuild :: FilePath -> [BuildMode] -> [String] -> Trace ()+rebuild dir modes opts = do   debuild dir ["clean"]-  buildPackage dir mode opts+  sequence_ [ buildPackage dir mode opts | mode <- modes ]  -- | Remove ghc library packages under specified source package directory removeGhcLibrary :: BuildMode -> Hackage -> Trace ()
src/Debian/Package/Build/Sequence.hs view
@@ -39,7 +39,7 @@ import Debian.Package.Data   (Hackage, hackageLongName, hackageArchive,    Source, origArchiveName, nativeArchiveName, sourceDirName, isNative,-   ChangesType, takeChangesType,+   PackageType, takeChangesType,    HaskellPackage, hackage, package, haskellPackageFromPackage) import Debian.Package.Build.Monad   (Build, liftTrace, bracketBuild_, Config (..), askConfig, askBaseDir, askBuildDir)@@ -233,7 +233,7 @@              else Nothing  -- | Find debian .changes files-findDebianChanges :: Build [(FilePath, ChangesType)]+findDebianChanges :: Build [(FilePath, PackageType)] findDebianChanges =  do   bd <- getBuildDir   fs <- liftIO $ getDirectoryContents bd
src/Debian/Package/Data.hs view
@@ -10,8 +10,8 @@ -- This module provides data-type namespace. module Debian.Package.Data        ( module Debian.Package.Data.Hackage-       , module Debian.Package.Data.Source+       , module Debian.Package.Data.Packages        ) where  import Debian.Package.Data.Hackage-import Debian.Package.Data.Source+import Debian.Package.Data.Packages
+ src/Debian/Package/Data/Packages.hs view
@@ -0,0 +1,310 @@+-- |+-- Module      : Debian.Package.Data.Packages+-- Copyright   : 2014 Kei Hibino+-- License     : BSD3+--+-- Maintainer  : ex8k.hibino@gmail.com+-- Stability   : experimental+-- Portability : portable+--+-- This module provides data types of debian packages meta information.+module Debian.Package.Data.Packages+       ( DebianVersion, versionFromHackageVersion, readDebianVersion, origVersion', isNative'++       , Source, mkSource, sourceName, version, origVersion, isNative++       , origArchiveName, nativeArchiveName, sourceDirName, deriveHackageVersion++       , parseChangeLog++       , PackageType (..), takeChangesType, isSourcePackage, isBinaryPackage++       , Control (..), parseControlEntry, parseControl++       , HaskellPackage, hackage, package+       , haskellPackageDefault, haskellPackageFromPackage+       ) where++import Control.Applicative ((<$>), pure, (<*>), (*>), (<*), empty, (<|>), many, some, optional)+import Control.Monad.Trans.State (StateT, runStateT, get, put)+import Data.Maybe (listToMaybe, maybeToList, mapMaybe)+import Data.Char (isSpace, isDigit)+import Data.Version (Version (Version, versionBranch), showVersion)+import Data.List.Split (splitOn)+import System.FilePath ((<.>), takeFileName, splitExtension)++import Debian.Package.Data.Hackage+  (HackageVersion, mkHackageVersion', hackageVersionNumbers,+   Hackage, mkHackageDefault, NameRule (Simple), debianNamesFromSourceName)+++type Parser = StateT String Maybe++satisfy :: (Char -> Bool) -> Parser Char+satisfy p = do+  s <- get+  case s of+    c:cs -> if p c+            then  put cs *> pure c+            else  empty+    []   ->       empty++_look :: Parser String+_look =  get++eof :: Parser ()+eof =  do+  s <- get+  case s of+    []   -> pure ()+    _:_  -> empty++runParser :: Parser a -> String -> Maybe (a, String)+runParser =  runStateT++anyChar :: Parser Char+anyChar =  satisfy (const True)++char :: Char -> Parser Char+char x = satisfy (== x)++notChar :: Char -> Parser Char+notChar x = satisfy (/= x)++space :: Parser Char+space =  char ' '++digit :: Parser Char+digit =  satisfy isDigit++int :: Parser Int+int =  read <$> some digit++string :: String -> Parser String+string =  mapM char+++-- | Version type for Debian+data DebianVersion+  = DebianNative    Version (Maybe Int)+  | DebianNonNative Version String++debianNativeVersion :: [Int] -> Maybe Int -> DebianVersion+debianNativeVersion v =  DebianNative (Version v [])++debianNonNativeVersion :: [Int] -> String -> DebianVersion+debianNonNativeVersion v = DebianNonNative (Version v [])++-- | Make deebian version from hackage version+versionFromHackageVersion :: HackageVersion -> Maybe String -> DebianVersion+versionFromHackageVersion hv = d where+  d (Just rev) = debianNonNativeVersion ns rev+  d Nothing    = debianNativeVersion    ns Nothing+  ns = hackageVersionNumbers hv++-- | Version without debian revision+origVersion' :: DebianVersion -> Version+origVersion' =  d  where+  d (DebianNative    v _) = v+  d (DebianNonNative v _) = v++-- | Is debian-native or not+isNative' :: DebianVersion -> Bool+isNative' = d where+  d (DebianNative    _ _) = True+  d (DebianNonNative _ _) = False++parseVersion' :: Parser Version+parseVersion' =+  Version+  <$> ((:) <$> int <*> many (char '.' *> int))+  <*> pure []++parseDebianVersion :: Parser DebianVersion+parseDebianVersion = do+  v <- parseVersion'+  (DebianNonNative v <$> (char '-' *> some (satisfy (not . isSpace)))+   <|>+   DebianNative    v <$> optional (string "+nmu" *> int))++_testParseDebianVersion :: [Maybe (DebianVersion, String)]+_testParseDebianVersion =+  [ runParser parseDebianVersion s | s <- [ "1.23.3-4", "1.23", "12.3+nmu2" ] ]++instance Show DebianVersion where+  show = d  where+    d (DebianNative    v nr) = showVersion v ++ maybe "" (("+nmu" ++) . show) nr+    d (DebianNonNative v r)  = showVersion v ++ '-': r++instance Read DebianVersion where+  readsPrec _ = maybeToList . runParser parseDebianVersion++readMaybe' :: Read a => String -> Maybe a+readMaybe' =  fmap fst . listToMaybe . filter ((== "") . snd) . reads++-- | Try to read debian package version+readDebianVersion :: String -> Maybe DebianVersion+readDebianVersion =  readMaybe'++-- | Debian source package type, name with version+data Source = Source String DebianVersion  deriving Show++-- | Make 'Source'+mkSource :: String -> DebianVersion -> Source+mkSource =  Source++-- | Source package name of 'Source'+sourceName :: Source -> String+sourceName (Source n _) = n++-- | Debian version of 'Source'+version :: Source -> DebianVersion+version (Source _ v) = v++-- | Version without debian revision+origVersion :: Source -> Version+origVersion =  origVersion' . version++-- | Is debian-native or not+isNative :: Source -> Bool+isNative =  isNative' . version++-- | Original source archive basename+origArchiveName :: Source -> FilePath+origArchiveName pkg = sourceName pkg ++ '_' : showVersion (origVersion pkg) <.> "orig" <.> "tar" <.> "gz"++-- | Debian native archive basename+nativeArchiveName :: Source -> String+nativeArchiveName pkg = sourceName pkg ++ '_' : show (version pkg) <.> "tar" <.> "gz"++-- | Source directory basename+sourceDirName :: Source -> FilePath+sourceDirName pkg = sourceName pkg ++ '-' : showVersion (origVersion pkg)++-- | Try to make 'HackageVersion' from 'Source'+deriveHackageVersion :: Source -> HackageVersion+deriveHackageVersion =  mkHackageVersion' . versionBranch . origVersion where++parseColonLine :: String -> Maybe (String, String)+parseColonLine =+  (fmap fst .) . runParser $+  (,) <$> some (notChar ':') <*> (char ':' *> many space *> many anyChar <* eof)++-- | Try to generate 'Source' from debian changelog string+parseChangeLog :: String       -- ^ dpkg-parsechangelog result string+               -> Maybe Source -- ^ Source structure+parseChangeLog log' = do+  deb  <- mayDebSrc+  dver <- mayDebVer+  return $ mkSource deb dver+  where+    pairs = mapMaybe parseColonLine . lines $ log'+    lookup' = (`lookup` pairs)+    mayDebSrc = lookup' "Source"+    mayDebVer = do+      dverS <- lookup' "Version"+      readDebianVersion dverS++-- | Debian package types+data PackageType+  = PackageArch (Maybe String)+  | PackageAll+  | PackageSource+  deriving (Eq, Show)++-- | Take 'PackageType' from debian .changes file path+takeChangesType :: FilePath -> Maybe PackageType+takeChangesType path = d . splitExtension $ takeFileName path  where+  d (n, ".changes") = case xs of+    [_, _, a] -> case a of+      "all"    -> Just   PackageAll+      "source" -> Just   PackageSource+      _        -> Just . PackageArch $ Just a+    _          -> Nothing+    where xs = splitOn "_" n+  d (_, _)     =  Nothing++-- | Test package type is source package.+isSourcePackage :: PackageType -> Bool+isSourcePackage = d where+  d (PackageArch _) = False+  d  PackageAll     = False+  d  PackageSource  = True++-- | Test package type is binary package.+isBinaryPackage :: PackageType -> Bool+isBinaryPackage = not . isSourcePackage++-- | Type for debian control meta-data.+data Control =+  Control+  { controlSource :: String+  , controlArch   :: [String]+  , controlAll    :: [String]+  } deriving (Eq, Show)++-- | Parse an package entry in control file.+parseControlEntry :: [String] -> Maybe (PackageType, String)+parseControlEntry b =+  do a <- lookup' "Architecture"+     p <- lookup' "Package"+     Just $ if a == "all"+            then (PackageAll, p)+            else (PackageArch $ Just a, p)+  <|>+  do s <- lookup' "Source"+     Just (PackageSource, s)+  where ps = mapMaybe parseColonLine b+        lookup' = (`lookup` ps)++packagesPartition :: [(PackageType, a)] -> ([a], [a], [a])+packagesPartition = rec'  where+  rec' []      = ([], [], [])+  rec' (x:xs)  = case x of+    (PackageSource, a) -> (a:p, q, r)+    (PackageArch _, a) -> (p, a:q, r)+    (PackageAll   , a) -> (p, q, a:r)+    where (p, q, r) = rec' xs++-- | Parse debian control file into package list.+parseControl :: String -> Maybe Control+parseControl in' = do+  let (src, arch, all') =+        packagesPartition . mapMaybe parseControlEntry+        . filter (not . null) . splitOn [""] . lines $ in'+  s <- listToMaybe src+  Just $ Control s arch all'+++-- | Debian source package type for Haskell+data HaskellPackage = HaskellPackage Hackage Source deriving Show++-- | 'Hackage' meta-info of 'HaskellPackage'+hackage :: HaskellPackage -> Hackage+hackage (HaskellPackage h _) = h++-- | Debian source package meta-info of 'HaskellPackage'+package :: HaskellPackage -> Source+package (HaskellPackage _ p) = p++-- | Generate 'HaskellPackage' type from debian package name and version+--   using 'NameRule'+haskellPackageDefault :: NameRule+                      -> String         -- ^ Hackage name string+                      -> HackageVersion -- ^ Version of hackage+                      -> Maybe String   -- ^ Debian revision String+                      -> HaskellPackage -- ^ Result structure+haskellPackageDefault rule hname hver mayDevRev =+  HaskellPackage+  (mkHackageDefault rule hname hver)+  (mkSource sn (versionFromHackageVersion hver mayDevRev))+  where+    (sn, _) = debianNamesFromSourceName rule hname++-- | Generate 'HaskellPackage' with hackage name and debian package meta-info+haskellPackageFromPackage :: String         -- ^ Hackage name string+                          -> Source         -- ^ Debian package meta info+                          -> HaskellPackage -- ^ Result+haskellPackageFromPackage hname pkg = HaskellPackage hkg pkg  where+  hv  = deriveHackageVersion pkg+  hkg = mkHackageDefault Simple hname hv
− src/Debian/Package/Data/Source.hs
@@ -1,268 +0,0 @@--- |--- Module      : Debian.Package.Data.Source--- Copyright   : 2014 Kei Hibino--- License     : BSD3------ Maintainer  : ex8k.hibino@gmail.com--- Stability   : experimental--- Portability : portable------ This module provides data types of debian source package meta information.-module Debian.Package.Data.Source-       ( DebianVersion, versionFromHackageVersion, readDebianVersion, origVersion', isNative'--       , Source, mkSource, sourceName, version, origVersion, isNative--       , origArchiveName, nativeArchiveName, sourceDirName, deriveHackageVersion--       , parseChangeLog--       , ChangesType (..), takeChangesType, isSourceChanges, isBinaryChanges--       , HaskellPackage, hackage, package-       , haskellPackageDefault, haskellPackageFromPackage-       ) where--import Control.Applicative ((<$>), pure, (<*>), (*>), (<*), empty, (<|>), many, some, optional)-import Control.Monad.Trans.State (StateT, runStateT, get, put)-import Data.Maybe (listToMaybe, maybeToList, mapMaybe)-import Data.Char (isSpace, isDigit)-import Data.Version (Version (Version, versionBranch), showVersion)-import Data.List.Split (splitOn)-import System.FilePath ((<.>), takeFileName, splitExtension)--import Debian.Package.Data.Hackage-  (HackageVersion, mkHackageVersion', hackageVersionNumbers,-   Hackage, mkHackageDefault, NameRule (Simple), debianNamesFromSourceName)---type Parser = StateT String Maybe--satisfy :: (Char -> Bool) -> Parser Char-satisfy p = do-  s <- get-  case s of-    c:cs -> if p c-            then  put cs *> pure c-            else  empty-    []   ->       empty--_look :: Parser String-_look =  get--eof :: Parser ()-eof =  do-  s <- get-  case s of-    []   -> pure ()-    _:_  -> empty--runParser :: Parser a -> String -> Maybe (a, String)-runParser =  runStateT--anyChar :: Parser Char-anyChar =  satisfy (const True)--char :: Char -> Parser Char-char x = satisfy (== x)--notChar :: Char -> Parser Char-notChar x = satisfy (/= x)--space :: Parser Char-space =  char ' '--digit :: Parser Char-digit =  satisfy isDigit--int :: Parser Int-int =  read <$> some digit--string :: String -> Parser String-string =  mapM char----- | Version type for Debian-data DebianVersion-  = DebianNative    Version (Maybe Int)-  | DebianNonNative Version String--debianNativeVersion :: [Int] -> Maybe Int -> DebianVersion-debianNativeVersion v =  DebianNative (Version v [])--debianNonNativeVersion :: [Int] -> String -> DebianVersion-debianNonNativeVersion v = DebianNonNative (Version v [])---- | Make deebian version from hackage version-versionFromHackageVersion :: HackageVersion -> Maybe String -> DebianVersion-versionFromHackageVersion hv = d where-  d (Just rev) = debianNonNativeVersion ns rev-  d Nothing    = debianNativeVersion    ns Nothing-  ns = hackageVersionNumbers hv---- | Version without debian revision-origVersion' :: DebianVersion -> Version-origVersion' =  d  where-  d (DebianNative    v _) = v-  d (DebianNonNative v _) = v---- | Is debian-native or not-isNative' :: DebianVersion -> Bool-isNative' = d where-  d (DebianNative    _ _) = True-  d (DebianNonNative _ _) = False--parseVersion' :: Parser Version-parseVersion' =-  Version-  <$> ((:) <$> int <*> many (char '.' *> int))-  <*> pure []--parseDebianVersion :: Parser DebianVersion-parseDebianVersion = do-  v <- parseVersion'-  (DebianNonNative v <$> (char '-' *> some (satisfy (not . isSpace)))-   <|>-   DebianNative    v <$> optional (string "+nmu" *> int))--_testParseDebianVersion :: [Maybe (DebianVersion, String)]-_testParseDebianVersion =-  [ runParser parseDebianVersion s | s <- [ "1.23.3-4", "1.23", "12.3+nmu2" ] ]--instance Show DebianVersion where-  show = d  where-    d (DebianNative    v nr) = showVersion v ++ maybe "" (("+nmu" ++) . show) nr-    d (DebianNonNative v r)  = showVersion v ++ '-': r--instance Read DebianVersion where-  readsPrec _ = maybeToList . runParser parseDebianVersion--readMaybe' :: Read a => String -> Maybe a-readMaybe' =  fmap fst . listToMaybe . filter ((== "") . snd) . reads---- | Try to read debian package version-readDebianVersion :: String -> Maybe DebianVersion-readDebianVersion =  readMaybe'---- | Debian source package type, name with version-data Source = Source String DebianVersion  deriving Show---- | Make 'Source'-mkSource :: String -> DebianVersion -> Source-mkSource =  Source---- | Source package name of 'Source'-sourceName :: Source -> String-sourceName (Source n _) = n---- | Debian version of 'Source'-version :: Source -> DebianVersion-version (Source _ v) = v---- | Version without debian revision-origVersion :: Source -> Version-origVersion =  origVersion' . version---- | Is debian-native or not-isNative :: Source -> Bool-isNative =  isNative' . version---- | Original source archive basename-origArchiveName :: Source -> FilePath-origArchiveName pkg = sourceName pkg ++ '_' : showVersion (origVersion pkg) <.> "orig" <.> "tar" <.> "gz"---- | Debian native archive basename-nativeArchiveName :: Source -> String-nativeArchiveName pkg = sourceName pkg ++ '_' : show (version pkg) <.> "tar" <.> "gz"---- | Source directory basename-sourceDirName :: Source -> FilePath-sourceDirName pkg = sourceName pkg ++ '-' : showVersion (origVersion pkg)---- | Try to make 'HackageVersion' from 'Source'-deriveHackageVersion :: Source -> HackageVersion-deriveHackageVersion =  mkHackageVersion' . versionBranch . origVersion where--parseLine :: String -> Maybe (String, String)-parseLine =-  (fmap fst .) . runParser $-  (,) <$> some (notChar ':') <*> (char ':' *> many space *> many anyChar <* eof)---- | Try to generate 'Source' from debian changelog string-parseChangeLog :: String       -- ^ dpkg-parsechangelog result string-               -> Maybe Source -- ^ Source structure-parseChangeLog log' = do-  deb  <- mayDebSrc-  dver <- mayDebVer-  return $ mkSource deb dver-  where-    pairs = mapMaybe parseLine . lines $ log'-    lookup' = (`lookup` pairs)-    mayDebSrc = lookup' "Source"-    mayDebVer = do-      dverS <- lookup' "Version"-      readDebianVersion dverS---- | Debian .changes file types-data ChangesType-  = ChangesArch String-  | ChangesAll-  | ChangesSource-  deriving (Eq, Show)---- | Take 'ChangesType' from debian .changes file path-takeChangesType :: FilePath -> Maybe ChangesType-takeChangesType path = d . splitExtension $ takeFileName path  where-  d (n, ".changes") = case xs of-    [_, _, a] -> case a of-      "all"    -> Just   ChangesAll-      "source" -> Just   ChangesSource-      _        -> Just $ ChangesArch a-    _          -> Nothing-    where xs = splitOn "_" n-  d (_, _)     =  Nothing---- | Test changes file type is source package.-isSourceChanges :: ChangesType -> Bool-isSourceChanges = d where-  d (ChangesArch _) = False-  d  ChangesAll     = False-  d  ChangesSource  = True---- | Test changes file type is binary package.-isBinaryChanges :: ChangesType -> Bool-isBinaryChanges = not . isSourceChanges----- | Debian source package type for Haskell-data HaskellPackage = HaskellPackage Hackage Source deriving Show---- | 'Hackage' meta-info of 'HaskellPackage'-hackage :: HaskellPackage -> Hackage-hackage (HaskellPackage h _) = h---- | Debian source package meta-info of 'HaskellPackage'-package :: HaskellPackage -> Source-package (HaskellPackage _ p) = p---- | Generate 'HaskellPackage' type from debian package name and version---   using 'NameRule'-haskellPackageDefault :: NameRule-                      -> String         -- ^ Hackage name string-                      -> HackageVersion -- ^ Version of hackage-                      -> Maybe String   -- ^ Debian revision String-                      -> HaskellPackage -- ^ Result structure-haskellPackageDefault rule hname hver mayDevRev =-  HaskellPackage-  (mkHackageDefault rule hname hver)-  (mkSource sn (versionFromHackageVersion hver mayDevRev))-  where-    (sn, _) = debianNamesFromSourceName rule hname---- | Generate 'HaskellPackage' with hackage name and debian package meta-info-haskellPackageFromPackage :: String         -- ^ Hackage name string-                          -> Source         -- ^ Debian package meta info-                          -> HaskellPackage -- ^ Result-haskellPackageFromPackage hname pkg = HaskellPackage hkg pkg  where-  hv  = deriveHackageVersion pkg-  hkg = mkHackageDefault Simple hname hv