packages feed

zuul 0.1.0.0 → 0.1.1.0

raw patch · 7 files changed

+159/−51 lines, 7 filesdep ~aesondep ~containersPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: aeson, containers

API changes (from Hackage documentation)

+ Zuul: [jcExtraVariables] :: JobConfig -> JobVariables
+ Zuul: [jcGroupVariables] :: JobConfig -> JobVariables
+ Zuul: [jcHostVariables] :: JobConfig -> JobVariables
+ Zuul: [jcVariables] :: JobConfig -> JobVariables
+ Zuul: [ppjExtraVariables] :: ProjectPipelineJob -> JobVariables
+ Zuul: [ppjGroupVariables] :: ProjectPipelineJob -> JobVariables
+ Zuul: [ppjHostVariables] :: ProjectPipelineJob -> JobVariables
+ Zuul: [ppjVariables] :: ProjectPipelineJob -> JobVariables
+ Zuul: type JobVariables = Map Text Value
+ Zuul.JobConfig: [jcExtraVariables] :: JobConfig -> JobVariables
+ Zuul.JobConfig: [jcGroupVariables] :: JobConfig -> JobVariables
+ Zuul.JobConfig: [jcHostVariables] :: JobConfig -> JobVariables
+ Zuul.JobConfig: [jcVariables] :: JobConfig -> JobVariables
+ Zuul.JobConfig: type JobVariables = Map Text Value
+ Zuul.ProjectConfig: [ppjExtraVariables] :: ProjectPipelineJob -> JobVariables
+ Zuul.ProjectConfig: [ppjGroupVariables] :: ProjectPipelineJob -> JobVariables
+ Zuul.ProjectConfig: [ppjHostVariables] :: ProjectPipelineJob -> JobVariables
+ Zuul.ProjectConfig: [ppjVariables] :: ProjectPipelineJob -> JobVariables
- Zuul: JobConfig :: Text -> Maybe SourceContext -> Maybe Text -> Maybe Nodeset -> JobConfig
+ Zuul: JobConfig :: Text -> Maybe SourceContext -> Maybe Text -> Maybe Nodeset -> JobVariables -> JobVariables -> JobVariables -> JobVariables -> JobConfig
- Zuul: ProjectPipelineJob :: Text -> SourceContext -> Maybe Nodeset -> ProjectPipelineJob
+ Zuul: ProjectPipelineJob :: Text -> SourceContext -> Maybe Nodeset -> JobVariables -> JobVariables -> JobVariables -> JobVariables -> ProjectPipelineJob
- Zuul.JobConfig: JobConfig :: Text -> Maybe SourceContext -> Maybe Text -> Maybe Nodeset -> JobConfig
+ Zuul.JobConfig: JobConfig :: Text -> Maybe SourceContext -> Maybe Text -> Maybe Nodeset -> JobVariables -> JobVariables -> JobVariables -> JobVariables -> JobConfig
- Zuul.ProjectConfig: ProjectPipelineJob :: Text -> SourceContext -> Maybe Nodeset -> ProjectPipelineJob
+ Zuul.ProjectConfig: ProjectPipelineJob :: Text -> SourceContext -> Maybe Nodeset -> JobVariables -> JobVariables -> JobVariables -> JobVariables -> ProjectPipelineJob

Files

