packages feed

fedora-repoquery 0.7.4 → 0.8

raw patch · 9 files changed

+236/−89 lines, 9 filesdep +optparse-applicative

Dependencies added: optparse-applicative

Files

ChangeLog.md view
@@ -1,5 +1,20 @@ # Revision history for fedora-repoquery +## 0.8 (2025-09-23)+- rework dnf option handling with full parsing and completions:+  with free ordering of arguments, releases and options+- no longer outputs "(using system repos)" when no release specified+- `--list-releases` lists in order (was `--list`)+- rename `--arch` to `--repo-arch`+- new `--all-fedora` releases option+- alias `--changelog` to `--changelogs`+- `--queryformat` now accepts format alias 'default'+- add `--help-dnf` option for 'dnf --help' output++## 0.7.4 (2025-08-16)+- Query renderRepoConfig: disable skip_if_unavailable+- Query: don't use dnf --quiet output for --debug+ ## 0.7.3 (2025-06-03) - fix the naming of koji dnf repos - flip the --dl and --debug short options
README.md view
@@ -10,7 +10,7 @@ `$ fedora-repoquery rawhide firefox`  ```-firefox-142.0-1.fc44.x86_64 (fedora-rawhide)+firefox-143.0.1-1.fc44.x86_64 (fedora-rawhide) ```  `$ fedora-repoquery 43 --requires filesystem`@@ -35,25 +35,24 @@ `$ fedora-repoquery eln kernel`  ```-kernel-6.17.0-0.rc1.250814g0cc53520e68b.20.eln151.x86_64 (eln-BaseOS)+kernel-6.17.0-0.rc6.250919g097a6c336d008.53.eln151.x86_64 (eln-BaseOS) ```  Without a release argument, the system yum repo configuration is used: -`$ fedora-repoquery pandoc`+`$ fedora-repoquery pandoc-cli`  ```-pandoc-3.6.4-37.fc43.x86_64 (rawhide)+pandoc-cli-3.6.4-38.fc44.x86_64 (rawhide) ```-but then currently you have to insert `--` before a query option: -`$ fedora-repoquery -- --whatrequires pandoc`+`$ fedora-repoquery --whatrequires pandoc`  ``` R-reprex-2.1.1-2.fc43.noarch (rawhide) R-rmarkdown-2.24-9.fc43.noarch (rawhide)-pandoc-pdf-3.6.4-37.fc43.x86_64 (rawhide)-python3-pypandoc-1.15-6.fc43.noarch (rawhide)+pandoc-pdf-3.6.4-38.fc44.x86_64 (rawhide)+python3-pypandoc-1.15-8.fc44.noarch (rawhide) ```  Use the --time (-T) option to display repo timestamps:@@ -71,7 +70,7 @@  ``` 2025-04-15 01:43:43 +08 <https://mirror.freedif.org/fedora/fedora/linux/releases/42/>-2025-08-16 09:11:49 +08 <https://mirror.freedif.org/fedora/fedora/linux/updates/42/>+2025-09-23 09:11:46 +08 <https://mirror.freedif.org/fedora/fedora/linux/updates/42/> ```  One can also query multiple releases (or arch's):@@ -80,8 +79,9 @@  ``` python3-3.13.2-2.fc42.x86_64 (f42)-python3-3.13.6-1.fc42.x86_64 (f42-updates)-python3-3.14.0~rc1-2.fc43.x86_64 (f43-development)+python3-3.13.7-1.fc42.x86_64 (f42-updates)+python3-3.14.0~rc2-1.fc43.x86_64 (f43-development)+python3-3.14.0~rc3-1.fc43.x86_64 (f43-updates-testing) ```  @@ -89,7 +89,7 @@ `$ fedora-repoquery --version`  ```-0.7.4+0.8 ```  `$ fedora-repoquery --help`@@ -99,16 +99,37 @@  Usage: fedora-repoquery [--version] [-4|--dnf4] [(-q|--quiet) | (-v|--verbose)]                          [--dynamic] [-T|--time] [-K|--koji] -                        [(-m|--mirror URL) | (-d|--dl)] -                        [(-s|--source) | (-A|--all-archs) | [-a|--arch ARCH]] -                        [-t|--testing] [-D|--debug] -                        ((-z|--cache-size) | (-e|--cache-clean-empty) | -                          (-l|--list) | -                          [RELEASE|--]... [REPOQUERY_OPTS]... [PACKAGE]...)+                        [(-m|--mirror URL) | (-d|--dl)] [-F|--all-fedora] +                        [(-s|--source) | (-A|--all-archs) | +                          [-a|--repo-arch ARCH]] [-t|--testing] [-D|--debug] +                        [(-z|--cache-size) | (-e|--cache-clean-empty) | +                          --list-releases | --help-dnf | +                          [--advisories ARG | --advisory-severities ARG | +                            --arch ARG | --available | --bugfix | --bzs ARG | +                            --cves ARG | --disable-modular-filtering | +                            --duplicates | --enhancement | --exactdeps | +                            --extras | (-f|--file ARG) | --installed | +                            --installed-from-repo ARG | --installonly | +                            --latest-limit ARG | --leaves | --newpackage | +                            --providers-of ARG | --recent | --recursive | +                            --security | --srpm | --unneeded | --upgrades | +                            --userinstalled | --whatconflicts ARG | +                            --whatdepends ARG | --whatenhances ARG | +                            --whatobsoletes ARG | --whatprovides ARG | +                            --whatrecommends ARG | --whatrequires ARG | +                            --whatsuggests ARG | --whatsupplements ARG | +                            --conflicts | --depends | --enhances | --files | +                            (-l|--list) | --obsoletes | --provides | +                            --recommends | --requires | --requires-pre | +                            --sourcerpm | --suggests | --supplements | +                            --location | (-i|--info) | +                            (--changelog|--changelogs) | --querytags | +                            (--qf|--queryformat ARG)] +                          [[RELEASE]... [REPOQUERY_OPTS]... [PKGSPECIFIER]...]]    where RELEASE is {fN or N (fedora), 'rawhide', epelN, epelN-next, cN (centos   stream), 'eln'}, with N the release version number.-  https://github.com/juhp/fedora-repoquery#readme+  <https://github.com/juhp/fedora-repoquery#readme>  Available options:   -h,--help                Show this help text@@ -122,14 +143,16 @@   -m,--mirror URL          Fedora mirror [default:                            https://download.fedoraproject.org/pub]   -d,--dl                  Use dl.fp.o+  -F,--all-fedora          Query all Fedora releases   -s,--source              Query source repos   -A,--all-archs           Query all (64 bit) arch repos-  -a,--arch ARCH           Specify arch [default: x86_64]+  -a,--repo-arch ARCH      Specify repo arch [default: x86_64]   -t,--testing             Fedora updates-testing   -D,--debug               Show some debug output   -z,--cache-size          Show total dnf repo metadata cache disksize   -e,--cache-clean-empty   Remove empty dnf caches-  -l,--list                List Fedora versions+  --list-releases          List Fedora versions+  --help-dnf               Show dnf --help ``` The default arch is the system arch. 
fedora-repoquery.cabal view
@@ -1,5 +1,5 @@ name:                fedora-repoquery-version:             0.7.4+version:             0.8 synopsis:            Fedora release repos package query tool description:         A CLI tool for repoquerying Fedora and Centos Stream release packages:@@ -52,6 +52,7 @@                        fedora-releases >= 0.2,                        filepath,                        Glob,+                       optparse-applicative,                        regex-compat,                        safe,                        simple-cmd >= 0.2,
src/BodhiRelease.hs view
@@ -5,8 +5,7 @@   activeFedoraRelease,   activeFedoraReleases,   fedoraReleaseState,-  rawhideFedoraRelease,-  fedoraReleasePostBeta+  rawhideFedoraRelease   ) where @@ -64,11 +63,3 @@   actives <- activeFedoraReleases   let pending = map releaseVersion (filter (\r -> releaseState r == "pending") actives)   return $ read $ maximum (L.delete "eln" pending)--fedoraReleasePostBeta :: Natural -> IO Bool-fedoraReleasePostBeta n = do-  eactive <- activeFedoraRelease n-  return $-    case eactive of-      Left _ -> error' $ "could find F" ++ show n ++ " release (setting)"-      Right rel -> releasePostBeta rel
src/List.hs view
@@ -3,13 +3,17 @@   ) where  import Data.List.Extra+import Data.Ord (Down(Down)) import SimpleCmd ((+-+))  import Release (activeFedoraReleases, BodhiRelease(..))  listVersionsCmd :: IO () listVersionsCmd =-  activeFedoraReleases >>= mapM_ printRelease . sortOn releaseState+  activeFedoraReleases >>= mapM_ printRelease . sortOn releaseSorter   where     printRelease (Release _version state branch _composed _postbeta) =       putStrLn $ branch +-+ state++    releaseSorter rel =+      (Down (releaseState rel), Down(releaseVersion rel))
src/Main.hs view
@@ -13,34 +13,48 @@ #endif   ) #endif-import Control.Monad (forM_, when)-import Data.Either (partitionEithers)-import Data.Tuple (swap)+import Control.Monad (forM_, unless, when)+import Data.Either (rights, partitionEithers)+#if !MIN_VERSION_base(4,11,0)+import Data.Semigroup ((<>))+#endif+import Options.Applicative (flag', long, short, strOption, #if !MIN_VERSION_simple_cmd_args(0,1,7)-import Options.Applicative (eitherReader, maybeReader, ReadM)+    eitherReader #endif-import SimpleCmd ((+-+), warning)+    )+import SimpleCmd ((+-+), cmd_, error', warning) import SimpleCmdArgs+import System.Environment (getArgs, withArgs) import System.IO (BufferMode(NoBuffering), hSetBuffering, stdout)  import Arch import Cache (cacheSize, cleanEmptyCaches) import List (listVersionsCmd) import Paths_fedora_repoquery (version)-import Query (repoqueryCmd)-import Release (showReleaseCmd, downloadServer)+import Query+import Release (activeFedoraReleases, downloadServer, releaseBranch,+                showReleaseCmd) import Types (Mirror(..), Release (System), RepoSource(..), Verbosity(..),               eitherRelease) -data Command = Query [String] | CacheSize | CacheEmpties | List+data Command = Query [DnfOption] [String]+             | CacheSize | CacheEmpties | DnfHelp | ReleaseList  main :: IO () main = do   hSetBuffering stdout NoBuffering+  args <- getArgs+  if null args+    then withArgs ["--help"] main'+    else main'++main' :: IO ()+main' = do   sysarch <- getSystemArch-  simpleCmdArgs' (Just version) "fedora-repoquery tool for querying Fedora repos for packages."+  simpleCmdArgs (Just version) "fedora-repoquery tool for querying Fedora repos for packages."     ("where RELEASE is {fN or N (fedora), 'rawhide', epelN, epelN-next, cN (centos stream), 'eln'}, with N the release version number." +-+-     "https://github.com/juhp/fedora-repoquery#readme") $+     "<https://github.com/juhp/fedora-repoquery#readme>") $     runMain sysarch     <$> switchWith '4' "dnf4" "Use dnf4 instead of dnf5 (if available)"     <*> (flagWith' Quiet 'q' "quiet" "Avoid output to stderr" <|>@@ -51,34 +65,122 @@           <$> switchWith 'K' "koji" "Use Koji buildroot"           <*> ((Mirror <$> strOptionWith 'm' "mirror" "URL" ("Fedora mirror [default: " ++ downloadServer ++ "]")) <|>                flagWith DownloadFpo DlFpo 'd' "dl" "Use dl.fp.o"))+    -- FIXME: --all-epel and --all-releases+    <*> switchWith 'F' "all-fedora" "Query all Fedora releases"     <*> (flagWith' [Source] 's' "source" "Query source repos" <|>          flagWith' allArchs 'A' "all-archs" "Query all (64 bit) arch repos" <|>-         many (optionWith (eitherReader eitherArch) 'a' "arch" "ARCH" ("Specify arch [default:" +-+ showArch sysarch ++ "]")))+         many (optionWith (eitherReader eitherArch) 'a' "repo-arch" "ARCH" ("Specify repo arch [default:" +-+ showArch sysarch ++ "]")))     <*> switchWith 't' "testing" "Fedora updates-testing"     <*> switchWith 'D' "debug" "Show some debug output"     <*> (flagWith' CacheSize 'z' "cache-size" "Show total dnf repo metadata cache disksize"          <|> flagWith' CacheEmpties 'e' "cache-clean-empty" "Remove empty dnf caches"-         <|> flagWith' List 'l' "list" "List Fedora versions"-         <|> Query <$> some (strArg "[RELEASE|--]... [REPOQUERY_OPTS]... [PACKAGE]..."))+         <|> flagLongWith' ReleaseList "list-releases" "List Fedora versions"+         <|> flagLongWith' DnfHelp "help-dnf" "Show dnf --help"+         <|> Query <$> many queryOptions <*> many (strArg "[RELEASE]... [REPOQUERY_OPTS]... [PKGSPECIFIER]...")) -runMain :: Arch -> Bool -> Verbosity -> Bool -> Bool -> RepoSource -> [Arch]-        -> Bool -> Bool -> Command -> IO ()-runMain sysarch dnf4 verbose dynredir time reposource archs testing debug command = do+-- man 8 dnf-repoquery (dnf5-5.2.17.0-2.fc44)+-- https://github.com/rpm-software-management/dnf5/blob/main/doc/commands/repoquery.8.rst++dnfFlag, dnfOption :: String -> Parser DnfOption+dnfFlag o = flag' (DnfFlag o) (long o)+dnfOption o = DnfOption o <$> strOption (long o)+dnfFlag', dnfOption' :: Char -> String -> Parser DnfOption+dnfFlag' s l = flag' (DnfFlag l) (short s <> long l)+dnfOption' s l = DnfOption l <$> strOption (short s <> long l)+dnfFlag'', dnfOption'' :: String -> String -> Parser DnfOption+dnfFlag'' s l = flag' (DnfFlag l) (long s <> long l)+dnfOption'' s l = DnfOption l <$> strOption (long s <> long l)++queryOptions :: Parser DnfOption+queryOptions =+  -- # OPTIONS+  dnfOption "advisories"+  <|> dnfOption "advisory-severities"+  <|> dnfOption "arch"+  <|> dnfFlag "available" -- default+  <|> dnfFlag "bugfix"+  <|> dnfOption "bzs"+  <|> dnfOption "cves"+  <|> dnfFlag "disable-modular-filtering"+  <|> dnfFlag "duplicates"+  <|> dnfFlag "enhancement"+  <|> dnfFlag "exactdeps"+  <|> dnfFlag "extras"+  <|> dnfOption' 'f' "file"+  <|> dnfFlag "installed"+  <|> dnfOption "installed-from-repo"+  <|> dnfFlag "installonly"+  <|> dnfOption "latest-limit"+  <|> dnfFlag "leaves"+  <|> dnfFlag "newpackage"+  <|> dnfOption "providers-of" -- for certain commands see manpage+  <|> dnfFlag "recent"+  <|> dnfFlag "recursive" -- with --whatrequires or --providers-of only+  <|> dnfFlag "security"+  <|> dnfFlag "srpm"+  <|> dnfFlag "unneeded"+  <|> dnfFlag "upgrades"+  <|> dnfFlag "userinstalled"+  <|> dnfOption "whatconflicts"+  <|> dnfOption "whatdepends"+  <|> dnfOption "whatenhances"+  <|> dnfOption "whatobsoletes"+  <|> dnfOption "whatprovides"+  <|> dnfOption "whatrecommends"+  <|> dnfOption "whatrequires"+  <|> dnfOption "whatsuggests"+  <|> dnfOption "whatsupplements"+  -- # FORMATTING+  <|> dnfFlag "conflicts"+  <|> dnfFlag "depends"+  <|> dnfFlag "enhances"+  <|> dnfFlag "files"+  <|> dnfFlag' 'l' "list"+  <|> dnfFlag "obsoletes"+  <|> dnfFlag "provides"+  <|> dnfFlag "recommends"+  <|> dnfFlag "requires"+  <|> dnfFlag "requires-pre"+  <|> dnfFlag "sourcerpm"+  <|> dnfFlag "suggests"+  <|> dnfFlag "supplements"+  <|> dnfFlag "location"+  <|> dnfFlag' 'i' "info"+  <|> dnfFlag'' "changelog" "changelogs"+  <|> dnfFlag "querytags"+  <|> dnfOption'' "qf" "queryformat"++runMain :: Arch -> Bool -> Verbosity -> Bool -> Bool -> RepoSource -> Bool+        -> [Arch] -> Bool -> Bool -> Command -> IO ()+runMain sysarch dnf4 verbose dynredir time reposource allreleases archs testing debug command = do   case command of     CacheSize -> cacheSize     CacheEmpties -> cleanEmptyCaches-    List -> listVersionsCmd-    Query relargs ->+    ReleaseList -> listVersionsCmd+    DnfHelp -> cmd_ (if dnf4 then "dnf4" else "dnf") ["--help"]+    Query opts relargs ->       -- spanJust from utility-ht nicer but this gets us enough-      let (releases,args) = swap $ partitionEithers $ map eitherRelease relargs+      let (args,releases) = partitionEithers $ map eitherRelease relargs       in do-        when (null releases && verbose /= Quiet) $+        unless (null releases || not allreleases) $+          error' "cannot specify releases and --all-releases"+        when (null releases && not allreleases) $+          when (verbose == Verbose || debug) $           warning "(using system repos)"-        forM_ (if null releases then [System] else releases) $ \release ->-          if null args+        releaselist <-+          if null releases+          then+            if allreleases+            then+              rights . map (eitherRelease . releaseBranch)+              <$> activeFedoraReleases+            else return [System]+          else return releases+        forM_ releaselist $ \release ->+          if null args && null opts           then if null archs                then showReleaseCmd debug dynredir reposource release sysarch Nothing testing                else forM_ archs $ \arch -> showReleaseCmd debug dynredir reposource release sysarch (Just arch) testing           else-            let multiple = length releases > 1 || length archs > 1-            in repoqueryCmd dnf4 debug verbose multiple dynredir time release reposource sysarch archs testing args+            let multiple = length releaselist > 1 || length archs > 1+            in repoqueryCmd dnf4 debug verbose multiple dynredir time release reposource sysarch archs testing opts args
src/Query.hs view
@@ -2,6 +2,7 @@  module Query (   repoqueryCmd,+  DnfOption(..)   ) where  import Control.Monad.Extra@@ -19,11 +20,18 @@ import Types import URL (FileDir(Dir), URL, renderUrl) --- from dnf5 repoquery.cpp pkg_attrs_options-pkgAttrsOptions :: [String]-pkgAttrsOptions =-  map ("--" ++)+data DnfOption =+  DnfFlag String | DnfOption String String+  deriving Eq++renderOption :: DnfOption -> String+renderOption (DnfFlag o) = '-' : '-' : o+renderOption (DnfOption o v) = '-' : '-' : o ++ '=' : v++noQueryFormatOptions :: [String]+noQueryFormatOptions =   [+    -- from dnf5 repoquery.cpp pkg_attrs_options     "conflicts",     "depends",     "enhances",@@ -31,20 +39,27 @@     "provides",     "recommends",     "requires",-    "requires_pre",+    "require-pre",     "suggests",-    "supplements"+    "supplements",+    -- others conflicting with '--qf'+    "info",+    "list",+    "location",+    "source",+    "queryformat",+    "changelogs"   ]  repoqueryCmd :: Bool -> Bool -> Verbosity -> Bool -> Bool -> Bool -> Release-             -> RepoSource -> Arch -> [Arch] -> Bool -> [String] -> IO ()-repoqueryCmd dnf4 debug verbose multiple dynredir checkdate release reposource sysarch archs testing args = do+             -> RepoSource -> Arch -> [Arch] -> Bool -> [DnfOption]+             -> [String] -> IO ()+repoqueryCmd dnf4 debug verbose multiple dynredir checkdate release reposource sysarch archs testing opts args = do   forM_ (if null archs then [sysarch] else archs) $ \arch -> do     repoConfigs <-       if release == System       then return []       else getRelease debug dynredir True checkdate reposource release sysarch (Just arch) testing-    let qfAllowed = not $ any (`elem` ["-i","--info","-l","--list","-s","--source","--nvr","--nevra","--envra","--qf","--queryformat", "--changelog"] ++ pkgAttrsOptions) args     -- dnf5 writes repo update output to stdout     -- https://github.com/rpm-software-management/dnf5/issues/1361     -- but seems to cache better@@ -59,11 +74,11 @@                   ["--quiet" | verbose /= Verbose || not debug] ++                   -- https://bugzilla.redhat.com/show_bug.cgi?id=1876828                   ["--disableplugin=subscription-manager" | rhsm] ++-                  (if qfAllowed then ["--qf", queryformat] else []) +++                  ["--queryformat=" ++ queryformat | queryFormatAllowed] ++                   -- drop modules for F39+                   ["--setopt=module_platform_id=platform:" ++ show release] ++                   concatMap renderRepoConfig repoConfigs ++-                  tweakedArgs (isJust mdnf5)+                  map (renderOption . tweakQfOpt (isJust mdnf5)) opts ++ args     -- FIXME drop "/usr/bin/"?     let dnf = fromMaybe "/usr/bin/dnf-3" mdnf5     when debug $@@ -73,26 +88,20 @@       unless (not checkdate || release == System || multiple) $ warning ""       putStrLn $ intercalate "\n" res   where-    tweakedArgs dnf5 =-      if not dnf5-      then args-      else tweakQfOpt $ map tweakInfo args-      where-        -- dnf5 only has --info not -i-        tweakInfo "-i" = "--info"-        tweakInfo arg = arg+    queryFormatAllowed =+      not $ any (`elem` map DnfFlag noQueryFormatOptions) opts +    tweakQfOpt dnf5 opt =+        case opt of+          DnfOption "queryformat" fv -> DnfOption "queryformat" (tweakQf fv)+          _ -> opt+      where         -- dnf5 doesn't append \n to queryformat-        tweakQfOpt (x:y:rest) | x `elem` ["--qf","--queryformat"] =-                                   x : tweakQf y : rest-                              | otherwise = x : tweakQfOpt (y:rest)-        tweakQfOpt xs = xs--        tweakQf qf =-          expandQf qf ++-          case lastMay qf of-            Just lc -> if isSpace lc then "" else "\n"-            Nothing -> ""+        tweakQf fv =+          expandQf fv +++          case lastMay fv of+            Just lc | dnf5 -> if isSpace lc then "" else "\n"+            _ -> ""          expandQf qf =           case lower qf of@@ -100,8 +109,10 @@             "nv" -> "%{name}-%{version}"             "nvr" -> expandQf "nv" ++ "-%{release}"             "nvra" -> expandQf "nvr" <.> "%{arch}"+            -- fixme? check order correct for epoch             "envr" -> "%{epoch}:" ++ expandQf "nvr"             "envra" -> "%{epoch}:" ++ expandQf "nvra"+            "default" -> "%{full_nevra}"             _ -> qf  renderRepoConfig :: (String, URL) -> [String]
src/Release.hs view
@@ -32,8 +32,8 @@ showReleaseCmd debug dynredir reposource release sysarch march testing =   void $ getRelease debug dynredir False True reposource release sysarch march testing -getRelease :: Bool -> Bool -> Bool -> Bool -> RepoSource-            -> Release -> Arch -> Maybe Arch -> Bool -> IO [(String, URL)]+getRelease :: Bool -> Bool -> Bool -> Bool -> RepoSource -> Release -> Arch+           -> Maybe Arch -> Bool -> IO [(String, URL)] getRelease debug dynredir warn checkdate reposource@(RepoSource koji _mirror) release sysarch march testing = do   let arch = fromMaybe sysarch march   (url,path) <- getURL debug dynredir reposource release arch
test/tests.hs view
@@ -18,7 +18,7 @@  -- copied from dl-fedora branched :: Int-branched = 42+branched = 43 current, previous, prevprev, rawhide :: String current = show branched previous = show (branched - 1)