rpmbuild-order 0.4.5 → 0.4.6
raw patch · 9 files changed
+255/−112 lines, 9 filesdep −containersdep −processdep ~basedep ~filepathdep ~simple-cmdPVP ok
version bump matches the API change (PVP)
Dependencies removed: containers, process
Dependency ranges changed: base, filepath, simple-cmd
API changes (from Hackage documentation)
+ Distribution.RPM.Build.Graph: createGraph1 :: Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO PackageGraph
+ Distribution.RPM.Build.Graph: createGraph2 :: [String] -> Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO PackageGraph
+ Distribution.RPM.Build.Graph: createGraph3 :: [String] -> [String] -> Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO PackageGraph
+ Distribution.RPM.Build.Graph: createGraph4 :: Bool -> [String] -> [String] -> Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO PackageGraph
Files
- ChangeLog.md +8/−0
- README.md +21/−10
- TODO +2/−2
- rpmbuild-order.1 +4/−4
- rpmbuild-order.cabal +13/−12
- src/Distribution/RPM/Build/Graph.hs +178/−61
- src/Main.hs +12/−11
- test/Spec.hs +16/−11
- test/pkgs/A/A.spec +1/−1
ChangeLog.md view
@@ -1,3 +1,11 @@+# 0.4.6 (2022-05-30)+- handle Dynamic BuildRequires (#3)+ with special support for golang Provs and rust & ruby BRs+- Graph: new aliases createGraph1 for createGraph',+ createGraph2 for createGraph'', createGraph3 for createGraph''',+ and createGraph4 for createGraph'''' (deprecating the primed names)+- Graph: use simple-cmd+ # 0.4.5 (2021-05-29) - 'render': do not reverse arrows - 'render': rename -o/--output option to -g/--gv-output
README.md view
@@ -5,7 +5,7 @@ # rpmbuild-order This is a tool to sort RPM source packages in build dependency order.-This code is originally derived from+The code was originally derived from [cabal-sort](http://hackage.haskell.org/package/cabal-sort) by Henning Thielemann. @@ -45,20 +45,31 @@ 1. Given packages A, B, C, where C depends on B, and B depends on A, and you call - rpmbuild-order sort C.spec A.spec+ rpmbuild-order sort C.spec A.spec -then the output may be wrong if C does not have a direct dependency on A.-Even if the order is correct, B is missing in the output-and thus in this case the list of packages cannot be reliably used-for a sequence of builds.+ then the output may be wrong if C does not have a direct dependency on A.+ Even if the order is correct, B is missing in the output+ and thus in this case the list of packages cannot be reliably used+ for a sequence of builds. -However the `deps` and `rdeps` commands take-other neighbouring package directories into account.+ However the `deps` and `rdeps` commands take+ other neighbouring package directories into account. 2. repoquery is not used to resolve meta-dependencies or files to packages. So if a package BuildRequires a file, it will not be resolved to a package.-This may get addressed some day, but file dependencies seem less common for-BuildRequires than Requires.+This may get addressed some day, but file dependencies seem uncommon for+BuildRequires compared to Requires. 3. rpmspec is used to parse spec files (for macro expansion etc): so missing macros packages can lead to erroneous results in some cases.++4. Since version 0.4.6 there is some support now for packages using+dynamic buildrequires (in Fedora: golang, python, ruby, and rust packages).++## Installation++rpmbuild-order is packaged in Fedora Linux.++## Building from source++Use `cabal-rpm builddep && cabal-install` or `stack install`.
TODO view
@@ -1,8 +1,8 @@ - --quiet to silence rpmspec warnings - use record to set createGraph options -- try topograph-- use Set?+- try topograph or agl+- use Data.Set * warn about uninstalled (specific?) macros packages - handle duplicate packages? - (r)deps: optimize using actual deps
rpmbuild-order.1 view
@@ -1,7 +1,7 @@-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.3.-.TH RPMBUILD-ORDER "1" "May 2021" "rpmbuild-order 0.4.5" "User Commands"+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.+.TH RPMBUILD-ORDER "1" "May 2022" "rpmbuild-order 0.4.6" "User Commands" .SH NAME-rpmbuild-order \- manual page for rpmbuild-order 0.4.5+rpmbuild-order \- manual page for rpmbuild-order 0.4.6 .SH SYNOPSIS .B rpmbuild-order [\fI\,--version\/\fR] \fI\,COMMAND\/\fR@@ -28,7 +28,7 @@ sort dependents .TP layers-ordered output suitable for a chain\-build+ordered output of dependency layers .TP chain ordered output suitable for a chain\-build
rpmbuild-order.cabal view
@@ -1,12 +1,12 @@ Name: rpmbuild-order-Version: 0.4.5+Version: 0.4.6 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-2021 Jens Petersen <petersen@redhat.com>+ 2018-2022 Jens Petersen <petersen@redhat.com> Category: Distribution Homepage: https://github.com/juhp/rpmbuild-order Bug-reports: https://github.com/juhp/rpmbuild-order/issues@@ -23,10 +23,9 @@ which can affect dependencies. It can also output dependency graphs. Since version 0.4, a library API is also provided.-Tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4,- GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2,+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.4, GHC == 9.0.1+ GHC == 8.10.7, GHC == 9.0.2 Cabal-Version: 1.18 Build-Type: Simple Extra-doc-files: README.md TODO ChangeLog.md@@ -50,6 +49,7 @@ simple-cmd-args Main-Is: src/Main.hs Other-modules: Paths_rpmbuild_order+ default-language: Haskell2010 GHC-Options: -Wall if impl(ghc >= 8.0) ghc-options: -Wcompat@@ -62,21 +62,22 @@ if impl(ghc >= 8.4) ghc-options: -Wmissing-export-lists -Wpartial-fields- default-language: Haskell2010+ if impl(ghc >= 8.10)+ ghc-options: -Wunused-packages Library Exposed-Modules: Distribution.RPM.Build.Graph Distribution.RPM.Build.Order Build-Depends: base < 5, case-insensitive,- containers, directory, extra >= 1.6.4,- filepath,+ filepath >= 1.4.2, fgl >= 5.5.4, graphviz,- process+ simple-cmd >= 0.2.3 HS-Source-Dirs: src+ default-language: Haskell2010 GHC-Options: -Wall if impl(ghc >= 8.0) ghc-options: -Wcompat@@ -89,8 +90,8 @@ if impl(ghc >= 8.4) ghc-options: -Wmissing-export-lists -Wpartial-fields-- default-language: Haskell2010+ if impl(ghc >= 8.10)+ ghc-options: -Wunused-packages test-suite test main-is: Spec.hs@@ -106,4 +107,4 @@ , rpmbuild-order , simple-cmd , unix- build-tools: rpmbuild-order+ build-tool-depends: rpmbuild-order:rpmbuild-order
src/Distribution/RPM/Build/Graph.hs view
@@ -15,6 +15,10 @@ (PackageGraph, createGraph, createGraphRpmOpts,+ createGraph1,+ createGraph2,+ createGraph3,+ createGraph4, createGraph', createGraph'', createGraph''',@@ -41,22 +45,23 @@ #endif import Control.Monad (forM_, guard, when, unless) import Data.Maybe (catMaybes, fromMaybe, mapMaybe)-import Data.List.Extra (dropSuffix, find, intercalate, nub, nubOrdOn, sort, sortOn)+import Data.List.Extra import Data.GraphViz+import SimpleCmd import System.Directory (doesDirectoryExist, doesFileExist,+ withCurrentDirectory,+#if !MIN_VERSION_simple_cmd(0,2,4) #if MIN_VERSION_directory(1,2,5) listDirectory #else getDirectoryContents #endif+#endif )-import System.Exit (ExitCode (..), exitFailure)+import System.Exit (exitFailure) import System.FilePath--- replace with warning-import System.IO (hPutStrLn, stderr)-import System.Process (readProcessWithExitCode) -#if !MIN_VERSION_directory(1,2,5)+#if !MIN_VERSION_directory(1,2,5) && !MIN_VERSION_simple_cmd(0,2,4) listDirectory :: FilePath -> IO [FilePath] listDirectory path = filter f <$> getDirectoryContents path@@ -90,34 +95,45 @@ third (_, _, c, _) = c -- | Create a directed dependency graph for a set of packages--- This is a convenience wrapper for createGraph' False False True Nothing+-- This is a convenience wrapper for createGraph1 False False True Nothing createGraph :: [FilePath] -- ^ package paths (directories or spec filepaths) -> IO PackageGraph -- ^ dependency graph labelled by package paths-createGraph = createGraph' False False True Nothing+createGraph = createGraph1 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@+-- This is a convenience wrapper for @createGraph2 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+ createGraph2 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'' []@+-- This is the same as @createGraph2 []@+--+-- @since 0.4.6+createGraph1 :: 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+createGraph1 = createGraph2 []++-- | Alias for createGraph1 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' = createGraph'' []+createGraph' = createGraph1 -- | Create a directed dependency graph for a set of packages -- For the (createGraph default) reverse deps graph the arrows point back@@ -127,7 +143,19 @@ -- Additionally this function allows passing options to rpmspec: -- eg `--with bootstrap` etc ----- @since 0.4.2+-- @since 0.4.6+createGraph2 :: [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+createGraph2 = createGraph3 []++-- | Alias for createGraph2+--+-- @since 0.4.2 (deprecated) createGraph'' :: [String] -- ^ rpmspec options -> Bool -- ^ verbose -> Bool -- ^ lenient (skip rpmspec failures)@@ -135,13 +163,26 @@ -> 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'' = createGraph''' []+createGraph'' = createGraph2 -- | Create a directed dependency graph for a set of packages ----- Like createGraph'' but with additional parameter for any BRs to be ignored.+-- Like createGraph2 but with additional parameter for any BRs to be ignored. ----- @since 0.4.3+-- @since 0.4.6+createGraph3 :: [String] -- ^ ignored BuildRequires+ -> [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+createGraph3 = createGraph4 True++-- | Alias for createGraph3+--+-- @since 0.4.3 (deprecated) createGraph''' :: [String] -- ^ ignored BuildRequires -> [String] -- ^ rpmspec options -> Bool -- ^ verbose@@ -150,23 +191,24 @@ -> 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''' = createGraph'''' True+createGraph''' = createGraph3 -- | Create a directed dependency graph for a set of packages ----- Like createGraph''' but can disable check for cycles+-- Like createGraph3 but can disable check for cycles ----- @since 0.4.4-createGraph'''' :: Bool -- ^ check for cycles- -> [String] -- ^ ignored BuildRequires- -> [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'''' checkcycles ignoredBRs rpmopts verbose lenient rev mdir paths = do+-- @since 0.4.6+createGraph4 :: Bool -- ^ check for cycles+ -> [String] -- ^ ignored BuildRequires+ -> [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+createGraph4 checkcycles ignoredBRs rpmopts verbose lenient rev mdir paths =+ do metadata <- catMaybes <$> mapM readSpecMetadata paths let realpkgs = map fst3 metadata deps = mapMaybe (getDepsSrcResolved metadata) realpkgs@@ -178,21 +220,51 @@ where readSpecMetadata :: FilePath -> IO (Maybe (FilePath,[String],[String])) readSpecMetadata path = do- mspec <- findSpec- case mspec of+ mspecdir <- findSpec+ case mspecdir of Nothing -> return Nothing- Just spec -> do- when verbose $ warn spec- mcontent <- rpmspecParse spec- case mcontent of- Nothing -> return Nothing- Just content ->- let pkg = takeBaseName spec- (provs,brs) = extractMetadata pkg ([],[]) $ lines content- in return (Just (path, provs, brs))+ 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+ case mprovbrs of+ Nothing -> return Nothing+ Just (provs,brs) -> do+ when verbose $ do+ warning $ show $ sort provs+ warning $ show $ mapMaybe simplifyDep $ sort brs+ return $ Just (path,+ nub provs, -- FIXME filter 'name(arch)'+ nub (mapMaybe simplifyDep brs) \\ ignoredBRs) where- findSpec :: IO (Maybe FilePath)+ -- (dir,specfile)+ findSpec :: IO (Maybe (FilePath,FilePath)) findSpec =+ fmap splitFileName <$> if takeExtension path == ".spec" then checkFile lenient path else do@@ -210,27 +282,28 @@ else do specs <- filesWithExtension dir ".spec" case specs of- [spec] -> return $ Just spec+ [spec] -> return $ Just $ dir </> spec _ -> if lenient then return Nothing- else errorWithoutStackTrace $+ else error' $ if null specs then "No spec file found in " ++ path else "More than one .spec file found in " ++ dir- else errorWithoutStackTrace $ "No spec file found for " ++ path+ else error' $ "No spec file found for " ++ path where checkFile :: Bool -> FilePath -> IO (Maybe FilePath) checkFile may f = do e <- doesFileExist f- if e- then return $ Just f- else return $ if may- then Nothing- else errorWithoutStackTrace $ f ++ " not found"+ return $ if e+ then Just f+ else if may+ then Nothing+ else error' $ f ++ " not found" +#if !MIN_VERSION_simple_cmd(0,2,4) filesWithExtension :: FilePath -> String -> IO [FilePath] filesWithExtension dir ext =- map (dir </>) . filter (\ f -> takeExtension f == ext) <$>- listDirectory dir+ filter (ext `isExtensionOf`) <$> listDirectory dir+#endif extractMetadata :: FilePath -> ([String],[String]) -> [String] -> ([String],[String]) extractMetadata _ acc [] = acc@@ -271,7 +344,7 @@ let cycles = filter ((>= 2) . length) (scc graph) unless (null cycles) $ do let plural = if length cycles > 1 then "s" else ""- errorWithoutStackTrace $ unlines $+ error' $ unlines $ ("ordering not possible due to build dependency cycle" ++ plural ++ ":\n") : intercalate [""] (map (renderCycles . subcycles) cycles) where -- shortest subcycle@@ -300,7 +373,7 @@ case mapMaybe (\ (p,provs,_) -> if br `elem` provs then Just p else Nothing) metadata of [] -> br [p] -> p- ps -> errorWithoutStackTrace $ pkg ++ ": " ++ br ++ " is provided by: " ++ unwords ps+ ps -> error' $ pkg ++ ": " ++ br ++ " is provided by: " ++ unwords ps thd (_,_,c) = c @@ -314,15 +387,59 @@ rpmspecParse :: FilePath -> IO (Maybe String) rpmspecParse spec = do- (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- ExitSuccess -> return $ Just out+ (ok, out, err) <- cmdFull "rpmspec" (["-P", "--define", "ghc_version any"] ++ rpmopts ++ [spec]) ""+ unless (null err) $ warning err+ if ok+ then return $ Just out+ else if lenient then return Nothing else exitFailure - warn :: String -> IO ()- warn = hPutStrLn stderr+ 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+ (out,err) <- cmdStdErr "rpmbuild" ["-br", "--nodeps", spec]+ unless (null err) $+ when verbose $ warning err+ -- Wrote: /current/dir/SRPMS/name-version-release.buildreqs.nosrc.rpm+ cmdLines "rpm" ["-qp", "--requires", last (words out)]++ 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)+createGraph'''' :: Bool -- ^ check for cycles+ -> [String] -- ^ ignored BuildRequires+ -> [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'''' = createGraph4+ -- | A flipped version of subgraph subgraph' :: Gr a b -> [G.Node] -> Gr a b subgraph' = flip G.subgraph@@ -377,4 +494,4 @@ then do let g = G.emap (const ("" :: String)) graph runGraphvizCanvas' (setDirectedness graphToDot quickParams g) Xlib- else errorWithoutStackTrace "please install graphviz first"+ else error' "please install graphviz first"
src/Main.hs view
@@ -45,7 +45,7 @@ depsPackages False <$> rpmOpts <*> verboseOpt <*> excludeOpts <*> ignoredBRopts <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs , Subcommand "rdeps" "sort dependents" $ depsPackages True <$> rpmOpts <*> verboseOpt <*> excludeOpts <*> ignoredBRopts <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs- , Subcommand "layers" "ordered output suitable for a chain-build" $+ , Subcommand "layers" "ordered output of dependency layers" $ layerPackages <$> rpmOpts <*> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs , Subcommand "chain" "ordered output suitable for a chain-build" $ chainPackages <$> rpmOpts <*> verboseOpt <*> lenientOpt <*> combineOpt <*> subdirOpt <*> pkgArgs@@ -61,7 +61,7 @@ lenientOpt = switchWith 'l' "lenient" "Ignore rpmspec errors" combineOpt = switchWith 'c' "combine" "Combine independent packages" subdirOpt = optional (strOptionWith 'd' "dir" "SUBDIR" "Branch directory")- pkgArgs = some (argumentWith str "PKG...")+ pkgArgs = some (strArg "PKG...") componentsOpt = flagWith' Connected 'C' "connected" "Only include connected packages" <|> flagWith' Separate 'i' "independent" "Only list independent packages" <|>@@ -72,7 +72,7 @@ sortPackages :: [String] -> Bool -> Bool -> Components -> Maybe FilePath -> [FilePath] -> IO () sortPackages rpmopts verbose lenient opts mdir pkgs = do- createGraph'' rpmopts verbose lenient True mdir pkgs >>= sortGraph opts+ createGraph2 rpmopts verbose lenient True mdir pkgs >>= sortGraph opts depsPackages :: Bool -> [String] -> Bool-> [String] -> [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO () depsPackages rev rpmopts verbose excludedPkgs ignoredBRs lenient parallel mdir pkgs = do@@ -80,8 +80,8 @@ errorWithoutStackTrace "Please use package directory paths" listDirectory "." >>= -- filter out dotfiles- createGraph''' ignoredBRs rpmopts verbose lenient (not rev) mdir . filter ((/= '.') . head) . filter (`notElem` excludedPkgs) >>=- createGraph'' rpmopts verbose lenient True mdir . dependencyNodes pkgs >>=+ createGraph3 ignoredBRs rpmopts verbose lenient (not rev) mdir . filter ((/= '.') . head) . filter (`notElem` excludedPkgs) >>=+ createGraph2 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))@@ -94,15 +94,16 @@ 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+ graph <- createGraph2 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 :: [String] -> Bool -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO () chainPackages rpmopts verbose lenient combine mdir pkgs = do- graph <- createGraph'' rpmopts verbose lenient True mdir pkgs+ graph <- createGraph2 rpmopts verbose lenient True mdir pkgs if combine then doChain graph else mapM_ (doChain . subgraph' graph) (components graph) where@@ -112,16 +113,16 @@ leavesPackages :: [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO () leavesPackages rpmopts verbose lenient mdir pkgs = do- graph <- createGraph'' rpmopts verbose lenient True mdir pkgs+ graph <- createGraph2 rpmopts verbose lenient True mdir pkgs mapM_ putStrLn $ packageLeaves graph rootPackages :: [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO () rootPackages rpmopts verbose lenient mdir pkgs = do- graph <- createGraph'' rpmopts verbose lenient True mdir pkgs+ graph <- createGraph2 rpmopts verbose lenient True mdir pkgs mapM_ putStrLn $ lowestLayer graph renderPkgGraph :: Bool -> [String] -> Bool -> Bool -> Maybe FilePath -> [FilePath] -> IO () renderPkgGraph dot rpmopts verbose lenient mdir pkgs =- createGraph'''' False [] rpmopts verbose lenient False mdir pkgs >>=+ createGraph4 False [] rpmopts verbose lenient False mdir pkgs >>= if dot then printGraph else renderGraph
test/Spec.hs view
@@ -18,32 +18,32 @@ spec :: Version -> Spec spec rpmver = do- describe "sorting" $ do- it "sort A B" $+ describe "sort" $ do+ it "A B" $ dependencySort [pkg "A", pkg "B"] >>= (`shouldBe` [pkg "B", pkg "A"]) - it "sort 1 2" $+ it "1 2" $ dependencySort [pkg "1", pkg "2"] >>= (`shouldBe` [pkg "2", pkg "1"]) - it "sort A/ B/" $+ it "A/ B/" $ dependencySort [pkg "A/", pkg "B/"] >>= (`shouldBe` [pkg "B/", pkg "A/"]) - it "sort 1/ 2/" $+ it "1/ 2/" $ dependencySort [pkg "1/", pkg "2/"] >>= (`shouldBe` [pkg "2/", pkg "1/"]) - it "sort A.spec B.spec" $+ it "A.spec B.spec" $ dependencySort [pkg "A/A.spec", pkg "B/B.spec"] >>= (`shouldBe` [pkg "B/B.spec", pkg "A/A.spec"]) - it "sort 1.spec 2.spec" $+ it "1.spec 2.spec" $ dependencySort [pkg "1/A.spec", pkg "2/B.spec"] >>= (`shouldBe` [pkg "2/B.spec", pkg "1/A.spec"]) - it "sort A/ B.spec" $+ it "A/ B.spec" $ dependencySort [pkg "A/", pkg "B/B.spec"] >>= (`shouldBe` [pkg "B/B.spec", pkg "A/"]) @@ -51,22 +51,27 @@ dependencySort [pkg "A", pkg "B", pkg "C"] `shouldThrow` anyException - it "sort A B D1.0" $+ it "A B D1.0" $ dependencySort [pkg "A", pkg "B/", pkg "D1.0"] >>= (`shouldBe` [pkg "B/", pkg "D1.0", pkg "A"]) + when (rpmver > makeVersion [4,15,0]) $+ it "dynbr A B" $+ 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"] >>= (`shouldBe` [pkg "C", pkg "B", pkg "A"]) describe "layers" $- it "layers A B" $+ it "A B" $ dependencyLayers [pkg "A", pkg "B"] >>= (`shouldBe` [[pkg "B"], [pkg "A"]]) describe "leaves" $- it "leaves A B D" $+ it "A B D" $ leafPackages [pkg "A", pkg "B", pkg "D1.0"] >>= (`shouldBe` [pkg "A", pkg "D1.0"])
test/pkgs/A/A.spec view
@@ -3,7 +3,7 @@ Release: 1%{?dist} Summary: package A License: GPL-BuildRequires: B+BuildRequires: B-devel %description Test package A