packages feed

pagure-cli 0.2.2 → 0.2.3

raw patch · 4 files changed

+123/−71 lines, 4 filesdep +extradep +vectordep ~pagure

Dependencies added: extra, vector

Dependency ranges changed: pagure

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Changelog +## 0.2.3 (2026-02-11)+- hide output of empty lists and object by default (behind --show-empty)+- add 'contributors' command+- use pagureGroupRepos from pagure-0.2.1+ ## 0.2.2 (2024-05-06) - new add group and groupinfo commands - help: order commands with better grouping
README.md view
@@ -30,10 +30,10 @@  Count projects of a user: -`$ pagure user --server pagure.io --count mattdm`+`$ pagure user --server pagure.io --count jspaleta`  ```-120+11 ```  ### List groups:@@ -47,7 +47,13 @@ `$ pagure group budgie-sig`  ```+rpms/bluejay+rpms/budgie-desktop-services+rpms/budgie-display-configurator+rpms/gtklock+rpms/gtk-session-lock rpms/libxfce4windowing+rpms/pocillo-gtk-theme rpms/sassc rpms/wlrctl ```@@ -55,7 +61,7 @@ `$ pagure group -c rust-sig`  ```-3093+4266 ```  ## Help@@ -63,7 +69,7 @@ `$ pagure --version`  ```-0.2.2+0.2.3 ```  `$ pagure --help`@@ -86,6 +92,7 @@   project                  show project details   branches                 list project branches   git-url                  show project repo's git urls+  contributors             show project repo's contributors   issues                   list project issues   issue                    show project issue   users                    list users@@ -98,7 +105,7 @@   ## Installation-pagure-cli is packaged in Fedora and EPEL 9: <https://src.fedoraproject.org/rpms/pagure-cli>+pagure-cli is packaged in Fedora and EPEL: <https://src.fedoraproject.org/rpms/pagure-cli>  ## Build from source To build the latest release you will need cabal-install and ghc, or stack:
pagure-cli.cabal view
@@ -1,6 +1,6 @@ cabal-version:       1.18 name:                pagure-cli-version:             0.2.2+version:             0.2.3 synopsis:            A Pagure gitforge query tool description:         A command-line Pagure (gitforge) client for querying                      and listing projects, users, groups, and issues.@@ -10,14 +10,15 @@ license-file:        LICENSE author:              Jens Petersen <juhpetersen@gmail.com> maintainer:          Jens Petersen <juhpetersen@gmail.com>-copyright:           2019-2020,2022,2024 Jens Petersen+copyright:           2019-2020,2022,2024-2026 Jens Petersen category:            Utility build-type:          Simple extra-doc-files:     README.md                      CHANGELOG.md 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.4, GHC == 9.0.2, GHC == 9.2.8,-                     GHC == 9.4.8, GHC == 9.6.5, GHC == 9.8.2+                     GHC == 9.4.8, GHC == 9.6.6, GHC == 9.8.4, GHC == 9.10.3,+                     GHC == 9.12.3  source-repository head   type:                git@@ -30,14 +31,16 @@                      , aeson-pretty                      , base < 5                      , bytestring+                     , extra                      , filepath                      , http-query                      , optparse-applicative-                     , pagure >= 0.2+                     , pagure >= 0.2.1                      , simple-cmd                      , simple-cmd-args >= 0.1.6                      , text                      , unordered-containers+                     , vector                      , yaml    if impl(ghc<8.0)
src/Main.hs view
@@ -11,7 +11,7 @@                             (<|>) #endif                            )-import Control.Monad (unless, when)+import Control.Monad.Extra (unless, when, whenJust) import Data.Aeson.Encode.Pretty (encodePretty) import Data.Aeson.Types #if MIN_VERSION_aeson(2,0,0)@@ -25,6 +25,7 @@ import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.IO as T+import qualified Data.Vector as V import Data.Yaml (encode) import Network.HTTP.Query ((+/+)) import SimpleCmd (error', (+-+))@@ -41,6 +42,7 @@     listProjects     <$> serverOpt     <*> countOpt+    <*> nohideOpt     <*> formatOpt     <*> forksOpt     <*> optional namespaceOpt@@ -60,22 +62,32 @@   , Subcommand "project" "show project details" $     projectInfo     <$> serverOpt+    <*> nohideOpt     <*> formatOpt     <*> strArg "PROJECT"   , Subcommand "branches" "list project branches" $     repoBranches     <$> serverOpt+    <*> nohideOpt     <*> formatOpt     <*> strArg "REPO"   , Subcommand "git-url" "show project repo's git urls" $     gitUrl     <$> serverOpt+    <*> nohideOpt     <*> formatOpt     <*> strArg "REPO"+  , Subcommand "contributors" "show project repo's contributors" $+    contributors+    <$> serverOpt+    <*> nohideOpt+    <*> formatOpt+    <*> strArg "REPO"   , Subcommand "issues" "list project issues" $     projectIssues     <$> serverOpt     <*> countOpt+    <*> nohideOpt     <*> formatOpt     <*> strArg "REPO"     <*> switchWith 'A' "all" "list Open and Closed issues"@@ -85,39 +97,46 @@   , Subcommand "issue" "show project issue" $     projectIssue     <$> serverOpt+    <*> nohideOpt     <*> formatOpt     <*> strArg "REPO"     <*> argumentWith auto "ISSUE"   , Subcommand "users" "list users" $     users     <$> serverOpt+    <*> nohideOpt     <*> formatOpt     <*> strArg "PATTERN"   , Subcommand "username" "fullname of user" $     username     <$> serverOpt+    <*> nohideOpt     <*> formatOpt     <*> strArg "USERNAME"   , Subcommand "userinfo" "show user details" $     userInfo     <$> serverOpt+    <*> nohideOpt     <*> formatOpt     <*> strArg "USERNAME"   , Subcommand "groups" "list groups" $     groups     <$> serverOpt     <*> countOpt+    <*> nohideOpt     <*> formatOpt     <*> optional (strArg "PATTERN")   , Subcommand "groupinfo" "show group details" $     groupInfo     <$> serverOpt     <*> switchWith 'p' "projects" "List projects"+    <*> nohideOpt     <*> formatOpt     <*> strArg "GROUP"   ]   where     countOpt = switchWith 'c' "count" "Show number only"+    nohideOpt = switchWith 'e' "show-empty" "Display empty lists and objects"     formatOpt = flagWith' FormatJson 'j' "json" "Output JSON" <|> flagWith FormatDefault FormatYaml 'y' "yaml" "YAML output"     namespaceOpt = strOptionWith 'n' "namespace" "NAMESPACE" "Specify project repo namespace"     packagerOpt = Owner <$> ownerOpt <|> Committer <$> usernameOpt@@ -136,19 +155,20 @@ srcFedoraprojectOrg :: String srcFedoraprojectOrg = "src.fedoraproject.org" -defaultPrinter :: OutputFormat -> (Object -> IO ()) -> Object -> IO ()-defaultPrinter FormatDefault pr = pr-defaultPrinter FormatJson _ = BL.putStrLn . encodePretty-defaultPrinter FormatYaml _ = B.putStrLn . encode+defaultPrinter :: Bool -> OutputFormat -> (Object -> IO ()) -> Object -> IO ()+defaultPrinter _ FormatDefault pr = pr+defaultPrinter nohide fmt _ = yamlPrinter nohide fmt -listProjects :: String -> Bool -> OutputFormat -> Forks -> Maybe String -> Maybe Packager -> Maybe String -> IO ()-listProjects server count format forks mnamespace mpackager mpattern = do+listProjects :: String -> Bool -> Bool -> OutputFormat -> Forks -> Maybe String+             -> Maybe Packager -> Maybe String -> IO ()+listProjects server count nohide format forks mnamespace mpackager mpattern = do   unless (count || isJust mpackager || isJust mpattern) $     error' "Please give a package pattern, --count, or --owner/--username"   let path = "projects"       params = makeKey "short" "1" ++ fork ++ packager ++ maybeKey "namespace" mnamespace ++ maybeKey "pattern" mpattern   pages <- queryPagureCountPaged server count path params ("pagination", "page")-  mapM_ (defaultPrinter format printPage) pages+  let projects = concatMap (lookupKey' "projects") pages+  mapM_ (defaultPrinter nohide format printProject) projects   where     -- (!orphan only works on pagure >=0.29)     packager = case mpackager of@@ -161,11 +181,10 @@       IncludeForks -> []       OnlyForks -> makeKey "fork" "1" -    printPage :: Object -> IO ()-    printPage result = do+    printProject :: Object -> IO ()+    printProject project = do       let key' = if isJust mnamespace then "name" else "fullname"-          projects = lookupKey' "projects" result-      (mapM_ T.putStrLn . mapMaybe (lookupKey key')) projects+      whenJust (lookupKey key' project) T.putStrLn  -- FIXME duplicates subset of listProjects userRepos :: String -> Bool -> Bool -> String -> IO ()@@ -187,13 +206,14 @@ boolKey k True val = makeKey k val  -- FIXME limit max number of issues-projectIssues :: String -> Bool -> OutputFormat -> String -> Bool -> Maybe String -> Maybe String -> Maybe String -> IO ()-projectIssues server count format repo allstatus mauthor msince mpat = do+projectIssues :: String -> Bool -> Bool -> OutputFormat -> String -> Bool+              -> Maybe String -> Maybe String -> Maybe String -> IO ()+projectIssues server count nohide format repo allstatus mauthor msince mpat = do   let path = repo +/+ "issues"       params = [makeItem "status" "all" | allstatus] ++                maybeKey "author" mauthor ++ maybeKey "since" msince   pages <- queryPagureCountPaged server count path params ("pagination", "page")-  mapM_ (defaultPrinter format printIssues) pages+  mapM_ (defaultPrinter nohide format printIssues) pages   where     printIssues :: Object -> IO ()     printIssues result = do@@ -217,54 +237,54 @@         status <- obj .: "status"         return (id',title,status) -repoBranches :: String -> OutputFormat -> String -> IO ()-repoBranches server format repo = do+repoBranches :: String -> Bool -> OutputFormat -> String -> IO ()+repoBranches server nohide format repo = do   let namespace =         if server == srcFedoraprojectOrg && '/' `notElem` repo         then "rpms/" else ""       path = namespace ++ repo +/+ "git/branches"   eres <- queryPagureSingle server path []-  either error' (defaultPrinter format (printKeyList "branches")) eres+  either error' (defaultPrinter nohide format (printKeyList "branches")) eres -users :: String -> OutputFormat -> String -> IO ()-users server format pat = do+users :: String -> Bool -> OutputFormat -> String -> IO ()+users server nohide format pat = do   let path = "users"       params = makeKey "pattern" pat   res <- queryPagure server path params-  defaultPrinter format (printKeyList "users") res+  defaultPrinter nohide format (printKeyList "users") res -username :: String -> OutputFormat -> String -> IO ()-username server format user = do+username :: String -> Bool -> OutputFormat -> String -> IO ()+username server nohide format user = do   let path = "user" +/+ user   eres <- queryPagureSingle server path $ makeKey "per_page" "1"   case eres of     Left err -> error' err-    Right res -> defaultPrinter format printName res+    Right res -> defaultPrinter nohide format printName res   where     printName res =       case lookupKey "user" res >>= lookupKey "fullname" of         Nothing -> error' "User fullname not found"         Just fn -> T.putStrLn fn -groups :: String -> Bool -> OutputFormat -> Maybe String -> IO ()-groups server count format mpat = do+groups :: String -> Bool -> Bool -> OutputFormat -> Maybe String -> IO ()+groups server count nohide format mpat = do   let path = "groups"       params = maybeKey "pattern" mpat   pages <- queryPagureCountPaged server count path params ("pagination", "page")-  mapM_ (defaultPrinter format (printKeyList "groups")) pages+  mapM_ (defaultPrinter nohide format (printKeyList "groups")) pages  printKeyList :: String -> Object -> IO () printKeyList key' res =   mapM_ T.putStrLn (lookupKey' (T.pack key') res :: [Text]) -gitUrl :: String -> OutputFormat -> String -> IO ()-gitUrl server format repo = do+gitUrl :: String -> Bool -> OutputFormat -> String -> IO ()+gitUrl server nohide format repo = do   let namespace =         if server == srcFedoraprojectOrg && '/' `notElem` repo         then "rpms/" else ""       path = namespace ++ repo +/+ "git/urls"   res <- queryPagure server path []-  defaultPrinter format printURLs res+  defaultPrinter nohide format printURLs res   where     printURLs result =       mapM_ T.putStrLn $@@ -278,51 +298,68 @@ #endif     localLookupKey = lookupKey' . T.pack -yamlPrinter :: OutputFormat -> Object -> IO ()-yamlPrinter FormatDefault = yamlPrinter FormatYaml-yamlPrinter FormatJson = BL.putStrLn . encodePretty-yamlPrinter FormatYaml = B.putStrLn . encode+contributors :: String -> Bool -> OutputFormat -> String -> IO ()+contributors server nohide format repo = do+  let namespace =+        if server == srcFedoraprojectOrg && '/' `notElem` repo+        then "rpms/" else ""+      path = namespace ++ repo +/+ "contributors"+  res <- queryPagure server path []+  yamlPrinter nohide format res -projectInfo :: String -> OutputFormat -> String -> IO ()-projectInfo server format repo = do+yamlPrinter :: Bool -> OutputFormat -> Object -> IO ()+yamlPrinter nohide format =+  case format of+    FormatDefault -> yamlPrinter nohide FormatYaml+    FormatJson -> BL.putStrLn . encodePretty . hideEmpty+    FormatYaml -> B.putStrLn . encode . hideEmpty+  where+    hideEmpty = if nohide then id else cleanObject++cleanObject :: Object -> Object+cleanObject = M.mapMaybe go+  where+    go :: Value -> Maybe Value+    -- drop empty lists+    go (Array v) | V.null v = Nothing+                 | otherwise = Just $ Array (V.map (wrap go) v)+                 where+                   wrap f (Object o) = Object (M.mapMaybe f o)+                   wrap f (Array a)  = Array (V.map (wrap f) a)+                   wrap _ x          = x+    -- drop empty objects+    go (Object o) =+        let cleaned = M.mapMaybe go o+        in if M.null cleaned then Nothing else Just (Object cleaned)+    go other = Just other++projectInfo :: String -> Bool -> OutputFormat -> String -> IO ()+projectInfo server nohide format repo = do   let namespace =         if server == srcFedoraprojectOrg && '/' `notElem` repo         then "rpms/" else ""       path = namespace ++ repo   eval <- pagureProjectInfo server path-  either error' (yamlPrinter format) eval+  either error' (yamlPrinter nohide format) eval -projectIssue :: String -> OutputFormat -> String -> Int -> IO ()-projectIssue server format repo issue = do+projectIssue :: String -> Bool -> OutputFormat -> String -> Int -> IO ()+projectIssue server nohide format repo issue = do   eval <- pagureProjectIssueInfo server repo issue-  either error' (yamlPrinter format) eval+  either error' (yamlPrinter nohide format) eval -userInfo :: String -> OutputFormat -> String -> IO ()-userInfo server format user = do+userInfo :: String -> Bool -> OutputFormat -> String -> IO ()+userInfo server nohide format user = do   eval <- pagureUserInfo server user []-  either error' (yamlPrinter format) eval+  either error' (yamlPrinter nohide format) eval -groupInfo :: String -> Bool -> OutputFormat -> String -> IO ()-groupInfo server projects format group = do+groupInfo :: String -> Bool -> Bool -> OutputFormat -> String -> IO ()+groupInfo server projects nohide format group = do   let params = [makeItem "projects" "1" | projects]   eval <- pagureGroupInfo server group params-  either error' (yamlPrinter format) eval+  either error' (yamlPrinter nohide format) eval  -- FIXME support acl parameter (admin, commit or ticket) groupProjects :: String -> Bool -> String -> IO ()-groupProjects server count group = do-  let path = "group" +/+ group-      params = makeKey "projects" "1"-  pages <- queryPagureCountPaged server count path params ("pagination", "page")-  mapM_ (defaultPrinter FormatDefault printPage) pages-  where-    -- acl-    -- packager = case mpackager of-    --   Nothing -> boolKey "owner" (server == srcFedoraprojectOrg) "!orphan"-    --   Just (Owner o) -> makeKey "owner" o-    --   Just (Committer c) -> makeKey "username" c--    printPage :: Object -> IO ()-    printPage result = do-     let projects = lookupKey' "projects" result-     (mapM_ T.putStrLn . mapMaybe (lookupKey "fullname")) projects+groupProjects server count group =+  pagureGroupRepos server count group >>=+  mapM_ T.putStrLn