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 +3/−2
- mains/odebuild.hs +6/−4
- src/Debian/Package/Build/Command.hs +24/−6
- src/Debian/Package/Build/Sequence.hs +2/−2
- src/Debian/Package/Data.hs +2/−2
- src/Debian/Package/Data/Packages.hs +310/−0
- src/Debian/Package/Data/Source.hs +0/−268
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