packages feed

rpmbuild-order 0.4.1 → 0.4.2

raw patch · 9 files changed

+105/−40 lines, 9 files

Files

ChangeLog.md view
@@ -1,3 +1,10 @@+# 0.4.2 (2020-08-04)+- support options for rpmspec (suggested by QuLogic)+  eg `rpmbuild-order sort --rpmopt --with=bootstrap ...`+- Graph: add createGraphRpmOpts and createGraph''+- Order: add dependencySortRpmOpts+- add a newline between cycles+ # 0.4.1 (2020-08-03) - no longer assume pkg dir = pkg name (though still optimize for it) - output any subcycles for cyclic graph (suggested by QuLogic)
README.md view
@@ -21,9 +21,17 @@ dependencies and reverse dependencies of a package can be obtained from the current set of checked out package sources. +## Library As of version 0.4, a library is also provided.-See the modules' documentation for details. +There are two modules:++- `Distribution.RPM.Build.Graph` provides lower level functions for generating+  RPM dependency graphs+- `Distribution.RPM.Build.Order` provides higher level functions for sort packages in build dependency orders and output.++Please see the documentation for more details.+ ## Notes and known problems 1. Given packages A, B, C, where C depends on B, and B depends on A, and you call@@ -44,4 +52,4 @@ BuildRequires than Requires.  3. rpmspec is used to parse spec files (for macro expansion etc):-so missing macros packages may lead to erroneous results.+so missing macros packages can lead to erroneous results in some cases.
TODO view
rpmbuild-order.cabal view
@@ -1,8 +1,9 @@ Name:             rpmbuild-order-Version:          0.4.1+Version:          0.4.2 License:          BSD3 License-File:     LICENSE-Author:           Henning Thielemann <haskell@henning-thielemann.de>+Author:           Henning Thielemann <haskell@henning-thielemann.de>,+                  Jens Petersen <petersen@redhat.com> Maintainer:       Jens Petersen <petersen@redhat.com> Copyright:        2010-2018  Henning Thielemann,                   2018-2020 Jens Petersen <petersen@redhat.com>@@ -18,7 +19,8 @@   It can also output the ordered dependencies or reverse depends   for one or more packages, provided all the packages are checked out   in neighboring directories. This is also useful to see what packages-  are affected when a low-level package changes.+  are affected when a low-level package changes. It also have support+  for setting RPM options for bcond etc, which can affect dependencies.    Since version 0.4 there is a library too. Tested-with:       GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4,
src/Distribution/RPM/Build/Graph.hs view
@@ -12,16 +12,18 @@ -}  module Distribution.RPM.Build.Graph-  (createGraph,+  (PackageGraph,+   createGraph,+   createGraphRpmOpts,    createGraph',+   createGraph'',    dependencyNodes,    subgraph',    packageLayers,    lowestLayer,    lowestLayer',    packageLeaves,-   separatePackages,-   PackageGraph+   separatePackages   ) where  import qualified Data.CaseInsensitive as CI@@ -88,17 +90,47 @@             -> IO PackageGraph -- ^ dependency graph labelled by package paths createGraph = createGraph' False False True Nothing +-- | Create a directed dependency graph for a set of packages setting rpm options+-- This is a convenience wrapper for @createGraph'' rpmopts False False True Nothing@+--+-- @since 0.4.2+createGraphRpmOpts :: [String] -- ^ rpmspec options+                   -> [FilePath] -- ^ package paths (directories or spec filepaths)+                   -> IO PackageGraph -- ^ dependency graph labelled by package paths+createGraphRpmOpts rpmopts =+  createGraph'' rpmopts False False True Nothing+ -- | Create a directed dependency graph for a set of packages -- For the (createGraph default) reverse deps graph the arrows point back -- from the dependencies to the dependendent (parent/consumer) packages, -- and this allows forward sorting by dependencies (ie lowest deps first).+--+-- This is the same as @createGraph'' []@ createGraph' :: Bool -- ^ verbose              -> Bool -- ^ lenient (skip rpmspec failures)              -> Bool -- ^ reverse dependency graph              -> Maybe FilePath -- ^ look for spec file in a subdirectory              -> [FilePath] -- ^ package paths (directories or spec filepaths)              -> IO PackageGraph -- ^ dependency graph labelled by package paths-createGraph' verbose lenient rev mdir paths = do+createGraph' = createGraph'' []++-- | Create a directed dependency graph for a set of packages+-- For the (createGraph default) reverse deps graph the arrows point back+-- from the dependencies to the dependendent (parent/consumer) packages,+-- and this allows forward sorting by dependencies (ie lowest deps first).+--+-- Additionally this function allows passing options to rpmspec:+-- eg `--with bootstrap` etc+--+-- @since 0.4.2+createGraph'' :: [String] -- ^ rpmspec options+              -> Bool -- ^ verbose+              -> Bool -- ^ lenient (skip rpmspec failures)+              -> Bool -- ^ reverse dependency graph+              -> Maybe FilePath -- ^ look for spec file in a subdirectory+              -> [FilePath] -- ^ package paths (directories or spec filepaths)+              -> IO PackageGraph -- ^ dependency graph labelled by package paths+createGraph'' rpmopts verbose lenient rev mdir paths = do   metadata <- catMaybes <$> mapM readSpecMetadata paths   let realpkgs = map fst3 metadata       deps = mapMaybe (getDepsSrcResolved metadata) realpkgs@@ -198,7 +230,7 @@       unless (null cycles) $         error $ unlines $         "Cycles in dependencies:" :-        concatMap (renderCycles . subcycles) cycles+        concatMap ((++ [""]) . renderCycles . subcycles) cycles       where         cycles :: [[G.Node]]         cycles =@@ -242,7 +274,7 @@      rpmspecParse :: FilePath -> IO (Maybe String)     rpmspecParse spec = do-      (res, out, err) <- readProcessWithExitCode "rpmspec" ["-P", "--define", "ghc_version any", spec] ""+      (res, out, err) <- readProcessWithExitCode "rpmspec" (["-P", "--define", "ghc_version any"] ++ rpmopts ++ [spec]) ""       unless (null err) $ warn err       case res of         ExitFailure _ -> if lenient then return Nothing else exitFailure
src/Distribution/RPM/Build/Order.hs view
@@ -17,6 +17,7 @@  module Distribution.RPM.Build.Order   (dependencySort,+   dependencySortRpmOpts,    dependencySortParallel,    dependencyLayers,    leafPackages,@@ -34,8 +35,14 @@  -- | sort packages by dependencies dependencySort :: [FilePath] -> IO [FilePath]-dependencySort pkgs = do-  topsort' <$> createGraph pkgs+dependencySort = dependencySortRpmOpts []++-- | sort packages by dependencies with rpm options+--+-- @since 0.4.2+dependencySortRpmOpts :: [String] -> [FilePath] -> IO [FilePath]+dependencySortRpmOpts rpmopts pkgs = do+  topsort' <$> createGraphRpmOpts rpmopts pkgs  -- | dependency sort of packages in graph components dependencySortParallel :: [FilePath] -> IO [[FilePath]]
src/Main.hs view
@@ -5,7 +5,7 @@                             (<|>), #endif #if !MIN_VERSION_simple_cmd_args(0,1,4)-                            some,+                            many, some, #endif #if !MIN_VERSION_base(4,8,0)                             (<$>), (<*>)@@ -37,19 +37,19 @@   "Sort package sources (spec files) in build dependency order" $   subcommands   [ Subcommand "sort" "sort packages" $-    sortPackages <$> verboseOpt <*> lenientOpt <*> componentsOpt <*> subdirOpt <*> pkgArgs+    sortPackages <$> rpmOpts <*> verboseOpt <*> lenientOpt <*> componentsOpt <*> subdirOpt <*> pkgArgs   , Subcommand "deps" "sort dependencies" $-    depsPackages False <$> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs+    depsPackages False <$> rpmOpts <*> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs   , Subcommand "rdeps" "sort dependents" $-    depsPackages True <$> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs+    depsPackages True <$> rpmOpts <*> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs   , Subcommand "layers" "ordered output suitable for a chain-build" $-    layerPackages <$> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs+    layerPackages <$> rpmOpts <*> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs   , Subcommand "chain" "ordered output suitable for a chain-build" $-    chainPackages <$> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs+    chainPackages <$> rpmOpts <*> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs   , Subcommand "leaves" "List of the top leaves of package graph" $-    leavesPackages <$> verboseOpt <*> lenientOpt <*> subdirOpt <*> pkgArgs+    leavesPackages <$> rpmOpts <*> verboseOpt <*> lenientOpt <*> subdirOpt <*> pkgArgs   , Subcommand "roots" "List lowest root packages" $-    rootPackages <$> verboseOpt <*> lenientOpt <*> subdirOpt <*> pkgArgs+    rootPackages <$> rpmOpts <*> verboseOpt <*> lenientOpt <*> subdirOpt <*> pkgArgs   ]   where     verboseOpt = switchWith 'v' "verbose" "Verbose output for debugging"@@ -61,19 +61,20 @@       flagWith' Connected 'C' "connected" "Only include connected packages" <|>       flagWith' Separate 'i' "independent" "Only list independent packages" <|>       flagWith Parallel Combine 'c' "combine" "Combine connected and independent packages"+    rpmOpts = many (strOptionWith 'r' "rpmopt" "RPMOPT" "Option for rpmspec") -sortPackages :: Bool -> Bool -> Components -> Maybe FilePath -> [FilePath] -> IO ()-sortPackages verbose lenient opts mdir pkgs = do-  createGraph' verbose lenient True mdir pkgs >>= sortGraph opts+sortPackages :: [String] -> Bool -> Bool -> Components -> Maybe FilePath -> [FilePath] -> IO ()+sortPackages verbose lenient rpmopts opts mdir pkgs = do+  createGraph'' verbose lenient True rpmopts mdir pkgs >>= sortGraph opts -depsPackages :: Bool -> Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()-depsPackages rev verbose lenient parallel mdir pkgs = do+depsPackages :: Bool -> [String] ->Bool -> Bool ->  Bool -> Maybe FilePath -> [FilePath] -> IO ()+depsPackages rev rpmopts verbose lenient parallel mdir pkgs = do   unlessM (and <$> mapM doesDirectoryExist pkgs) $     error "Please use package directory paths"   listDirectory "." >>=     -- filter out dotfiles-    createGraph' verbose lenient (not rev) mdir . filter ((/= '.') . head) >>=-    createGraph' verbose lenient True mdir . dependencyNodes pkgs >>=+    createGraph'' rpmopts verbose lenient (not rev) mdir . filter ((/= '.') . head) >>=+    createGraph'' rpmopts verbose lenient True mdir . dependencyNodes pkgs >>=     sortGraph (if parallel then Parallel else Combine)  #if (defined(MIN_VERSION_directory) && MIN_VERSION_directory(1,2,5))@@ -84,17 +85,17 @@   where f filename = filename /= "." && filename /= ".." #endif -layerPackages :: Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()-layerPackages verbose lenient combine mdir pkgs = do-  graph <- createGraph' verbose lenient True mdir pkgs+layerPackages :: [String] -> Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()+layerPackages rpmopts verbose lenient combine mdir pkgs = do+  graph <- createGraph'' rpmopts verbose lenient True mdir pkgs   if combine then printLayers graph     else mapM_ (printLayers . subgraph' graph) (components graph)   where     printLayers =  putStrLn . unlines . map unwords . packageLayers -chainPackages :: Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()-chainPackages verbose lenient combine mdir pkgs = do-  graph <- createGraph' verbose lenient True mdir pkgs+chainPackages :: [String] -> Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()+chainPackages rpmopts verbose lenient combine mdir pkgs = do+  graph <- createGraph'' rpmopts verbose lenient True mdir pkgs   if combine then doChain graph     else mapM_ (doChain . subgraph' graph) (components graph)   where@@ -102,12 +103,12 @@       let chain = intercalate [":"] $ packageLayers graph       in putStrLn $ unwords chain -leavesPackages :: Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()-leavesPackages verbose lenient mdir pkgs = do-  graph <- createGraph' verbose lenient True mdir pkgs+leavesPackages :: [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()+leavesPackages rpmopts verbose lenient mdir pkgs = do+  graph <- createGraph'' rpmopts verbose lenient True mdir pkgs   mapM_ putStrLn $ packageLeaves graph -rootPackages :: Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()-rootPackages verbose lenient mdir pkgs = do-  graph <- createGraph' verbose lenient True mdir pkgs+rootPackages :: [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO ()+rootPackages rpmopts verbose lenient mdir pkgs = do+  graph <- createGraph'' rpmopts verbose lenient True mdir pkgs   mapM_ putStrLn $ lowestLayer graph
test/Spec.hs view
@@ -49,6 +49,10 @@       dependencySort [pkg "A", pkg "B/", pkg "D1.0"] >>=       (`shouldBe` [pkg "B/", pkg "D1.0", pkg "A"]) +    it "circular A B C boot" $+      dependencySortRpmOpts ["--with=boot"] [pkg "A", pkg "B", pkg "C"] >>=+      (`shouldBe` [pkg "C", pkg "B", pkg "A"])+   describe "layers" $     it "layers A B" $       dependencyLayers [pkg "A", pkg "B"] >>=
test/pkgs/C/C.spec view
@@ -1,9 +1,13 @@+%bcond_with boot+ Name:           C Version:        1 Release:        1%{?dist} Summary:        package C License:        GPL+%if %{without boot} BuildRequires:  C-A+%endif  %description Circular dep