packages feed

gitlab-haskell 0.1.1 → 0.1.2

raw patch · 3 files changed

+230/−1 lines, 3 filesdep +gitlab-haskelldep +optparse-applicativenew-component:exe:gitlab-toolsPVP ok

version bump matches the API change (PVP)

Dependencies added: gitlab-haskell, optparse-applicative

API changes (from Hackage documentation)

Files

README.md view
@@ -1,5 +1,7 @@ # A Haskell library for the GitLab web API +## gitlab-haskell library+ This library interacts with a GitLab server's API. It supports queries about and updates to: @@ -18,3 +20,61 @@  The library parses JSON results into Haskell data types in the `GitLab.Types` module.++## gitlab-tools executable++This package also includes a `gitlab-tools` executable.++```+> gitlab-tools --help+Program to execute bulk GitLab actions++Usage: gitlab-tools --host host [--token token] [--filename filename]+                    [--group group] [--project project]+                    [--add-reporters-to-group] [--share-projects-with-group]+                    [--registered]+  Executes actions against a GitLab server++Available options:+  --host host              URL of the GitLab server+  --token token            GitLab access token+  --filename filename      name of a CSV file+  --group group            name of a group+  --project project        name of a project+  --add-reporters-to-group Add users as reporters to a group+  --share-projects-with-group+                           Share all projects with a given name to the specific+                           group+  --registered             prints 'yes' or 'no' depending on whether a user+                           exists on the GitLab server+  -h,--help                Show this help text+```++### Examples++Sharing projects with a group:++```+> gitlab-tools \+    --host <GitLab url> --token <token> \+    --share-projects-with-group --project my_project \+    --group my_group+```++This commands finds all projects called `my_project` then adds the+`my_group` group to all of those projects as a member with the+Reporter role.++Adding users to a group:++```+> gitlab-tools \+    --host <GitLab url> --token <token> \+    --filename <filename>.csv \+    --add-reporters-to-group \+    --group my_group+```++This command reads usernames from a comma separated file, and if they+are registered on the GitLab server it adds them to the `my_group`+group with the Reporter role.
+ app/Main.hs view
@@ -0,0 +1,156 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-}+module Main where++import Control.Monad+import Control.Monad.IO.Class+import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.Text.IO as T+import GitLab+import Network.HTTP.Types.Status+import Data.Semigroup ((<>))+import Options.Applicative++main :: IO ()+main = processOptions =<< execParser opts+  where+    opts = info (parser <**> helper)+           ( fullDesc+             <> progDesc "Executes actions against a GitLab server"+             <> header "Program to execute bulk GitLab actions" )++data Options =+  Options+  { gitlabUrl :: String+  , gitlabToken :: String+  , addUsersFilename :: String+  , group :: String+  , project :: String+  , addReportersToGroup :: Bool+  , addGroupToProject :: Bool+  , isRegistered :: Bool+  }+  deriving (Show)++parser :: Parser Options+parser = Options+  <$> strOption+  ( long "host"+    <> metavar "host"+    <> help "URL of the GitLab server" )+  <*> strOption+  ( long "token"+    <> metavar "token"+    <> value ""+    <> help "GitLab access token" )+  <*> strOption+  ( long "filename"+    <> metavar "filename"+    <> value ""+    <> help "name of a CSV file" )+  <*> strOption+  ( long "group"+    <> metavar "group"+    <> value ""+    <> help "name of a group" )+  <*> strOption+  ( long "project"+    <> metavar "project"+    <> value ""+    <> help "name of a project" )+  <*> switch+  ( long "add-reporters-to-group"+    <> help "Add users as reporters to a group" )+  <*> switch+  ( long "share-projects-with-group"+    <> help "Share all projects with a given name to the specific group" )+  <*> switch+  ( long "registered"+    <> help "prints 'yes' or 'no' depending on whether a user exists on the GitLab server" )++processOptions :: Options -> IO ()+processOptions (Options _url _tok "" _grp _proj True _addGroup _isRegistered) =+  return ()+processOptions (Options _url _tok _filename "" _proj True _addGroup _isRegistered) =+  putStrLn "you must specify a group name too"+processOptions (Options _gUrl _gToken _fname _groupName _ True True _isRegistered) =+  putStrLn "you can only choose one of adding users to group or adding group to projects"++-- add reporters to a group+processOptions (Options gUrl gToken fname groupName _ True False _isRegistered) = do+  text <- T.readFile fname+  let usernames = T.splitOn "," text+  runGitLab+    (defaultGitLabServer+      { url = T.pack gUrl+      , token = T.pack gToken+      })+    (addUsersToGroupDbg (T.pack groupName) Reporter usernames)+    +-- add group as a member to all projects with a given name, as Reporter+processOptions (Options gUrl gToken _ groupName projectName False True _isRegistered) = do+  when (null groupName || null projectName)+    (error "for --share-project you must specify a group name and a project name")+  runGitLab+    (defaultGitLabServer+      { url = T.pack gUrl+      , token = T.pack gToken+      })+    (do groups <- groupsWithName (T.pack groupName)+        void $ liftIO $ when (null groups)+          (error ("group not found: " ++ groupName))+        void $ liftIO $ when (length groups > 1)+          (error ("multiple groups found for: " ++ groupName))+        -- should only be 1 group with this head+        let grp = head groups+        projects <- projectsWithName (T.pack projectName)+        mapM_+          (\prj -> do+             result <- shareProjectWithGroup (group_id grp) (project_id prj) Reporter+             case result of+               Left st -> liftIO (putStrLn ("unable to share project " ++ show (project_id prj) ++ " with group " ++ show (group_id grp) ++ ". Reason: " ++ show st))+               Right _details -> liftIO (putStrLn ("Added group " ++ show (group_id grp) ++ " to project " ++ show (project_id prj) ++ " as a Reporter"))+          )+          projects+    )++-- ask if users are registered for a given GitLab server+processOptions (Options _gUrl _gToken "" __groupName _ False False True) =+  putStrLn "--registered needs a filename with --filename"+processOptions (Options gUrl gToken fname _groupName _ False False True) = do+  text <- T.readFile fname+  let usernames = T.splitOn "," text+  runGitLab+    (defaultGitLabServer+      { url = T.pack gUrl+      , token = T.pack gToken+      })+    (mapM_+      (\usrName ->+          do res <- searchUser usrName+             -- empty list of returned users+             if null res+             then liftIO $ putStrLn (T.unpack usrName ++ ": no")+             else liftIO $ putStrLn (T.unpack usrName ++ ": yes")+      )+      usernames+    )++processOptions Options{} =+  error "combination of flags not recognised"+  +addUsersToGroupDbg ::+  (MonadIO m) => Text -> AccessLevel -> [Text] -> GitLab m ()+addUsersToGroupDbg groupName access usernames = do+  (results :: [Either Status Member]) <-+    addUsersToGroup groupName access usernames+  liftIO $ mapM_+    (\(result :: Either Status Member) ->+       case result of+         Left errorStatus -> print errorStatus+         Right member ->+           putStrLn+             ("Added to " +++              show groupName ++ ": " ++ show (member_username member)))+    results
gitlab-haskell.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name:           gitlab-haskell category:       Git-version:        0.1.1+version:        0.1.2 synopsis:       A Haskell library for the GitLab web API description:   This Haskell library queries and updates the database of a GitLab instance using the GitLab web API: <https://docs.gitlab.com/ee/api/>@@ -23,6 +23,19 @@ source-repository head   type: git   location: https://gitlab.com/robstewart57/gitlab-haskell++executable gitlab-tools+  main-is: Main.hs+  hs-source-dirs:+      app+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+                base >=4.7 && <5+              , gitlab-haskell+              , text+              , http-types+              , optparse-applicative+  default-language: Haskell2010  library   exposed-modules: