fedora-repoquery 0.2 → 0.3
raw patch · 8 files changed
+119/−72 lines, 8 files
Files
- ChangeLog.md +11/−0
- README.md +16/−12
- fedora-repoquery.cabal +1/−1
- src/List.hs +4/−4
- src/Main.hs +10/−9
- src/Query.hs +43/−27
- src/Types.hs +13/−3
- test/tests.hs +21/−16
ChangeLog.md view
@@ -1,5 +1,16 @@ # Revision history for fedora-repoquery +## 0.3 (2023-11-09)+- Query: no --qf with --changelog+- small OS versions now map to centos-stream+- use hostname not full url for mirror repo name+- repo urls should end with a slash+- improve tests to fail if no results+- map failing yzyu.jp http/3 mirror to main one+- development/39 also needs os/+- showRelease: reformat Centos and ELN repos+- default to system arch and introduce sysarch and march+ ## 0.2 (2023-05-12) - support fedora and epel testing repos - fix fedora archive urls
README.md view
@@ -6,29 +6,32 @@ ## Usage Usage examples: -`fdrq rawhide firefox`+- `fdrq rawhide firefox` -`fdrq 38 --requires podman`+- `fdrq 38 --requires podman` -`fdrq epel9 ghc`+- `fdrq epel9 ghc` -`fdrq c9 bash`+- `fdrq c9 bash` -`fdrq eln kernel`+- `fdrq eln kernel` etc -```shellsession-$ fdrq --version+`$ fdrq --version`+``` 0.2-$ fdrq --help+```+`$ fdrq --help`+``` fedora-repoquery tool for querying Fedora repos for packages. -Usage: fdrq [--version] [(-q|--quiet) | (-v|--verbose)] [-K|--koji]- [--devel-channel | --test-channel] [(-m|--mirror URL) | (-D|--dl)]- [(-s|--source) | (-a|--arch ARCH)] [-t|--testing] [-d|--debug]- ((-z|--cache-size) | (-e|--cache-clean-empty) | (-l|--list) |+Usage: fdrq [--version] [(-q|--quiet) | (-v|--verbose)] [-K|--koji] + [--devel-channel | --test-channel] [(-m|--mirror URL) | (-D|--dl)] + [(-s|--source) | (-a|--arch ARCH)] [-t|--testing] [-d|--debug] + ((-z|--cache-size) | (-e|--cache-clean-empty) | (-l|--list) | RELEASE [[REPOQUERY_OPTS] [PACKAGE]...])+ 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@@ -52,6 +55,7 @@ -e,--cache-clean-empty Remove empty dnf caches -l,--list List Fedora versions ```+The default arch is the system arch. ## Installation fedora-repoquery can be installed from
fedora-repoquery.cabal view
@@ -1,5 +1,5 @@ name: fedora-repoquery-version: 0.2+version: 0.3 synopsis: Fedora repoquery tool description: CLI tool for querying the location and version of Fedora packages
src/List.hs view
@@ -14,16 +14,16 @@ import Types import URL -listVersionsCmd :: Verbosity -> RepoSource -> IO ()+listVersionsCmd :: Verbosity -> RepoSource -> Arch -> IO () -- listVersionsCmd _verbose _reposource = -- error' "listing Centos Stream versions not supported"--- --showReleaseCmd mgr server (RepoCentosStream chan) X86_64+-- --showReleaseCmd mgr server (RepoCentosStream chan) arch -- listVersionsCmd _ RepoKoji = -- error' "listing Koji versions not supported"-listVersionsCmd verbose reposource = do+listVersionsCmd verbose reposource arch = do mgr <- httpManager -- FIXME handle non-fedora versions (eg epel)- (url,_) <- getFedoraServer False mgr reposource (fedoraTop X86_64) ["releases"]+ (url,_) <- getFedoraServer False mgr reposource (fedoraTop arch) ["releases"] let rurl = renderUrl url unless (verbose == Quiet) $ warning $! "<" ++ rurl ++ ">" -- FIXME filter very old releases
src/Main.hs view
@@ -16,7 +16,7 @@ #if !MIN_VERSION_simple_cmd_args(0,1,7) import Options.Applicative (eitherReader, maybeReader, ReadM) #endif-import SimpleCmd ((+-+))+import SimpleCmd (cmd, (+-+)) import SimpleCmdArgs import System.IO (BufferMode(NoBuffering), hSetBuffering, stdout) @@ -33,10 +33,11 @@ main :: IO () main = do hSetBuffering stdout NoBuffering+ sysarch <- readArch <$> cmd "rpm" ["--eval", "%{_arch}"] 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") $- runMain+ runMain sysarch <$> (flagWith' Quiet 'q' "quiet" "Avoid output to stderr" <|> flagWith Normal Verbose 'v' "verbose" "Show stderr from dnf repoquery") <*> (RepoSource <$> switchWith 'K' "koji" "Use Koji buildroot"@@ -44,8 +45,8 @@ flagLongWith ChanProd ChanTest "test-channel" "Use eln test compose [default: production]") <*> ((Mirror <$> strOptionWith 'm' "mirror" "URL" ("Fedora mirror [default: " ++ downloadServer ++ "]")) <|> flagWith DownloadFpo DlFpo 'D' "dl" "Use dl.fp.o"))- <*> (flagWith' Source 's' "source" "Query source repos" <|>- optionalWith (eitherReader readArch) 'a' "arch" "ARCH" "Specify arch [default: x86_64]" X86_64)+ <*> optional (flagWith' Source 's' "source" "Query source repos" <|>+ optionWith (eitherReader eitherArch) 'a' "arch" "ARCH" ("Specify 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"@@ -56,13 +57,13 @@ releaseM :: ReadM Release releaseM = maybeReader readRelease -runMain :: Verbosity -> RepoSource -> Arch -> Bool -> Bool -> Command -> IO ()-runMain verbose reposource arch testing debug command = do+runMain :: Arch -> Verbosity -> RepoSource -> Maybe Arch -> Bool -> Bool -> Command -> IO ()+runMain sysarch verbose reposource march testing debug command = do case command of CacheSize -> cacheSize CacheEmpties -> cleanEmptyCaches- List -> listVersionsCmd verbose reposource+ List -> listVersionsCmd verbose reposource sysarch Query release args -> do if null args- then showReleaseCmd debug reposource release arch testing- else repoqueryCmd debug verbose release reposource arch testing args+ then showReleaseCmd debug reposource release sysarch march testing+ else repoqueryCmd debug verbose release reposource sysarch march testing args
src/Query.hs view
@@ -10,8 +10,11 @@ import Control.Monad.Extra import qualified Data.ByteString.Char8 as B-import qualified Data.List as L+import qualified Data.List.Extra as L import Data.Maybe+#if !MIN_VERSION_base(4,11,0)+import Data.Monoid ((<>))+#endif import Data.Time.LocalTime (utcToLocalZonedTime) import Fedora.Bodhi import Network.HTTP.Directory@@ -26,15 +29,16 @@ import Types import URL -showReleaseCmd :: Bool -> RepoSource -> Release -> Arch -> Bool -> IO ()-showReleaseCmd debug reposource release arch testing =- void $ showRelease debug Normal False reposource release arch testing+showReleaseCmd :: Bool -> RepoSource -> Release -> Arch -> Maybe Arch -> Bool+ -> IO ()+showReleaseCmd debug reposource release sysarch march testing =+ void $ showRelease debug Normal False reposource release sysarch march testing -repoqueryCmd :: Bool -> Verbosity -> Release -> RepoSource -> Arch -> Bool- -> [String] -> IO ()-repoqueryCmd debug verbose release reposource arch testing args = do- repoConfigs <- showRelease debug verbose True reposource release arch testing- let qfAllowed = not $ any (`elem` ["-i","--info","-l","--list","-s","--source","--nvr","--nevra","--envra","-qf","--queryformat"]) args+repoqueryCmd :: Bool -> Verbosity -> Release -> RepoSource -> Arch+ -> Maybe Arch -> Bool -> [String] -> IO ()+repoqueryCmd debug verbose release reposource sysarch march testing args = do+ repoConfigs <- showRelease debug verbose True reposource release sysarch march testing+ let qfAllowed = not $ any (`elem` ["-i","--info","-l","--list","-s","--source","--nvr","--nevra","--envra","-qf","--queryformat", "--changelog"]) args queryformat = "%{name}-%{version}-%{release}.%{arch} (%{repoid})" -- LANG=C.utf8 rhsm <- doesFileExist "/etc/dnf/plugins/subscription-manager.conf"@@ -68,17 +72,17 @@ Fedora _ | repo /= "releases" -> '-':repo _ -> "" -repoConfigArgs :: RepoSource -> Arch -> Release- -> (String,URL) -> (String,(URL,[String]))+repoConfigArgs :: RepoSource -> Arch -> Maybe Arch -> Release -> (String,URL)+ -> (String,(URL,[String])) -- non-koji-repoConfigArgs (RepoSource False _chan mirror) arch release (repo,url) =- -- FIXME default to system arch- let archsuffix = if arch == X86_64 then "" else "-" ++ showArch arch+repoConfigArgs (RepoSource False _chan mirror) sysarch march release (repo,url) =+ let arch = fromMaybe sysarch march+ archsuffix = if arch == sysarch then "" else "-" ++ showArch arch reponame = repoVersion release repo ++ archsuffix ++ case mirror of DownloadFpo -> "" Mirror serv ->- '-' : subRegex (mkRegex "https?://") serv ""+ '-' : takeWhile (/= '/') (subRegex (mkRegex "https?://") serv "") DlFpo -> "-dl.fpo" path = case release of@@ -86,21 +90,22 @@ ELN -> [repo, showArch arch] ++ (if arch == Source then ["tree"] else ["os"]) EPEL n -> (if n >= 7 then ("Everything" :) else id) [showArch arch] EPELNext _n -> ["Everything", showArch arch]- Fedora _ -> ["Everything", showArch arch] ++ (if arch == Source then ["tree"] else ["os" | repo == "releases"])+ Fedora _ -> ["Everything", showArch arch] ++ (if arch == Source then ["tree"] else ["os" | repo `elem` ["releases","development"]]) Rawhide -> ["Everything", showArch arch, if arch == Source then "tree" else "os"]- in (reponame, (url, path))+ in (reponame, (url, path ++ ["/"])) -- koji-repoConfigArgs (RepoSource True _chan _mirror) arch release (repo,url) =+repoConfigArgs (RepoSource True _chan _mirror) sysarch march release (repo,url) = let (compose,path) = case release of Rawhide -> (["repos", show release, "latest"],"") _ -> (["repos", show release ++ "-build/latest"],"")+ arch = fromMaybe sysarch march reponame = repo ++ "-" ++ show release ++ "-build" ++- if arch == X86_64 then "" else "-" ++ showArch arch+ if arch == sysarch then "" else "-" ++ showArch arch in (reponame, (url +//+ compose, [path, showArch arch, ""])) -- repoConfigArgs url (RepoCentosStream chan) arch release repo = -- let (compose,path) = (["composes", channel chan, "latest-CentOS-Stream", "compose"], repo)--- reponame = repo ++ "-Centos-" ++ show release ++ "-Stream" ++ "-" ++ show chan ++ if arch == X86_64 then "" else "-" ++ showArch arch+-- reponame = repo ++ "-Centos-" ++ show release ++ "-Stream" ++ "-" ++ show chan ++ if arch == sysarch then "" else "-" ++ showArch arch -- in (reponame, (url +//+ compose, [path, showArch arch, "os/"])) renderRepoConfig :: (String, URL) -> [String]@@ -108,17 +113,22 @@ ["--repofrompath", name ++ "," ++ renderUrl url, "--repo", name] showRelease :: Bool -> Verbosity -> Bool -> RepoSource -> Release -> Arch- -> Bool -> IO [(String, URL)]-showRelease debug verbose warn reposource@(RepoSource koji _chan _mirror) release arch testing = do+ -> Maybe Arch -> Bool -> IO [(String, URL)]+showRelease debug verbose warn reposource@(RepoSource koji _chan _mirror) release sysarch march testing = do mgr <- httpManager+ let arch = fromMaybe sysarch march (url,path) <- getURL debug mgr reposource release arch let urlpath = url +//+ path when debug $ putStrLn $ renderUrl urlpath repos <- case release of -- RepoKoji -> ["koji-fedora"]- Centos n -> return [("BaseOS",urlpath), ("AppStream",url), (if n >= 9 then "CRB" else "PowerTools",url)]- ELN -> return [("BaseOS",urlpath), ("AppStream",urlpath), ("CRB",urlpath)]+ Centos n -> return [("BaseOS",urlpath),+ ("AppStream",url),+ (if n >= 9 then "CRB" else "PowerTools",url)]+ ELN -> return [("BaseOS",urlpath),+ ("AppStream",urlpath),+ ("CRB",urlpath)] Rawhide -> return [("development", urlpath)] Fedora n -> do pending <- pendingFedoraRelease n@@ -133,7 +143,7 @@ [("epel-testing",url +//+ ["testing", show n]) | testing] EPELNext _n -> return [("epelnext",urlpath)] forM repos $ \repourl -> do- let (reponame,(url',path')) = repoConfigArgs reposource arch release repourl+ let (reponame,(url',path')) = repoConfigArgs reposource sysarch march release repourl baserepo = url' +//+ path' when debug $ do putStrLn $ "url" +-+ renderUrl url'@@ -203,7 +213,7 @@ EPEL n -> getFedoraServer debug mgr reposource epelTop [show n] EPELNext n -> getFedoraServer debug mgr reposource (epelTop ++ ["next"]) [show n] -- FIXME hardcoded- Fedora n | n < 36 ->+ Fedora n | n < 37 -> return (URL "https://archives.fedoraproject.org/pub/archive" +//+ fedoraTop arch, ["releases", show n]) -- FIXME handle rawhide version@@ -234,10 +244,16 @@ warning $ "no redirect for" +-+ rurl return (URL downloadServer +//+ top,path) Just actual -> do+ let actual' =+ case B.stripPrefix "https://ftp.yzyu.jp/" actual of+ Nothing -> actual+ Just rest -> "https://ftp.yz.yamagata-u.ac.jp/" <> rest when debug $ do warning rurl warning $ "redirected to" +-+ show actual- return (URL $ removeSubpath path $ B.unpack actual, path)+ when (actual /= actual') $+ warning $ "replacing" +-+ B.unpack actual+ return (URL $ removeSubpath path $ B.unpack actual', path) -- FIXME how to handle any path Mirror serv -> return (URL serv,path) DlFpo -> return (URL "https://dl.fedoraproject.org/pub" +//+ top, path)
src/Types.hs view
@@ -2,6 +2,7 @@ module Types ( Arch(..),+ eitherArch, readArch, showArch, Mirror(..),@@ -17,6 +18,7 @@ import Data.Char (isDigit) import Data.List.Extra import Numeric.Natural+import SimpleCmd (error') --import Distribution.Fedora.Repoquery @@ -32,8 +34,8 @@ | I386 deriving Eq -readArch :: String -> Either String Arch-readArch s =+eitherArch :: String -> Either String Arch+eitherArch s = case lower s of "source" -> Right Source "x86_64" -> Right X86_64@@ -44,6 +46,10 @@ "i386" -> Right I386 _ -> Left $ "unknown arch: " ++ s +readArch :: String -> Arch+readArch =+ either error' id . eitherArch+ showArch :: Arch -> String showArch Source = "source" showArch X86_64 = "x86_64"@@ -76,6 +82,9 @@ data Release = EPEL Natural | EPELNext Natural | Centos Natural | Fedora Natural | ELN | Rawhide deriving (Eq, Ord) +newestRHEL :: Natural+newestRHEL = 10+ -- | Read a Release name, otherwise return an error message eitherRelease :: String -> Either String Release eitherRelease "rawhide" = Right Rawhide@@ -88,7 +97,8 @@ eitherRelease ('C':n) | all isDigit n = let r = read n in Right (Centos r) eitherRelease "eln" = Right ELN eitherRelease ('f':ns) | all isDigit ns = let r = read ns in Right (Fedora r)-eitherRelease ns | all isDigit ns = let r = read ns in Right (Fedora r)+eitherRelease ns | all isDigit ns = let r = read ns in+ Right $ (if r <= newestRHEL then Centos else Fedora) r eitherRelease cs = Left $ cs ++ " is not a known os release" -- | Read a Fedora Release name
test/tests.hs view
@@ -1,29 +1,34 @@+import Data.Maybe (fromMaybe, isNothing, maybeToList) import Control.Monad (unless) import SimpleCmd -fdrq :: [String] -> IO ()-fdrq args = do+fdrq :: ([String],Maybe String) -> IO ()+fdrq (args,mpkg) = do putStrLn ""- putStrLn $ "# " ++ unwords args+ putStrLn $ "# " ++ unwords args +-+ fromMaybe "" mpkg let debug = False- (ok, out, err) <- cmdFull "fdrq" (["-d" | debug] ++ args) ""+ (ok, out, err) <- cmdFull "fdrq" (["-d" | debug] ++ args ++ maybeToList mpkg) "" if null err- then if null out- then error' "no output"- else unless (length args == 1) $ error' "stderr empty"+ then unless (isNothing mpkg) $ putStrLn "stderr empty" else putStrLn err- putStrLn out+ if null out+ then unless (isNothing mpkg) $ error' "no output"+ else putStrLn out unless ok $ error' "failed" -tests :: [[String]]+tests :: [([String],Maybe String)] tests =- [["rawhide", "coreutils"]- ,["38", "fontconfig"]- ,["-t", "37", "podman"]- ,["eln", "ibus"]- ,["epel9", "ghc"]- ,["c9", "kernel"]- ,["c8", "pandoc"]+ [(["rawhide"], Nothing)+ ,(["39"], Nothing)+ ,(["38"], Nothing)+ ,(["rawhide"], Just "coreutils")+ ,(["39"], Just "bash")+ ,(["38"], Just "fontconfig")+ ,(["-t", "38"], Just "podman")+ ,(["eln"], Just "ibus")+ ,(["epel9"], Just "ghc")+ ,(["c9"], Just "kernel")+ ,(["c8"], Just "pandoc") ] main :: IO ()