CHANGELOG.md view
@@ -1,5 +1,11 @@ # Changelog +## 0.1.1.0 (2022-03-31)++- Add variables to JobConfig and ProjectConfig.+- job-vars command.+- Allow aeson 2+ ## 0.1.0.0 (2021-02-18)  - Basic Zuul API data types.
README.md view
@@ -11,7 +11,7 @@ - Command line utility to compute informations.   - live-changes: count the number of change running in a pipeline.   - nodepool-labels: get the label used in project pipelines.-+  - job-vars: get the job variables used in project pipelines.  ## Contribute 
app/Main.hs view
@@ -10,7 +10,10 @@ import Data.Aeson (FromJSON, ToJSON (..), eitherDecodeFileStrict, encodeFile, object, (.=)) import Data.Aeson.Encode.Pretty (encodePretty) import Data.Aeson.Text (encodeToLazyText)+import qualified Data.List as L+import qualified Data.Map as M import Data.Map.Strict (Map, fromListWith, toList, unionsWith)+import Data.Maybe (mapMaybe) import Data.Text (Text, pack, unpack) import qualified Data.Text as T import qualified Data.Text.IO as Text@@ -52,20 +55,115 @@       encodeFile cachePath value       pure value +withTenantCache ::+  (FromJSON a, ToJSON a) =>+  ZuulClient ->+  Text ->+  -- | The query IO+  (ZuulClient -> IO a) ->+  -- | The name of the cache+  Text ->+  IO a+withTenantCache client tenant action cacheName =+  withCache (client `onTenant` tenant) action (tenant <> "/" <> cacheName)+ -- | Get the list of tenant names-getTenantNames :: ZuulClient -> IO [Text]-getTenantNames client = fmap (fmap tenantName) (withCache client getTenants "tenants")+getTenantNames :: ZuulClient -> Maybe Text -> IO [Text]+getTenantNames client tenantm =+  case tenantm of+    Just tenant -> pure [tenant]+    Nothing -> fmap (fmap tenantName) (withCache client getTenants "tenants")  -- | Get the list of project names-getProjectNames :: Text -> ZuulClient -> IO [Text]-getProjectNames tenant client =-  fmap (fmap projectCanonicalName) (withCache client getProjects (tenant <> "/projects"))+getProjectNames :: ZuulClient -> Text -> IO [Text]+getProjectNames client tenant =+  fmap (fmap projectCanonicalName) (withTenantCache client tenant getProjects "projects")  -- | Get the list of job names-getJobNames :: Text -> ZuulClient -> IO [Text]-getJobNames tenant client = fmap (fmap jobName) (withCache client getJobs (tenant <> "/jobs"))+getJobNames :: ZuulClient -> Text -> IO [Text]+getJobNames client tenant = fmap (fmap jobName) (withTenantCache client tenant getJobs "jobs") +-- | Get all the project configs+getProjectConfigs :: ZuulClient -> Text -> IO [ProjectConfig]+getProjectConfigs client tenant = do+  projectNames <- getProjectNames client tenant+  mapM getProjectCache projectNames+  where+    getProjectCache name = withTenantCache client tenant (`getProjectConfig` name) ("project/" <> name)++-- | Get all the jobs+getJobConfigs :: ZuulClient -> Text -> IO [JobConfig]+getJobConfigs client tenant = do+  jobNames <- getJobNames client tenant+  mconcat <$> mapM getJobCache jobNames+  where+    getJobCache name = withTenantCache client tenant (`getJobConfig` name) ("job/" <> name)++getConfigs :: ZuulClient -> Maybe Text -> IO [(Text, [ProjectConfig], [JobConfig])]+getConfigs client tenant = do+  tenants <- getTenantNames client tenant+  zip3 tenants+    <$> mapM (getProjectConfigs client) tenants+    <*> mapM (getJobConfigs client) tenants++getProjectJobs :: ProjectConfig -> [ProjectPipelineJob]+getProjectJobs =+  mconcat+    . mconcat+    . map Zuul.ppJobs+    . mconcat+    . map Zuul.ppcPipelines+    . Zuul.projectConfigConfigs+ ----------------------------------------------------------------------------------------------------+-- Vars usages+----------------------------------------------------------------------------------------------------+data VarUsage = VarUsage+  { vuTenantName :: Text,+    vuJobName :: Text,+    vuSourceContext :: SourceContext,+    vuVars :: [(Text, JobVariables)]+  }+  deriving (Show, Eq, Ord)++filterEmptyVars :: [(a, Map k b)] -> [(a, Map k b)]+filterEmptyVars = filter (not . M.null . snd)++getProjectJobVars :: Text -> ProjectPipelineJob -> VarUsage+getProjectJobVars tenant ProjectPipelineJob {..} = VarUsage tenant ppjName ppjSourceContext (filterEmptyVars vars)+  where+    vars =+      [ ("vars", ppjVariables),+        ("extra", ppjExtraVariables),+        ("host", ppjHostVariables),+        ("group", ppjGroupVariables)+      ]++getJobVars :: Text -> JobConfig -> Maybe VarUsage+getJobVars tenant JobConfig {..} = case jcSourceContext of+  Nothing -> Nothing+  Just sc -> Just $ VarUsage tenant jcName sc (filterEmptyVars vars)+  where+    vars =+      [ ("vars", jcVariables),+        ("extra", jcExtraVariables),+        ("host", jcHostVariables),+        ("group", jcGroupVariables)+      ]++getVars :: (Text, [ProjectConfig], [JobConfig]) -> [VarUsage]+getVars (tenant, pcs, jcs) = filter (not . L.null . vuVars) xs+  where+    xs = map (getProjectJobVars tenant) ppjs <> mapMaybe (getJobVars tenant) jcs+    ppjs = concatMap getProjectJobs pcs++printJobVars :: Maybe Text -> ZuulClient -> IO ()+printJobVars tenant client = do+  configs <- getConfigs client tenant+  let vars = concatMap getVars configs+  mapM_ print vars++---------------------------------------------------------------------------------------------------- -- Label usages ---------------------------------------------------------------------------------------------------- type LabelName = Text@@ -95,50 +193,35 @@     nodeToLabel Node {..} = (nodeLabel, [LabelUsage (nodesetName nodeset) tenant job sc])  -- | Get LabelUsage of a project-getProjectLabel :: ZuulClient -> Text -> Text -> IO [(LabelName, [LabelUsage])]-getProjectLabel client tenant project = do-  projectConfig <- withCache client (`getProjectConfig` project) (tenant <> "/project/" <> project)-  let jobs :: [ProjectPipelineJob]-      -- this penetrates the project config structure to get all the job in a flat list-      jobs = mconcat $ mconcat $ fmap ppJobs $ mconcat $ fmap ppcPipelines (projectConfigConfigs projectConfig)-  pure $ mconcat $ map projectPipelineJobToLabel jobs+getProjectLabel :: Text -> ProjectConfig -> [(LabelName, [LabelUsage])]+getProjectLabel tenant pc = mconcat $ map projectPipelineJobToLabel jobs   where+    jobs :: [ProjectPipelineJob]+    -- this penetrates the project config structure to get all the job in a flat list+    jobs = mconcat $ mconcat $ fmap ppJobs $ mconcat $ fmap ppcPipelines (projectConfigConfigs pc)     projectPipelineJobToLabel :: ProjectPipelineJob -> [(LabelName, [LabelUsage])]     projectPipelineJobToLabel ProjectPipelineJob {..} = case ppjNodeset of       Nothing -> []       Just nodeset -> nodesetToLabel tenant ppjName ppjSourceContext nodeset  -- | Get LabelUsage of a job-getJobLabel :: ZuulClient -> Text -> Text -> IO [(LabelName, [LabelUsage])]-getJobLabel client tenant job = do-  jobConfig <- withCache client (`getJobConfig` job) (tenant <> "/job/" <> job)-  pure $ mconcat $ map jobConfigToLabel jobConfig-  where-    jobConfigToLabel :: JobConfig -> [(LabelName, [LabelUsage])]-    jobConfigToLabel JobConfig {..} = case (jcNodeset, jcSourceContext) of-      (Just nodeset, Just sc) -> nodesetToLabel tenant job sc nodeset-      _ -> []+getJobLabel :: Text -> JobConfig -> [(LabelName, [LabelUsage])]+getJobLabel tenant JobConfig {..} = case (jcNodeset, jcSourceContext) of+  (Just nodeset, Just sc) -> nodesetToLabel tenant jcName sc nodeset+  _ -> []  -- | Get LabelUsage of a tenant projects and jobs-getTenantNodepoolLabels :: ZuulClient -> Text -> IO (Map LabelName [LabelUsage])-getTenantNodepoolLabels client tenant = fromListWith (<>) <$> go+getNodepoolLabels :: (Text, [ProjectConfig], [JobConfig]) -> Map LabelName [LabelUsage]+getNodepoolLabels (tenant, pcs, jcs) = fromListWith (<>) labels   where-    tenantClient = client `onTenant` tenant-    go :: IO [(LabelName, [LabelUsage])]-    go = do-      projectNames <- getProjectNames tenant tenantClient-      projectLabels <- mconcat <$> mapM (getProjectLabel tenantClient tenant) projectNames-      jobNames <- getJobNames tenant tenantClient-      jobLabels <- mconcat <$> mapM (getJobLabel tenantClient tenant) jobNames-      pure $ jobLabels <> projectLabels+    labels :: [(LabelName, [LabelUsage])]+    labels = concatMap (getProjectLabel tenant) pcs <> concatMap (getJobLabel tenant) jcs  -- | Print LabelUsage of one or all tenants-printNodepoolLabels :: Bool -> Text -> Maybe Text -> IO ()-printNodepoolLabels json url tenant = withClient url $ \client -> do-  tenants <- case tenant of-    Nothing -> getTenantNames client-    Just tenant' -> pure [tenant']-  labels <- unionsWith (<>) <$> mapM (getTenantNodepoolLabels client) tenants+printNodepoolLabels :: Bool -> Maybe Text -> ZuulClient -> IO ()+printNodepoolLabels json tenant client = do+  configs <- getConfigs client tenant+  let labels = unionsWith (<>) (map getNodepoolLabels configs)   Text.putStrLn $     if json       then toStrict (decodeUtf8 (encodePretty labels))@@ -150,8 +233,8 @@ ---------------------------------------------------------------------------------------------------- -- Live Changes -----------------------------------------------------------------------------------------------------printLiveChanges :: Text -> Text -> Maybe Text -> IO ()-printLiveChanges url pipeline queue = withClient url $ \client -> do+printLiveChanges :: Text -> Maybe Text -> ZuulClient -> IO ()+printLiveChanges pipeline queue client = do   status <- getStatus client   case Zuul.Status.pipelineChanges pipeline queue status of     Just changes -> print (map Zuul.Status.changeProject (Zuul.Status.liveChanges changes))@@ -166,6 +249,10 @@         json :: w ::: Bool <?> "Output JSON",         tenant :: w ::: Maybe Text <?> "A tenant filter"       }+  | JobVars+      { url :: w ::: Text <?> "Zuul API url",+        tenant :: w ::: Maybe Text <?> "A tenant filter"+      }   | LiveChanges       { url :: w ::: Text <?> "Zuul API url",         pipeline :: w ::: Text <?> "Pipeline name",@@ -180,5 +267,6 @@ main = do   args <- unwrapRecord "Zuul stats client"   case args of-    NodepoolLabels {..} -> printNodepoolLabels json url tenant-    LiveChanges {..} -> printLiveChanges url pipeline queue+    NodepoolLabels {..} -> withClient url (printNodepoolLabels json tenant)+    JobVars {..} -> withClient url (printJobVars tenant)+    LiveChanges {..} -> withClient url (printLiveChanges pipeline queue)
src/Zuul.hs view
@@ -29,6 +29,7 @@     Zuul.Status (..),     Zuul.SourceContext (..),     Zuul.Tenant (..),+    Zuul.JobVariables,   ) where 
src/Zuul/JobConfig.hs view
@@ -2,20 +2,27 @@ {-# LANGUAGE OverloadedStrings #-}  -- | The zuul job config data type-module Zuul.JobConfig (JobConfig (..)) where+module Zuul.JobConfig (JobConfig (..), JobVariables) where -import Data.Aeson (FromJSON (..), ToJSON (..))+import Data.Aeson (FromJSON (..), ToJSON (..), Value)+import Data.Map.Strict (Map) import Data.Text (Text) import GHC.Generics (Generic) import Zuul.Aeson (zuulParseJSON, zuulToJSON) import Zuul.Nodeset (Nodeset) import Zuul.SourceContext (SourceContext) +type JobVariables = Map Text Value+ data JobConfig = JobConfig   { jcName :: Text,     jcSourceContext :: Maybe SourceContext,     jcDescription :: Maybe Text,-    jcNodeset :: Maybe Nodeset+    jcNodeset :: Maybe Nodeset,+    jcVariables :: JobVariables,+    jcExtraVariables :: JobVariables,+    jcHostVariables :: JobVariables,+    jcGroupVariables :: JobVariables   }   deriving (Show, Eq, Ord, Generic) 
src/Zuul/ProjectConfig.hs view
@@ -13,13 +13,18 @@ import Data.Text (Text) import GHC.Generics (Generic) import Zuul.Aeson (zuulParseJSON, zuulToJSON)+import Zuul.JobConfig (JobVariables) import Zuul.Nodeset (Nodeset) import Zuul.SourceContext (SourceContext)  data ProjectPipelineJob = ProjectPipelineJob   { ppjName :: Text,     ppjSourceContext :: SourceContext,-    ppjNodeset :: Maybe Nodeset+    ppjNodeset :: Maybe Nodeset,+    ppjVariables :: JobVariables,+    ppjExtraVariables :: JobVariables,+    ppjHostVariables :: JobVariables,+    ppjGroupVariables :: JobVariables   }   deriving (Show, Eq, Ord, Generic) 
zuul.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.4 name:                zuul-version:             0.1.0.0+version:             0.1.1.0 synopsis:            A zuul client library description:     Zuul is a client library to interface with https://zuul-ci.org.@@ -29,7 +29,7 @@  common common-options   build-depends:       base                   >= 4.11.0.0 && < 5-                     , aeson                  >= 1.0.0.0  && < 1.6+                     , aeson                  >= 1.0.0.0  && < 2.1   ghc-options:         -Wall                        -Wcompat                        -Widentities@@ -48,7 +48,8 @@  library   import:              common-options-  build-depends:       http-client            >= 0.5.0    && < 0.8+  build-depends:       containers             <  0.7+                     , http-client            >= 0.5.0    && < 0.8                      , http-client-tls        >= 0.2.0    && < 0.4                      , text                   >= 0.11.1.0 && < 1.3   hs-source-dirs:      src