rpmbuild-order 0.4.10 → 0.4.11
raw patch · 13 files changed
+323/−134 lines, 13 filesdep +regex-tdfadep −optparse-applicativePVP ok
version bump matches the API change (PVP)
Dependencies added: regex-tdfa
Dependencies removed: optparse-applicative
API changes (from Hackage documentation)
+ Distribution.RPM.Build.Order: dependencyLayersRpmOpts :: [String] -> [FilePath] -> IO [[FilePath]]
+ Distribution.RPM.Build.ProvReqs: rpmspecProvidesBuildRequires :: Bool -> [String] -> FilePath -> IO (Maybe ([String], [String]))
Files
- ChangeLog.md +7/−0
- README.md +13/−4
- rpmbuild-order.1 +3/−3
- rpmbuild-order.cabal +11/−6
- src/Distribution/RPM/Build/Graph.hs +9/−101
- src/Distribution/RPM/Build/Order.hs +11/−2
- src/Distribution/RPM/Build/ProvReqs.hs +140/−0
- src/Main.hs +10/−5
- test/Spec.hs +57/−13
- test/pkgs/cmake/A/A.spec +13/−0
- test/pkgs/cmake/B/B.spec +22/−0
- test/pkgs/pkgconf/A/A.spec +13/−0
- test/pkgs/pkgconf/C/C.spec +14/−0
ChangeLog.md view
@@ -1,3 +1,10 @@+# 0.4.11 (2024-02-18)+- ProvReqs: new module for rpmspec dependency functions+- ProvReqs: generate pkgconfig and cmake provides from %files (#4)+- Graph depsGraph: include package set in potential deps+- Order: add dependencyLayersRpmOpts+- more tests+ # 0.4.10 (2022-10-28) - Graph: add depsGraphDeps which takes a list of possible deps - Graph: add topsortGraph (factored out of sortGraph)
README.md view
@@ -11,13 +11,16 @@ ## Usage +`$ rpmbuild-order --version` ```-$ rpmbuild-order --version-0.4.10-$ rpmbuild-order --help+0.4.11+```+`$ rpmbuild-order --help`+``` Order packages by build dependencies Usage: rpmbuild-order [--version] COMMAND+ Sort package sources (spec files) in build dependency order Available options:@@ -33,7 +36,9 @@ leaves List of the top leaves of package graph roots List lowest root packages render Show graph with graphviz+``` +``` $ rpmbuild-order sort mycore mylib myapp mylib mycore myapp ```@@ -48,7 +53,9 @@ dependencies and reverse dependencies of a package can be obtained within the current set of checked out package sources. ie If you have a directory with packages:-`pkg1/ pkg2/ lib1/ lib2/ lib3/ misc1/`+```+pkg1/ pkg2/ lib1/ lib2/ lib3/ misc1/+``` then the output of `rpmbuild-order deps pkg1` might be `lib1 lib3 pkg1` for example. @@ -68,6 +75,8 @@ Please see their documentation for more details. ## Notes and known problems+0. Handles pkgconfig() provides by grepping .spec for .pc files+ 1. Given packages A, B, C, where C depends on B, and B depends on A, and you call
rpmbuild-order.1 view
@@ -1,7 +1,7 @@-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.-.TH RPMBUILD-ORDER "1" "August 2022" "rpmbuild-order 0.4.9" "User Commands"+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.+.TH RPMBUILD-ORDER "1" "February 2024" "rpmbuild-order 0.4.11" "User Commands" .SH NAME-rpmbuild-order \- manual page for rpmbuild-order 0.4.9+rpmbuild-order \- manual page for rpmbuild-order 0.4.11 .SH SYNOPSIS .B rpmbuild-order [\fI\,--version\/\fR] \fI\,COMMAND\/\fR
rpmbuild-order.cabal view
@@ -1,12 +1,12 @@ Name: rpmbuild-order-Version: 0.4.10+Version: 0.4.11 License: BSD3 License-File: LICENSE Author: Jens Petersen <petersen@redhat.com>, Henning Thielemann <haskell@henning-thielemann.de> Maintainer: Jens Petersen <petersen@redhat.com> Copyright: 2010-2018 Henning Thielemann,- 2018-2022 Jens Petersen <petersen@redhat.com>+ 2018-2024 Jens Petersen <petersen@redhat.com> Category: Distribution Homepage: https://github.com/juhp/rpmbuild-order Bug-reports: https://github.com/juhp/rpmbuild-order/issues@@ -24,9 +24,9 @@ which can affect dependencies. It can also output dependency graphs. Since version 0.4, a library API is provided.-Tested-with: GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2,- GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4,- GHC == 8.10.7, GHC == 9.0.2+Tested-with: GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5,+ GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.8,+ GHC == 9.4.8, GHC == 9.6.4, GHC == 9.8.1 Cabal-Version: 1.18 Build-Type: Simple Extra-doc-files: README.md TODO ChangeLog.md@@ -35,7 +35,11 @@ test/pkgs/B/B.spec test/pkgs/C/C.spec test/pkgs/D1.0/D1.0.spec+ test/pkgs/cmake/A/A.spec+ test/pkgs/cmake/B/B.spec test/pkgs/dynbr/A/A.spec+ test/pkgs/pkgconf/A/A.spec+ test/pkgs/pkgconf/C/C.spec source-repository head type: git@@ -45,7 +49,6 @@ Build-Depends: base < 5, extra, fgl,- optparse-applicative, rpmbuild-order, simple-cmd-args Main-Is: src/Main.hs@@ -69,6 +72,7 @@ Library Exposed-Modules: Distribution.RPM.Build.Graph Distribution.RPM.Build.Order+ Distribution.RPM.Build.ProvReqs Build-Depends: base < 5, case-insensitive, directory >= 1.2.5,@@ -76,6 +80,7 @@ filepath, fgl >= 5.5.4, graphviz,+ regex-tdfa, simple-cmd >= 0.2.3 HS-Source-Dirs: src default-language: Haskell2010
src/Distribution/RPM/Build/Graph.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-}-{-# LANGUAGE OverloadedStrings #-} {-| This module provides simple dependency graph making for rpm packages:@@ -38,7 +37,6 @@ topsortGraph, ) where -import qualified Data.CaseInsensitive as CI import Data.Graph.Inductive.Query.DFS (components, scc, topsort', xdfsWith) import Data.Graph.Inductive.Query.SP (sp) import Data.Graph.Inductive.PatriciaTree (Gr)@@ -53,13 +51,11 @@ import Data.GraphViz import SimpleCmd import System.Directory (doesDirectoryExist, doesFileExist,- getCurrentDirectory, withCurrentDirectory,- listDirectory- )-import System.Exit (exitFailure)+ withCurrentDirectory, listDirectory) import System.FilePath-import System.IO.Extra (withTempDir) +import Distribution.RPM.Build.ProvReqs (rpmspecProvidesBuildRequires)+ data SourcePackage = SourcePackage { packagePath :: FilePath,@@ -220,31 +216,7 @@ Just (dir,spec) -> do when verbose $ warning spec withCurrentDirectory dir $ do- dynbr <- egrep_ "^\\(%generate_buildrequires\\|%gometa\\)" spec- mprovbrs <-- if dynbr- then do- brs <- rpmspecDynBuildRequires spec- provs <- do- dynprovs <-- if "golang-" `isPrefixOf` takeBaseName spec- then do- macro <- grep "%global goipath" spec- return $- case macro of- [def] -> ["golang(" ++ last (words def) ++ ")"]- _ -> error' $ "failed to find %goipath in " ++ spec- else return []- prs <- rpmspecProvides spec- return $ dynprovs ++ prs- return $ Just (provs,brs)- else do- mcontent <- rpmspecParse spec- return $ case mcontent of- Nothing -> Nothing- Just content ->- let pkg = takeBaseName spec- in Just $ extractMetadata pkg ([],[]) $ lines content+ mprovbrs <- rpmspecProvidesBuildRequires lenient rpmopts spec case mprovbrs of Nothing -> return Nothing Just (provs,brs) -> do@@ -252,10 +224,10 @@ let provs' = filter (not . ("(x86-64)" `isSuffixOf`)) provs when verbose $ do warning $ show $ sort provs'- warning $ show $ mapMaybe simplifyDep $ sort brs+ warning $ show $ sort brs return $ Just (path, nub provs',- nub (mapMaybe simplifyDep brs) \\ ignoredBRs)+ nub brs \\ ignoredBRs) where -- (dir,specfile) findSpec :: IO (Maybe (FilePath,FilePath))@@ -295,27 +267,6 @@ then Nothing else error' $ f ++ " not found" - extractMetadata :: FilePath -> ([String],[String]) -> [String] -> ([String],[String])- extractMetadata _ acc [] = acc- extractMetadata pkg acc@(provs,brs) (l:ls) =- let ws = words l in- if length ws < 2 then extractMetadata pkg acc ls- else case CI.mk (head ws) of- "BuildRequires:" ->- let br = (head . tail) ws- brs' = if br `elem` ignoredBRs then brs else br:brs- in extractMetadata pkg (provs, brs') ls- "Name:" -> extractMetadata pkg ((head . tail) ws : provs, brs) ls- "Provides:" -> extractMetadata pkg ((head . tail) ws : provs, brs) ls- "%package" ->- let subpkg =- let sub = last ws in- if length ws == 2- then pkg ++ '-' : sub- else sub- in extractMetadata pkg (subpkg : provs, brs) ls- _ -> extractMetadata pkg acc ls- getBuildGraph :: [SourcePackage] -> PackageGraph getBuildGraph srcPkgs = let nodes = zip [0..] srcPkgs@@ -375,50 +326,6 @@ map (fromMaybe (error "node not found in graph") . G.lab graph) - rpmspecParse :: FilePath -> IO (Maybe String)- rpmspecParse spec = do- (ok, out, err) <- cmdFull "rpmspec" (["-P", "--define", "ghc_version any"] ++ rpmopts ++ [spec]) ""- unless (null err) $ warning $ spec +-+ err- if ok- then return $ Just out- else if lenient then return Nothing else exitFailure-- rpmspecProvides :: FilePath -> IO [String]- rpmspecProvides spec = do- (ok, out, err) <- cmdFull "rpmspec" (["--define", "ghc_version any", "-q", "--provides"] ++ rpmopts ++ [spec]) ""- unless (null err) $ warning err- if ok- then return $ map (head . words) $ lines out- else if lenient then return [] else exitFailure-- rpmspecDynBuildRequires :: FilePath -> IO [String]- rpmspecDynBuildRequires spec = do- cwd <- getCurrentDirectory- withTempDir $ \tmpdir -> do- (out,err) <- cmdStdErr "rpmbuild" ["-br", "--nodeps", "--define", "_srcrpmdir " ++ tmpdir, cwd </> spec]- unless (null err) $ when verbose $ warning err- -- Wrote: /current/dir/SRPMS/name-version-release.buildreqs.nosrc.rpm- case words out of- [] -> error' $ spec +-+ "could not generate source rpm for dynamic buildrequires"- ws -> cmdLines "rpm" ["-qp", "--requires", last ws]-- simplifyDep br =- case (head . words) br of- '(':dep -> simplifyDep dep- dep -> case splitOn "(" (dropSuffix ")" dep) of- ("rpmlib":_) -> Nothing- ("crate":[crate]) -> Just $ "rust-" ++ replace "/" "+" crate ++ "-devel"- ("rubygem":[gem]) -> Just $ "rubygem-" ++ gem- _ -> Just dep-- -- rpmspecBuildRequires :: FilePath -> IO [String]- -- rpmspecBuildRequires spec = do- -- (ok, out, err) <- cmdFull "rpmspec" (["--define", "ghc_version any", "-q", "--buildrequires"] ++ rpmopts ++ [spec]) ""- -- unless (null err) $ warning err- -- if ok- -- then return $ lines out- -- else if lenient then return [] else exitFailure- -- | Alias for createGraph4 -- -- @since 0.4.4 (deprecated)@@ -504,7 +411,8 @@ -> IO PackageGraph -- ^ dependency graph of the packages depsGraph rev rpmopts verbose excludedPkgs ignoredBRs lenient mdir pkgs = listDirectory "." >>=- depsGraphDeps rev rpmopts verbose excludedPkgs ignoredBRs lenient mdir pkgs+ depsGraphDeps rev rpmopts verbose excludedPkgs ignoredBRs lenient mdir pkgs .+ (`union` pkgs) -- | Given a list of one or more packages and a list of potential dependencies, -- return a package dependency graph@@ -524,7 +432,7 @@ unlessM (and <$> mapM doesDirectoryExist pkgs) $ errorWithoutStackTrace "Please use package directory paths" -- filter out dotfiles- createGraph3 ignoredBRs rpmopts verbose lenient (not rev) mdir (filter ((/= '.') . head) (filter (`notElem` excludedPkgs) deps)) >>=+ createGraph3 ignoredBRs rpmopts verbose lenient (not rev) mdir (filter (\d -> d `notElem` excludedPkgs && head d /= '.') deps) >>= createGraph2 rpmopts verbose lenient True mdir . dependencyNodes pkgs -- | Used to control the output from sortGraph
src/Distribution/RPM/Build/Order.hs view
@@ -20,6 +20,7 @@ dependencySortRpmOpts, dependencySortParallel, dependencyLayers,+ dependencyLayersRpmOpts, leafPackages, independentPackages, Components (..),@@ -58,6 +59,14 @@ graph <- createGraph pkgs return $ packageLayers graph +-- | like dependencyLayers but with rpm options+--+-- @since 0.4.11+dependencyLayersRpmOpts :: [String] -> [FilePath] -> IO [[FilePath]]+dependencyLayersRpmOpts rpmopts pkgs = do+ graph <- createGraphRpmOpts rpmopts pkgs+ return $ packageLayers graph+ -- | returns the leaves of a set of packages leafPackages :: [FilePath] -> IO [FilePath] leafPackages pkgs = do@@ -75,9 +84,9 @@ sortGraph opt graph = mapM_ (putStrLn . unwords) $ case opt of- Parallel -> intersperse ["\n"]+ Parallel -> intersperse [""] Combine -> id- Connected -> intersperse ["\n"]+ Connected -> intersperse [""] Separate -> id $ topsortGraph opt graph
+ src/Distribution/RPM/Build/ProvReqs.hs view
@@ -0,0 +1,140 @@+{-# LANGUAGE OverloadedStrings #-}++{-|+This module has commands for reading the Requires and Provides+from an RPM package spec file.+-}++module Distribution.RPM.Build.ProvReqs+ (rpmspecProvidesBuildRequires)+where++import Control.Monad (unless)+import qualified Data.CaseInsensitive as CI+import Data.List.Extra+import Data.Maybe (mapMaybe)+import SimpleCmd (cmdFull, cmdLines, cmdStdErr, egrep_, error',+ grep, warning, (+-+))+import System.Directory (doesFileExist)+import System.Exit (exitFailure)+import System.FilePath+import System.IO.Extra (withTempDir)+import Text.Regex.TDFA ((=~))++generateBuildRequires :: FilePath -> IO Bool+generateBuildRequires =+ egrep_ "^\\(%generate_buildrequires\\|%gometa\\)"++-- | Get RPM Provides and BuildRequires based on spec file.+rpmspecProvidesBuildRequires :: Bool -- ^ lenient (allow failure)+ -> [String] -- ^ RPM opts+ -> FilePath -- ^ spec file+ -> IO (Maybe ([String], -- ^ Provides+ [String] -- ^ BuildRequires+ ))+rpmspecProvidesBuildRequires lenient rpmopts spec = do+ dynbr <- generateBuildRequires spec+ if dynbr+ then do+ brs <- rpmspecDynBuildRequires spec+ provs <- do+ dynprovs <- dynProvides+ prs <- rpmspecProvides lenient rpmopts spec+ return $ dynprovs ++ prs+ return $ Just (provs, brs)+ else do+ mcontent <- rpmspecParse+ case mcontent of+ Nothing -> return Nothing+ Just content ->+ let pkg = takeBaseName spec+ in fmap Just <$> extractMetadata pkg ([],[]) $ lines content+ where+ extractMetadata :: FilePath -> ([String],[String]) -> [String]+ -> IO ([String],[String])+ extractMetadata _ (provs,brs) [] =+ return (provs, mapMaybe simplifyDep brs)+ extractMetadata pkg acc@(provs,brs) (l:ls) =+ case words l of+ [] -> extractMetadata pkg acc ls+ [w]+ | w =~ ("^/usr/(lib(64)?|share)/pkgconfig/.*\\.pc" :: String) ->+ let pc = metaName "pkgconfig" $ takeBaseName w+ in extractMetadata pkg (pc : provs, brs) ls+ | w =~ ("^/usr/(lib(64)?|share)/cmake/[^/]*$" :: String) ->+ let p = takeFileName w+ cm = map (metaName "cmake") $+ if lower p == p then [p] else [p, lower p]+ in extractMetadata pkg (provs ++ cm, brs) ls+ | otherwise -> extractMetadata pkg acc ls+ (w:w':ws) ->+ case CI.mk w of+ "BuildRequires:" ->+ -- FIXME could be more than one package: parse ws+ extractMetadata pkg (provs, w':brs) ls+ "Name:" -> extractMetadata pkg (w' : provs, brs) ls+ "Provides:" -> extractMetadata pkg (w' : provs, brs) ls+ "%package" ->+ let subpkg =+ if null ws+ then pkg ++ '-' : w'+ else last ws+ in extractMetadata pkg (subpkg : provs, brs) ls+ _ -> extractMetadata pkg acc ls++ rpmspecParse :: IO (Maybe String)+ rpmspecParse = do+ (ok, out, err) <- cmdFull "rpmspec" (["-P"] ++ rpmopts ++ [spec]) ""+ unless (null err) $ warning $ spec +-+ err+ if ok+ then return $ Just out+ else if lenient then return Nothing else exitFailure++ dynProvides :: IO [String]+ dynProvides =+ if "golang-" `isPrefixOf` takeBaseName spec+ then do+ macro <- grep "%global goipath" spec+ return $+ case macro of+ [def] -> ["golang(" ++ last (words def) ++ ")"]+ _ -> error' $ "failed to find %goipath in" +-+ spec+ else return []++ simplifyDep br =+ case (head . words) br of+ '(':dep -> simplifyDep dep+ dep -> case splitOn "(" (dropSuffix ")" dep) of+ ("rpmlib":_) -> Nothing+ ("crate":[crate]) -> Just $ "rust-" ++ replace "/" "+" crate ++ "-devel"+ ("rubygem":[gem]) -> Just $ "rubygem-" ++ gem+ _ -> Just dep++rpmspecDynBuildRequires :: FilePath -> IO [String]+rpmspecDynBuildRequires spec = do+ withTempDir $ \tmpdir -> do+ (out,err) <- cmdStdErr "rpmbuild" ["-br", "--nodeps", "--define", "_srcrpmdir" +-+ tmpdir, spec]+ -- Wrote: /current/dir/SRPMS/name-version-release.buildreqs.nosrc.rpm+ let errmsg =+ "failed to generate srpm for dynamic buildrequires for" +-+ spec +++ "\n\n" ++ err+ case words out of+ [] -> error' errmsg+ ws -> do+ let srpm = last ws+ exists <- doesFileExist srpm+ if exists+ then cmdLines "rpm" ["-qp", "--requires", last ws]+ else error' errmsg++rpmspecProvides :: Bool -> [String] -> FilePath -> IO [String]+rpmspecProvides lenient rpmopts spec = do+ (ok, out, err) <- cmdFull "rpmspec" (["-q", "--provides"] ++ rpmopts ++ [spec]) ""+ unless (null err) $ warning err+ if ok+ then return $ map (head . words) $ lines out+ else if lenient then return [] else exitFailure++metaName :: String -> String -> String+metaName meta name =+ meta ++ '(' : name ++ ")"
src/Main.hs view
@@ -59,11 +59,13 @@ ignoredBRopts = many (strOptionWith 'I' "ignore-BR" "PKG" "BuildRequires to exclude from graph") excludeOpts = many (dropSuffix "/" <$> strOptionWith 'x' "exclude" "PKG" "Package dirs to exclude from graph") -sortPackages :: [String] -> Bool -> Bool -> Components -> Maybe FilePath -> [FilePath] -> IO ()+sortPackages :: [String] -> Bool -> Bool -> Components -> Maybe FilePath+ -> [FilePath] -> IO () sortPackages rpmopts verbose lenient opts mdir pkgs = do createGraph2 rpmopts verbose lenient True mdir pkgs >>= sortGraph opts -layerPackages :: [String] -> Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()+layerPackages :: [String] -> Bool -> Bool -> Bool -> Maybe FilePath+ -> [FilePath] -> IO () layerPackages rpmopts verbose lenient combine mdir pkgs = do graph <- createGraph2 rpmopts verbose lenient True mdir pkgs if combine@@ -72,7 +74,8 @@ where printLayers = putStrLn . unlines . map unwords . packageLayers -chainPackages :: [String] -> Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()+chainPackages :: [String] -> Bool -> Bool -> Bool -> Maybe FilePath+ -> [FilePath] -> IO () chainPackages rpmopts verbose lenient combine mdir pkgs = do graph <- createGraph2 rpmopts verbose lenient True mdir pkgs if combine then doChain graph@@ -82,12 +85,14 @@ let chain = intercalate [":"] $ packageLayers graph in putStrLn $ unwords chain -leavesPackages :: [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()+leavesPackages :: [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath]+ -> IO () leavesPackages rpmopts verbose lenient mdir pkgs = do graph <- createGraph2 rpmopts verbose lenient True mdir pkgs mapM_ putStrLn $ packageLeaves graph -rootPackages :: [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()+rootPackages :: [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath]+ -> IO () rootPackages rpmopts verbose lenient mdir pkgs = do graph <- createGraph2 rpmopts verbose lenient True mdir pkgs mapM_ putStrLn $ lowestLayer graph
test/Spec.hs view
@@ -17,53 +17,70 @@ pkg :: FilePath -> FilePath pkg = ("test/pkgs/" ++) +-- FIXME refactor to test both subdir and withCurrentDirectory spec :: Version -> Spec spec rpmver = do describe "sort" $ do it "A B" $- dependencySort [pkg "A", pkg "B"] >>=+ both dependencySort [pkg "A", pkg "B"] >>= (`shouldBe` [pkg "B", pkg "A"]) it "1 2" $- dependencySort [pkg "1", pkg "2"] >>=+ both dependencySort [pkg "1", pkg "2"] >>= (`shouldBe` [pkg "2", pkg "1"]) it "A/ B/" $- dependencySort [pkg "A/", pkg "B/"] >>=+ both dependencySort [pkg "A/", pkg "B/"] >>= (`shouldBe` [pkg "B/", pkg "A/"]) it "1/ 2/" $- dependencySort [pkg "1/", pkg "2/"] >>=+ both dependencySort [pkg "1/", pkg "2/"] >>= (`shouldBe` [pkg "2/", pkg "1/"]) it "A.spec B.spec" $- dependencySort [pkg "A/A.spec", pkg "B/B.spec"] >>=+ both dependencySort [pkg "A/A.spec", pkg "B/B.spec"] >>= (`shouldBe` [pkg "B/B.spec", pkg "A/A.spec"]) it "1.spec 2.spec" $- dependencySort [pkg "1/A.spec", pkg "2/B.spec"] >>=+ both dependencySort [pkg "1/A.spec", pkg "2/B.spec"] >>= (`shouldBe` [pkg "2/B.spec", pkg "1/A.spec"]) it "A/ B.spec" $- dependencySort [pkg "A/", pkg "B/B.spec"] >>=+ both dependencySort [pkg "A/", pkg "B/B.spec"] >>= (`shouldBe` [pkg "B/B.spec", pkg "A/"]) it "circular A B C" $- dependencySort [pkg "A", pkg "B", pkg "C"]+ both dependencySort [pkg "A", pkg "B", pkg "C"] `shouldThrow` anyException it "A B D1.0" $ dependencySort [pkg "A", pkg "B/", pkg "D1.0"] >>= (`shouldBe` [pkg "B/", pkg "D1.0", pkg "A"]) + it "A D" $+ indy dependencySort [pkg "A", pkg "D1.0"] >>=+ (`shouldBe` [pkg "A", pkg "D1.0"])++ it "C D" $+ indy dependencySort [pkg "C", pkg "D1.0"] >>=+ (`shouldBe` [pkg "C", pkg "D1.0"])++ it "pkgconf" $+ both dependencySort [pkg "pkgconf/C", pkg "pkgconf/A"] >>=+ (`shouldBe` [pkg "pkgconf/C", pkg "pkgconf/A"])++ it "cmake" $+ both dependencySort [pkg "cmake/A", pkg "cmake/B"] >>=+ (`shouldBe` [pkg "cmake/B", pkg "cmake/A"])+ when (rpmver > makeVersion [4,15,0]) $ it "dynbr A B" $- dependencySort [pkg "dynbr/A", pkg "B"] >>=+ both dependencySort [pkg "dynbr/A", pkg "B"] >>= (`shouldBe` [pkg "B", pkg "dynbr/A"]) when (rpmver > makeVersion [4,15,1]) $ it "circular A B C boot" $- dependencySortRpmOpts ["--with=boot"] [pkg "A", pkg "B", pkg "C"] >>=+ both (dependencySortRpmOpts ["--with=boot"]) [pkg "A", pkg "B", pkg "C"] >>= (`shouldBe` [pkg "C", pkg "B", pkg "A"]) describe "layers" $@@ -76,17 +93,44 @@ leafPackages [pkg "A", pkg "B", pkg "D1.0"] >>= (`shouldBe` [pkg "A", pkg "D1.0"]) + let rpmbuildOrder f c = fmap f . cmd "rpmbuild-order" . (c:)+ describe "rpmbuild-order" $ do it "sort A B" $- cmd "rpmbuild-order" ["sort", pkg "A", pkg "B"] >>=- (`shouldBe` unwords [pkg "B", pkg "A"])+ both (rpmbuildOrder words "sort") [pkg "A", pkg "B"] >>=+ (`shouldBe` [pkg "B", pkg "A"]) + it "sort A D" $+ indy (rpmbuildOrder lines "sort") [pkg "A", pkg "D1.0"] >>=+ (`shouldBe` [pkg "D1.0", "", pkg "A"])++ it "sort pkgconf" $+ both (rpmbuildOrder words "sort") [pkg "pkgconf/A", pkg "pkgconf/C"] >>=+ (`shouldBe` [pkg "pkgconf/C", pkg "pkgconf/A"])++ it "sort cmake" $+ both (rpmbuildOrder words "sort") [pkg "cmake/A", pkg "cmake/B"] >>=+ (`shouldBe` [pkg "cmake/B", pkg "cmake/A"])+ it "deps A" $ withCurrentDirectory "test/pkgs" $ cmd "rpmbuild-order"- ["deps", "-x", "dynbr", "-x", "1", "-x", "2", "-x", "C", "A"] >>=+ ["deps", "-x", "dynbr", "-x", "pkgconf", "-x", "1", "-x", "2", "-x", "C","-x", "cmake", "A"] >>= (`shouldBe` unwords ["B", "A"])+ where+ both :: ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [FilePath]+ both io fs = do+ r <- io fs+ r' <- io $ reverse fs+ r `shouldBe` r'+ return r + indy :: ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [FilePath]+ indy io fs = do+ r <- io fs+ r' <- io $ reverse fs+ r `shouldBe` reverse r'+ return r' setupSymlinks :: IO () setupSymlinks =
+ test/pkgs/cmake/A/A.spec view
@@ -0,0 +1,13 @@+Name: A+Version: 1+Release: 1%{?dist}+Summary: package A+License: GPL+BuildRequires: cmake(libB)++%description+Test package A pkgconfig++%changelog+* Wed Jul 29 13:38:27 +08 2020 Jens Petersen <petersen@redhat.com>+-
+ test/pkgs/cmake/B/B.spec view
@@ -0,0 +1,22 @@+Name: B+Version: 1+Release: 1%{?dist}+Summary: package B+License: GPL++%description+Test package B++%prep++%build++%install++%files+%{_libdir}/cmake/libB+%{_libdir}/cmake/libB/B.cmake++%changelog+* Wed Jul 29 13:38:27 +08 2020 Jens Petersen <petersen@redhat.com>+-
+ test/pkgs/pkgconf/A/A.spec view
@@ -0,0 +1,13 @@+Name: A+Version: 1+Release: 1%{?dist}+Summary: package A+License: GPL+BuildRequires: pkgconfig(libC)++%description+Test package A pkgconfig++%changelog+* Wed Jul 29 13:38:27 +08 2020 Jens Petersen <petersen@redhat.com>+-
+ test/pkgs/pkgconf/C/C.spec view
@@ -0,0 +1,14 @@+Name: C+Version: 1+Release: 1%{?dist}+Summary: package C+License: GPL++%description++%files+%{_libdir}/pkgconfig/libC.pc++%changelog+* Wed Jul 29 13:38:27 +08 2020 Jens Petersen <petersen@redhat.com>+-