gitlab-haskell 0.1.8 → 0.2
raw patch · 22 files changed
+3509/−547 lines, 22 filesdep +gitlab-haskelldep +tastydep +tasty-hunitdep ~aesondep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: gitlab-haskell, tasty, tasty-hunit
Dependency ranges changed: aeson, base
API changes (from Hackage documentation)
- GitLab.Types: [artifacts] :: Job -> [Artifact]
- GitLab.Types: [artifacts_expire_at] :: Job -> Maybe Text
- GitLab.Types: [commit] :: Job -> Commit
- GitLab.Types: [coverage] :: Job -> Maybe Text
- GitLab.Types: [created_at] :: Job -> Text
- GitLab.Types: [duration] :: Job -> Double
- GitLab.Types: [finished_at] :: Job -> Text
- GitLab.Types: [id] :: Job -> Int
- GitLab.Types: [name] :: Job -> Text
- GitLab.Types: [parent_ids] :: Commit -> Maybe [Int]
- GitLab.Types: [path_with_namespace] :: Project -> Text
- GitLab.Types: [pipeline] :: Job -> Pipeline
- GitLab.Types: [stage] :: Job -> Text
- GitLab.Types: [started_at] :: Job -> Text
- GitLab.Types: [status] :: Job -> Text
- GitLab.Types: [tag] :: Job -> Bool
- GitLab.Types: [user] :: Job -> User
+ GitLab: runGitLabDbg :: GitLab a -> IO a
+ GitLab.API.Issues: editIssue :: ProjectId -> IssueId -> EditIssueReq -> GitLab (Either Status Issue)
+ GitLab.API.Issues: newIssue :: Project -> Text -> Text -> GitLab (Either Status Issue)
+ GitLab.API.Issues: newIssue' :: Int -> Text -> Text -> GitLab (Either Status Issue)
+ GitLab.SystemHooks.GitLabSystemHooks: receive :: [Rule] -> GitLab ()
+ GitLab.SystemHooks.GitLabSystemHooks: receiveString :: String -> [Rule] -> GitLab ()
+ GitLab.SystemHooks.GitLabSystemHooks: tryFire :: String -> Rule -> GitLab Bool
+ GitLab.SystemHooks.Types: CommitAuthorEvent :: Text -> Text -> CommitAuthorEvent
+ GitLab.SystemHooks.Types: CommitEvent :: Text -> Text -> Text -> Text -> CommitAuthorEvent -> CommitEvent
+ GitLab.SystemHooks.Types: GroupCreate :: Text -> Text -> Text -> Text -> Maybe Text -> Maybe Text -> Text -> Int -> GroupCreate
+ GitLab.SystemHooks.Types: GroupMemberRemove :: Text -> Text -> Text -> Text -> Int -> Text -> Text -> Text -> Text -> Text -> Int -> GroupMemberRemove
+ GitLab.SystemHooks.Types: GroupMemberUpdate :: Text -> Text -> Text -> Text -> Int -> Text -> Text -> Text -> Text -> Text -> Int -> GroupMemberUpdate
+ GitLab.SystemHooks.Types: GroupRemove :: Text -> Text -> Text -> Text -> Maybe Text -> Maybe Text -> Text -> Int -> GroupRemove
+ GitLab.SystemHooks.Types: GroupRename :: Text -> Text -> Text -> Text -> Text -> Text -> Int -> Maybe Text -> Maybe Text -> Text -> Text -> GroupRename
+ GitLab.SystemHooks.Types: Internal :: Visibility
+ GitLab.SystemHooks.Types: KeyCreate :: Text -> Text -> Text -> Text -> Text -> Int -> KeyCreate
+ GitLab.SystemHooks.Types: KeyRemove :: Text -> Text -> Text -> Text -> Text -> Int -> KeyRemove
+ GitLab.SystemHooks.Types: NewGroupMember :: Text -> Text -> Text -> Text -> Int -> Text -> Text -> Text -> Text -> Text -> Int -> NewGroupMember
+ GitLab.SystemHooks.Types: Private :: Visibility
+ GitLab.SystemHooks.Types: ProjectCreate :: Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Int -> Visibility -> ProjectCreate
+ GitLab.SystemHooks.Types: ProjectDestroy :: Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Int -> Visibility -> ProjectDestroy
+ GitLab.SystemHooks.Types: ProjectEvent :: Text -> Text -> Text -> Maybe Text -> Text -> Text -> Text -> Visibility -> Text -> Text -> Maybe Text -> Text -> Text -> Text -> ProjectEvent
+ GitLab.SystemHooks.Types: ProjectRename :: Text -> Text -> Text -> Text -> Text -> Text -> Int -> Text -> Text -> Visibility -> Text -> ProjectRename
+ GitLab.SystemHooks.Types: ProjectTransfer :: Text -> Text -> Text -> Text -> Text -> Text -> Int -> Text -> Text -> Visibility -> Text -> ProjectTransfer
+ GitLab.SystemHooks.Types: ProjectUpdate :: Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Int -> Visibility -> ProjectUpdate
+ GitLab.SystemHooks.Types: Public :: Visibility
+ GitLab.SystemHooks.Types: Push :: Text -> Text -> Text -> Text -> Text -> Int -> Text -> Text -> Text -> Int -> ProjectEvent -> RepositoryEvent -> [CommitEvent] -> Int -> Push
+ GitLab.SystemHooks.Types: RepositoryEvent :: Text -> Text -> Text -> Maybe Text -> Text -> Text -> Visibility -> RepositoryEvent
+ GitLab.SystemHooks.Types: TagPush :: Text -> Text -> Text -> Text -> Text -> Int -> Text -> Text -> Int -> ProjectEvent -> RepositoryEvent -> [CommitEvent] -> Int -> TagPush
+ GitLab.SystemHooks.Types: UserAddToTeam :: Text -> Text -> Text -> Text -> Int -> Text -> Text -> Text -> Text -> Text -> Text -> Int -> Visibility -> UserAddToTeam
+ GitLab.SystemHooks.Types: UserCreate :: Text -> Text -> Text -> Text -> Text -> Text -> Int -> UserCreate
+ GitLab.SystemHooks.Types: UserFailedLogin :: Text -> Text -> Text -> Text -> Text -> Int -> Text -> Text -> UserFailedLogin
+ GitLab.SystemHooks.Types: UserRemove :: Text -> Text -> Text -> Text -> Text -> Text -> Int -> UserRemove
+ GitLab.SystemHooks.Types: UserRemoveFromTeam :: Text -> Text -> Text -> Text -> Int -> Text -> Text -> Text -> Text -> Text -> Text -> Int -> Visibility -> UserRemoveFromTeam
+ GitLab.SystemHooks.Types: UserRename :: Text -> Text -> Text -> Text -> Text -> Int -> Text -> Text -> UserRename
+ GitLab.SystemHooks.Types: UserUpdateForTeam :: Text -> Text -> Text -> Text -> Int -> Text -> Text -> Text -> Text -> Text -> Text -> Int -> Visibility -> UserUpdateForTeam
+ GitLab.SystemHooks.Types: [$sel:commitAuthorEvent_email:CommitAuthorEvent] :: CommitAuthorEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:commitAuthorEvent_name:CommitAuthorEvent] :: CommitAuthorEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:commitEvent_author:CommitEvent] :: CommitEvent -> CommitAuthorEvent
+ GitLab.SystemHooks.Types: [$sel:commitEvent_id:CommitEvent] :: CommitEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:commitEvent_message:CommitEvent] :: CommitEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:commitEvent_timestamp:CommitEvent] :: CommitEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:commitEvent_url:CommitEvent] :: CommitEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:groupCreate_created_at:GroupCreate] :: GroupCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupCreate_event_name:GroupCreate] :: GroupCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupCreate_group_id:GroupCreate] :: GroupCreate -> Int
+ GitLab.SystemHooks.Types: [$sel:groupCreate_name:GroupCreate] :: GroupCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupCreate_owner_email:GroupCreate] :: GroupCreate -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:groupCreate_owner_name:GroupCreate] :: GroupCreate -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:groupCreate_path:GroupCreate] :: GroupCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupCreate_updated_at:GroupCreate] :: GroupCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_created_at:GroupMemberRemove] :: GroupMemberRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_event_name:GroupMemberRemove] :: GroupMemberRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_group_access:GroupMemberRemove] :: GroupMemberRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_group_id:GroupMemberRemove] :: GroupMemberRemove -> Int
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_group_name:GroupMemberRemove] :: GroupMemberRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_group_path:GroupMemberRemove] :: GroupMemberRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_updated_at:GroupMemberRemove] :: GroupMemberRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_user_email:GroupMemberRemove] :: GroupMemberRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_user_id:GroupMemberRemove] :: GroupMemberRemove -> Int
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_user_name:GroupMemberRemove] :: GroupMemberRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberRemove_user_username:GroupMemberRemove] :: GroupMemberRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_created_at:GroupMemberUpdate] :: GroupMemberUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_event_name:GroupMemberUpdate] :: GroupMemberUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_group_access:GroupMemberUpdate] :: GroupMemberUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_group_id:GroupMemberUpdate] :: GroupMemberUpdate -> Int
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_group_name:GroupMemberUpdate] :: GroupMemberUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_group_path:GroupMemberUpdate] :: GroupMemberUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_updated_at:GroupMemberUpdate] :: GroupMemberUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_user_email:GroupMemberUpdate] :: GroupMemberUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_user_id:GroupMemberUpdate] :: GroupMemberUpdate -> Int
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_user_name:GroupMemberUpdate] :: GroupMemberUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupMemberUpdate_user_username:GroupMemberUpdate] :: GroupMemberUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRemove_created_at:GroupRemove] :: GroupRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRemove_event_name:GroupRemove] :: GroupRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRemove_group_id:GroupRemove] :: GroupRemove -> Int
+ GitLab.SystemHooks.Types: [$sel:groupRemove_name:GroupRemove] :: GroupRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRemove_owner_email:GroupRemove] :: GroupRemove -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:groupRemove_owner_name:GroupRemove] :: GroupRemove -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:groupRemove_path:GroupRemove] :: GroupRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRemove_updated_at:GroupRemove] :: GroupRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_created_at:GroupRename] :: GroupRename -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_event_name:GroupRename] :: GroupRename -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_full_path:GroupRename] :: GroupRename -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_group_id:GroupRename] :: GroupRename -> Int
+ GitLab.SystemHooks.Types: [$sel:groupRename_name:GroupRename] :: GroupRename -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_old_full_path:GroupRename] :: GroupRename -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_old_path:GroupRename] :: GroupRename -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_owner_email:GroupRename] :: GroupRename -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_owner_name:GroupRename] :: GroupRename -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_path:GroupRename] :: GroupRename -> Text
+ GitLab.SystemHooks.Types: [$sel:groupRename_updated_at:GroupRename] :: GroupRename -> Text
+ GitLab.SystemHooks.Types: [$sel:keyCreate_created_at:KeyCreate] :: KeyCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:keyCreate_event_name:KeyCreate] :: KeyCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:keyCreate_id:KeyCreate] :: KeyCreate -> Int
+ GitLab.SystemHooks.Types: [$sel:keyCreate_key:KeyCreate] :: KeyCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:keyCreate_updated_at:KeyCreate] :: KeyCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:keyCreate_username:KeyCreate] :: KeyCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:keyRemove_created_at:KeyRemove] :: KeyRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:keyRemove_event_name:KeyRemove] :: KeyRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:keyRemove_id:KeyRemove] :: KeyRemove -> Int
+ GitLab.SystemHooks.Types: [$sel:keyRemove_key:KeyRemove] :: KeyRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:keyRemove_updated_at:KeyRemove] :: KeyRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:keyRemove_username:KeyRemove] :: KeyRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_created_at:NewGroupMember] :: NewGroupMember -> Text
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_event_name:NewGroupMember] :: NewGroupMember -> Text
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_group_access:NewGroupMember] :: NewGroupMember -> Text
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_group_id:NewGroupMember] :: NewGroupMember -> Int
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_group_name:NewGroupMember] :: NewGroupMember -> Text
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_group_path:NewGroupMember] :: NewGroupMember -> Text
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_updated_at:NewGroupMember] :: NewGroupMember -> Text
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_user_email:NewGroupMember] :: NewGroupMember -> Text
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_user_id:NewGroupMember] :: NewGroupMember -> Int
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_user_name:NewGroupMember] :: NewGroupMember -> Text
+ GitLab.SystemHooks.Types: [$sel:newGroupMember_user_username:NewGroupMember] :: NewGroupMember -> Text
+ GitLab.SystemHooks.Types: [$sel:projectCreate_action:ProjectCreate] :: ProjectCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectCreate_created_at:ProjectCreate] :: ProjectCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectCreate_name:ProjectCreate] :: ProjectCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectCreate_owner_email:ProjectCreate] :: ProjectCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectCreate_owner_name:ProjectCreate] :: ProjectCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectCreate_path:ProjectCreate] :: ProjectCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectCreate_path_with_namespace:ProjectCreate] :: ProjectCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectCreate_project_id:ProjectCreate] :: ProjectCreate -> Int
+ GitLab.SystemHooks.Types: [$sel:projectCreate_project_visibility:ProjectCreate] :: ProjectCreate -> Visibility
+ GitLab.SystemHooks.Types: [$sel:projectCreate_updated_at:ProjectCreate] :: ProjectCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_action:ProjectDestroy] :: ProjectDestroy -> Text
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_created_at:ProjectDestroy] :: ProjectDestroy -> Text
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_name:ProjectDestroy] :: ProjectDestroy -> Text
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_owner_email:ProjectDestroy] :: ProjectDestroy -> Text
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_owner_name:ProjectDestroy] :: ProjectDestroy -> Text
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_path:ProjectDestroy] :: ProjectDestroy -> Text
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_path_with_namespace:ProjectDestroy] :: ProjectDestroy -> Text
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_project_id:ProjectDestroy] :: ProjectDestroy -> Int
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_project_visibility:ProjectDestroy] :: ProjectDestroy -> Visibility
+ GitLab.SystemHooks.Types: [$sel:projectDestroy_updated_at:ProjectDestroy] :: ProjectDestroy -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_avatar_url:ProjectEvent] :: ProjectEvent -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_default_branch:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_description:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_git_http_url:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_git_ssh_url:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_homepage:ProjectEvent] :: ProjectEvent -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_http_url:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_name:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_namespace:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_path_with_namespace:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_ssh_url:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_url:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectEvent_visibility_level:ProjectEvent] :: ProjectEvent -> Visibility
+ GitLab.SystemHooks.Types: [$sel:projectEvent_web_url:ProjectEvent] :: ProjectEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:projectRename_created_at:ProjectRename] :: ProjectRename -> Text
+ GitLab.SystemHooks.Types: [$sel:projectRename_event_name:ProjectRename] :: ProjectRename -> Text
+ GitLab.SystemHooks.Types: [$sel:projectRename_name:ProjectRename] :: ProjectRename -> Text
+ GitLab.SystemHooks.Types: [$sel:projectRename_old_path_with_namespace:ProjectRename] :: ProjectRename -> Text
+ GitLab.SystemHooks.Types: [$sel:projectRename_owner_email:ProjectRename] :: ProjectRename -> Text
+ GitLab.SystemHooks.Types: [$sel:projectRename_owner_name:ProjectRename] :: ProjectRename -> Text
+ GitLab.SystemHooks.Types: [$sel:projectRename_path:ProjectRename] :: ProjectRename -> Text
+ GitLab.SystemHooks.Types: [$sel:projectRename_path_with_namespace:ProjectRename] :: ProjectRename -> Text
+ GitLab.SystemHooks.Types: [$sel:projectRename_project_id:ProjectRename] :: ProjectRename -> Int
+ GitLab.SystemHooks.Types: [$sel:projectRename_project_visibility:ProjectRename] :: ProjectRename -> Visibility
+ GitLab.SystemHooks.Types: [$sel:projectRename_updated_at:ProjectRename] :: ProjectRename -> Text
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_created_at:ProjectTransfer] :: ProjectTransfer -> Text
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_event_name:ProjectTransfer] :: ProjectTransfer -> Text
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_name:ProjectTransfer] :: ProjectTransfer -> Text
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_old_path_with_namespace:ProjectTransfer] :: ProjectTransfer -> Text
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_owner_email:ProjectTransfer] :: ProjectTransfer -> Text
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_owner_name:ProjectTransfer] :: ProjectTransfer -> Text
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_path:ProjectTransfer] :: ProjectTransfer -> Text
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_path_with_namespace:ProjectTransfer] :: ProjectTransfer -> Text
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_project_id:ProjectTransfer] :: ProjectTransfer -> Int
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_project_visibility:ProjectTransfer] :: ProjectTransfer -> Visibility
+ GitLab.SystemHooks.Types: [$sel:projectTransfer_updated_at:ProjectTransfer] :: ProjectTransfer -> Text
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_created_at:ProjectUpdate] :: ProjectUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_event_name:ProjectUpdate] :: ProjectUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_name:ProjectUpdate] :: ProjectUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_owner_email:ProjectUpdate] :: ProjectUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_owner_name:ProjectUpdate] :: ProjectUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_path:ProjectUpdate] :: ProjectUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_path_with_namespace:ProjectUpdate] :: ProjectUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_project_id:ProjectUpdate] :: ProjectUpdate -> Int
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_project_visibility:ProjectUpdate] :: ProjectUpdate -> Visibility
+ GitLab.SystemHooks.Types: [$sel:projectUpdate_updated_at:ProjectUpdate] :: ProjectUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:push_after:Push] :: Push -> Text
+ GitLab.SystemHooks.Types: [$sel:push_before:Push] :: Push -> Text
+ GitLab.SystemHooks.Types: [$sel:push_checkout_sha:Push] :: Push -> Text
+ GitLab.SystemHooks.Types: [$sel:push_commits:Push] :: Push -> [CommitEvent]
+ GitLab.SystemHooks.Types: [$sel:push_event_name:Push] :: Push -> Text
+ GitLab.SystemHooks.Types: [$sel:push_project:Push] :: Push -> ProjectEvent
+ GitLab.SystemHooks.Types: [$sel:push_project_id:Push] :: Push -> Int
+ GitLab.SystemHooks.Types: [$sel:push_ref:Push] :: Push -> Text
+ GitLab.SystemHooks.Types: [$sel:push_repository:Push] :: Push -> RepositoryEvent
+ GitLab.SystemHooks.Types: [$sel:push_total_commits_count:Push] :: Push -> Int
+ GitLab.SystemHooks.Types: [$sel:push_user_avatar:Push] :: Push -> Text
+ GitLab.SystemHooks.Types: [$sel:push_user_email:Push] :: Push -> Text
+ GitLab.SystemHooks.Types: [$sel:push_user_id:Push] :: Push -> Int
+ GitLab.SystemHooks.Types: [$sel:push_user_name:Push] :: Push -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_description:RepositoryEvent] :: RepositoryEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_git_http_url:RepositoryEvent] :: RepositoryEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_git_ssh_url:RepositoryEvent] :: RepositoryEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_homepage:RepositoryEvent] :: RepositoryEvent -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_name:RepositoryEvent] :: RepositoryEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_url:RepositoryEvent] :: RepositoryEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_visibility_level:RepositoryEvent] :: RepositoryEvent -> Visibility
+ GitLab.SystemHooks.Types: [$sel:tagPush_after:TagPush] :: TagPush -> Text
+ GitLab.SystemHooks.Types: [$sel:tagPush_before:TagPush] :: TagPush -> Text
+ GitLab.SystemHooks.Types: [$sel:tagPush_checkout_sha:TagPush] :: TagPush -> Text
+ GitLab.SystemHooks.Types: [$sel:tagPush_commits:TagPush] :: TagPush -> [CommitEvent]
+ GitLab.SystemHooks.Types: [$sel:tagPush_event_name:TagPush] :: TagPush -> Text
+ GitLab.SystemHooks.Types: [$sel:tagPush_project:TagPush] :: TagPush -> ProjectEvent
+ GitLab.SystemHooks.Types: [$sel:tagPush_project_id:TagPush] :: TagPush -> Int
+ GitLab.SystemHooks.Types: [$sel:tagPush_ref:TagPush] :: TagPush -> Text
+ GitLab.SystemHooks.Types: [$sel:tagPush_repository:TagPush] :: TagPush -> RepositoryEvent
+ GitLab.SystemHooks.Types: [$sel:tagPush_total_commits_count:TagPush] :: TagPush -> Int
+ GitLab.SystemHooks.Types: [$sel:tagPush_user_avatar:TagPush] :: TagPush -> Text
+ GitLab.SystemHooks.Types: [$sel:tagPush_user_id:TagPush] :: TagPush -> Int
+ GitLab.SystemHooks.Types: [$sel:tagPush_user_name:TagPush] :: TagPush -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_access_level:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_created_at:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_event_name:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_project_id:UserAddToTeam] :: UserAddToTeam -> Int
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_project_name:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_project_path:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_project_path_with_namespace:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_project_visibility:UserAddToTeam] :: UserAddToTeam -> Visibility
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_updated_at:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_user_email:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_user_id:UserAddToTeam] :: UserAddToTeam -> Int
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_user_name:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userAddTeam_user_username:UserAddToTeam] :: UserAddToTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userCreate_created_at:UserCreate] :: UserCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:userCreate_email:UserCreate] :: UserCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:userCreate_event_name:UserCreate] :: UserCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:userCreate_name:UserCreate] :: UserCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:userCreate_updated_at:UserCreate] :: UserCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:userCreate_user_id:UserCreate] :: UserCreate -> Int
+ GitLab.SystemHooks.Types: [$sel:userCreate_username:UserCreate] :: UserCreate -> Text
+ GitLab.SystemHooks.Types: [$sel:userFailedLogin_created_at:UserFailedLogin] :: UserFailedLogin -> Text
+ GitLab.SystemHooks.Types: [$sel:userFailedLogin_email:UserFailedLogin] :: UserFailedLogin -> Text
+ GitLab.SystemHooks.Types: [$sel:userFailedLogin_event_name:UserFailedLogin] :: UserFailedLogin -> Text
+ GitLab.SystemHooks.Types: [$sel:userFailedLogin_name:UserFailedLogin] :: UserFailedLogin -> Text
+ GitLab.SystemHooks.Types: [$sel:userFailedLogin_state:UserFailedLogin] :: UserFailedLogin -> Text
+ GitLab.SystemHooks.Types: [$sel:userFailedLogin_updated_at:UserFailedLogin] :: UserFailedLogin -> Text
+ GitLab.SystemHooks.Types: [$sel:userFailedLogin_user_id:UserFailedLogin] :: UserFailedLogin -> Int
+ GitLab.SystemHooks.Types: [$sel:userFailedLogin_username:UserFailedLogin] :: UserFailedLogin -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_access_level:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_created_at:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_event_name:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_project_id:UserRemoveFromTeam] :: UserRemoveFromTeam -> Int
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_project_name:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_project_path:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_project_path_with_namespace:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_project_visibility:UserRemoveFromTeam] :: UserRemoveFromTeam -> Visibility
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_updated_at:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_user_email:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_user_id:UserRemoveFromTeam] :: UserRemoveFromTeam -> Int
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_user_name:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemoveTeam_user_username:UserRemoveFromTeam] :: UserRemoveFromTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemove_created_at:UserRemove] :: UserRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemove_email:UserRemove] :: UserRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemove_event_name:UserRemove] :: UserRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemove_name:UserRemove] :: UserRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemove_updated_at:UserRemove] :: UserRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:userRemove_user_id:UserRemove] :: UserRemove -> Int
+ GitLab.SystemHooks.Types: [$sel:userRemove_username:UserRemove] :: UserRemove -> Text
+ GitLab.SystemHooks.Types: [$sel:userRename_created_at:UserRename] :: UserRename -> Text
+ GitLab.SystemHooks.Types: [$sel:userRename_email:UserRename] :: UserRename -> Text
+ GitLab.SystemHooks.Types: [$sel:userRename_event_name:UserRename] :: UserRename -> Text
+ GitLab.SystemHooks.Types: [$sel:userRename_name:UserRename] :: UserRename -> Text
+ GitLab.SystemHooks.Types: [$sel:userRename_old_username:UserRename] :: UserRename -> Text
+ GitLab.SystemHooks.Types: [$sel:userRename_updated_at:UserRename] :: UserRename -> Text
+ GitLab.SystemHooks.Types: [$sel:userRename_user_id:UserRename] :: UserRename -> Int
+ GitLab.SystemHooks.Types: [$sel:userRename_username:UserRename] :: UserRename -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_access_level:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_created_at:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_event_name:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_project_id:UserUpdateForTeam] :: UserUpdateForTeam -> Int
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_project_name:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_project_path:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_project_path_with_namespace:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_project_visibility:UserUpdateForTeam] :: UserUpdateForTeam -> Visibility
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_updated_at:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_user_email:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_user_id:UserUpdateForTeam] :: UserUpdateForTeam -> Int
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_user_name:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [$sel:userUpdateTeam_user_username:UserUpdateForTeam] :: UserUpdateForTeam -> Text
+ GitLab.SystemHooks.Types: [MatchIf] :: Typeable a => String -> (a -> GitLab Bool) -> (a -> GitLab ()) -> Rule
+ GitLab.SystemHooks.Types: [Match] :: Typeable a => String -> (a -> GitLab ()) -> Rule
+ GitLab.SystemHooks.Types: class (FromJSON a) => SystemHook a
+ GitLab.SystemHooks.Types: data CommitAuthorEvent
+ GitLab.SystemHooks.Types: data CommitEvent
+ GitLab.SystemHooks.Types: data GroupCreate
+ GitLab.SystemHooks.Types: data GroupMemberRemove
+ GitLab.SystemHooks.Types: data GroupMemberUpdate
+ GitLab.SystemHooks.Types: data GroupRemove
+ GitLab.SystemHooks.Types: data GroupRename
+ GitLab.SystemHooks.Types: data KeyCreate
+ GitLab.SystemHooks.Types: data KeyRemove
+ GitLab.SystemHooks.Types: data NewGroupMember
+ GitLab.SystemHooks.Types: data ProjectCreate
+ GitLab.SystemHooks.Types: data ProjectDestroy
+ GitLab.SystemHooks.Types: data ProjectEvent
+ GitLab.SystemHooks.Types: data ProjectRename
+ GitLab.SystemHooks.Types: data ProjectTransfer
+ GitLab.SystemHooks.Types: data ProjectUpdate
+ GitLab.SystemHooks.Types: data Push
+ GitLab.SystemHooks.Types: data RepositoryEvent
+ GitLab.SystemHooks.Types: data Rule
+ GitLab.SystemHooks.Types: data TagPush
+ GitLab.SystemHooks.Types: data UserAddToTeam
+ GitLab.SystemHooks.Types: data UserCreate
+ GitLab.SystemHooks.Types: data UserFailedLogin
+ GitLab.SystemHooks.Types: data UserRemove
+ GitLab.SystemHooks.Types: data UserRemoveFromTeam
+ GitLab.SystemHooks.Types: data UserRename
+ GitLab.SystemHooks.Types: data UserUpdateForTeam
+ GitLab.SystemHooks.Types: data Visibility
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.CommitAuthorEvent
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.CommitEvent
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.GroupCreate
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.GroupMemberRemove
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.GroupMemberUpdate
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.GroupRemove
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.GroupRename
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.KeyCreate
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.KeyRemove
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.NewGroupMember
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.ProjectAction
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.ProjectCreate
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.ProjectDestroy
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.ProjectEvent
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.ProjectRename
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.ProjectTransfer
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.ProjectUpdate
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.Push
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.RepositoryEvent
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.TagPush
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.UserAddToTeam
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.UserCreate
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.UserFailedLogin
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.UserRemove
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.UserRemoveFromTeam
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.UserRename
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.UserUpdateForTeam
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.Visibility
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.CommitAuthorEvent
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.CommitEvent
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.GroupCreate
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.GroupMemberRemove
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.GroupMemberUpdate
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.GroupRemove
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.GroupRename
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.KeyCreate
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.KeyRemove
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.NewGroupMember
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.ProjectAction
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.ProjectCreate
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.ProjectDestroy
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.ProjectEvent
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.ProjectRename
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.ProjectTransfer
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.ProjectUpdate
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.Push
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.RepositoryEvent
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.TagPush
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.UserAddToTeam
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.UserCreate
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.UserFailedLogin
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.UserRemove
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.UserRemoveFromTeam
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.UserRename
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.UserUpdateForTeam
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.Visibility
+ GitLab.SystemHooks.Types: instance GHC.Generics.Generic GitLab.SystemHooks.Types.CommitAuthorEvent
+ GitLab.SystemHooks.Types: instance GHC.Generics.Generic GitLab.SystemHooks.Types.CommitEvent
+ GitLab.SystemHooks.Types: instance GHC.Generics.Generic GitLab.SystemHooks.Types.ProjectEvent
+ GitLab.SystemHooks.Types: instance GHC.Generics.Generic GitLab.SystemHooks.Types.RepositoryEvent
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.CommitAuthorEvent
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.CommitEvent
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.GroupCreate
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.GroupMemberRemove
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.GroupMemberUpdate
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.GroupRemove
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.GroupRename
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.KeyCreate
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.KeyRemove
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.NewGroupMember
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.ProjectAction
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.ProjectCreate
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.ProjectDestroy
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.ProjectEvent
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.ProjectRename
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.ProjectTransfer
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.ProjectUpdate
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.Push
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.RepositoryEvent
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.TagPush
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.UserAddToTeam
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.UserCreate
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.UserFailedLogin
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.UserRemove
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.UserRemoveFromTeam
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.UserRename
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.UserUpdateForTeam
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.Visibility
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.GroupCreate
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.GroupMemberRemove
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.GroupMemberUpdate
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.GroupRemove
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.GroupRename
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.KeyCreate
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.KeyRemove
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.NewGroupMember
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.ProjectCreate
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.ProjectDestroy
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.ProjectRename
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.ProjectTransfer
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.ProjectUpdate
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.Push
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.TagPush
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.UserAddToTeam
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.UserCreate
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.UserFailedLogin
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.UserRemove
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.UserRemoveFromTeam
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.UserRename
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.UserUpdateForTeam
+ GitLab.SystemHooks.Types: match :: SystemHook a => String -> (a -> GitLab ()) -> Rule
+ GitLab.SystemHooks.Types: matchIf :: SystemHook a => String -> (a -> GitLab Bool) -> (a -> GitLab ()) -> Rule
+ GitLab.SystemHooks.Types: parseEvent :: FromJSON a => String -> Maybe a
+ GitLab.Types: EditIssueReq :: ProjectId -> IssueId -> Maybe Text -> Maybe Text -> Maybe Bool -> Maybe [Int] -> Maybe Int -> Maybe [Text] -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Int -> Maybe Bool -> Maybe Int -> Maybe Int -> EditIssueReq
+ GitLab.Types: MSActive :: MilestoneState
+ GitLab.Types: MSClosed :: MilestoneState
+ GitLab.Types: TP :: Int -> Text -> Text -> Text -> Text -> Text -> UTCTime -> TodoProject
+ GitLab.Types: [commit_parent_ids] :: Commit -> Maybe [String]
+ GitLab.Types: [edit_issue_assignee_ids] :: EditIssueReq -> Maybe [Int]
+ GitLab.Types: [edit_issue_confidential] :: EditIssueReq -> Maybe Bool
+ GitLab.Types: [edit_issue_description] :: EditIssueReq -> Maybe Text
+ GitLab.Types: [edit_issue_discussion_locked] :: EditIssueReq -> Maybe Bool
+ GitLab.Types: [edit_issue_due_date] :: EditIssueReq -> Maybe Text
+ GitLab.Types: [edit_issue_epic_id] :: EditIssueReq -> Maybe Int
+ GitLab.Types: [edit_issue_epic_iid] :: EditIssueReq -> Maybe Int
+ GitLab.Types: [edit_issue_id] :: EditIssueReq -> ProjectId
+ GitLab.Types: [edit_issue_issue_iid] :: EditIssueReq -> IssueId
+ GitLab.Types: [edit_issue_labels] :: EditIssueReq -> Maybe [Text]
+ GitLab.Types: [edit_issue_milestone_id] :: EditIssueReq -> Maybe Int
+ GitLab.Types: [edit_issue_state_event] :: EditIssueReq -> Maybe Text
+ GitLab.Types: [edit_issue_title] :: EditIssueReq -> Maybe Text
+ GitLab.Types: [edit_issue_updated_at] :: EditIssueReq -> Maybe Text
+ GitLab.Types: [edit_issue_weight] :: EditIssueReq -> Maybe Int
+ GitLab.Types: [job_artifacts] :: Job -> [Artifact]
+ GitLab.Types: [job_artifacts_expire_at] :: Job -> Maybe Text
+ GitLab.Types: [job_commit] :: Job -> Commit
+ GitLab.Types: [job_coverage] :: Job -> Maybe Text
+ GitLab.Types: [job_created_at] :: Job -> Text
+ GitLab.Types: [job_duration] :: Job -> Double
+ GitLab.Types: [job_finished_at] :: Job -> Text
+ GitLab.Types: [job_id] :: Job -> Int
+ GitLab.Types: [job_name] :: Job -> Text
+ GitLab.Types: [job_pipeline] :: Job -> Pipeline
+ GitLab.Types: [job_stage] :: Job -> Text
+ GitLab.Types: [job_started_at] :: Job -> Text
+ GitLab.Types: [job_status] :: Job -> Text
+ GitLab.Types: [job_tag] :: Job -> Bool
+ GitLab.Types: [job_user] :: Job -> User
+ GitLab.Types: [project_path_with_namespace] :: Project -> Text
+ GitLab.Types: [tp_created_at] :: TodoProject -> UTCTime
+ GitLab.Types: [tp_description] :: TodoProject -> Text
+ GitLab.Types: [tp_id] :: TodoProject -> Int
+ GitLab.Types: [tp_name] :: TodoProject -> Text
+ GitLab.Types: [tp_name_with_namespace] :: TodoProject -> Text
+ GitLab.Types: [tp_path] :: TodoProject -> Text
+ GitLab.Types: [tp_path_with_namespace] :: TodoProject -> Text
+ GitLab.Types: data EditIssueReq
+ GitLab.Types: data MilestoneState
+ GitLab.Types: data TodoProject
+ GitLab.Types: instance Data.Aeson.Types.ToJSON.ToJSON GitLab.Types.EditIssueReq
+ GitLab.Types: instance GHC.Generics.Generic GitLab.Types.EditIssueReq
+ GitLab.Types: instance GHC.Show.Show GitLab.Types.EditIssueReq
+ GitLab.Types: type IssueId = Int
+ GitLab.Types: type ProjectId = Int
- GitLab: runGitLab :: (MonadUnliftIO m, MonadIO m) => GitLabServerConfig -> GitLab m a -> m a
+ GitLab: runGitLab :: GitLabServerConfig -> GitLab a -> IO a
- GitLab: runGitLabWithManager :: (MonadUnliftIO m, MonadIO m) => Manager -> GitLabServerConfig -> GitLab m a -> m a
+ GitLab: runGitLabWithManager :: Manager -> GitLabServerConfig -> GitLab a -> IO a
- GitLab.API.Branches: branches :: MonadIO m => Project -> GitLab m [Branch]
+ GitLab.API.Branches: branches :: Project -> GitLab [Branch]
- GitLab.API.Branches: branches' :: MonadIO m => Int -> GitLab m (Either Status [Branch])
+ GitLab.API.Branches: branches' :: Int -> GitLab (Either Status [Branch])
- GitLab.API.Commits: commitDetails :: MonadIO m => Project -> Text -> GitLab m (Maybe Commit)
+ GitLab.API.Commits: commitDetails :: Project -> Text -> GitLab (Maybe Commit)
- GitLab.API.Commits: commitDetails' :: MonadIO m => Int -> Text -> GitLab m (Either Status (Maybe Commit))
+ GitLab.API.Commits: commitDetails' :: Int -> Text -> GitLab (Either Status (Maybe Commit))
- GitLab.API.Commits: projectCommits :: MonadIO m => Project -> GitLab m [Commit]
+ GitLab.API.Commits: projectCommits :: Project -> GitLab [Commit]
- GitLab.API.Commits: projectCommits' :: MonadIO m => Int -> GitLab m (Either Status [Commit])
+ GitLab.API.Commits: projectCommits' :: Int -> GitLab (Either Status [Commit])
- GitLab.API.Groups: addAllUsersToGroup :: (MonadIO m, MonadUnliftIO m) => Text -> AccessLevel -> GitLab m [Either Status Member]
+ GitLab.API.Groups: addAllUsersToGroup :: Text -> AccessLevel -> GitLab [Either Status Member]
- GitLab.API.Groups: addUserToGroup :: (MonadIO m, MonadUnliftIO m) => Text -> AccessLevel -> User -> GitLab m (Either Status Member)
+ GitLab.API.Groups: addUserToGroup :: Text -> AccessLevel -> User -> GitLab (Either Status Member)
- GitLab.API.Groups: addUserToGroup' :: (MonadIO m, MonadUnliftIO m) => Text -> AccessLevel -> Int -> GitLab m (Either Status Member)
+ GitLab.API.Groups: addUserToGroup' :: Text -> AccessLevel -> Int -> GitLab (Either Status Member)
- GitLab.API.Groups: addUsersToGroup :: (MonadIO m, MonadUnliftIO m) => Text -> AccessLevel -> [User] -> GitLab m [Either Status Member]
+ GitLab.API.Groups: addUsersToGroup :: Text -> AccessLevel -> [User] -> GitLab [Either Status Member]
- GitLab.API.Groups: addUsersToGroup' :: (MonadIO m, MonadUnliftIO m) => Text -> AccessLevel -> [Text] -> GitLab m [Either Status Member]
+ GitLab.API.Groups: addUsersToGroup' :: Text -> AccessLevel -> [Text] -> GitLab [Either Status Member]
- GitLab.API.Groups: groupsWithNameOrPath :: (MonadUnliftIO m, MonadIO m) => Text -> GitLab m (Either Status [Group])
+ GitLab.API.Groups: groupsWithNameOrPath :: Text -> GitLab (Either Status [Group])
- GitLab.API.Issues: projectOpenedIssues :: (MonadIO m, MonadUnliftIO m) => Project -> GitLab m [Issue]
+ GitLab.API.Issues: projectOpenedIssues :: Project -> GitLab [Issue]
- GitLab.API.Issues: projectOpenedIssues' :: (MonadIO m, MonadUnliftIO m) => Int -> GitLab m (Either Status [Issue])
+ GitLab.API.Issues: projectOpenedIssues' :: Int -> GitLab (Either Status [Issue])
- GitLab.API.Issues: userIssues :: MonadIO m => User -> GitLab m [Issue]
+ GitLab.API.Issues: userIssues :: User -> GitLab [Issue]
- GitLab.API.Jobs: jobs :: MonadIO m => Project -> GitLab m [Job]
+ GitLab.API.Jobs: jobs :: Project -> GitLab [Job]
- GitLab.API.Jobs: jobs' :: MonadIO m => Int -> GitLab m (Either Status [Job])
+ GitLab.API.Jobs: jobs' :: Int -> GitLab (Either Status [Job])
- GitLab.API.Members: addMemberToProject :: MonadIO m => Project -> AccessLevel -> User -> GitLab m (Either Status Member)
+ GitLab.API.Members: addMemberToProject :: Project -> AccessLevel -> User -> GitLab (Either Status Member)
- GitLab.API.Members: addMemberToProject' :: MonadIO m => Int -> AccessLevel -> Int -> GitLab m (Either Status Member)
+ GitLab.API.Members: addMemberToProject' :: Int -> AccessLevel -> Int -> GitLab (Either Status Member)
- GitLab.API.Members: addMembersToProject :: MonadIO m => Project -> AccessLevel -> [User] -> GitLab m [Either Status Member]
+ GitLab.API.Members: addMembersToProject :: Project -> AccessLevel -> [User] -> GitLab [Either Status Member]
- GitLab.API.Members: addMembersToProject' :: MonadIO m => Int -> AccessLevel -> [Int] -> GitLab m [Either Status Member]
+ GitLab.API.Members: addMembersToProject' :: Int -> AccessLevel -> [Int] -> GitLab [Either Status Member]
- GitLab.API.Members: membersOfProject :: MonadIO m => Project -> GitLab m [Member]
+ GitLab.API.Members: membersOfProject :: Project -> GitLab [Member]
- GitLab.API.Members: membersOfProject' :: MonadIO m => Int -> GitLab m (Either Status [Member])
+ GitLab.API.Members: membersOfProject' :: Int -> GitLab (Either Status [Member])
- GitLab.API.MergeRequests: acceptMergeRequest :: MonadIO m => Project -> Int -> GitLab m (Either Status MergeRequest)
+ GitLab.API.MergeRequests: acceptMergeRequest :: Project -> Int -> GitLab (Either Status MergeRequest)
- GitLab.API.MergeRequests: acceptMergeRequest' :: MonadIO m => Int -> Int -> GitLab m (Either Status MergeRequest)
+ GitLab.API.MergeRequests: acceptMergeRequest' :: Int -> Int -> GitLab (Either Status MergeRequest)
- GitLab.API.MergeRequests: createMergeRequest :: MonadIO m => Project -> Text -> Text -> Int -> Text -> Text -> GitLab m (Either Status MergeRequest)
+ GitLab.API.MergeRequests: createMergeRequest :: Project -> Text -> Text -> Int -> Text -> Text -> GitLab (Either Status MergeRequest)
- GitLab.API.MergeRequests: createMergeRequest' :: MonadIO m => Int -> Text -> Text -> Int -> Text -> Text -> GitLab m (Either Status MergeRequest)
+ GitLab.API.MergeRequests: createMergeRequest' :: Int -> Text -> Text -> Int -> Text -> Text -> GitLab (Either Status MergeRequest)
- GitLab.API.MergeRequests: mergeRequests :: MonadIO m => Project -> GitLab m [MergeRequest]
+ GitLab.API.MergeRequests: mergeRequests :: Project -> GitLab [MergeRequest]
- GitLab.API.MergeRequests: mergeRequests' :: MonadIO m => Int -> GitLab m (Either Status [MergeRequest])
+ GitLab.API.MergeRequests: mergeRequests' :: Int -> GitLab (Either Status [MergeRequest])
- GitLab.API.Pipelines: pipelines :: MonadIO m => Project -> GitLab m [Pipeline]
+ GitLab.API.Pipelines: pipelines :: Project -> GitLab [Pipeline]
- GitLab.API.Pipelines: pipelines' :: MonadIO m => Int -> GitLab m (Either Status [Pipeline])
+ GitLab.API.Pipelines: pipelines' :: Int -> GitLab (Either Status [Pipeline])
- GitLab.API.Projects: allProjects :: MonadIO m => GitLab m [Project]
+ GitLab.API.Projects: allProjects :: GitLab [Project]
- GitLab.API.Projects: commitsEmailAddresses :: (MonadUnliftIO m, MonadIO m) => Project -> GitLab m [Text]
+ GitLab.API.Projects: commitsEmailAddresses :: Project -> GitLab [Text]
- GitLab.API.Projects: commitsEmailAddresses' :: (MonadUnliftIO m, MonadIO m) => Int -> GitLab m (Either Status [Text])
+ GitLab.API.Projects: commitsEmailAddresses' :: Int -> GitLab (Either Status [Text])
- GitLab.API.Projects: issuesCreatedByUser :: (MonadUnliftIO m, MonadIO m) => Text -> GitLab m (Maybe (User, [Project]))
+ GitLab.API.Projects: issuesCreatedByUser :: Text -> GitLab (Maybe (User, [Project]))
- GitLab.API.Projects: issuesOnForks :: (MonadUnliftIO m, MonadIO m) => Text -> GitLab m [(Project, [Issue], [User])]
+ GitLab.API.Projects: issuesOnForks :: Text -> GitLab [(Project, [Issue], [User])]
- GitLab.API.Projects: multipleCommitters :: (MonadUnliftIO m, MonadIO m) => Project -> GitLab m Bool
+ GitLab.API.Projects: multipleCommitters :: Project -> GitLab Bool
- GitLab.API.Projects: namespacePathToUserId :: MonadIO m => Text -> GitLab m (Maybe Int)
+ GitLab.API.Projects: namespacePathToUserId :: Text -> GitLab (Maybe Int)
- GitLab.API.Projects: projectCISuccess :: MonadIO m => Project -> GitLab m Bool
+ GitLab.API.Projects: projectCISuccess :: Project -> GitLab Bool
- GitLab.API.Projects: projectDiffs :: MonadIO m => Project -> Text -> GitLab m (Either Status [Diff])
+ GitLab.API.Projects: projectDiffs :: Project -> Text -> GitLab (Either Status [Diff])
- GitLab.API.Projects: projectDiffs' :: MonadIO m => Int -> Text -> GitLab m (Either Status [Diff])
+ GitLab.API.Projects: projectDiffs' :: Int -> Text -> GitLab (Either Status [Diff])
- GitLab.API.Projects: projectForks :: (MonadUnliftIO m, MonadIO m) => Text -> GitLab m (Either Status [Project])
+ GitLab.API.Projects: projectForks :: Text -> GitLab (Either Status [Project])
- GitLab.API.Projects: projectMemebersCount :: MonadIO m => Project -> GitLab m (Text, [(Text, Text)])
+ GitLab.API.Projects: projectMemebersCount :: Project -> GitLab (Text, [(Text, Text)])
- GitLab.API.Projects: projectOfIssue :: MonadIO m => Issue -> GitLab m Project
+ GitLab.API.Projects: projectOfIssue :: Issue -> GitLab Project
- GitLab.API.Projects: projectsWithName :: (MonadUnliftIO m, MonadIO m) => Text -> GitLab m [Project]
+ GitLab.API.Projects: projectsWithName :: Text -> GitLab [Project]
- GitLab.API.Projects: projectsWithNameAndUser :: (MonadUnliftIO m, MonadIO m) => Text -> Text -> GitLab m (Either Status (Maybe Project))
+ GitLab.API.Projects: projectsWithNameAndUser :: Text -> Text -> GitLab (Either Status (Maybe Project))
- GitLab.API.Projects: searchProjectId :: MonadIO m => Int -> GitLab m (Either Status (Maybe Project))
+ GitLab.API.Projects: searchProjectId :: Int -> GitLab (Either Status (Maybe Project))
- GitLab.API.Projects: shareProjectWithGroup :: MonadIO m => Int -> Int -> AccessLevel -> GitLab m (Either Status GroupShare)
+ GitLab.API.Projects: shareProjectWithGroup :: Int -> Int -> AccessLevel -> GitLab (Either Status GroupShare)
- GitLab.API.Projects: userProjects :: (MonadUnliftIO m, MonadIO m) => User -> GitLab m (Maybe [Project])
+ GitLab.API.Projects: userProjects :: User -> GitLab (Maybe [Project])
- GitLab.API.Projects: userProjects' :: (MonadUnliftIO m, MonadIO m) => Text -> GitLab m (Maybe [Project])
+ GitLab.API.Projects: userProjects' :: Text -> GitLab (Maybe [Project])
- GitLab.API.Repositories: getFileArchive :: MonadIO m => Project -> ArchiveFormat -> FilePath -> GitLab m (Either Status ())
+ GitLab.API.Repositories: getFileArchive :: Project -> ArchiveFormat -> FilePath -> GitLab (Either Status ())
- GitLab.API.Repositories: getFileArchive' :: MonadIO m => Int -> ArchiveFormat -> FilePath -> GitLab m (Either Status ())
+ GitLab.API.Repositories: getFileArchive' :: Int -> ArchiveFormat -> FilePath -> GitLab (Either Status ())
- GitLab.API.Repositories: getFileArchiveBS :: MonadIO m => Project -> ArchiveFormat -> GitLab m (Either Status ByteString)
+ GitLab.API.Repositories: getFileArchiveBS :: Project -> ArchiveFormat -> GitLab (Either Status ByteString)
- GitLab.API.Repositories: getFileArchiveBS' :: MonadIO m => Int -> ArchiveFormat -> GitLab m (Either Status ByteString)
+ GitLab.API.Repositories: getFileArchiveBS' :: Int -> ArchiveFormat -> GitLab (Either Status ByteString)
- GitLab.API.Repositories: repositories :: MonadIO m => Project -> GitLab m [Repository]
+ GitLab.API.Repositories: repositories :: Project -> GitLab [Repository]
- GitLab.API.Repositories: repositories' :: MonadIO m => Int -> GitLab m (Either Status [Repository])
+ GitLab.API.Repositories: repositories' :: Int -> GitLab (Either Status [Repository])
- GitLab.API.RepositoryFiles: repositoryFileBlob :: MonadIO m => Int -> Text -> GitLab m (Either Status String)
+ GitLab.API.RepositoryFiles: repositoryFileBlob :: Int -> Text -> GitLab (Either Status String)
- GitLab.API.RepositoryFiles: repositoryFiles :: MonadIO m => Project -> Text -> Text -> GitLab m (Either Status (Maybe RepositoryFile))
+ GitLab.API.RepositoryFiles: repositoryFiles :: Project -> Text -> Text -> GitLab (Either Status (Maybe RepositoryFile))
- GitLab.API.RepositoryFiles: repositoryFiles' :: MonadIO m => Int -> Text -> Text -> GitLab m (Either Status (Maybe RepositoryFile))
+ GitLab.API.RepositoryFiles: repositoryFiles' :: Int -> Text -> Text -> GitLab (Either Status (Maybe RepositoryFile))
- GitLab.API.Todos: todos :: MonadIO m => GitLab m [Todo]
+ GitLab.API.Todos: todos :: GitLab [Todo]
- GitLab.API.Users: allUsers :: MonadIO m => GitLab m [User]
+ GitLab.API.Users: allUsers :: GitLab [User]
- GitLab.API.Users: orderedUsers :: MonadIO m => [Text] -> GitLab m [User]
+ GitLab.API.Users: orderedUsers :: [Text] -> GitLab [User]
- GitLab.API.Users: searchUser :: MonadIO m => Text -> GitLab m (Maybe User)
+ GitLab.API.Users: searchUser :: Text -> GitLab (Maybe User)
- GitLab.API.Version: gitlabVersion :: MonadIO m => GitLab m (Either Status (Maybe Version))
+ GitLab.API.Version: gitlabVersion :: GitLab (Either Status (Maybe Version))
- GitLab.Types: Commit :: Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Maybe [Int] -> Maybe Pipeline -> Maybe CommitStats -> Maybe Text -> Commit
+ GitLab.Types: Commit :: Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Maybe [String] -> Maybe Pipeline -> Maybe CommitStats -> Maybe Text -> Commit
- GitLab.Types: CommitTodo :: Text -> Text -> Text -> Maybe [Int] -> CommitTodo
+ GitLab.Types: CommitTodo :: Text -> Text -> Text -> Maybe [String] -> CommitTodo
- GitLab.Types: Issue :: Text -> Text -> User -> Maybe Milestone -> Int -> Maybe [User] -> Maybe User -> Text -> Maybe Text -> Maybe User -> Int -> Text -> Text -> Int -> [Text] -> Int -> Int -> Int -> Maybe Text -> Text -> Bool -> Maybe Text -> Maybe Bool -> TimeStats -> Issue
+ GitLab.Types: Issue :: Text -> Maybe Text -> User -> Maybe Milestone -> ProjectId -> Maybe [User] -> Maybe User -> Text -> Maybe Text -> Maybe User -> IssueId -> Text -> Text -> Int -> [Text] -> Int -> Int -> Int -> Maybe Text -> Text -> Bool -> Maybe Text -> Maybe Bool -> TimeStats -> Issue
- GitLab.Types: [issue_description] :: Issue -> Text
+ GitLab.Types: [issue_description] :: Issue -> Maybe Text
- GitLab.Types: [issue_id] :: Issue -> Int
+ GitLab.Types: [issue_id] :: Issue -> IssueId
- GitLab.Types: [issue_project_id] :: Issue -> Int
+ GitLab.Types: [issue_project_id] :: Issue -> ProjectId
- GitLab.Types: [todo_parent_ids] :: CommitTodo -> Maybe [Int]
+ GitLab.Types: [todo_parent_ids] :: CommitTodo -> Maybe [String]
- GitLab.Types: type GitLab m a = ReaderT GitLabState m a
+ GitLab.Types: type GitLab a = ReaderT GitLabState IO a
Files
- gitlab-haskell.cabal +32/−2
- src/GitLab.hs +16/−6
- src/GitLab/API/Branches.hs +2/−3
- src/GitLab/API/Commits.hs +4/−9
- src/GitLab/API/Groups.hs +8/−17
- src/GitLab/API/Issues.hs +61/−8
- src/GitLab/API/Jobs.hs +2/−5
- src/GitLab/API/Members.hs +6/−11
- src/GitLab/API/MergeRequests.hs +6/−13
- src/GitLab/API/Pipelines.hs +2/−5
- src/GitLab/API/Projects.hs +24/−37
- src/GitLab/API/Repositories.hs +6/−12
- src/GitLab/API/RepositoryFiles.hs +3/−7
- src/GitLab/API/Todos.hs +1/−2
- src/GitLab/API/Users.hs +6/−9
- src/GitLab/API/Version.hs +2/−2
- src/GitLab/SystemHooks/GitLabSystemHooks.hs +262/−0
- src/GitLab/SystemHooks/Types.hs +1154/−0
- src/GitLab/Types.hs +414/−384
- src/GitLab/WebRequests/GitLabWebCalls.hs +90/−15
- tests/SystemHookTests.hs +1392/−0
- tests/Tests.hs +16/−0
gitlab-haskell.cabal view
@@ -1,11 +1,13 @@ cabal-version: 2.4 name: gitlab-haskell category: Git-version: 0.1.8+version: 0.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/> .+ It also features an API for writing Gitlab file hook applications+ . Run all GitLab actions with `runGitLab`: . > runGitLab :: (MonadUnliftIO m, MonadIO m)@@ -26,6 +28,16 @@ > searchUser :: Text -> GitLab m (Maybe User) > userProjects :: User -> GitLab m (Maybe [Project]) .+ This library can also be used to develop rule based GitLab file hooks that react in real time to GitLab events with:+ .+ > receive :: [Rule] -> GitLab ()+ .+ > class (FromJSON a) => SystemHook a where+ > match :: String -> (a -> GitLab ()) -> Rule+ > matchIf :: String -> (a -> GitLab Bool) -> (a -> GitLab ()) -> Rule+ .+ For more details about the file hooks support: <https://www.macs.hw.ac.uk/~rs46/posts/2020-06-06-gitlab-system-hooks.html>+ . Unsurprisingly, this library is maintained on GitLab: <https://gitlab.com/robstewart57/gitlab-haskell> @@ -33,7 +45,7 @@ bug-reports: https://gitlab.com/robstewart57/gitlab-haskell/issues author: Rob Stewart maintainer: robstewart57@gmail.com-copyright: 2019 Rob Stewart, Heriot-Watt University+copyright: 2020 Rob Stewart, Heriot-Watt University license: BSD-3-Clause license-file: LICENSE build-type: Simple@@ -62,6 +74,8 @@ , GitLab.API.RepositoryFiles , GitLab.API.Todos , GitLab.API.Version+ , GitLab.SystemHooks.Types+ , GitLab.SystemHooks.GitLabSystemHooks other-modules: GitLab.WebRequests.GitLabWebCalls hs-source-dirs:@@ -80,3 +94,19 @@ , time default-language: Haskell2010 ghc-options: -Wall+ -- the following two for the stan static analysis tool+ -- -fwrite-ide-info+ -- -hiedir=.hie++test-suite test-gitlab-haskell+ type: exitcode-stdio-1.0+ main-is: Tests.hs+ other-modules: SystemHookTests+ hs-source-dirs: tests/+ default-language: Haskell2010+ build-depends: base >= 4.8.0.0 && < 6+ , tasty+ , tasty-hunit+ , gitlab-haskell+ , bytestring+ , aeson
src/GitLab.hs view
@@ -9,6 +9,7 @@ -- Stability : stable module GitLab ( runGitLab,+ runGitLabDbg, runGitLabWithManager, module GitLab.Types, module GitLab.API.Pipelines,@@ -25,11 +26,12 @@ module GitLab.API.RepositoryFiles, module GitLab.API.Todos, module GitLab.API.Version,+ module GitLab.SystemHooks.GitLabSystemHooks,+ module GitLab.SystemHooks.Types, ) where import Control.Monad.IO.Class-import Control.Monad.IO.Unlift import Control.Monad.Trans.Reader import GitLab.API.Branches import GitLab.API.Commits@@ -45,6 +47,8 @@ import GitLab.API.Todos import GitLab.API.Users import GitLab.API.Version+import GitLab.SystemHooks.GitLabSystemHooks+import GitLab.SystemHooks.Types import GitLab.Types import Network.Connection (TLSSettings (..)) import Network.HTTP.Conduit@@ -61,15 +65,14 @@ -- -- > projectsWithIssuesEnabled :: IO [Project] -- > projectsWithIssuesEnabled =--- > runGitLab myConfig $ filter (issueEnabled . issues_enabled) <$> allProjects+-- > runGitLabyConfig $ filter (issueEnabled . issues_enabled) <$> allProjects -- > where -- > myConfig = defaultGitLabServer -- > { url = "https://gitlab.example.com" -- > , token = "my_access_token" } -- > issueEnabled Nothing = False -- > issueEnabled (Just b) = b-runGitLab ::- (MonadUnliftIO m, MonadIO m) => GitLabServerConfig -> GitLab m a -> m a+runGitLab :: GitLabServerConfig -> GitLab a -> IO a runGitLab cfg action = do liftIO $ hSetBuffering stdout LineBuffering let settings = mkManagerSettings (TLSSettingsSimple True False False) Nothing@@ -78,8 +81,7 @@ -- | The same as 'runGitLab', except that it also takes a connection -- manager as an argument.-runGitLabWithManager ::- (MonadUnliftIO m, MonadIO m) => Manager -> GitLabServerConfig -> GitLab m a -> m a+runGitLabWithManager :: Manager -> GitLabServerConfig -> GitLab a -> IO a runGitLabWithManager manager cfg action = do -- test the token access tokenTest <- runReaderT gitlabVersion (GitLabState cfg manager)@@ -89,3 +91,11 @@ Right _versionInfo -> -- it worked, run the user code. runReaderT action (GitLabState cfg manager)++-- | Only useful for testing GitLab actions that lift IO actions with+-- liftIO. Cannot speak to a GitLab server. Only useful for the+-- gitlab-haskell tests.+runGitLabDbg :: GitLab a -> IO a+runGitLabDbg action = do+ liftIO $ hSetBuffering stdout LineBuffering+ runReaderT action undefined
src/GitLab/API/Branches.hs view
@@ -9,7 +9,6 @@ -- Stability : stable module GitLab.API.Branches where -import Control.Monad.IO.Unlift import Data.Either import qualified Data.Text as T import GitLab.Types@@ -18,14 +17,14 @@ -- | Get a list of repository branches from a project, sorted by name -- alphabetically.-branches :: (MonadIO m) => Project -> GitLab m [Branch]+branches :: Project -> GitLab [Branch] branches project = do result <- branches' (project_id project) return (fromRight (error "branches error") result) -- | Get a list of repository branches from a project given its -- project ID, sorted by name alphabetically.-branches' :: (MonadIO m) => Int -> GitLab m (Either Status [Branch])+branches' :: Int -> GitLab (Either Status [Branch]) branches' projectId = gitlab addr where
src/GitLab/API/Commits.hs view
@@ -9,7 +9,6 @@ -- Stability : stable module GitLab.API.Commits where -import Control.Monad.IO.Unlift import Data.Either import Data.Text (Text) import qualified Data.Text as T@@ -19,20 +18,18 @@ -- | returns all commits for a project. projectCommits ::- (MonadIO m) => -- | the project Project ->- GitLab m [Commit]+ GitLab [Commit] projectCommits project = do result <- projectCommits' (project_id project) return (fromRight (error "projectCommits error") result) -- | returns all commits for a project given its project ID. projectCommits' ::- (MonadIO m) => -- | project ID Int ->- GitLab m (Either Status [Commit])+ GitLab (Either Status [Commit]) projectCommits' projectId = gitlabWithAttrs (commitsAddr projectId) "&with_stats=true" where@@ -43,12 +40,11 @@ -- | returns a commit for the given project and commit hash, if such -- a commit exists. commitDetails ::- (MonadIO m) => -- | the project Project -> -- | the commit hash Text ->- GitLab m (Maybe Commit)+ GitLab (Maybe Commit) commitDetails project theHash = do result <- commitDetails' (project_id project) theHash return (fromRight (error "commitDetails error") result)@@ -56,12 +52,11 @@ -- | returns a commit for the given project ID and commit hash, if -- such a commit exists. commitDetails' ::- (MonadIO m) => -- | project ID Int -> -- | the commit hash Text ->- GitLab m (Either Status (Maybe Commit))+ GitLab (Either Status (Maybe Commit)) commitDetails' projectId hash = gitlabOne (commitsAddr projectId) where
src/GitLab/API/Groups.hs view
@@ -10,9 +10,6 @@ -- Stability : stable module GitLab.API.Groups where -import Control.Monad.IO.Class-import Control.Monad.IO.Unlift-import qualified Data.ByteString.Char8 as C import Data.Maybe import Data.Text (Text) import qualified Data.Text as T@@ -28,10 +25,9 @@ -- -- > projectsWithNameOrPath "group1" groupsWithNameOrPath ::- (MonadUnliftIO m, MonadIO m) => -- | group name being searched for. Text ->- GitLab m (Either Status [Group])+ GitLab (Either Status [Group]) groupsWithNameOrPath groupName = do result <- gitlabWithAttrs "/groups" ("&search=" <> groupName) case result of@@ -49,12 +45,11 @@ -- | adds all registered users to a group. addAllUsersToGroup ::- (MonadIO m, MonadUnliftIO m) => -- | group name Text -> -- | level of access granted AccessLevel ->- GitLab m [Either Status Member]+ GitLab [Either Status Member] addAllUsersToGroup groupName access = do allRegisteredUsers <- allUsers let allUserIds = map user_username allRegisteredUsers@@ -62,32 +57,30 @@ -- | adds a user to a group. addUserToGroup ::- (MonadIO m, MonadUnliftIO m) => -- | group name Text -> -- | level of access granted AccessLevel -> -- | the user User ->- GitLab m (Either Status Member)+ GitLab (Either Status Member) addUserToGroup groupName access usr = addUserToGroup' groupName access (user_id usr) -- | adds a user with a given user ID to a group. addUserToGroup' ::- (MonadIO m, MonadUnliftIO m) => -- | group name Text -> -- | level of access granted AccessLevel -> -- | user ID Int ->- GitLab m (Either Status Member)+ GitLab (Either Status Member) addUserToGroup' groupName access userId = do attempt <- groupsWithNameOrPath groupName case attempt of Left httpStatus -> return (Left httpStatus)- Right [] -> return (Left (mkStatus 404 (C.pack "cannot find group")))+ Right [] -> return (Left (mkStatus 404 (T.encodeUtf8 (T.pack "cannot find group")))) Right [grp] -> gitlabPost addr dataBody where@@ -100,31 +93,29 @@ <> T.decodeUtf8 (urlEncode False (T.encodeUtf8 (T.pack (show (group_id grp))))) <> "/members" Right (_ : _) ->- return (Left (mkStatus 404 (C.pack "too many groups found")))+ return (Left (mkStatus 404 (T.encodeUtf8 (T.pack "too many groups found")))) -- | adds a list of users to a group. addUsersToGroup ::- (MonadIO m, MonadUnliftIO m) => -- | group name Text -> -- | level of access granted AccessLevel -> -- | list of usernames to be added to the group [User] ->- GitLab m [Either Status Member]+ GitLab [Either Status Member] addUsersToGroup groupName access = mapM (addUserToGroup groupName access) -- | adds a list of users to a group. addUsersToGroup' ::- (MonadIO m, MonadUnliftIO m) => -- | group name Text -> -- | level of access granted AccessLevel -> -- | list of usernames to be added to the group [Text] ->- GitLab m [Either Status Member]+ GitLab [Either Status Member] addUsersToGroup' groupName access usernames = do users <- catMaybes <$> mapM searchUser usernames mapM (addUserToGroup' groupName access . user_id) users
src/GitLab/API/Issues.hs view
@@ -10,30 +10,30 @@ -- Stability : stable module GitLab.API.Issues where -import Control.Monad.IO.Class-import Control.Monad.IO.Unlift+import qualified Data.Aeson as J import Data.Either+import Data.Text (Text) import qualified Data.Text as T+import qualified Data.Text.Lazy+import qualified Data.Text.Lazy.Encoding import GitLab.Types import GitLab.WebRequests.GitLabWebCalls import Network.HTTP.Types.Status -- | returns all issues against a project. projectOpenedIssues ::- (MonadIO m, MonadUnliftIO m) => -- | the project Project ->- GitLab m [Issue]+ GitLab [Issue] projectOpenedIssues p = do result <- projectOpenedIssues' (project_id p) return (fromRight (error "projectOpenedIssues error") result) -- | returns all issues against a project given its project ID. projectOpenedIssues' ::- (MonadIO m, MonadUnliftIO m) => -- | the project ID Int ->- GitLab m (Either Status [Issue])+ GitLab (Either Status [Issue]) projectOpenedIssues' projectId = do let path = "/projects/" <> T.pack (show projectId) <> "/issues" gitlab path@@ -42,10 +42,9 @@ -- | gets all issues create by a user. userIssues ::- (MonadIO m) => -- | the user User ->- GitLab m [Issue]+ GitLab [Issue] userIssues usr = gitlabWithAttrsUnsafe addr attrs where@@ -55,3 +54,57 @@ "&author_id=" <> show (user_id usr) <> "&scope=all"++-- | create a new issue.+newIssue ::+ -- | project+ Project ->+ -- | issue title+ Text ->+ -- | issue description+ Text ->+ GitLab (Either Status Issue)+newIssue project =+ newIssue' (project_id project)++-- | create a new issue.+newIssue' ::+ -- | project ID+ Int ->+ -- | issue title+ Text ->+ -- | issue description+ Text ->+ GitLab (Either Status Issue)+newIssue' projectId issueTitle issueDescription =+ gitlabPost addr dataBody+ where+ dataBody :: Text+ dataBody =+ "title="+ <> issueTitle+ <> "&description="+ <> issueDescription+ addr =+ "/projects/"+ <> T.pack (show projectId)+ <> "/issues"++-- | edits an issue. see <https://docs.gitlab.com/ee/api/issues.html#edit-issue>+editIssue ::+ ProjectId ->+ IssueId ->+ EditIssueReq ->+ GitLab (Either Status Issue)+editIssue projId issueId editIssueReq = do+ let path =+ "/projects/" <> T.pack (show projId)+ <> "/issues/"+ <> T.pack (show issueId)+ gitlabPut+ path+ ( Data.Text.Lazy.toStrict+ ( Data.Text.Lazy.Encoding.decodeUtf8+ (J.encode editIssueReq)+ )+ )
src/GitLab/API/Jobs.hs view
@@ -9,7 +9,6 @@ -- Stability : stable module GitLab.API.Jobs where -import Control.Monad.IO.Unlift import Data.Either import qualified Data.Text as T import GitLab.Types@@ -18,20 +17,18 @@ -- | returns all jobs ran on a project. jobs ::- (MonadIO m) => -- | the project Project ->- GitLab m [Job]+ GitLab [Job] jobs project = do result <- jobs' (project_id project) return (fromRight (error "jobs error") result) -- | returns all jobs ran on a project given its project ID. jobs' ::- (MonadIO m) => -- | the project ID Int ->- GitLab m (Either Status [Job])+ GitLab (Either Status [Job]) jobs' projectId = gitlab addr where
src/GitLab/API/Members.hs view
@@ -10,7 +10,6 @@ -- Stability : stable module GitLab.API.Members where -import Control.Monad.IO.Class import Data.Either import Data.Text (Text) import qualified Data.Text as T@@ -34,13 +33,13 @@ show Owner = "50" -- | the members of a project.-membersOfProject :: (MonadIO m) => Project -> GitLab m [Member]+membersOfProject :: Project -> GitLab [Member] membersOfProject p = do result <- membersOfProject' (project_id p) return (fromRight (error "membersOfProject error") result) -- | the members of a project given its ID.-membersOfProject' :: (MonadIO m) => Int -> GitLab m (Either Status [Member])+membersOfProject' :: Int -> GitLab (Either Status [Member]) membersOfProject' projectId = gitlab addr where@@ -51,14 +50,13 @@ -- 'Right Member' for each successful action, otherwise it returns -- 'Left Status'. addMemberToProject ::- (MonadIO m) => -- | the project Project -> -- | level of access AccessLevel -> -- | the user User ->- GitLab m (Either Status Member)+ GitLab (Either Status Member) addMemberToProject project access usr = addMemberToProject' (project_id project) access (user_id usr) @@ -66,14 +64,13 @@ -- project's ID and the user's ID. Returns @Right Member@ for each -- successful action, otherwise it returns @Left Status@. addMemberToProject' ::- (MonadIO m) => -- | project ID Int -> -- | level of access AccessLevel -> -- | user ID Int ->- GitLab m (Either Status Member)+ GitLab (Either Status Member) addMemberToProject' projectId access userId = gitlabPost addr dataBody where@@ -87,14 +84,13 @@ -- level. Returns 'Right Member' for each successful action, otherwise -- it returns 'Left Status'. addMembersToProject ::- (MonadIO m) => -- | the project Project -> -- | level of access AccessLevel -> -- | users to add to the project [User] ->- GitLab m [Either Status Member]+ GitLab [Either Status Member] addMembersToProject project access = mapM (addMemberToProject project access) @@ -102,13 +98,12 @@ -- given the project's ID and the user IDs. Returns @Right Member@ for -- each successful action, otherwise it returns @Left Status@. addMembersToProject' ::- (MonadIO m) => -- | project ID Int -> -- | level of acces AccessLevel -> -- | IDs of users to add to the project [Int] ->- GitLab m [Either Status Member]+ GitLab [Either Status Member] addMembersToProject' projectId access = mapM (addMemberToProject' projectId access)
src/GitLab/API/MergeRequests.hs view
@@ -9,7 +9,6 @@ -- Stability : stable module GitLab.API.MergeRequests where -import Control.Monad.IO.Unlift import Data.Either import Data.Text (Text) import qualified Data.Text as T@@ -19,20 +18,18 @@ -- | returns the merge requests for a project. mergeRequests ::- (MonadIO m) => -- | the project Project ->- GitLab m [MergeRequest]+ GitLab [MergeRequest] mergeRequests p = do result <- mergeRequests' (project_id p) return (fromRight (error "mergeRequests error") result) -- | returns the merge requests for a project given its project ID. mergeRequests' ::- (MonadIO m) => -- | project ID Int ->- GitLab m (Either Status [MergeRequest])+ GitLab (Either Status [MergeRequest]) mergeRequests' projectId = gitlabWithAttrs addr "&scope=all" where@@ -43,7 +40,6 @@ -- | Creates a merge request. createMergeRequest ::- (MonadIO m) => -- | project Project -> -- | source branch@@ -56,13 +52,12 @@ Text -> -- | merge request description Text ->- GitLab m (Either Status MergeRequest)+ GitLab (Either Status MergeRequest) createMergeRequest project = createMergeRequest' (project_id project) -- | Creates a merge request. createMergeRequest' ::- (MonadIO m) => -- | project ID Int -> -- | source branch@@ -75,7 +70,7 @@ Text -> -- | merge request description Text ->- GitLab m (Either Status MergeRequest)+ GitLab (Either Status MergeRequest) createMergeRequest' projectId sourceBranch targetBranch targetProjectId mrTitle mrDescription = gitlabPost addr dataBody where@@ -92,23 +87,21 @@ -- | Accepts a merge request. acceptMergeRequest ::- (MonadIO m) => -- | project Project -> -- | merge request IID Int ->- GitLab m (Either Status MergeRequest)+ GitLab (Either Status MergeRequest) acceptMergeRequest project = acceptMergeRequest' (project_id project) -- | Accepts a merge request. acceptMergeRequest' ::- (MonadIO m) => -- | project ID Int -> -- | merge request IID Int ->- GitLab m (Either Status MergeRequest)+ GitLab (Either Status MergeRequest) acceptMergeRequest' projectId mergeRequestIid = gitlabPost addr dataBody where dataBody :: Text
src/GitLab/API/Pipelines.hs view
@@ -9,7 +9,6 @@ -- Stability : stable module GitLab.API.Pipelines where -import Control.Monad.IO.Unlift import Data.Either import qualified Data.Text as T import GitLab.Types@@ -18,20 +17,18 @@ -- | returns the pipelines for a project. pipelines ::- (MonadIO m) => -- | the project Project ->- GitLab m [Pipeline]+ GitLab [Pipeline] pipelines p = do result <- pipelines' (project_id p) return (fromRight (error "pipelines error") result) -- | returns the pipelines for a project given its project ID. pipelines' ::- (MonadIO m) => -- | the project ID Int ->- GitLab m (Either Status [Pipeline])+ GitLab (Either Status [Pipeline]) pipelines' projectId = gitlabWithAttrs addr
src/GitLab/API/Projects.hs view
@@ -10,11 +10,8 @@ -- Stability : stable module GitLab.API.Projects where -import Control.Monad.IO.Class-import Control.Monad.IO.Unlift import Data.Either import Data.List-import Data.Maybe import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Encoding as T@@ -30,7 +27,7 @@ import UnliftIO.Async -- | gets all projects.-allProjects :: (MonadIO m) => GitLab m [Project]+allProjects :: GitLab [Project] allProjects = gitlabWithAttrsUnsafe "/projects" "&statistics=true" @@ -39,10 +36,9 @@ -- > projectForks "project1" -- > projectForks "group1/project1" projectForks ::- (MonadUnliftIO m, MonadIO m) => -- | name or namespace of the project Text ->- GitLab m (Either Status [Project])+ GitLab (Either Status [Project]) projectForks projectName = do let urlPath = "/projects/"@@ -53,10 +49,9 @@ -- | searches for a 'Project' with the given project ID, returns -- 'Nothing' if a project with the given ID is not found. searchProjectId ::- (MonadIO m) => -- | project ID Int ->- GitLab m (Either Status (Maybe Project))+ GitLab (Either Status (Maybe Project)) searchProjectId projectId = do let urlPath = T.pack ("/projects/" <> show projectId) gitlabWithAttrsOne urlPath "&statistics=true"@@ -65,10 +60,9 @@ -- -- > projectsWithName "project1" projectsWithName ::- (MonadUnliftIO m, MonadIO m) => -- | project name being searched for. Text ->- GitLab m [Project]+ GitLab [Project] projectsWithName projectName = filter (\project -> projectName == project_path project) <$> gitlabWithAttrsUnsafe "/projects" ("&search=" <> projectName)@@ -78,8 +72,7 @@ -- > projectsNamespaceName "user1" "project1" -- -- looks for "user1/project1"-projectsWithNameAndUser ::- (MonadUnliftIO m, MonadIO m) => Text -> Text -> GitLab m (Either Status (Maybe Project))+projectsWithNameAndUser :: Text -> Text -> GitLab (Either Status (Maybe Project)) projectsWithNameAndUser username projectName = gitlabWithAttrsOne ( "/projects/"@@ -90,22 +83,21 @@ -- | returns 'True' if a project has multiple committers, according to -- the email addresses of the commits.-multipleCommitters :: (MonadUnliftIO m, MonadIO m) => Project -> GitLab m Bool+multipleCommitters :: Project -> GitLab Bool multipleCommitters project = do emailAddresses <- commitsEmailAddresses project return (length (nub emailAddresses) > 1) -- | gets the email addresses in the author information in all commit -- for a project.-commitsEmailAddresses ::- (MonadUnliftIO m, MonadIO m) => Project -> GitLab m [Text]+commitsEmailAddresses :: Project -> GitLab [Text] commitsEmailAddresses project = do result <- commitsEmailAddresses' (project_id project) return (fromRight (error "commitsEmailAddresses error") result) -- | gets the email addresses in the author information in all commit -- for a project defined by the project's ID.-commitsEmailAddresses' :: (MonadUnliftIO m, MonadIO m) => Int -> GitLab m (Either Status [Text])+commitsEmailAddresses' :: Int -> GitLab (Either Status [Text]) commitsEmailAddresses' projectId = do -- (commits :: [Commit]) <- projectCommits' projectId attempt <- projectCommits' projectId@@ -117,8 +109,7 @@ -- | gets all projects for a user given their username. -- -- > userProjects "harry"-userProjects' ::- (MonadUnliftIO m, MonadIO m) => Text -> GitLab m (Maybe [Project])+userProjects' :: Text -> GitLab (Maybe [Project]) userProjects' username = do userMaybe <- searchUser username case userMaybe of@@ -130,26 +121,27 @@ -- | gets all projects for a user. -- -- > userProjects myUser-userProjects ::- (MonadUnliftIO m, MonadIO m) => User -> GitLab m (Maybe [Project])+userProjects :: User -> GitLab (Maybe [Project]) userProjects theUser = userProjects' (user_username theUser) -- | gets the 'GitLab.Types.Project' against which the given 'Issue' -- was created.-projectOfIssue :: (MonadIO m) => Issue -> GitLab m Project+projectOfIssue :: Issue -> GitLab Project projectOfIssue issue = do result <- searchProjectId (issue_project_id issue)- return (fromJust (fromRight (error "projectOfIssue error") result))+ case fromRight (error "projectOfIssue error") result of+ Nothing -> error "projectOfIssue error"+ Just proj -> return proj -- | finds all issues created by a user. -- -- > issuesCreatedByUser "user1" ----- returns a (user,projects) tuple, where 'user' is the 'User' found+-- returns a (user,projects) tuple, where user is the 'User' found -- for the given searched username, and a list of 'Project's that the -- user has created issues for.-issuesCreatedByUser :: (MonadUnliftIO m, MonadIO m) => Text -> GitLab m (Maybe (User, [Project]))+issuesCreatedByUser :: Text -> GitLab (Maybe (User, [Project])) issuesCreatedByUser username = do user_maybe <- searchUser username case user_maybe of@@ -163,18 +155,16 @@ -- of triples of: 1) the found project, 2) the list of issues for the -- found projects, and 3) a list of users who've created issues. issuesOnForks ::- (MonadUnliftIO m, MonadIO m) => -- | name or namespace of the project Text ->- GitLab m [(Project, [Issue], [User])]+ GitLab [(Project, [Issue], [User])] issuesOnForks projectName = do projects <- projectsWithName projectName mapM processProject projects where processProject ::- (MonadUnliftIO m, MonadIO m) => Project ->- GitLab m (Project, [Issue], [User])+ GitLab (Project, [Issue], [User]) processProject proj = do (openIssues :: [Issue]) <- projectOpenedIssues proj let authors = map issue_author openIssues@@ -184,7 +174,7 @@ -- where namespace is the namespace of the project -- e.g. "user1/project1", and members is a list of (username,name) -- tuples about all members of the project.-projectMemebersCount :: (MonadIO m) => Project -> GitLab m (Text, [(Text, Text)])+projectMemebersCount :: Project -> GitLab (Text, [(Text, Text)]) projectMemebersCount project = do friends <- count return (namespace_name (namespace project), friends)@@ -198,10 +188,9 @@ -- | returns 'True' is the last commit for a project passes all -- continuous integration tests. projectCISuccess ::- (MonadIO m) => -- | the name or namespace of the project Project ->- GitLab m Bool+ GitLab Bool projectCISuccess project = do pipes <- pipelines project case pipes of@@ -211,10 +200,9 @@ -- | searches for a username, and returns a user ID for that user, or -- 'Nothing' if a user cannot be found. namespacePathToUserId ::- (MonadIO m) => -- | name or namespace of project Text ->- GitLab m (Maybe Int)+ GitLab (Maybe Int) namespacePathToUserId namespacePath = do user_maybe <- searchUser namespacePath case user_maybe of@@ -222,13 +210,13 @@ Just usr -> return (Just (user_id usr)) -- | gets all diffs in a project for a given commit SHA.-projectDiffs :: (MonadIO m) => Project -> Text -> GitLab m (Either Status [Diff])+projectDiffs :: Project -> Text -> GitLab (Either Status [Diff]) projectDiffs proj = projectDiffs' (project_id proj) -- | gets all diffs in a project for a given project ID, for a given -- commit SHA.-projectDiffs' :: (MonadIO m) => Int -> Text -> GitLab m (Either Status [Diff])+projectDiffs' :: Int -> Text -> GitLab (Either Status [Diff]) projectDiffs' projId commitSha = gitlab ( "/projects/"@@ -240,14 +228,13 @@ -- | share a project with a group. shareProjectWithGroup ::- (MonadIO m) => -- | group ID Int -> -- | project ID Int -> -- | level of access granted AccessLevel ->- GitLab m (Either Status GroupShare)+ GitLab (Either Status GroupShare) shareProjectWithGroup groupId projectId access = gitlabPost addr dataBody where
src/GitLab/API/Repositories.hs view
@@ -19,20 +19,18 @@ -- | returns a list of repository files and directories in a project. repositories ::- (MonadIO m) => -- | the project Project ->- GitLab m [Repository]+ GitLab [Repository] repositories project = fromRight (error "repositories error") <$> repositories' (project_id project) -- | returns a list of repository files and directories in a project -- given its project ID. repositories' ::- (MonadIO m) => -- | the project ID Int ->- GitLab m (Either Status [Repository])+ GitLab (Either Status [Repository]) repositories' projectId = gitlab addr where@@ -46,14 +44,13 @@ -- -- > getFileArchive myProject TarGz "/tmp/myProject.tar.gz" getFileArchive ::- (MonadIO m) => -- | project Project -> -- | file format ArchiveFormat -> -- | file path to store the archive FilePath ->- GitLab m (Either Status ())+ GitLab (Either Status ()) getFileArchive project = getFileArchive' (project_id project) -- | get a file archive of the repository files as a@@ -61,12 +58,11 @@ -- -- > getFileArchiveBS myProject TarGz "/tmp/myProject.tar.gz" getFileArchiveBS ::- (MonadIO m) => -- | project Project -> -- | file format ArchiveFormat ->- GitLab m (Either Status BSL.ByteString)+ GitLab (Either Status BSL.ByteString) getFileArchiveBS project = getFileArchiveBS' (project_id project) -- | get a file archive of the repository files using the project's@@ -74,14 +70,13 @@ -- -- > getFileArchive' 3453 Zip "/tmp/myProject.zip" getFileArchive' ::- (MonadIO m) => -- | project ID Int -> -- | file format ArchiveFormat -> -- | file path to store the archive FilePath ->- GitLab m (Either Status ())+ GitLab (Either Status ()) getFileArchive' projectId format path = do attempt <- getFileArchiveBS' projectId format case attempt of@@ -94,12 +89,11 @@ -- -- > getFileArchiveBS' 3453 Zip "/tmp/myProject.zip" getFileArchiveBS' ::- (MonadIO m) => -- | project ID Int -> -- | file format ArchiveFormat ->- GitLab m (Either Status BSL.ByteString)+ GitLab (Either Status BSL.ByteString) getFileArchiveBS' projectId format = gitlabReqByteString addr where
src/GitLab/API/RepositoryFiles.hs view
@@ -9,7 +9,6 @@ -- Stability : stable module GitLab.API.RepositoryFiles where -import Control.Monad.IO.Unlift import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Encoding as T@@ -20,27 +19,25 @@ -- | Get a list of repository files and directories in a project. repositoryFiles ::- (MonadIO m) => -- | the project Project -> -- | the file path Text -> -- | name of the branch, tag or commit Text ->- GitLab m (Either Status (Maybe RepositoryFile))+ GitLab (Either Status (Maybe RepositoryFile)) repositoryFiles project = repositoryFiles' (project_id project) -- | Get a list of repository files and directories in a project given -- the project's ID. repositoryFiles' ::- (MonadIO m) => -- | project ID Int -> -- | the file path Text -> -- | name of the branch, tag or commit Text ->- GitLab m (Either Status (Maybe RepositoryFile))+ GitLab (Either Status (Maybe RepositoryFile)) repositoryFiles' projectId filePath reference = gitlabWithAttrsOne addr ("&ref=" <> reference) where@@ -54,12 +51,11 @@ -- | Get raw data for a given file blob hash. repositoryFileBlob ::- (MonadIO m) => -- | project ID Int -> -- | blob SHA Text ->- GitLab m (Either Status String)+ GitLab (Either Status String) repositoryFileBlob projectId blobSha = gitlabReqText addr where
src/GitLab/API/Todos.hs view
@@ -9,10 +9,9 @@ -- Stability : stable module GitLab.API.Todos where -import Control.Monad.IO.Class import GitLab.Types import GitLab.WebRequests.GitLabWebCalls -- | returns all pending todos for the user, as defined by the access token.-todos :: (MonadIO m) => GitLab m [Todo]+todos :: GitLab [Todo] todos = gitlabUnsafe "/todos"
src/GitLab/API/Users.hs view
@@ -10,7 +10,6 @@ -- Stability : stable module GitLab.API.Users where -import Control.Monad.IO.Class import Data.List import Data.Maybe import Data.Text (Text)@@ -18,7 +17,7 @@ import GitLab.WebRequests.GitLabWebCalls -- | all registered users.-allUsers :: (MonadIO m) => GitLab m [User]+allUsers :: GitLab [User] allUsers = do let path = "/users" gitlabUnsafe path@@ -26,25 +25,23 @@ -- | searches for a user given a username. Returns @Just User@ if the -- user is found, otherwise @Nothing@. searchUser ::- (MonadIO m) => -- | username to search for Text ->- GitLab m (Maybe User)+ GitLab (Maybe User) searchUser username = do let path = "/users" attrs = "&username=" <> username res <- gitlabWithAttrsUnsafe path attrs- if null res- then return Nothing- else return (Just (head res))+ case res of+ [] -> return Nothing+ (user : _) -> return (Just user) -- | searches for users given a list of usernames, returns them in -- alphabetical order of their usernames. orderedUsers ::- (MonadIO m) => -- | usernames to search for [Text] ->- GitLab m [User]+ GitLab [User] orderedUsers usernames = do users <- catMaybes <$> mapM searchUser usernames return (orderUsersByName users)
src/GitLab/API/Version.hs view
@@ -9,12 +9,12 @@ -- Stability : stable module GitLab.API.Version where -import Control.Monad.IO.Class import GitLab.Types import GitLab.WebRequests.GitLabWebCalls import Network.HTTP.Types.Status -gitlabVersion :: (MonadIO m) => GitLab m (Either Status (Maybe Version))+-- | Get the version of the GitLab server.+gitlabVersion :: GitLab (Either Status (Maybe Version)) gitlabVersion = do let path = "/version" gitlabOne path
+ src/GitLab/SystemHooks/GitLabSystemHooks.hs view
@@ -0,0 +1,262 @@+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- |+-- Module : GitLab.SystemHooks.GitLabSystemHooks+-- Description : Haskell records corresponding to JSON data from GitLab system hooks+-- Copyright : (c) Rob Stewart, Heriot-Watt University, 2020+-- License : BSD3+-- Maintainer : robstewart57@gmail.com+-- Stability : stable+module GitLab.SystemHooks.GitLabSystemHooks+ ( receive,+ receiveString,+ tryFire,+ )+where++import Control.Monad+import Control.Monad.IO.Class+import Data.Typeable+import GitLab.SystemHooks.Types+import GitLab.Types++-- | Attempts to fire each rule in sequence. Reads the JSON data+-- received from the GitLab server from standard input.+receive :: [Rule] -> GitLab ()+receive rules = do+ eventContent <- liftIO getContents+ receiveString eventContent rules++-- | Attempts to fire each rule in sequence. Reads the JSON data+-- received from a function argument.+receiveString :: String -> [Rule] -> GitLab ()+receiveString eventContent rules = do+ mapM_ (fire eventContent) rules++orElse :: GitLab Bool -> GitLab Bool -> GitLab Bool+orElse f g = do+ x <- f+ if x+ then return True+ else g++fire :: String -> Rule -> GitLab ()+fire contents rule = do+ result <- tryFire contents rule+ when result $+ liftIO (putStrLn ("fired: " <> labelOf rule))+ where+ labelOf :: Rule -> String+ labelOf (Match lbl _) = lbl+ labelOf (MatchIf lbl _ _) = lbl++-- | Try to fire a GitLab rule, returns 'True' if the rule fired and+-- 'False' if it did not fire.+tryFire :: String -> Rule -> GitLab Bool+tryFire contents (Match _ f) = do+ fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (ProjectCreate -> GitLab ()))+ (parseEvent contents :: Maybe ProjectCreate)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (ProjectDestroy -> GitLab ()))+ (parseEvent contents :: Maybe ProjectDestroy)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (ProjectRename -> GitLab ()))+ (parseEvent contents :: Maybe ProjectRename)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (ProjectTransfer -> GitLab ()))+ (parseEvent contents :: Maybe ProjectTransfer)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (ProjectUpdate -> GitLab ()))+ (parseEvent contents :: Maybe ProjectUpdate)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (GroupMemberUpdate -> GitLab ()))+ (parseEvent contents :: Maybe GroupMemberUpdate)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (UserAddToTeam -> GitLab ()))+ (parseEvent contents :: Maybe UserAddToTeam)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (UserUpdateForTeam -> GitLab ()))+ (parseEvent contents :: Maybe UserUpdateForTeam)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (UserRemoveFromTeam -> GitLab ()))+ (parseEvent contents :: Maybe UserRemoveFromTeam)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (UserCreate -> GitLab ()))+ (parseEvent contents :: Maybe UserCreate)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (UserRemove -> GitLab ()))+ (parseEvent contents :: Maybe UserRemove)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (UserFailedLogin -> GitLab ()))+ (parseEvent contents :: Maybe UserFailedLogin)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (UserRename -> GitLab ()))+ (parseEvent contents :: Maybe UserRename)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (KeyCreate -> GitLab ()))+ (parseEvent contents :: Maybe KeyCreate)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (KeyRemove -> GitLab ()))+ (parseEvent contents :: Maybe KeyRemove)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (GroupCreate -> GitLab ()))+ (parseEvent contents :: Maybe GroupCreate)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (GroupRemove -> GitLab ()))+ (parseEvent contents :: Maybe GroupRemove)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (GroupRename -> GitLab ()))+ (parseEvent contents :: Maybe GroupRename)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (NewGroupMember -> GitLab ()))+ (parseEvent contents :: Maybe NewGroupMember)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (GroupMemberRemove -> GitLab ()))+ (parseEvent contents :: Maybe GroupMemberRemove)+ -- `orElse` fireIf'+ -- (Just (\_ -> return True))+ -- (cast f :: Maybe (ProjectEvent -> GitLab ()))+ -- (parseEvent contents :: Maybe ProjectEvent)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (Push -> GitLab ()))+ (parseEvent contents :: Maybe Push)+ `orElse` fireIf'+ (Just (\_ -> return True))+ (cast f :: Maybe (TagPush -> GitLab ()))+ (parseEvent contents :: Maybe TagPush)+tryFire contents (MatchIf _ predF f) = do+ fireIf'+ (cast predF :: Maybe (ProjectCreate -> GitLab Bool))+ (cast f :: Maybe (ProjectCreate -> GitLab ()))+ (parseEvent contents :: Maybe ProjectCreate)+ `orElse` fireIf'+ (cast predF :: Maybe (ProjectDestroy -> GitLab Bool))+ (cast f :: Maybe (ProjectDestroy -> GitLab ()))+ (parseEvent contents :: Maybe ProjectDestroy)+ `orElse` fireIf'+ (cast predF :: Maybe (ProjectRename -> GitLab Bool))+ (cast f :: Maybe (ProjectRename -> GitLab ()))+ (parseEvent contents :: Maybe ProjectRename)+ `orElse` fireIf'+ (cast predF :: Maybe (ProjectTransfer -> GitLab Bool))+ (cast f :: Maybe (ProjectTransfer -> GitLab ()))+ (parseEvent contents :: Maybe ProjectTransfer)+ `orElse` fireIf'+ (cast predF :: Maybe (ProjectUpdate -> GitLab Bool))+ (cast f :: Maybe (ProjectUpdate -> GitLab ()))+ (parseEvent contents :: Maybe ProjectUpdate)+ `orElse` fireIf'+ (cast predF :: Maybe (GroupMemberUpdate -> GitLab Bool))+ (cast f :: Maybe (GroupMemberUpdate -> GitLab ()))+ (parseEvent contents :: Maybe GroupMemberUpdate)+ `orElse` fireIf'+ (cast predF :: Maybe (UserAddToTeam -> GitLab Bool))+ (cast f :: Maybe (UserAddToTeam -> GitLab ()))+ (parseEvent contents :: Maybe UserAddToTeam)+ `orElse` fireIf'+ (cast predF :: Maybe (UserUpdateForTeam -> GitLab Bool))+ (cast f :: Maybe (UserUpdateForTeam -> GitLab ()))+ (parseEvent contents :: Maybe UserUpdateForTeam)+ `orElse` fireIf'+ (cast predF :: Maybe (UserRemoveFromTeam -> GitLab Bool))+ (cast f :: Maybe (UserRemoveFromTeam -> GitLab ()))+ (parseEvent contents :: Maybe UserRemoveFromTeam)+ `orElse` fireIf'+ (cast predF :: Maybe (UserCreate -> GitLab Bool))+ (cast f :: Maybe (UserCreate -> GitLab ()))+ (parseEvent contents :: Maybe UserCreate)+ `orElse` fireIf'+ (cast predF :: Maybe (UserRemove -> GitLab Bool))+ (cast f :: Maybe (UserRemove -> GitLab ()))+ (parseEvent contents :: Maybe UserRemove)+ `orElse` fireIf'+ (cast predF :: Maybe (UserFailedLogin -> GitLab Bool))+ (cast f :: Maybe (UserFailedLogin -> GitLab ()))+ (parseEvent contents :: Maybe UserFailedLogin)+ `orElse` fireIf'+ (cast predF :: Maybe (UserRename -> GitLab Bool))+ (cast f :: Maybe (UserRename -> GitLab ()))+ (parseEvent contents :: Maybe UserRename)+ `orElse` fireIf'+ (cast predF :: Maybe (KeyCreate -> GitLab Bool))+ (cast f :: Maybe (KeyCreate -> GitLab ()))+ (parseEvent contents :: Maybe KeyCreate)+ `orElse` fireIf'+ (cast predF :: Maybe (KeyRemove -> GitLab Bool))+ (cast f :: Maybe (KeyRemove -> GitLab ()))+ (parseEvent contents :: Maybe KeyRemove)+ `orElse` fireIf'+ (cast predF :: Maybe (GroupCreate -> GitLab Bool))+ (cast f :: Maybe (GroupCreate -> GitLab ()))+ (parseEvent contents :: Maybe GroupCreate)+ `orElse` fireIf'+ (cast predF :: Maybe (GroupRemove -> GitLab Bool))+ (cast f :: Maybe (GroupRemove -> GitLab ()))+ (parseEvent contents :: Maybe GroupRemove)+ `orElse` fireIf'+ (cast predF :: Maybe (GroupRename -> GitLab Bool))+ (cast f :: Maybe (GroupRename -> GitLab ()))+ (parseEvent contents :: Maybe GroupRename)+ `orElse` fireIf'+ (cast predF :: Maybe (NewGroupMember -> GitLab Bool))+ (cast f :: Maybe (NewGroupMember -> GitLab ()))+ (parseEvent contents :: Maybe NewGroupMember)+ `orElse` fireIf'+ (cast predF :: Maybe (GroupMemberRemove -> GitLab Bool))+ (cast f :: Maybe (GroupMemberRemove -> GitLab ()))+ (parseEvent contents :: Maybe GroupMemberRemove)+ -- `orElse` fireIf'+ -- (cast predF :: Maybe (ProjectEvent -> GitLab Bool))+ -- (cast f :: Maybe (ProjectEvent -> GitLab ()))+ -- (parseEvent contents :: Maybe ProjectEvent)+ `orElse` fireIf'+ (cast predF :: Maybe (Push -> GitLab Bool))+ (cast f :: Maybe (Push -> GitLab ()))+ (parseEvent contents :: Maybe Push)+ `orElse` fireIf'+ (cast predF :: Maybe (TagPush -> GitLab Bool))+ (cast f :: Maybe (TagPush -> GitLab ()))+ (parseEvent contents :: Maybe TagPush)++fireIf' :: (Typeable a, Show a) => Maybe (a -> GitLab Bool) -> Maybe (a -> GitLab ()) -> Maybe a -> GitLab Bool+fireIf' castPred castF parsed = do+ case castPred of+ Nothing -> return False+ Just pred' ->+ case castF of+ Nothing -> return False+ Just f' ->+ case parsed of+ Nothing -> return False+ Just parsed' -> do+ testPred <- pred' parsed'+ if testPred+ then do+ f' parsed'+ return True+ else return False
+ src/GitLab/SystemHooks/Types.hs view
@@ -0,0 +1,1154 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StrictData #-}+{-# LANGUAGE TypeFamilies #-}++-- |+-- Module : GitLab.SystemHooks.Types+-- Description : Haskell records corresponding to JSON data from GitLab system hook events+-- Copyright : (c) Rob Stewart, Heriot-Watt University, 2020+-- License : BSD3+-- Maintainer : robstewart57@gmail.com+-- Stability : stable+module GitLab.SystemHooks.Types+ ( Rule (..),+ SystemHook (..),+ ProjectCreate (..),+ ProjectDestroy (..),+ ProjectRename (..),+ ProjectTransfer (..),+ ProjectUpdate (..),+ UserAddToTeam (..),+ UserUpdateForTeam (..),+ UserRemoveFromTeam (..),+ UserCreate (..),+ UserRemove (..),+ UserFailedLogin (..),+ UserRename (..),+ KeyCreate (..),+ KeyRemove (..),+ GroupCreate (..),+ GroupRemove (..),+ GroupRename (..),+ NewGroupMember (..),+ GroupMemberRemove (..),+ GroupMemberUpdate (..),+ Push (..),+ TagPush (..),+ ProjectEvent (..),+ RepositoryEvent (..),+ CommitEvent (..),+ CommitAuthorEvent (..),+ Visibility (..),+ parseEvent,+ )+where++import Data.Aeson+import qualified Data.ByteString.Lazy.Char8 as BSL+import Data.Text (Text)+import Data.Typeable+import GHC.Generics+import GitLab.Types++-- | Pattern matching rules on GitLab hook events.+data Rule where+ Match :: (Typeable a) => String -> (a -> GitLab ()) -> Rule+ MatchIf :: (Typeable a) => String -> (a -> GitLab Bool) -> (a -> GitLab ()) -> Rule++-- | A typeclass for GitLab hook events.+class (FromJSON a) => SystemHook a where+ match :: String -> (a -> GitLab ()) -> Rule+ matchIf :: String -> (a -> GitLab Bool) -> (a -> GitLab ()) -> Rule++-- | Parse JSON data into GitLab events.+parseEvent :: (FromJSON a) => String -> Maybe a+parseEvent string =+ case eitherDecode (BSL.pack string) of+ Left _error -> Nothing+ Right event -> Just event++instance SystemHook ProjectCreate where+ match = Match+ matchIf = MatchIf++-- | GitLab project creation.+data ProjectCreate = ProjectCreate+ { projectCreate_created_at :: Text,+ projectCreate_updated_at :: Text,+ projectCreate_action :: Text,+ projectCreate_name :: Text,+ projectCreate_owner_email :: Text,+ projectCreate_owner_name :: Text,+ projectCreate_path :: Text,+ projectCreate_path_with_namespace :: Text,+ projectCreate_project_id :: Int,+ projectCreate_project_visibility :: Visibility+ }+ deriving (Typeable, Show, Eq)++instance SystemHook ProjectDestroy where+ match = Match+ matchIf = MatchIf++-- | Removal of a GitLab removal.+data ProjectDestroy = ProjectDestroy+ { projectDestroy_created_at :: Text,+ projectDestroy_updated_at :: Text,+ projectDestroy_action :: Text,+ projectDestroy_name :: Text,+ projectDestroy_owner_email :: Text,+ projectDestroy_owner_name :: Text,+ projectDestroy_path :: Text,+ projectDestroy_path_with_namespace :: Text,+ projectDestroy_project_id :: Int,+ projectDestroy_project_visibility :: Visibility+ }+ deriving (Typeable, Show, Eq)++instance SystemHook ProjectRename where+ match = Match+ matchIf = MatchIf++-- | Renaming of a GitLab project.+data ProjectRename = ProjectRename+ { projectRename_created_at :: Text,+ projectRename_updated_at :: Text,+ projectRename_event_name :: Text,+ projectRename_name :: Text,+ projectRename_path :: Text,+ projectRename_path_with_namespace :: Text,+ projectRename_project_id :: Int,+ projectRename_owner_name :: Text,+ projectRename_owner_email :: Text,+ projectRename_project_visibility :: Visibility,+ projectRename_old_path_with_namespace :: Text+ }+ deriving (Typeable, Show, Eq)++instance SystemHook ProjectTransfer where+ match = Match+ matchIf = MatchIf++-- | A project has been transferred.+data ProjectTransfer = ProjectTransfer+ { projectTransfer_created_at :: Text,+ projectTransfer_updated_at :: Text,+ projectTransfer_event_name :: Text,+ projectTransfer_name :: Text,+ projectTransfer_path :: Text,+ projectTransfer_path_with_namespace :: Text,+ projectTransfer_project_id :: Int,+ projectTransfer_owner_name :: Text,+ projectTransfer_owner_email :: Text,+ projectTransfer_project_visibility :: Visibility,+ projectTransfer_old_path_with_namespace :: Text+ }+ deriving (Typeable, Show, Eq)++instance SystemHook ProjectUpdate where+ match = Match+ matchIf = MatchIf++-- | A project has been updated.+data ProjectUpdate = ProjectUpdate+ { projectUpdate_created_at :: Text,+ projectUpdate_updated_at :: Text,+ projectUpdate_event_name :: Text,+ projectUpdate_name :: Text,+ projectUpdate_owner_email :: Text,+ projectUpdate_owner_name :: Text,+ projectUpdate_path :: Text,+ projectUpdate_path_with_namespace :: Text,+ projectUpdate_project_id :: Int,+ projectUpdate_project_visibility :: Visibility+ }+ deriving (Typeable, Show, Eq)++instance SystemHook UserAddToTeam where+ match = Match+ matchIf = MatchIf++-- | A user has been added to a team.+data UserAddToTeam = UserAddToTeam+ { userAddTeam_created_at :: Text, -- todo improve: date+ userAddTeam_updated_at :: Text, -- todo improve: date+ userAddTeam_event_name :: Text,+ userAddTeam_access_level :: Text, -- todo improve: Maintainer/...+ userAddTeam_project_id :: Int,+ userAddTeam_project_name :: Text,+ userAddTeam_project_path :: Text,+ userAddTeam_project_path_with_namespace :: Text,+ userAddTeam_user_email :: Text,+ userAddTeam_user_name :: Text,+ userAddTeam_user_username :: Text,+ userAddTeam_user_id :: Int,+ userAddTeam_project_visibility :: Visibility+ }+ deriving (Typeable, Show, Eq)++instance SystemHook UserUpdateForTeam where+ match = Match+ matchIf = MatchIf++-- | A user in a team has been updated.+data UserUpdateForTeam = UserUpdateForTeam+ { userUpdateTeam_created_at :: Text, -- todo improve: date+ userUpdateTeam_updated_at :: Text, -- todo improve: date+ userUpdateTeam_event_name :: Text,+ userUpdateTeam_access_level :: Text, -- todo improve: Maintainer/...+ userUpdateTeam_project_id :: Int,+ userUpdateTeam_project_name :: Text,+ userUpdateTeam_project_path :: Text,+ userUpdateTeam_project_path_with_namespace :: Text,+ userUpdateTeam_user_email :: Text,+ userUpdateTeam_user_name :: Text,+ userUpdateTeam_user_username :: Text,+ userUpdateTeam_user_id :: Int,+ userUpdateTeam_project_visibility :: Visibility+ }+ deriving (Typeable, Show, Eq)++instance SystemHook UserRemoveFromTeam where+ match = Match+ matchIf = MatchIf++-- | A user has been removed from a team.+data UserRemoveFromTeam = UserRemoveFromTeam+ { userRemoveTeam_created_at :: Text, -- todo improve: date+ userRemoveTeam_updated_at :: Text, -- todo improve: date+ userRemoveTeam_event_name :: Text,+ userRemoveTeam_access_level :: Text, -- todo improve: Maintainer/...+ userRemoveTeam_project_id :: Int,+ userRemoveTeam_project_name :: Text,+ userRemoveTeam_project_path :: Text,+ userRemoveTeam_project_path_with_namespace :: Text,+ userRemoveTeam_user_email :: Text,+ userRemoveTeam_user_name :: Text,+ userRemoveTeam_user_username :: Text,+ userRemoveTeam_user_id :: Int,+ userRemoveTeam_project_visibility :: Visibility+ }+ deriving (Typeable, Show, Eq)++instance SystemHook UserCreate where+ match = Match+ matchIf = MatchIf++-- | A user has been created.+data UserCreate = UserCreate+ { userCreate_created_at :: Text, -- todo improve: date+ userCreate_updated_at :: Text, -- todo improve: date+ userCreate_email :: Text,+ userCreate_event_name :: Text,+ userCreate_name :: Text,+ userCreate_username :: Text,+ userCreate_user_id :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook UserRemove where+ match = Match+ matchIf = MatchIf++-- | A user has been removed.+data UserRemove = UserRemove+ { userRemove_created_at :: Text, -- todo improve: date+ userRemove_updated_at :: Text, -- todo improve: date+ userRemove_email :: Text,+ userRemove_event_name :: Text,+ userRemove_name :: Text,+ userRemove_username :: Text,+ userRemove_user_id :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook UserFailedLogin where+ match = Match+ matchIf = MatchIf++-- | A user has failed to log in.+data UserFailedLogin = UserFailedLogin+ { userFailedLogin_event_name :: Text,+ userFailedLogin_created_at :: Text, -- todo improve: date+ userFailedLogin_updated_at :: Text, -- todo improve: date+ userFailedLogin_name :: Text,+ userFailedLogin_email :: Text,+ userFailedLogin_user_id :: Int,+ userFailedLogin_username :: Text,+ -- create Haskell sum type for this+ userFailedLogin_state :: Text+ }+ deriving (Typeable, Show, Eq)++instance SystemHook UserRename where+ match = Match+ matchIf = MatchIf++-- | A user has been renamed.+data UserRename = UserRename+ { userRename_event_name :: Text,+ userRename_created_at :: Text, -- todo improve: date+ userRename_updated_at :: Text, -- todo improve: date+ userRename_name :: Text,+ userRename_email :: Text,+ userRename_user_id :: Int,+ userRename_username :: Text,+ userRename_old_username :: Text+ }+ deriving (Typeable, Show, Eq)++instance SystemHook KeyCreate where+ match = Match+ matchIf = MatchIf++-- | A key has been created.+data KeyCreate = KeyCreate+ { keyCreate_event_name :: Text,+ keyCreate_created_at :: Text, -- todo improve: date+ keyCreate_updated_at :: Text, -- todo improve: date+ keyCreate_username :: Text,+ keyCreate_key :: Text,+ keyCreate_id :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook KeyRemove where+ match = Match+ matchIf = MatchIf++-- | A key has been removed.+data KeyRemove = KeyRemove+ { keyRemove_event_name :: Text,+ keyRemove_created_at :: Text, -- todo improve: date+ keyRemove_updated_at :: Text, -- todo improve: date+ keyRemove_username :: Text,+ keyRemove_key :: Text,+ keyRemove_id :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook GroupCreate where+ match = Match+ matchIf = MatchIf++-- | A group has been created.+data GroupCreate = GroupCreate+ { groupCreate_created_at :: Text, -- todo improve: date+ groupCreate_updated_at :: Text, -- todo improve: date+ groupCreate_event_name :: Text,+ groupCreate_name :: Text,+ groupCreate_owner_email :: Maybe Text,+ groupCreate_owner_name :: Maybe Text,+ groupCreate_path :: Text,+ groupCreate_group_id :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook GroupRemove where+ match = Match+ matchIf = MatchIf++-- | A group has been removed.+data GroupRemove = GroupRemove+ { groupRemove_created_at :: Text, -- todo improve: date+ groupRemove_updated_at :: Text, -- todo improve: date+ groupRemove_event_name :: Text,+ groupRemove_name :: Text,+ groupRemove_owner_email :: Maybe Text,+ groupRemove_owner_name :: Maybe Text,+ groupRemove_path :: Text,+ groupRemove_group_id :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook GroupRename where+ match = Match+ matchIf = MatchIf++-- | A group has been renamed.+data GroupRename = GroupRename+ { groupRename_event_name :: Text,+ groupRename_created_at :: Text, -- todo improve: date+ groupRename_updated_at :: Text, -- todo improve: date+ groupRename_name :: Text,+ groupRename_path :: Text,+ groupRename_full_path :: Text,+ groupRename_group_id :: Int,+ groupRename_owner_name :: Maybe Text,+ groupRename_owner_email :: Maybe Text,+ groupRename_old_path :: Text,+ groupRename_old_full_path :: Text+ }+ deriving (Typeable, Show, Eq)++instance SystemHook NewGroupMember where+ match = Match+ matchIf = MatchIf++-- | A user has been added to a group.+data NewGroupMember = NewGroupMember+ { newGroupMember_created_at :: Text, -- todo improve: date+ newGroupMember_updated_at :: Text, -- todo improve: date+ newGroupMember_event_name :: Text,+ newGroupMember_group_access :: Text, -- todo Haskell type for this+ newGroupMember_group_id :: Int,+ newGroupMember_group_name :: Text,+ newGroupMember_group_path :: Text,+ newGroupMember_user_email :: Text,+ newGroupMember_user_name :: Text,+ newGroupMember_user_username :: Text,+ newGroupMember_user_id :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook GroupMemberRemove where+ match = Match+ matchIf = MatchIf++-- | A user has been removed from a group.+data GroupMemberRemove = GroupMemberRemove+ { groupMemberRemove_created_at :: Text, -- todo improve: date+ groupMemberRemove_updated_at :: Text, -- todo improve: date+ groupMemberRemove_event_name :: Text,+ groupMemberRemove_group_access :: Text, -- todo Haskell type for this+ groupMemberRemove_group_id :: Int,+ groupMemberRemove_group_name :: Text,+ groupMemberRemove_group_path :: Text,+ groupMemberRemove_user_email :: Text,+ groupMemberRemove_user_name :: Text,+ groupMemberRemove_user_username :: Text,+ groupMemberRemove_user_id :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook GroupMemberUpdate where+ match = Match+ matchIf = MatchIf++-- | A group member has been updated.+data GroupMemberUpdate = GroupMemberUpdate+ { groupMemberUpdate_created_at :: Text, -- todo improve: date+ groupMemberUpdate_updated_at :: Text, -- todo improve: date+ groupMemberUpdate_event_name :: Text,+ groupMemberUpdate_group_access :: Text, -- todo Haskell type for this+ groupMemberUpdate_group_id :: Int,+ groupMemberUpdate_group_name :: Text,+ groupMemberUpdate_group_path :: Text,+ groupMemberUpdate_user_email :: Text,+ groupMemberUpdate_user_name :: Text,+ groupMemberUpdate_user_username :: Text,+ groupMemberUpdate_user_id :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook Push where+ match = Match+ matchIf = MatchIf++-- | Commits have been pushed to the server.+data Push = Push+ { push_event_name :: Text,+ push_before :: Text,+ push_after :: Text,+ push_ref :: Text,+ push_checkout_sha :: Text,+ push_user_id :: Int,+ push_user_name :: Text,+ push_user_email :: Text,+ push_user_avatar :: Text,+ push_project_id :: Int,+ push_project :: ProjectEvent,+ push_repository :: RepositoryEvent,+ push_commits :: [CommitEvent],+ push_total_commits_count :: Int+ }+ deriving (Typeable, Show, Eq)++instance SystemHook TagPush where+ match = Match+ matchIf = MatchIf++-- | Tags have been pushed to the server.+data TagPush = TagPush+ { tagPush_event_name :: Text,+ tagPush_before :: Text,+ tagPush_after :: Text,+ tagPush_ref :: Text,+ tagPush_checkout_sha :: Text,+ tagPush_user_id :: Int,+ tagPush_user_name :: Text,+ tagPush_user_avatar :: Text,+ tagPush_project_id :: Int,+ tagPush_project :: ProjectEvent,+ tagPush_repository :: RepositoryEvent,+ tagPush_commits :: [CommitEvent],+ tagPush_total_commits_count :: Int+ }+ deriving (Typeable, Show, Eq)++-- | A project event.+data ProjectEvent = ProjectEvent+ { projectEvent_name :: Text,+ projectEvent_description :: Text,+ projectEvent_web_url :: Text,+ projectEvent_avatar_url :: Maybe Text,+ projectEvent_git_ssh_url :: Text,+ projectEvent_git_http_url :: Text,+ projectEvent_namespace :: Text,+ projectEvent_visibility_level :: Visibility,+ projectEvent_path_with_namespace :: Text,+ projectEvent_default_branch :: Text,+ -- projectEvent_ci_config_path :: Maybe Text,+ projectEvent_homepage :: Maybe Text,+ projectEvent_url :: Text,+ projectEvent_ssh_url :: Text,+ projectEvent_http_url :: Text+ }+ deriving (Typeable, Show, Eq, Generic)++-- | A repository event.+data RepositoryEvent = RepositoryEvent+ { repositoryEvent_name :: Text,+ repositoryEvent_url :: Text,+ repositoryEvent_description :: Text,+ repositoryEvent_homepage :: Maybe Text,+ repositoryEvent_git_http_url :: Text,+ repositoryEvent_git_ssh_url :: Text,+ repositoryEvent_visibility_level :: Visibility+ }+ deriving (Typeable, Show, Eq, Generic)++-- | A commit event.+data CommitEvent = CommitEvent+ { commitEvent_id :: Text,+ commitEvent_message :: Text,+ commitEvent_timestamp :: Text, -- TODO improve.+ commitEvent_url :: Text,+ commitEvent_author :: CommitAuthorEvent+ }+ deriving (Typeable, Show, Eq, Generic)++-- | Commit author information.+data CommitAuthorEvent = CommitAuthorEvent+ { commitAuthorEvent_name :: Text,+ commitAuthorEvent_email :: Text+ }+ deriving (Typeable, Show, Eq, Generic)++data ProjectAction+ = ProjectCreated+ | ProjectDestroyed+ | ProjectRenamed+ | ProjectTransferred+ | ProjectUpdated+ | UserAddedToTeam+ | UserUpdatedForTeam+ | UserRemovedFromTeam+ | UserCreated+ | UserRemoved+ | UserFailedToLogin+ | UserRenamed+ | KeyCreated+ | KeyRemoved+ | GroupCreated+ | GroupRemoved+ | GroupRenamed+ | GroupMemberAdded+ | GroupMemberRemoved+ | GroupMemberUpdated+ | Pushed+ | TagPushed+ deriving (Show, Eq)++-- | Project visibility.+data Visibility+ = Public+ | Private+ | Internal+ deriving (Show, Eq)++instance FromJSON ProjectCreate where+ parseJSON =+ withObject "ProjectCreate" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ ProjectCreated ->+ ProjectCreate+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "name"+ <*> v .: "owner_email"+ <*> v .: "owner_name"+ <*> v .: "path"+ <*> v .: "path_with_namespace"+ <*> v .: "project_id"+ <*> v .: "project_visibility"+ _unexpected -> fail "project_create parsing failed"+ _unexpected -> fail "project_create parsing failed"++instance FromJSON ProjectDestroy where+ parseJSON =+ withObject "ProjectDestroy" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ ProjectDestroyed ->+ ProjectDestroy+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "name"+ <*> v .: "owner_email"+ <*> v .: "owner_name"+ <*> v .: "path"+ <*> v .: "path_with_namespace"+ <*> v .: "project_id"+ <*> v .: "project_visibility"+ _unexpected -> fail "project_destroy parsing failed"+ _unexpected -> fail "project_destroy parsing failed"++instance FromJSON ProjectRename where+ parseJSON =+ withObject "ProjectRename" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ ProjectRenamed ->+ ProjectRename+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "name"+ <*> v .: "path"+ <*> v .: "path_with_namespace"+ <*> v .: "project_id"+ <*> v .: "owner_name"+ <*> v .: "owner_email"+ <*> v .: "project_visibility"+ <*> v .: "old_path_with_namespace"+ _unexpected -> fail "project_rename parsing failed"+ _unexpected -> fail "project_rename parsing failed"++instance FromJSON ProjectTransfer where+ parseJSON =+ withObject "ProjectTransfer" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ ProjectTransferred ->+ ProjectTransfer+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "name"+ <*> v .: "path"+ <*> v .: "path_with_namespace"+ <*> v .: "project_id"+ <*> v .: "owner_name"+ <*> v .: "owner_email"+ <*> v .: "project_visibility"+ <*> v .: "old_path_with_namespace"+ _unexpected -> fail "project_transfer parsing failed"+ _unexpected -> fail "project_transfer parsing failed"++instance FromJSON ProjectUpdate where+ parseJSON =+ withObject "ProjectUpdate" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ ProjectUpdated ->+ ProjectUpdate+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "name"+ <*> v .: "owner_email"+ <*> v .: "owner_name"+ <*> v .: "path"+ <*> v .: "path_with_namespace"+ <*> v .: "project_id"+ <*> v .: "project_visibility"+ _unexpected -> fail "project_update parsing failed"+ _unexpected -> fail "project_update parsing failed"++instance FromJSON UserAddToTeam where+ parseJSON =+ withObject "UserAddToTeam" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ UserAddedToTeam ->+ UserAddToTeam+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "access_level"+ <*> v .: "project_id"+ <*> v .: "project_name"+ <*> v .: "project_path"+ <*> v .: "project_path_with_namespace"+ <*> v .: "user_email"+ <*> v .: "user_name"+ <*> v .: "user_username"+ <*> v .: "user_id"+ <*> v .: "project_visibility"+ _unexpected -> fail "user_add_to_team parsing failed"+ _unexpected -> fail "user_add_to_team parsing failed"++instance FromJSON UserUpdateForTeam where+ parseJSON =+ withObject "UserUpdateForTeam" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ UserUpdatedForTeam ->+ UserUpdateForTeam+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "access_level"+ <*> v .: "project_id"+ <*> v .: "project_name"+ <*> v .: "project_path"+ <*> v .: "project_path_with_namespace"+ <*> v .: "user_email"+ <*> v .: "user_name"+ <*> v .: "user_username"+ <*> v .: "user_id"+ <*> v .: "project_visibility"+ _unexpected -> fail "user_update_for_team parsing failed"+ _unexpected -> fail "user_update_for_team parsing failed"++instance FromJSON UserRemoveFromTeam where+ parseJSON =+ withObject "UserRemoveFromTeam" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ UserRemovedFromTeam ->+ UserRemoveFromTeam+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "access_level"+ <*> v .: "project_id"+ <*> v .: "project_name"+ <*> v .: "project_path"+ <*> v .: "project_path_with_namespace"+ <*> v .: "user_email"+ <*> v .: "user_name"+ <*> v .: "user_username"+ <*> v .: "user_id"+ <*> v .: "project_visibility"+ _unexpected -> fail "user_remove_from_team parsing failed"+ _unexpected -> fail "user_remove_from_team parsing failed"++instance FromJSON UserCreate where+ parseJSON =+ withObject "UserCreate" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ UserCreated ->+ UserCreate+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "email"+ <*> v .: "event_name"+ <*> v .: "name"+ <*> v .: "username"+ <*> v .: "user_id"+ _unexpected -> fail "user_create parsing failed"+ _unexpected -> fail "user_create parsing failed"++instance FromJSON UserRemove where+ parseJSON =+ withObject "UserRemove" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ UserRemoved ->+ UserRemove+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "email"+ <*> v .: "event_name"+ <*> v .: "name"+ <*> v .: "username"+ <*> v .: "user_id"+ _unexpected -> fail "user_destroy parsing failed"+ _unexpected -> fail "user_destroy parsing failed"++instance FromJSON UserFailedLogin where+ parseJSON =+ withObject "UserFailedLogin" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ UserFailedToLogin ->+ UserFailedLogin+ <$> v .: "event_name"+ <*> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "name"+ <*> v .: "email"+ <*> v .: "user_id"+ <*> v .: "username"+ <*> v .: "state"+ _unexpected -> fail "user_failed_login parsing failed"+ _unexpected -> fail "user_failed_login parsing failed"++instance FromJSON UserRename where+ parseJSON =+ withObject "UserRename" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ UserRenamed ->+ UserRename+ <$> v .: "event_name"+ <*> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "name"+ <*> v .: "email"+ <*> v .: "user_id"+ <*> v .: "username"+ <*> v .: "old_username"+ _unexpected -> fail "user_rename parsing failed"+ _unexpected -> fail "user_rename parsing failed"++instance FromJSON KeyCreate where+ parseJSON =+ withObject "KeyCreate" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ KeyCreated ->+ KeyCreate+ <$> v .: "event_name"+ <*> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "username"+ <*> v .: "key"+ <*> v .: "id"+ _unexpected -> fail "key_create parsing failed"+ _unexpected -> fail "key_create parsing failed"++instance FromJSON KeyRemove where+ parseJSON =+ withObject "KeyRemove" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ KeyRemoved ->+ KeyRemove+ <$> v .: "event_name"+ <*> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "username"+ <*> v .: "key"+ <*> v .: "id"+ _unexpected -> fail "key_destroy parsing failed"+ _unexpected -> fail "key_destroy parsing failed"++instance FromJSON GroupCreate where+ parseJSON =+ withObject "GroupCreate" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ GroupCreated ->+ GroupCreate+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "name"+ <*> v .: "owner_email"+ <*> v .: "owner_name"+ <*> v .: "path"+ <*> v .: "group_id"+ _unexpected -> fail "group_create parsing failed"+ _unexpected -> fail "group_create parsing failed"++instance FromJSON GroupRemove where+ parseJSON =+ withObject "GroupRemove" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ GroupRemoved ->+ GroupRemove+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "name"+ <*> v .: "owner_email"+ <*> v .: "owner_name"+ <*> v .: "path"+ <*> v .: "group_id"+ _unexpected -> fail "group_remove parsing failed"+ _unexpected -> fail "group_remove parsing failed"++instance FromJSON GroupRename where+ parseJSON =+ withObject "GroupRename" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ GroupRenamed ->+ GroupRename+ <$> v .: "event_name"+ <*> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "name"+ <*> v .: "path"+ <*> v .: "full_path"+ <*> v .: "group_id"+ <*> v .: "owner_name"+ <*> v .: "owner_email"+ <*> v .: "old_path"+ <*> v .: "old_full_path"+ _unexpected -> fail "group_rename parsing failed"+ _unexpected -> fail "group_rename parsing failed"++instance FromJSON NewGroupMember where+ parseJSON =+ withObject "NewGroupMember" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ GroupMemberAdded ->+ NewGroupMember+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "group_access"+ <*> v .: "group_id"+ <*> v .: "group_name"+ <*> v .: "group_path"+ <*> v .: "user_email"+ <*> v .: "user_name"+ <*> v .: "user_username"+ <*> v .: "user_id"+ _unexpected -> fail "user_add_to_group parsing failed"+ _unexpected -> fail "user_add_to_group parsing failed"++instance FromJSON GroupMemberRemove where+ parseJSON =+ withObject "GroupMemberRemove" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ GroupMemberRemoved ->+ GroupMemberRemove+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "group_access"+ <*> v .: "group_id"+ <*> v .: "group_name"+ <*> v .: "group_path"+ <*> v .: "user_email"+ <*> v .: "user_name"+ <*> v .: "user_username"+ <*> v .: "user_id"+ _unexpected -> fail "user_remove_from_group parsing failed"+ _unexpected -> fail "user_remove_from_group parsing failed"++instance FromJSON GroupMemberUpdate where+ parseJSON =+ withObject "GroupMemberUpdate" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ GroupMemberUpdated ->+ GroupMemberUpdate+ <$> v .: "created_at"+ <*> v .: "updated_at"+ <*> v .: "event_name"+ <*> v .: "group_access"+ <*> v .: "group_id"+ <*> v .: "group_name"+ <*> v .: "group_path"+ <*> v .: "user_email"+ <*> v .: "user_name"+ <*> v .: "user_username"+ <*> v .: "user_id"+ _unexpected -> fail "user_update_for_group parsing failed"+ _unexpected -> fail "user_update_for_group parsing failed"++instance FromJSON Push where+ parseJSON =+ withObject "Push" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ Pushed ->+ Push+ <$> v .: "event_name"+ <*> v .: "before"+ <*> v .: "after"+ <*> v .: "ref"+ <*> v .: "checkout_sha"+ <*> v .: "user_id"+ <*> v .: "user_name"+ <*> v .: "user_email"+ <*> v .: "user_avatar"+ <*> v .: "project_id"+ <*> v .: "project"+ <*> v .: "repository"+ <*> v .: "commits"+ <*> v .: "total_commits_count"+ _unexpected -> fail "push parsing failed"+ _unexpected -> fail "push parsing failed"++instance FromJSON TagPush where+ parseJSON =+ withObject "Push" $ \v -> do+ isProjectEvent <- v .:? "event_name"+ case isProjectEvent of+ Just theEvent ->+ case theEvent of+ TagPushed ->+ TagPush+ <$> v .: "event_name"+ <*> v .: "before"+ <*> v .: "after"+ <*> v .: "ref"+ <*> v .: "checkout_sha"+ <*> v .: "user_id"+ <*> v .: "user_name"+ <*> v .: "user_avatar"+ <*> v .: "project_id"+ <*> v .: "project"+ <*> v .: "repository"+ <*> v .: "commits"+ <*> v .: "total_commits_count"+ _unexpected -> fail "tag_push parsing failed"+ _unexpected -> fail "tag_push parsing failed"++bodyNoPrefix :: String -> String+bodyNoPrefix "projectEvent_name" = "name"+bodyNoPrefix "projectEvent_description" = "description"+bodyNoPrefix "projectEvent_web_url" = "web_url"+bodyNoPrefix "projectEvent_avatar_url" = "avatar_url"+bodyNoPrefix "projectEvent_git_ssh_url" = "git_ssh_url"+bodyNoPrefix "projectEvent_git_http_url" = "git_http_url"+bodyNoPrefix "projectEvent_namespace" = "namespace"+bodyNoPrefix "projectEvent_visibility_level" = "visibility_level"+bodyNoPrefix "projectEvent_path_with_namespace" = "path_with_namespace"+bodyNoPrefix "projectEvent_default_branch" = "default_branch"+-- bodyNoPrefix "projectEvent_ci_config_path" = "ci_config_path"+bodyNoPrefix "projectEvent_homepage" = "homepage"+bodyNoPrefix "projectEvent_url" = "url"+bodyNoPrefix "projectEvent_ssh_url" = "ssh_url"+bodyNoPrefix "projectEvent_http_url" = "http_url"+bodyNoPrefix "repositoryEvent_name" = "name"+bodyNoPrefix "repositoryEvent_url" = "url"+bodyNoPrefix "repositoryEvent_description" = "description"+bodyNoPrefix "repositoryEvent_homepage" = "homepage"+bodyNoPrefix "repositoryEvent_git_http_url" = "git_http_url"+bodyNoPrefix "repositoryEvent_git_ssh_url" = "git_ssh_url"+bodyNoPrefix "repositoryEvent_visibility_level" = "visibility_level"+bodyNoPrefix "commitEvent_id" = "id"+bodyNoPrefix "commitEvent_message" = "message"+bodyNoPrefix "commitEvent_timestamp" = "timestamp"+bodyNoPrefix "commitEvent_url" = "url"+bodyNoPrefix "commitEvent_author" = "author"+bodyNoPrefix "commitAuthorEvent_name" = "name"+bodyNoPrefix "commitAuthorEvent_email" = "email"+bodyNoPrefix s = error s++instance FromJSON ProjectEvent where+ parseJSON =+ genericParseJSON+ ( defaultOptions+ { fieldLabelModifier = bodyNoPrefix+ }+ )++instance FromJSON CommitEvent where+ parseJSON =+ genericParseJSON+ ( defaultOptions+ { fieldLabelModifier = bodyNoPrefix+ }+ )++instance FromJSON RepositoryEvent where+ parseJSON =+ genericParseJSON+ ( defaultOptions+ { fieldLabelModifier = bodyNoPrefix+ }+ )++instance FromJSON CommitAuthorEvent where+ parseJSON =+ genericParseJSON+ ( defaultOptions+ { fieldLabelModifier = bodyNoPrefix+ }+ )++instance FromJSON ProjectAction where+ parseJSON (String "project_create") = return ProjectCreated+ parseJSON (String "project_destroy") = return ProjectDestroyed+ parseJSON (String "project_rename") = return ProjectRenamed+ parseJSON (String "project_transfer") = return ProjectTransferred+ parseJSON (String "project_update") = return ProjectUpdated+ parseJSON (String "user_add_to_team") = return UserAddedToTeam+ parseJSON (String "user_update_for_team") = return UserUpdatedForTeam+ parseJSON (String "user_remove_from_team") = return UserRemovedFromTeam+ parseJSON (String "user_create") = return UserCreated+ parseJSON (String "user_destroy") = return UserRemoved+ parseJSON (String "user_failed_login") = return UserFailedToLogin+ parseJSON (String "user_rename") = return UserRenamed+ parseJSON (String "key_create") = return KeyCreated+ parseJSON (String "key_destroy") = return KeyRemoved+ parseJSON (String "group_create") = return GroupCreated+ parseJSON (String "group_destroy") = return GroupRemoved+ parseJSON (String "group_rename") = return GroupRenamed+ parseJSON (String "user_add_to_group") = return GroupMemberAdded+ parseJSON (String "user_remove_from_group") = return GroupMemberRemoved+ parseJSON (String "user_update_for_group") = return GroupMemberUpdated+ parseJSON (String "push") = return Pushed+ parseJSON (String "tag_push") = return TagPushed+ parseJSON s = error (show s)++instance FromJSON Visibility where+ parseJSON (String "public") = return Public+ parseJSON (String "private") = return Private+ parseJSON (String "internal") = return Internal+ parseJSON (Number 0) = return Private+ parseJSON (Number 10) = return Internal+ parseJSON (Number 20) = return Public+ parseJSON n = error (show n)
src/GitLab/Types.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StrictData #-} -- | -- Module : GitLab.Types@@ -21,11 +22,14 @@ Links (..), Owner (..), Permissions (..),+ ProjectId, Project (..), ProjectStats (..), User (..), Milestone (..),+ MilestoneState (..), TimeStats (..),+ IssueId, Issue (..), Pipeline (..), Commit (..),@@ -41,11 +45,13 @@ RepositoryFile (..), MergeRequest (..), Todo (..),+ TodoProject (..), TodoAction (..), TodoTarget (..), TodoState (..), Version (..), URL,+ EditIssueReq (..), ) where @@ -53,31 +59,30 @@ import Data.Aeson import Data.Aeson.Types import Data.Text (Text)+import qualified Data.Text as T import Data.Time.Clock import GHC.Generics import Network.HTTP.Conduit -- | type synonym for all GitLab actions.-type GitLab m a = ReaderT GitLabState m a+type GitLab a = ReaderT GitLabState IO a -- | state used by GitLab actions, used internally.-data GitLabState- = GitLabState- { serverCfg :: GitLabServerConfig,- httpManager :: Manager- }+data GitLabState = GitLabState+ { serverCfg :: GitLabServerConfig,+ httpManager :: Manager+ } -- | configuration data specific to a GitLab server.-data GitLabServerConfig- = GitLabServerConfig- { url :: Text,- -- | personal access token, see <https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html>- token :: Text,- -- | milliseconds- timeout :: Int,- -- | how many times to retry a HTTP request before giving up and returning an error.- retries :: Int- }+data GitLabServerConfig = GitLabServerConfig+ { url :: Text,+ -- | personal access token, see <https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html>+ token :: Text,+ -- | milliseconds+ timeout :: Int,+ -- | how many times to retry a HTTP request before giving up and returning an error.+ retries :: Int+ } -- | default settings, the 'url' and 'token' values will need to be overwritten. defaultGitLabServer :: GitLabServerConfig@@ -123,138 +128,130 @@ show Zip = ".zip" -- | member of a project.-data Member- = Member- { member_id :: Int,- member_name :: Text,- member_username :: Text,- member_state :: Text,- member_avatar_uri :: Maybe Text,- member_web_url :: Maybe Text,- access_level :: Int,- expires_at :: Maybe Text- }+data Member = Member+ { member_id :: Int,+ member_name :: Text,+ member_username :: Text,+ member_state :: Text,+ member_avatar_uri :: Maybe Text,+ member_web_url :: Maybe Text,+ access_level :: Int,+ expires_at :: Maybe Text+ } deriving (Generic, Show) -- | namespaces.-data Namespace- = Namespace- { namespace_id :: Int,- namespace_name :: Text,- namespace_path :: Text,- kind :: Text,- full_path :: Text,- parent_id :: Maybe Int- }+data Namespace = Namespace+ { namespace_id :: Int,+ namespace_name :: Text,+ namespace_path :: Text,+ kind :: Text,+ full_path :: Text,+ parent_id :: Maybe Int+ } deriving (Generic, Show) -- | links.-data Links- = Links- { self :: Text,- issues :: Text,- merge_requests :: Text,- repo_branches :: Text,- link_labels :: Text,- link_events :: Text,- members :: Text- }+data Links = Links+ { self :: Text,+ issues :: Text,+ merge_requests :: Text,+ repo_branches :: Text,+ link_labels :: Text,+ link_events :: Text,+ members :: Text+ } deriving (Generic, Show) -- | owners.-data Owner- = Ownwer- { owner_id :: Int,- owner_name :: Text,- owner_username :: Text,- state :: Text,- owner_avatar_url :: Maybe Text,- owner_web_url :: Text- }+data Owner = Ownwer+ { owner_id :: Int,+ owner_name :: Text,+ owner_username :: Text,+ state :: Text,+ owner_avatar_url :: Maybe Text,+ owner_web_url :: Text+ } deriving (Generic, Show) -- | permissions.-data Permissions- = Permissions- { project_access :: Maybe Object,- group_access :: Maybe Object- }+data Permissions = Permissions+ { project_access :: Maybe Object,+ group_access :: Maybe Object+ } deriving (Generic, Show) -- | projects.-data Project- = Project- { project_id :: Int,- description :: Maybe Text,- project_name :: Text,- name_with_namespace :: Text,- project_path :: Text,- path_with_namespace :: Text,- project_created_at :: Text,- default_branch :: Maybe Text,- tag_list :: [Text], -- check- ssh_url_to_repo :: Text,- http_url_to_repo :: Text,- project_web_url :: Text,- readme_url :: Maybe Text, -- check- project_avatar_url :: Maybe Text, -- check- star_count :: Int,- forks_count :: Int,- last_activity_at :: Text,- namespace :: Namespace,- _links :: Maybe Links,- archived :: Maybe Bool,- visibility :: Maybe Text,- owner :: Maybe Owner,- resolve_outdated_diff_discussions :: Maybe Bool,- container_registry_enabled :: Maybe Bool,- issues_enabled :: Maybe Bool,- merge_requests_enabled :: Maybe Bool,- wiki_enabled :: Maybe Bool,- jobs_enabled :: Maybe Bool,- snippets_enabled :: Maybe Bool,- shared_runners_enabled :: Maybe Bool,- lfs_enabled :: Maybe Bool,- creator_id :: Maybe Int,- forked_from_project :: Maybe Project,- import_status :: Maybe String,- open_issues_count :: Maybe Int,- public_jobs :: Maybe Bool,- ci_config_path :: Maybe Text, -- check null- shared_with_groups :: Maybe [Object],- only_allow_merge_if_pipeline_succeeds :: Maybe Bool,- request_access_enabled :: Maybe Bool,- only_allow_merge_if_all_discussions_are_resolved :: Maybe Bool,- printing_merge_request_link_enabled :: Maybe Bool,- merge_method :: Maybe Text,- permissions :: Maybe Permissions,- project_stats :: Maybe ProjectStats- }+data Project = Project+ { project_id :: Int,+ description :: Maybe Text,+ project_name :: Text,+ name_with_namespace :: Text,+ project_path :: Text,+ project_path_with_namespace :: Text,+ project_created_at :: Text,+ default_branch :: Maybe Text,+ tag_list :: [Text], -- check+ ssh_url_to_repo :: Text,+ http_url_to_repo :: Text,+ project_web_url :: Text,+ readme_url :: Maybe Text, -- check+ project_avatar_url :: Maybe Text, -- check+ star_count :: Int,+ forks_count :: Int,+ last_activity_at :: Text,+ namespace :: Namespace,+ _links :: Maybe Links,+ archived :: Maybe Bool,+ visibility :: Maybe Text,+ owner :: Maybe Owner,+ resolve_outdated_diff_discussions :: Maybe Bool,+ container_registry_enabled :: Maybe Bool,+ issues_enabled :: Maybe Bool,+ merge_requests_enabled :: Maybe Bool,+ wiki_enabled :: Maybe Bool,+ jobs_enabled :: Maybe Bool,+ snippets_enabled :: Maybe Bool,+ shared_runners_enabled :: Maybe Bool,+ lfs_enabled :: Maybe Bool,+ creator_id :: Maybe Int,+ forked_from_project :: Maybe Project,+ import_status :: Maybe String,+ open_issues_count :: Maybe Int,+ public_jobs :: Maybe Bool,+ ci_config_path :: Maybe Text, -- check null+ shared_with_groups :: Maybe [Object],+ only_allow_merge_if_pipeline_succeeds :: Maybe Bool,+ request_access_enabled :: Maybe Bool,+ only_allow_merge_if_all_discussions_are_resolved :: Maybe Bool,+ printing_merge_request_link_enabled :: Maybe Bool,+ merge_method :: Maybe Text,+ permissions :: Maybe Permissions,+ project_stats :: Maybe ProjectStats+ } deriving (Generic, Show) -- | project statistics.-data ProjectStats- = ProjectStats- { commit_count :: Int,- storage_size :: Int,- repository_size :: Int,- wiki_size :: Maybe Int,- lfs_objects_size :: Maybe Int,- job_artifacts_size :: Maybe Int,- packages_size :: Maybe Int- }+data ProjectStats = ProjectStats+ { commit_count :: Int,+ storage_size :: Int,+ repository_size :: Int,+ wiki_size :: Maybe Int,+ lfs_objects_size :: Maybe Int,+ job_artifacts_size :: Maybe Int,+ packages_size :: Maybe Int+ } deriving (Generic, Show) -- | registered users.-data User- = User- { user_id :: Int,- user_username :: Text,- user_name :: Text,- user_state :: Text,- user_avatar_uri :: Maybe Text,- user_web_url :: Maybe Text- }+data User = User+ { user_id :: Int,+ user_username :: Text,+ user_name :: Text,+ user_state :: Text,+ user_avatar_uri :: Maybe Text,+ user_web_url :: Maybe Text+ } deriving (Generic, Show) -- | milestone state.@@ -269,282 +266,272 @@ parseJSON x = unexpected x -- | milestones.-data Milestone- = Milestone- { milestone_project_id :: Maybe Int,- milestone_group_id :: Maybe Int,- milestone_description :: Text,- milestone_state :: MilestoneState,- milestone_due_date :: Maybe UTCTime,- milestone_iid :: Int,- milestone_created_at :: Maybe UTCTime,- milestone_title :: Text,- milestone_id :: Int,- milestone_updated_at :: UTCTime,- milestone_web_url :: URL- }+data Milestone = Milestone+ { milestone_project_id :: Maybe Int,+ milestone_group_id :: Maybe Int,+ milestone_description :: Text,+ milestone_state :: MilestoneState,+ milestone_due_date :: Maybe UTCTime,+ milestone_iid :: Int,+ milestone_created_at :: Maybe UTCTime,+ milestone_title :: Text,+ milestone_id :: Int,+ milestone_updated_at :: UTCTime,+ milestone_web_url :: URL+ } deriving (Generic, Show) instance FromJSON Milestone where parseJSON = genericParseJSON (defaultOptions {fieldLabelModifier = drop 10}) -- | time stats.-data TimeStats- = TimeStats- { time_estimate :: Int,- total_time_spent :: Int,- humane_time_estimate :: Maybe Int,- human_total_time_spent :: Maybe Int- }+data TimeStats = TimeStats+ { time_estimate :: Int,+ total_time_spent :: Int,+ humane_time_estimate :: Maybe Int,+ human_total_time_spent :: Maybe Int+ } deriving (Generic, Show) +-- | alias for project id+type ProjectId = Int++-- | alias for issue id+type IssueId = Int+ -- | project issues.-data Issue- = Issue- { issue_state :: Text,- issue_description :: Text,- issue_author :: User,- milestone :: Maybe Milestone,- issue_project_id :: Int,- assignees :: Maybe [User],- assignee :: Maybe User,- updated_at :: Text,- closed_at :: Maybe Text,- closed_by :: Maybe User,- issue_id :: Int,- issue_title :: Text,- issue_created_at :: Text,- iid :: Int,- issue_labels :: [Text],- upvotes :: Int,- downvotes :: Int,- user_notes_count :: Int,- issue_due_date :: Maybe Text,- issue_web_url :: Text,- confidential :: Bool,- weight :: Maybe Text, -- Int?- discussion_locked :: Maybe Bool,- time_stats :: TimeStats- }+data Issue = Issue+ { issue_state :: Text,+ issue_description :: Maybe Text,+ issue_author :: User,+ milestone :: Maybe Milestone,+ issue_project_id :: ProjectId,+ assignees :: Maybe [User],+ assignee :: Maybe User,+ updated_at :: Text,+ closed_at :: Maybe Text,+ closed_by :: Maybe User,+ issue_id :: IssueId,+ issue_title :: Text,+ issue_created_at :: Text,+ iid :: Int,+ issue_labels :: [Text],+ upvotes :: Int,+ downvotes :: Int,+ user_notes_count :: Int,+ issue_due_date :: Maybe Text,+ issue_web_url :: Text,+ confidential :: Bool,+ weight :: Maybe Text, -- Int?+ discussion_locked :: Maybe Bool,+ time_stats :: TimeStats+ } deriving (Generic, Show) -- | project pipelines-data Pipeline- = Pipeline- { pipeline_id :: Int,- sha :: Text,- pipeline_ref :: Text,- pipeline_status :: Text,- pipeline_web_url :: Maybe Text- }+data Pipeline = Pipeline+ { pipeline_id :: Int,+ sha :: Text,+ pipeline_ref :: Text,+ pipeline_status :: Text,+ pipeline_web_url :: Maybe Text+ } deriving (Generic, Show) -- | code commits.-data Commit- = Commit- { commit_id :: Text,- short_id :: Text,- title :: Text,- author_name :: Text,- author_email :: Text,- authored_date :: Text,- committer_name :: Text,- committer_email :: Text,- committed_date :: Text,- commit_created_at :: Text,- message :: Text,- parent_ids :: Maybe [Int],- last_pipeline :: Maybe Pipeline,- commit_stats :: Maybe CommitStats,- commit_status :: Maybe Text- }+data Commit = Commit+ { commit_id :: Text,+ short_id :: Text,+ title :: Text,+ author_name :: Text,+ author_email :: Text,+ authored_date :: Text,+ committer_name :: Text,+ committer_email :: Text,+ committed_date :: Text,+ commit_created_at :: Text,+ message :: Text,+ commit_parent_ids :: Maybe [String],+ last_pipeline :: Maybe Pipeline,+ commit_stats :: Maybe CommitStats,+ commit_status :: Maybe Text+ } deriving (Generic, Show) -- | summary of a code commit for TODOs.-data CommitTodo- = CommitTodo- { todo_commit_id :: Text,- todo_commit_short_id :: Text,- todo_commit_created_at :: Text,- todo_parent_ids :: Maybe [Int]- }+data CommitTodo = CommitTodo+ { todo_commit_id :: Text,+ todo_commit_short_id :: Text,+ todo_commit_created_at :: Text,+ todo_parent_ids :: Maybe [String]+ } deriving (Generic, Show) -- | commit stats.-data CommitStats- = Stats- { additions :: Int,- deletions :: Int,- total :: Int- }+data CommitStats = Stats+ { additions :: Int,+ deletions :: Int,+ total :: Int+ } deriving (Generic, Show) -- | diff between two commits.-data Diff- = Diff- { diff :: Text,- new_path :: Text,- old_path :: Text,- a_mode :: Maybe Text,- b_mode :: Maybe Text,- new_file :: Bool,- renamed_file :: Bool,- deleted_file :: Bool- }+data Diff = Diff+ { diff :: Text,+ new_path :: Text,+ old_path :: Text,+ a_mode :: Maybe Text,+ b_mode :: Maybe Text,+ new_file :: Bool,+ renamed_file :: Bool,+ deleted_file :: Bool+ } deriving (Generic, Show) -- | repositories.-data Repository- = Repository- { repository_id :: Text,- repository_name :: Text,- repository_type :: Text,- repository_path :: Text,- mode :: Text- }+data Repository = Repository+ { repository_id :: Text,+ repository_name :: Text,+ repository_type :: Text,+ repository_path :: Text,+ mode :: Text+ } deriving (Generic, Show) -- | jobs.-data Job- = Job- { commit :: Commit,- coverage :: Maybe Text, -- ?- created_at :: Text,- started_at :: Text,- finished_at :: Text,- duration :: Double,- artifacts_expire_at :: Maybe Text,- id :: Int,- name :: Text,- pipeline :: Pipeline,- job_ref :: Text,- artifacts :: [Artifact],- -- , runner :: Maybe Text- stage :: Text,- status :: Text,- tag :: Bool,- job_web_url :: Text,- user :: User- }+data Job = Job+ { job_commit :: Commit,+ job_coverage :: Maybe Text, -- ?+ job_created_at :: Text,+ job_started_at :: Text,+ job_finished_at :: Text,+ job_duration :: Double,+ job_artifacts_expire_at :: Maybe Text,+ job_id :: Int,+ job_name :: Text,+ job_pipeline :: Pipeline,+ job_ref :: Text,+ job_artifacts :: [Artifact],+ -- , runner :: Maybe Text+ job_stage :: Text,+ job_status :: Text,+ job_tag :: Bool,+ job_web_url :: Text,+ job_user :: User+ } deriving (Generic, Show) -- | artifacts.-data Artifact- = Artifact- { file_type :: Text,- size :: Int,- filename :: Text,- file_format :: Maybe Text- }+data Artifact = Artifact+ { file_type :: Text,+ size :: Int,+ filename :: Text,+ file_format :: Maybe Text+ } deriving (Generic, Show) -- | groups.-data Group- = Group- { group_id :: Int,- group_name :: Text,- group_path :: Text,- group_description :: Text,- group_visibility :: Text,- group_lfs_enabled :: Bool,- group_avatar_url :: Maybe Text,- group_web_url :: Text,- group_request_access_enabled :: Bool,- group_full_name :: Text,- group_full_path :: Text,- group_file_template_project_id :: Maybe Int,- group_parent_id :: Maybe Int- }+data Group = Group+ { group_id :: Int,+ group_name :: Text,+ group_path :: Text,+ group_description :: Text,+ group_visibility :: Text,+ group_lfs_enabled :: Bool,+ group_avatar_url :: Maybe Text,+ group_web_url :: Text,+ group_request_access_enabled :: Bool,+ group_full_name :: Text,+ group_full_path :: Text,+ group_file_template_project_id :: Maybe Int,+ group_parent_id :: Maybe Int+ } deriving (Generic, Show) -- | response to sharing a project with a group.-data GroupShare- = GroupShare- { share_id :: Int,- share_project_id :: Int,- share_group_id :: Int,- share_group_access :: Int,- share_expires_at :: Maybe Text- }+data GroupShare = GroupShare+ { share_id :: Int,+ share_project_id :: Int,+ share_group_id :: Int,+ share_group_access :: Int,+ share_expires_at :: Maybe Text+ } deriving (Generic, Show) -- | code branches.-data Branch- = Branch- { branch_name :: Text,- merged :: Bool,- protected :: Bool,- branch_default :: Bool,- developers_can_push :: Bool,- developers_can_merge :: Bool,- can_push :: Bool,- branch_commit :: Commit- }+data Branch = Branch+ { branch_name :: Text,+ merged :: Bool,+ protected :: Bool,+ branch_default :: Bool,+ developers_can_push :: Bool,+ developers_can_merge :: Bool,+ can_push :: Bool,+ branch_commit :: Commit+ } deriving (Generic, Show) -- | files in a repository.-data RepositoryFile- = RepositoryFile- { repository_file_file_name :: Text,- repository_file_file_path :: Text,- repository_file_size :: Int,- encoding :: Text,- content :: Text,- content_sha256 :: Text,- ref :: Text,- blob_id :: Text,- repository_file_commit_id :: Text,- last_commit_id :: Text- }+data RepositoryFile = RepositoryFile+ { repository_file_file_name :: Text,+ repository_file_file_path :: Text,+ repository_file_size :: Int,+ encoding :: Text,+ content :: Text,+ content_sha256 :: Text,+ ref :: Text,+ blob_id :: Text,+ repository_file_commit_id :: Text,+ last_commit_id :: Text+ } deriving (Generic, Show) -- | project merge requests.-data MergeRequest- = MergeRequest- { merge_request_id :: Int,- merge_request_iid :: Int,- merge_request_project_id :: Int,- merge_request_title :: Text,- merge_request_description :: Text,- merge_request_state :: Text,- merge_request_merged_by :: Maybe User,- merge_request_merged_at :: Maybe Text,- merge_request_closed_by :: Maybe User,- merge_request_closed_at :: Maybe Text,- merge_request_created_at :: Text,- merge_request_updated_at :: Text,- merge_request_target_branch :: Text,- merge_request_source_branch :: Text,- merge_request_upvotes :: Int,- merge_request_downvotes :: Int,- merge_request_author :: User,- merge_request_assignee :: Maybe User,- merge_request_source_project_id :: Int,- merge_request_target_project_id :: Int,- merge_request_labels :: [Text],- merge_request_work_in_progress :: Bool,- merge_request_milestone :: Maybe Milestone,- merge_request_merge_when_pipeline_succeeds :: Bool,- merge_request_merge_status :: Text,- merge_request_sha :: Text,- merge_request_merge_commit_sha :: Maybe Text,- merge_request_user_notes_count :: Int,- merge_request_discussion_locked :: Maybe Bool,- merge_request_should_remove_source_branch :: Maybe Bool,- merge_request_force_remove_source_branch :: Maybe Bool,- merge_request_allow_collaboration :: Maybe Bool,- merge_request_allow_maintainer_to_push :: Maybe Bool,- merge_request_web_url :: Text,- merge_request_time_stats :: TimeStats,- merge_request_squash :: Bool,- merge_request_changes_count :: Maybe Int,- merge_request_pipeline :: Maybe Pipeline,- merge_request_diverged_commits_count :: Maybe Int,- merge_request_rebase_in_progress :: Maybe Bool,- merge_request_has_conflicts :: Bool,- merge_request_blocking_discussions_resolved :: Maybe Bool,- merge_request_approvals_before_merge :: Maybe Bool -- ?- }+data MergeRequest = MergeRequest+ { merge_request_id :: Int,+ merge_request_iid :: Int,+ merge_request_project_id :: Int,+ merge_request_title :: Text,+ merge_request_description :: Text,+ merge_request_state :: Text,+ merge_request_merged_by :: Maybe User,+ merge_request_merged_at :: Maybe Text,+ merge_request_closed_by :: Maybe User,+ merge_request_closed_at :: Maybe Text,+ merge_request_created_at :: Text,+ merge_request_updated_at :: Text,+ merge_request_target_branch :: Text,+ merge_request_source_branch :: Text,+ merge_request_upvotes :: Int,+ merge_request_downvotes :: Int,+ merge_request_author :: User,+ merge_request_assignee :: Maybe User,+ merge_request_source_project_id :: Int,+ merge_request_target_project_id :: Int,+ merge_request_labels :: [Text],+ merge_request_work_in_progress :: Bool,+ merge_request_milestone :: Maybe Milestone,+ merge_request_merge_when_pipeline_succeeds :: Bool,+ merge_request_merge_status :: Text,+ merge_request_sha :: Text,+ merge_request_merge_commit_sha :: Maybe Text,+ merge_request_user_notes_count :: Int,+ merge_request_discussion_locked :: Maybe Bool,+ merge_request_should_remove_source_branch :: Maybe Bool,+ merge_request_force_remove_source_branch :: Maybe Bool,+ merge_request_allow_collaboration :: Maybe Bool,+ merge_request_allow_maintainer_to_push :: Maybe Bool,+ merge_request_web_url :: Text,+ merge_request_time_stats :: TimeStats,+ merge_request_squash :: Bool,+ merge_request_changes_count :: Maybe Int,+ merge_request_pipeline :: Maybe Pipeline,+ merge_request_diverged_commits_count :: Maybe Int,+ merge_request_rebase_in_progress :: Maybe Bool,+ merge_request_has_conflicts :: Bool,+ merge_request_blocking_discussions_resolved :: Maybe Bool,+ merge_request_approvals_before_merge :: Maybe Bool -- ?+ } deriving (Generic, Show) -- | TODO actions.@@ -589,34 +576,33 @@ parseJSON (String "done") = return TSDone parseJSON x = unexpected x -data TodoProject- = TP- { tp_id :: Int,- tp_description :: Text,- tp_name :: Text,- tp_name_with_namespace :: Text,- tp_path :: Text,- tp_path_with_namespace :: Text,- tp_created_at :: UTCTime- }+-- | A project TODO.+data TodoProject = TP+ { tp_id :: Int,+ tp_description :: Text,+ tp_name :: Text,+ tp_name_with_namespace :: Text,+ tp_path :: Text,+ tp_path_with_namespace :: Text,+ tp_created_at :: UTCTime+ } deriving (Generic, Show) instance FromJSON TodoProject where parseJSON = genericParseJSON (defaultOptions {fieldLabelModifier = drop 3}) -- | TODOs.-data Todo- = Todo- { todo_id :: Int,- todo_project :: TodoProject,- todo_author :: User,- todo_action_name :: TodoAction,- todo_target :: TodoTarget,- todo_target_url :: URL,- todo_body :: Text,- todo_state :: TodoState,- todo_created_at :: UTCTime- }+data Todo = Todo+ { todo_id :: Int,+ todo_project :: TodoProject,+ todo_author :: User,+ todo_action_name :: TodoAction,+ todo_target :: TodoTarget,+ todo_target_url :: URL,+ todo_body :: Text,+ todo_state :: TodoState,+ todo_created_at :: UTCTime+ } deriving (Show) instance FromJSON Todo where@@ -638,13 +624,32 @@ <*> v .: "created_at" -- | version of the GitLab instance.-data Version- = Version- { version :: Text,- revision :: Text- }+data Version = Version+ { version :: Text,+ revision :: Text+ } deriving (Generic, Show) +-- | An edit issue request.+data EditIssueReq = EditIssueReq+ { edit_issue_id :: ProjectId,+ edit_issue_issue_iid :: IssueId,+ edit_issue_title :: Maybe Text,+ edit_issue_description :: Maybe Text,+ edit_issue_confidential :: Maybe Bool,+ edit_issue_assignee_ids :: Maybe [Int],+ edit_issue_milestone_id :: Maybe Int,+ edit_issue_labels :: Maybe [Text],+ edit_issue_state_event :: Maybe Text,+ edit_issue_updated_at :: Maybe Text,+ edit_issue_due_date :: Maybe Text,+ edit_issue_weight :: Maybe Int,+ edit_issue_discussion_locked :: Maybe Bool,+ edit_issue_epic_id :: Maybe Int,+ edit_issue_epic_iid :: Maybe Int+ }+ deriving (Generic, Show)+ ----------------------------- -- JSON GitLab parsers below -----------------------------@@ -653,6 +658,7 @@ bodyNoPrefix "commit_created_at" = "created_at" bodyNoPrefix "commit_id" = "id" bodyNoPrefix "commit_status" = "status"+bodyNoPrefix "commit_parent_ids" = "parent_ids" bodyNoPrefix "todo_commit_id" = "id" bodyNoPrefix "todo_commit_short_id" = "short_id" bodyNoPrefix "todo_commit_created_at" = "created_at"@@ -667,7 +673,6 @@ bodyNoPrefix "issue_state" = "state" bodyNoPrefix "issue_title" = "title" bodyNoPrefix "issue_web_url" = "web_url"-bodyNoPrefix "job_web_url" = "web_url" bodyNoPrefix "link_events" = "events" bodyNoPrefix "link_labels" = "labels" bodyNoPrefix "member_avatar_url" = "avatar_url"@@ -692,6 +697,7 @@ bodyNoPrefix "project_id" = "id" bodyNoPrefix "project_name" = "name" bodyNoPrefix "project_path" = "path"+bodyNoPrefix "project_path_with_namespace" = "path_with_namespace" bodyNoPrefix "project_web_url" = "web_url" bodyNoPrefix "repository_id" = "id" bodyNoPrefix "repository_name" = "name"@@ -705,7 +711,6 @@ bodyNoPrefix "user_web_url" = "we_url" bodyNoPrefix "event_title" = "title" bodyNoPrefix "event_project_id" = "project_id"-bodyNoPrefix "job_ref" = "ref" bodyNoPrefix "pipeline_ref" = "ref" bodyNoPrefix "branch_name" = "name" bodyNoPrefix "branch_default" = "default"@@ -778,6 +783,23 @@ bodyNoPrefix "group_full_path" = "full_path" bodyNoPrefix "group_file_template_project_id" = "file_template_project_id" bodyNoPrefix "group_parent_id" = "parent_id"+bodyNoPrefix "job_commit" = "commit"+bodyNoPrefix "job_coverage" = "coverage"+bodyNoPrefix "job_created_at" = "created_at"+bodyNoPrefix "job_started_at" = "started_at"+bodyNoPrefix "job_finished_at" = "finished_at"+bodyNoPrefix "job_duration" = "duration"+bodyNoPrefix "job_artifacts_expire_at" = "artifacts_expire_at"+bodyNoPrefix "job_id" = "id"+bodyNoPrefix "job_name" = "name"+bodyNoPrefix "job_pipeline" = "pipeline"+bodyNoPrefix "job_ref" = "ref"+bodyNoPrefix "job_artifacts" = "artifacts"+bodyNoPrefix "job_stage" = "stage"+bodyNoPrefix "job_status" = "status"+bodyNoPrefix "job_tag" = "tag"+bodyNoPrefix "job_web_url" = "web_url"+bodyNoPrefix "job_user" = "user" -- TODO field names for Issues data type bodyNoPrefix s = s @@ -972,3 +994,11 @@ { fieldLabelModifier = bodyNoPrefix } )++instance ToJSON EditIssueReq where+ toEncoding =+ genericToEncoding+ defaultOptions+ { fieldLabelModifier = drop (T.length "edit_issue_"),+ omitNothingFields = True+ }
src/GitLab/WebRequests/GitLabWebCalls.hs view
@@ -8,10 +8,12 @@ gitlabWithAttrs, gitlabWithAttrsUnsafe, gitlabOne,+ -- gitlabOneIO, gitlabWithAttrsOne, -- not currently used. -- gitlabWithAttrsOneUnsafe, gitlabPost,+ gitlabPut, gitlabReqText, gitlabReqByteString, )@@ -31,6 +33,7 @@ import Network.HTTP.Conduit import Network.HTTP.Types.Status import Network.HTTP.Types.URI+import Text.Read newtype GitLabException = GitLabException String deriving (Eq, Show)@@ -41,12 +44,12 @@ -- error code responses, e.g. 404, 409. gitlabPost ::- (MonadIO m, FromJSON b) =>+ (FromJSON b) => -- | the URL to post to Text -> -- | the data to post Text ->- GitLab m (Either Status b)+ GitLab (Either Status b) gitlabPost urlPath dataBody = do cfg <- serverCfg <$> ask manager <- httpManager <$> ask@@ -71,6 +74,39 @@ ) else return (Left (responseStatus resp)) +gitlabPut ::+ FromJSON b =>+ -- | the URL to post to+ Text ->+ -- | the data to post+ Text ->+ GitLab (Either Status b)+gitlabPut urlPath dataBody = do+ cfg <- serverCfg <$> ask+ manager <- httpManager <$> ask+ let url' = url cfg <> "/api/v4" <> urlPath+ let request' = parseRequest_ (T.unpack url')+ request =+ request'+ { method = "PUT",+ requestHeaders =+ [ ("PRIVATE-TOKEN", T.encodeUtf8 (token cfg)),+ ("content-type", "application/json")+ ],+ requestBody = RequestBodyBS (T.encodeUtf8 dataBody)+ }+ resp <- liftIO $ tryGitLab 0 request (retries cfg) manager Nothing+ if successStatus (responseStatus resp)+ then+ return+ ( case parseBSOne (responseBody resp) of+ Just x -> Right x+ Nothing ->+ Left $+ mkStatus 409 "unable to parse PUT response"+ )+ else return (Left (responseStatus resp))+ tryGitLab :: -- | the current retry count Int ->@@ -102,7 +138,7 @@ Left s -> Exception.throwIO $ GitLabException s Right xs -> return xs -gitlabReqJsonMany :: (MonadIO m, FromJSON a) => Text -> Text -> GitLab m (Either Status [a])+gitlabReqJsonMany :: (FromJSON a) => Text -> Text -> GitLab (Either Status [a]) gitlabReqJsonMany urlPath attrs = go 1 [] where@@ -135,7 +171,32 @@ else go (i + 1) accum' else return (Left (responseStatus resp)) -gitlabReqOne :: (MonadIO m) => (BSL.ByteString -> output) -> Text -> Text -> GitLab m (Either Status output)+-- not sure what this was planned for+--+-- gitlabReqOneIO :: Manager -> GitLabServerConfig -> (BSL.ByteString -> output) -> Text -> Text -> IO (Either Status output)+-- gitlabReqOneIO manager cfg parser urlPath attrs = go+-- where+-- go = do+-- let url' =+-- url cfg+-- <> "/api/v4"+-- <> urlPath+-- <> "?per_page=100"+-- <> "&page=1"+-- <> attrs+-- let request' = parseRequest_ (T.unpack url')+-- request =+-- request'+-- { requestHeaders =+-- [("PRIVATE-TOKEN", T.encodeUtf8 (token cfg))],+-- responseTimeout = responseTimeoutMicro (timeout cfg)+-- }+-- resp <- tryGitLab 0 request (retries cfg) manager Nothing+-- if successStatus (responseStatus resp)+-- then return (Right (parser (responseBody resp)))+-- else return (Left (responseStatus resp))++gitlabReqOne :: (BSL.ByteString -> output) -> Text -> Text -> GitLab (Either Status output) gitlabReqOne parser urlPath attrs = go where go = do@@ -160,38 +221,49 @@ then return (Right (parser (responseBody resp))) else return (Left (responseStatus resp)) -gitlabReqJsonOne :: (MonadIO m, FromJSON a) => Text -> Text -> GitLab m (Either Status (Maybe a))+-- not sure what this was planned for+--+-- gitlabReqJsonOneIO :: (FromJSON a) => Manager -> GitLabServerConfig -> Text -> Text -> IO (Either Status (Maybe a))+-- gitlabReqJsonOneIO mgr cfg urlPath attrs =+-- gitlabReqOneIO mgr cfg parseBSOne urlPath attrs++gitlabReqJsonOne :: (FromJSON a) => Text -> Text -> GitLab (Either Status (Maybe a)) gitlabReqJsonOne = gitlabReqOne parseBSOne -gitlabReqText :: (MonadIO m) => Text -> GitLab m (Either Status String)+gitlabReqText :: Text -> GitLab (Either Status String) gitlabReqText urlPath = gitlabReqOne C.unpack urlPath "" -gitlabReqByteString :: (MonadIO m) => Text -> GitLab m (Either Status BSL.ByteString)+gitlabReqByteString :: Text -> GitLab (Either Status BSL.ByteString) gitlabReqByteString urlPath = gitlabReqOne Prelude.id urlPath "" -gitlab :: (MonadIO m, FromJSON a) => Text -> GitLab m (Either Status [a])+gitlab :: FromJSON a => Text -> GitLab (Either Status [a]) gitlab addr = gitlabReqJsonMany addr "" -gitlabUnsafe :: (MonadIO m, FromJSON a) => Text -> GitLab m [a]+gitlabUnsafe :: (FromJSON a) => Text -> GitLab [a] gitlabUnsafe addr = fromRight (error "gitlabUnsafe error") <$> gitlab addr -gitlabOne :: (MonadIO m, FromJSON a) => Text -> GitLab m (Either Status (Maybe a))+-- not sure what this was planned for+--+-- gitlabOneIO :: (FromJSON a) => Manager -> GitLabServerConfig -> Text -> IO (Either Status (Maybe a))+-- gitlabOneIO mgr cfg addr = gitlabReqJsonOneIO mgr cfg addr ""++gitlabOne :: (FromJSON a) => Text -> GitLab (Either Status (Maybe a)) gitlabOne addr = gitlabReqJsonOne addr "" -gitlabWithAttrs :: (MonadIO m, FromJSON a) => Text -> Text -> GitLab m (Either Status [a])+gitlabWithAttrs :: (FromJSON a) => Text -> Text -> GitLab (Either Status [a]) gitlabWithAttrs = gitlabReqJsonMany -gitlabWithAttrsUnsafe :: (MonadIO m, FromJSON a) => Text -> Text -> GitLab m [a]+gitlabWithAttrsUnsafe :: (FromJSON a) => Text -> Text -> GitLab [a] gitlabWithAttrsUnsafe gitlabURL attrs = fromRight (error "gitlabWithAttrsUnsafe error") <$> gitlabReqJsonMany gitlabURL attrs -gitlabWithAttrsOne :: (MonadIO m, FromJSON a) => Text -> Text -> GitLab m (Either Status (Maybe a))+gitlabWithAttrsOne :: (FromJSON a) => Text -> Text -> GitLab (Either Status (Maybe a)) gitlabWithAttrsOne = gitlabReqJsonOne -- not currently used.--- gitlabWithAttrsOneUnsafe :: (MonadIO m, FromJSON a) => Text -> Text -> GitLab m (Maybe a)+-- gitlabWithAttrsOneUnsafe :: (MonadIO m, FromJSON a) => Text -> Text -> GitLab (Maybe a) -- gitlabWithAttrsOneUnsafe gitlabURL attrs = -- fromRight (error "gitlabWithAttrsUnsafe error") <$> gitlabReqJsonOne gitlabURL attrs @@ -201,7 +273,10 @@ in findPages hdrs where findPages [] = 1 -- error "cannot find X-Total-Pages in header"- findPages (("X-Total-Pages", bs) : _) = read (T.unpack (T.decodeUtf8 bs))+ findPages (("X-Total-Pages", bs) : _) =+ case readMaybe (T.unpack (T.decodeUtf8 bs)) of+ Just s -> s+ Nothing -> error "cannot find X-Total-Pages in header" findPages (_ : xs) = findPages xs successStatus :: Status -> Bool
+ tests/SystemHookTests.hs view
@@ -0,0 +1,1392 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}++module SystemHookTests (systemHookTests) where++import Control.Monad.IO.Class+import Data.Aeson+import qualified Data.ByteString.Lazy.Char8 as BSL+import GitLab+import GitLab.SystemHooks.GitLabSystemHooks+import GitLab.SystemHooks.Types+import Test.Tasty+import Test.Tasty.HUnit++systemHookTests :: [TestTree]+systemHookTests =+ [parserTests, matchTests, matchIfTests, receiveTests]++parserTests :: TestTree+parserTests =+ testGroup+ "GitLab system hook rules"+ [ testCase+ "project-create-event"+ ( readFile "data/system-hooks/project-created.json"+ >>= \eventJson -> parseEvent eventJson @?= Just projectCreatedHaskell+ ),+ testCase+ "project-destroy-event"+ ( readFile "data/system-hooks/project-destroyed.json"+ >>= \eventJson -> parseEvent eventJson @?= Just projectDestroyedHaskell+ ),+ testCase+ "project-rename-event"+ ( readFile "data/system-hooks/project-renamed.json"+ >>= \eventJson -> parseEvent eventJson @?= Just projectRenamedHaskell+ ),+ testCase+ "project-transfer-event"+ ( readFile "data/system-hooks/project-transferred.json"+ >>= \eventJson -> parseEvent eventJson @?= Just projectTransferredHaskell+ ),+ testCase+ "project-update-event"+ ( readFile "data/system-hooks/project-updated.json"+ >>= \eventJson -> parseEvent eventJson @?= Just projectUpdatedHaskell+ ),+ testCase+ "new-team-member-event"+ ( readFile "data/system-hooks/new-team-member.json"+ >>= \eventJson -> parseEvent eventJson @?= Just userAddedToTeamHaskell+ ),+ testCase+ "team-member-removed-event"+ ( readFile "data/system-hooks/team-member-removed.json"+ >>= \eventJson -> parseEvent eventJson @?= Just userRemovedFromTeamHaskell+ ),+ testCase+ "team-member-updated-event"+ ( readFile "data/system-hooks/team-member-updated.json"+ >>= \eventJson -> parseEvent eventJson @?= Just userUpdatedForTeamHaskell+ ),+ testCase+ "user-created-event"+ ( readFile "data/system-hooks/user-created.json"+ >>= \eventJson -> parseEvent eventJson @?= Just userCreatedHaskell+ ),+ testCase+ "user-removed-event"+ ( readFile "data/system-hooks/user-removed.json"+ >>= \eventJson -> parseEvent eventJson @?= Just userRemovedHaskell+ ),+ testCase+ "user-failed-login-event"+ ( readFile "data/system-hooks/user-failed-login.json"+ >>= \eventJson -> parseEvent eventJson @?= Just userFailedLoginHaskell+ ),+ testCase+ "user-renamed-event"+ ( readFile "data/system-hooks/user-renamed.json"+ >>= \eventJson -> parseEvent eventJson @?= Just userRenamedHaskell+ ),+ testCase+ "key-added-event"+ ( readFile "data/system-hooks/key-added.json"+ >>= \eventJson -> parseEvent eventJson @?= Just keyCreatedHaskell+ ),+ testCase+ "key-removed-event"+ ( readFile "data/system-hooks/key-removed.json"+ >>= \eventJson -> parseEvent eventJson @?= Just keyRemovedHaskell+ ),+ testCase+ "group-created-event"+ ( readFile "data/system-hooks/group-created.json"+ >>= \eventJson -> parseEvent eventJson @?= Just groupCreatedHaskell+ ),+ testCase+ "group-removed-event"+ ( readFile "data/system-hooks/group-removed.json"+ >>= \eventJson -> parseEvent eventJson @?= Just groupRemovedHaskell+ ),+ testCase+ "group-renamed-event"+ ( readFile "data/system-hooks/group-renamed.json"+ >>= \eventJson -> parseEvent eventJson @?= Just groupRenamedHaskell+ ),+ testCase+ "new-group-member-event"+ ( readFile "data/system-hooks/new-group-member.json"+ >>= \eventJson -> parseEvent eventJson @?= Just newGroupMemberHaskell+ ),+ testCase+ "group-member-removed-event"+ ( readFile "data/system-hooks/group-member-removed.json"+ >>= \eventJson -> parseEvent eventJson @?= Just groupMemberRemovedHaskell+ ),+ testCase+ "group-member-updated-event"+ ( readFile "data/system-hooks/group-member-updated.json"+ >>= \eventJson -> parseEvent eventJson @?= Just groupMemberUpdatedHaskell+ ),+ testCase+ "push-event"+ ( readFile "data/system-hooks/push.json"+ >>= \eventJson -> parseEvent eventJson @?= Just pushHaskell+ ),+ testCase+ "tag-push-event"+ ( readFile "data/system-hooks/tag-push.json"+ >>= \eventJson -> parseEvent eventJson @?= Just tagPushHaskell+ )+ -- testCase+ -- "merge-request-event"+ -- ( readFile "data/system-hooks/merge-request.json"+ -- >>= \eventJson -> parseEvent eventJson @?= Just mergeRequestHaskell+ -- ),+ -- testCase+ -- "repository-update-event"+ -- ( readFile "data/system-hooks/repository-update.json"+ -- >>= \eventJson -> parseEvent eventJson @?= Just repositoryUpdateHaskell+ -- )+ ]++matchTest :: String -> String -> Rule -> String -> Rule -> [TestTree]+matchTest lbl jsonFilename rule wrongJson wrongRule =+ [ testCase lbl $+ runGitLabDbg+ ( liftIO (readFile ("data/system-hooks/" <> jsonFilename))+ >>= \eventJson -> tryFire eventJson rule+ )+ @? (lbl <> " failed"),+ testCase (lbl <> "-wrong-json") $+ not+ <$> runGitLabDbg+ ( liftIO (readFile ("data/system-hooks/" <> wrongJson))+ >>= \eventJson -> tryFire eventJson rule+ )+ @? (lbl <> "-wrong-json failed"),+ testCase (lbl <> "-wrong-rule") $+ not+ <$> runGitLabDbg+ ( liftIO (readFile ("data/system-hooks/" <> jsonFilename))+ >>= \eventJson -> tryFire eventJson wrongRule+ )+ @? (lbl <> "-wrong-rule failed")+ ]++matchIfTest :: String -> String -> Rule -> Rule -> [TestTree]+matchIfTest lbl jsonFilename yesFire noFire =+ [ testCase (lbl <> "-yes") $+ runGitLabDbg+ ( liftIO (readFile ("data/system-hooks/" <> jsonFilename))+ >>= \eventJson -> tryFire eventJson yesFire+ )+ @? "project-create-fireIf-yes failed",+ testCase (lbl <> "-no") $+ not+ <$> runGitLabDbg+ ( liftIO (readFile ("data/system-hooks/" <> jsonFilename))+ >>= \eventJson -> tryFire eventJson noFire+ )+ @? "project-create-fireIf-no failed"+ ]++-- [ testCase lbl $+-- runGitLabDbg+-- ( liftIO (readFile ("data/system-hooks/" <> jsonFilename))+-- >>= \eventJson -> fire eventJson rule+-- )+-- @? (lbl <> " failed"),+-- testCase (lbl <> "-wrong-json") $+-- not+-- <$> runGitLabDbg+-- ( liftIO (readFile ("data/system-hooks/" <> wrongJson))+-- >>= \eventJson -> fire eventJson rule+-- )+-- @? (lbl <> "-wrong-json failed"),+-- testCase (lbl <> "-wrong-rule") $+-- not+-- <$> runGitLabDbg+-- ( liftIO (readFile ("data/system-hooks/" <> jsonFilename))+-- >>= \eventJson -> fire eventJson wrongRule+-- )+-- @? (lbl <> "-wrong-rule failed")+-- ]++matchTests :: TestTree+matchTests =+ testGroup "GitLab system hook match" $+ matchTest "project-create" "project-created.json" projectCreateRule "project-destroyed.json" projectDestroyRule+ <> matchTest "project-destroy" "project-destroyed.json" projectDestroyRule "project-created.json" projectCreateRule+ <> matchTest "project-rename" "project-renamed.json" projectRenameRule "project-created.json" projectCreateRule+ <> matchTest "project-transfer" "project-transferred.json" projectTransferRule "project-created.json" projectCreateRule+ <> matchTest "project-update" "project-updated.json" projectUpdateRule "project-created.json" projectCreateRule+ <> matchTest "user-add-to-team" "new-team-member.json" userAddToTeamRule "project-created.json" projectCreateRule+ <> matchTest "user-update-for-team" "team-member-updated.json" userUpdateForTeamRule "project-created.json" projectCreateRule+ <> matchTest "user-remove-from-team" "team-member-removed.json" userRemoveFromTeamRule "project-created.json" projectCreateRule+ <> matchTest "user-create" "user-created.json" userCreateRule "project-created.json" projectCreateRule+ <> matchTest "user-remove" "user-removed.json" userRemoveRule "project-created.json" projectCreateRule+ <> matchTest "user-failed-login" "user-failed-login.json" userFailedLoginRule "project-created.json" projectCreateRule+ <> matchTest "user-rename" "user-renamed.json" userRenameRule "project-created.json" projectCreateRule+ <> matchTest "key-create" "key-added.json" keyCreateRule "project-created.json" projectCreateRule+ <> matchTest "key-remove" "key-removed.json" keyRemoveRule "project-created.json" projectCreateRule+ <> matchTest "group-create" "group-created.json" groupCreateRule "project-created.json" projectCreateRule+ <> matchTest "group-remove" "group-removed.json" groupRemoveRule "project-created.json" projectCreateRule+ <> matchTest "group-rename" "group-renamed.json" groupRenameRule "project-created.json" projectCreateRule+ <> matchTest "new-group-member" "new-group-member.json" newGroupMemberRule "project-created.json" projectCreateRule+ <> matchTest "group-member-remove" "group-member-removed.json" groupMemberRemoveRule "project-created.json" projectCreateRule+ <> matchTest "group-member-update" "group-member-updated.json" groupMemberUpdateRule "project-created.json" projectCreateRule+ <> matchTest "push" "push.json" pushRule "project-created.json" projectCreateRule+ <> matchTest "tag-push" "tag-push.json" tagPushRule "project-created.json" projectCreateRule++matchIfTests :: TestTree+matchIfTests =+ testGroup "GitLab system hook matchIf" $+ matchIfTest "project-create" "project-created.json" projectCreateIfRuleYes projectCreateIfRuleNo+ <> matchIfTest "project-destroy" "project-destroyed.json" projectDestroyIfRuleYes projectDestroyIfRuleNo+ <> matchIfTest "project-rename" "project-renamed.json" projectRenameIfRuleYes projectRenameIfRuleNo+ <> matchIfTest "project-transfer" "project-transferred.json" projectTransferIfRuleYes projectTransferIfRuleNo+ <> matchIfTest "project-update" "project-updated.json" projectUpdateIfRuleYes projectUpdateIfRuleNo+ <> matchIfTest "user-add-to-team" "new-team-member.json" userAddToTeamIfRuleYes userAddToTeamIfRuleNo+ <> matchIfTest "user-update-for-team" "team-member-updated.json" userUpdateForTeamIfRuleYes userUpdateForTeamIfRuleNo+ <> matchIfTest "user-remove-from-team" "team-member-removed.json" userRemoveFromTeamIfRuleYes userRemoveFromTeamIfRuleNo+ <> matchIfTest "user-create" "user-created.json" userCreateIfRuleYes userCreateIfRuleNo+ <> matchIfTest "user-remove" "user-removed.json" userRemoveIfRuleYes userRemoveIfRuleNo+ <> matchIfTest "user-failed-login" "user-failed-login.json" userFailedLoginIfRuleYes userFailedLoginIfRuleNo+ <> matchIfTest "user-rename" "user-renamed.json" userRenameIfRuleYes userRenameIfRuleNo+ <> matchIfTest "key-create" "key-added.json" keyCreateIfRuleYes keyCreateIfRuleNo+ <> matchIfTest "key-remove" "key-removed.json" keyRemoveIfRuleYes keyRemoveIfRuleNo+ <> matchIfTest "group-create" "group-created.json" groupCreateIfRuleYes groupCreateIfRuleNo+ <> matchIfTest "group-remove" "group-removed.json" groupRemoveIfRuleYes groupRemoveIfRuleNo+ <> matchIfTest "group-rename" "group-renamed.json" groupRenameIfRuleYes groupRenameIfRuleNo+ <> matchIfTest "new-group-member" "new-group-member.json" newGroupMemberIfRuleYes newGroupMemberIfRuleNo+ <> matchIfTest "group-member-remove" "group-member-removed.json" groupMemberRemoveIfRuleYes groupMemberRemoveIfRuleNo+ <> matchIfTest "group-member-update" "group-member-updated.json" groupMemberUpdateIfRuleYes groupMemberUpdateIfRuleNo+ <> matchIfTest "push" "push.json" pushIfRuleYes pushIfRuleNo+ <> matchIfTest "tag-push" "tag-push.json" tagPushIfRuleYes tagPushIfRuleNo++receiveTests :: TestTree+receiveTests =+ testGroup+ "GitLab system hooks receive"+ [ testCase "1-rule-match"+ $ runGitLabDbg+ $ liftIO (readFile "data/system-hooks/project-created.json")+ >>= \eventJson ->+ receiveString+ eventJson+ [projectCreateRule],+ testCase "1-rule-no-match"+ $ runGitLabDbg+ $ liftIO (readFile "data/system-hooks/project-created.json")+ >>= \eventJson ->+ receiveString+ eventJson+ [projectRenameRule],+ testCase+ "2-rules"+ $ runGitLabDbg+ $ liftIO (readFile "data/system-hooks/project-created.json")+ >>= \eventJson ->+ receiveString+ eventJson+ [ projectCreateRule,+ projectDestroyRule+ ]+ ]++projectCreateRule :: Rule+projectCreateRule =+ match+ "projectCreate rule"+ ( \ProjectCreate {} -> do+ return ()+ )++projectCreateIfRuleYes :: Rule+projectCreateIfRuleYes =+ matchIf+ "projectCreate-if rule"+ ( \proj@ProjectCreate {} -> do+ return (projectCreate_owner_email proj == "johnsmith@gmail.com")+ )+ ( \ProjectCreate {} -> do+ return ()+ )++projectCreateIfRuleNo :: Rule+projectCreateIfRuleNo =+ matchIf+ "projectCreate-if rule"+ ( \proj@ProjectCreate {} -> do+ return (projectCreate_owner_email proj == "johnsmith@hotmail.com")+ )+ ( \ProjectCreate {} -> do+ return ()+ )++projectDestroyRule :: Rule+projectDestroyRule =+ match+ "projectDestroy rule"+ ( \ProjectDestroy {} -> do+ return ()+ )++projectDestroyIfRuleYes :: Rule+projectDestroyIfRuleYes =+ matchIf+ "projectDestroy rule-if yes"+ ( \event@ProjectDestroy {} -> do+ return+ ( projectDestroy_owner_email event+ == "johnsmith@gmail.com"+ )+ )+ ( \ProjectDestroy {} -> do+ return ()+ )++projectDestroyIfRuleNo :: Rule+projectDestroyIfRuleNo =+ matchIf+ "projectDestroy rule-if no"+ ( \event@ProjectDestroy {} -> do+ return+ ( projectDestroy_owner_email event+ == "johnsmith@hotmail.com"+ )+ )+ ( \ProjectDestroy {} -> do+ return ()+ )++projectRenameRule :: Rule+projectRenameRule =+ match+ "projectRename rule"+ ( \ProjectRename {} -> do+ return ()+ )++projectRenameIfRuleYes :: Rule+projectRenameIfRuleYes =+ matchIf+ "projectRename rule-if yes"+ ( \event@ProjectRename {} -> do+ return+ ( projectRename_created_at event+ == "2012-07-21T07:30:58Z"+ )+ )+ ( \ProjectRename {} -> do+ return ()+ )++projectRenameIfRuleNo :: Rule+projectRenameIfRuleNo =+ matchIf+ "projectRename rule-if no"+ ( \event@ProjectRename {} -> do+ return+ ( projectRename_created_at event+ == ""+ )+ )+ ( \ProjectRename {} -> do+ return ()+ )++projectTransferRule :: Rule+projectTransferRule =+ match+ "projectTransfer rule"+ ( \ProjectTransfer {} -> do+ return ()+ )++projectTransferIfRuleYes :: Rule+projectTransferIfRuleYes =+ matchIf+ "projectTransfer rule-if yes"+ ( \event@ProjectTransfer {} -> do+ return+ ( projectTransfer_owner_name event+ == "John Smith"+ )+ )+ ( \ProjectTransfer {} -> do+ return ()+ )++projectTransferIfRuleNo :: Rule+projectTransferIfRuleNo =+ matchIf+ "projectTransfer rule-if no"+ ( \event@ProjectTransfer {} -> do+ return+ ( projectTransfer_owner_name event+ == ""+ )+ )+ ( \ProjectTransfer {} -> do+ return ()+ )++projectUpdateRule :: Rule+projectUpdateRule =+ match+ "projectTransfer rule"+ ( \ProjectUpdate {} -> do+ return ()+ )++projectUpdateIfRuleYes :: Rule+projectUpdateIfRuleYes =+ matchIf+ "projectTransfer rule-if yes"+ ( \event@ProjectUpdate {} -> do+ return+ ( projectUpdate_path event+ == "storecloud"+ )+ )+ ( \ProjectUpdate {} -> do+ return ()+ )++projectUpdateIfRuleNo :: Rule+projectUpdateIfRuleNo =+ matchIf+ "projectTransfer rule-if no"+ ( \event@ProjectUpdate {} -> do+ return+ ( projectUpdate_path event+ == ""+ )+ )+ ( \ProjectUpdate {} -> do+ return ()+ )++groupMemberUpdateRule :: Rule+groupMemberUpdateRule =+ match+ "groupMemberUpdate rule"+ ( \GroupMemberUpdate {} -> do+ return ()+ )++groupMemberUpdateIfRuleYes :: Rule+groupMemberUpdateIfRuleYes =+ matchIf+ "groupMemberUpdate rule-if yes"+ ( \event@GroupMemberUpdate {} -> do+ return+ ( groupMemberUpdate_user_email event+ == "johnsmith@gmail.com"+ )+ )+ ( \GroupMemberUpdate {} -> do+ return ()+ )++groupMemberUpdateIfRuleNo :: Rule+groupMemberUpdateIfRuleNo =+ matchIf+ "groupMemberUpdate rule-if no"+ ( \event@GroupMemberUpdate {} -> do+ return+ ( groupMemberUpdate_user_email event+ == "johnsmith@hotmail.com"+ )+ )+ ( \GroupMemberUpdate {} -> do+ return ()+ )++userAddToTeamRule :: Rule+userAddToTeamRule =+ match+ "userAddToTeam rule"+ ( \UserAddToTeam {} -> do+ return ()+ )++userAddToTeamIfRuleYes :: Rule+userAddToTeamIfRuleYes =+ matchIf+ "userAddToTeam rule-if yes"+ ( \event@UserAddToTeam {} -> do+ return+ ( userAddTeam_user_email event+ == "johnsmith@gmail.com"+ )+ )+ ( \UserAddToTeam {} -> do+ return ()+ )++userAddToTeamIfRuleNo :: Rule+userAddToTeamIfRuleNo =+ matchIf+ "userAddToTeam rule-if no"+ ( \event@UserAddToTeam {} ->+ return+ ( userAddTeam_user_email event+ == "johnsmith@hotmail.com"+ )+ )+ ( \UserAddToTeam {} -> do+ return ()+ )++userUpdateForTeamRule :: Rule+userUpdateForTeamRule =+ match+ "userUpdateForTeam rule"+ ( \UserUpdateForTeam {} -> do+ return ()+ )++userUpdateForTeamIfRuleYes :: Rule+userUpdateForTeamIfRuleYes =+ matchIf+ "userUpdateForTeam rule-if yes"+ ( \event@UserUpdateForTeam {} -> do+ return+ ( userUpdateTeam_project_path_with_namespace event+ == "jsmith/storecloud"+ )+ )+ ( \UserUpdateForTeam {} -> do+ return ()+ )++userUpdateForTeamIfRuleNo :: Rule+userUpdateForTeamIfRuleNo =+ matchIf+ "userUpdateForTeam rule-if no"+ ( \event@UserUpdateForTeam {} -> do+ return+ ( userUpdateTeam_project_path_with_namespace event+ == ""+ )+ )+ ( \UserUpdateForTeam {} -> do+ return ()+ )++userRemoveFromTeamRule :: Rule+userRemoveFromTeamRule =+ match+ "userRemoveFromTeam rule"+ ( \UserRemoveFromTeam {} -> do+ return ()+ )++userRemoveFromTeamIfRuleYes :: Rule+userRemoveFromTeamIfRuleYes =+ matchIf+ "userRemoveFromTeam rule-if yes"+ ( \event@UserRemoveFromTeam {} -> do+ return+ ( userRemoveTeam_user_email event+ == "johnsmith@gmail.com"+ )+ )+ ( \UserRemoveFromTeam {} -> do+ return ()+ )++userRemoveFromTeamIfRuleNo :: Rule+userRemoveFromTeamIfRuleNo =+ matchIf+ "userRemoveFromTeam rule-if no"+ ( \event@UserRemoveFromTeam {} -> do+ return+ ( userRemoveTeam_user_email event+ == "js@gmail.com"+ )+ )+ ( \UserRemoveFromTeam {} -> do+ return ()+ )++userCreateRule :: Rule+userCreateRule =+ match+ "userCreate rule"+ ( \UserCreate {} -> do+ return ()+ )++userCreateIfRuleYes :: Rule+userCreateIfRuleYes =+ matchIf+ "userCreate rule-if yes"+ ( \event@UserCreate {} -> do+ return+ ( userCreate_email event+ == "js@gitlabhq.com"+ )+ )+ ( \UserCreate {} -> do+ return ()+ )++userCreateIfRuleNo :: Rule+userCreateIfRuleNo =+ matchIf+ "userCreate rule-if no"+ ( \event@UserCreate {} -> do+ return+ ( userCreate_email event+ == "js@gmail.com"+ )+ )+ ( \UserCreate {} -> do+ return ()+ )++userRemoveRule :: Rule+userRemoveRule =+ match+ "userRemove rule"+ ( \UserRemove {} -> do+ return ()+ )++userRemoveIfRuleYes :: Rule+userRemoveIfRuleYes =+ matchIf+ "userRemove rule-if yes"+ ( \event@UserRemove {} -> do+ return+ ( userRemove_email event+ == "js@gitlabhq.com"+ )+ )+ ( \UserRemove {} -> do+ return ()+ )++userRemoveIfRuleNo :: Rule+userRemoveIfRuleNo =+ matchIf+ "userRemove rule-if no"+ ( \event@UserRemove {} -> do+ return+ ( userRemove_email event+ == "js@gmail.com"+ )+ )+ ( \UserRemove {} -> do+ return ()+ )++userFailedLoginRule :: Rule+userFailedLoginRule =+ match+ "userFailedLogin rule"+ ( \UserFailedLogin {} -> do+ return ()+ )++userFailedLoginIfRuleYes :: Rule+userFailedLoginIfRuleYes =+ matchIf+ "userFailedLogin rule"+ ( \event@UserFailedLogin {} -> do+ return+ ( userFailedLogin_email event+ == "user4@example.com"+ )+ )+ ( \UserFailedLogin {} -> do+ return ()+ )++userFailedLoginIfRuleNo :: Rule+userFailedLoginIfRuleNo =+ matchIf+ "userFailedLogin rule"+ ( \event@UserFailedLogin {} -> do+ return+ ( userFailedLogin_email event+ == "user4@gmail.com"+ )+ )+ ( \UserFailedLogin {} -> do+ return ()+ )++userRenameRule :: Rule+userRenameRule =+ match+ "userRename rule"+ ( \UserRename {} -> do+ return ()+ )++userRenameIfRuleYes :: Rule+userRenameIfRuleYes =+ matchIf+ "userRename rule-if yes"+ ( \event@UserRename {} -> do+ return+ ( userRename_username event+ == "new-exciting-name"+ )+ )+ ( \UserRename {} -> do+ return ()+ )++userRenameIfRuleNo :: Rule+userRenameIfRuleNo =+ matchIf+ "userRename rule-if no"+ ( \event@UserRename {} -> do+ return+ ( userRename_username event+ == "old-boring-name"+ )+ )+ ( \UserRename {} -> do+ return ()+ )++keyCreateRule :: Rule+keyCreateRule =+ match+ "keyCreate rule"+ ( \KeyCreate {} -> do+ return ()+ )++keyCreateIfRuleYes :: Rule+keyCreateIfRuleYes =+ matchIf+ "keyCreate rule-if yes"+ ( \event@KeyCreate {} -> do+ return+ ( keyCreate_updated_at event+ == "2012-07-21T07:38:22Z"+ )+ )+ ( \KeyCreate {} -> do+ return ()+ )++keyCreateIfRuleNo :: Rule+keyCreateIfRuleNo =+ matchIf+ "keyCreate rule-if no"+ ( \event@KeyCreate {} -> do+ return+ ( keyCreate_updated_at event+ == ""+ )+ )+ ( \KeyCreate {} -> do+ return ()+ )++keyRemoveRule :: Rule+keyRemoveRule =+ match+ "keyRemove rule"+ ( \KeyRemove {} -> do+ return ()+ )++keyRemoveIfRuleYes :: Rule+keyRemoveIfRuleYes =+ matchIf+ "keyRemove rule-if yes"+ ( \event@KeyRemove {} -> do+ return+ ( keyRemove_updated_at event+ == "2012-07-21T07:38:22Z"+ )+ )+ ( \KeyRemove {} -> do+ return ()+ )++keyRemoveIfRuleNo :: Rule+keyRemoveIfRuleNo =+ matchIf+ "keyRemove rule-if no"+ ( \event@KeyRemove {} -> do+ return+ ( keyRemove_updated_at event+ == ""+ )+ )+ ( \KeyRemove {} -> do+ return ()+ )++groupCreateRule :: Rule+groupCreateRule =+ match+ "groupCreate rule"+ ( \GroupCreate {} -> do+ return ()+ )++groupCreateIfRuleYes :: Rule+groupCreateIfRuleYes =+ matchIf+ "groupCreate rule-if yes"+ ( \event@GroupCreate {} -> do+ return+ ( groupCreate_name event+ == "StoreCloud"+ )+ )+ ( \GroupCreate {} -> do+ return ()+ )++groupCreateIfRuleNo :: Rule+groupCreateIfRuleNo =+ matchIf+ "groupCreate rule-if no"+ ( \event@GroupCreate {} -> do+ return+ ( groupCreate_name event+ == ""+ )+ )+ ( \GroupCreate {} -> do+ return ()+ )++groupRemoveRule :: Rule+groupRemoveRule =+ match+ "groupRemove rule"+ ( \GroupRemove {} -> do+ return ()+ )++groupRemoveIfRuleYes :: Rule+groupRemoveIfRuleYes =+ matchIf+ "groupRemove rule-if yes"+ ( \event@GroupRemove {} -> do+ return+ ( groupRemove_name event+ == "StoreCloud"+ )+ )+ ( \GroupRemove {} -> do+ return ()+ )++groupRemoveIfRuleNo :: Rule+groupRemoveIfRuleNo =+ matchIf+ "groupRemove rule-if no"+ ( \event@GroupRemove {} -> do+ return+ ( groupRemove_name event+ == ""+ )+ )+ ( \GroupRemove {} -> do+ return ()+ )++groupRenameRule :: Rule+groupRenameRule =+ match+ "groupRename rule"+ ( \GroupRename {} -> do+ return ()+ )++groupRenameIfRuleYes :: Rule+groupRenameIfRuleYes =+ matchIf+ "groupRename rule-if yes"+ ( \event@GroupRename {} -> do+ return+ ( groupRename_full_path event+ == "parent-group/better-name"+ )+ )+ ( \GroupRename {} -> do+ return ()+ )++groupRenameIfRuleNo :: Rule+groupRenameIfRuleNo =+ matchIf+ "groupRename rule-if no"+ ( \event@GroupRename {} -> do+ return+ ( groupRename_full_path event+ == "parent-group/wrong-name"+ )+ )+ ( \GroupRename {} -> do+ return ()+ )++newGroupMemberRule :: Rule+newGroupMemberRule =+ match+ "newGroupMember rule"+ ( \NewGroupMember {} -> do+ return ()+ )++newGroupMemberIfRuleYes :: Rule+newGroupMemberIfRuleYes =+ matchIf+ "newGroupMember rule-if yes"+ ( \event@NewGroupMember {} -> do+ return+ ( newGroupMember_user_email event+ == "johnsmith@gmail.com"+ )+ )+ ( \NewGroupMember {} -> do+ return ()+ )++newGroupMemberIfRuleNo :: Rule+newGroupMemberIfRuleNo =+ matchIf+ "newGroupMember rule-if no"+ ( \event@NewGroupMember {} -> do+ return+ ( newGroupMember_user_email event+ == "johnsmith@hotmail.com"+ )+ )+ ( \NewGroupMember {} -> do+ return ()+ )++groupMemberRemoveRule :: Rule+groupMemberRemoveRule =+ match+ "groupMemberRemove rule"+ ( \GroupMemberRemove {} -> do+ return ()+ )++groupMemberRemoveIfRuleYes :: Rule+groupMemberRemoveIfRuleYes =+ matchIf+ "groupMemberRemove rule-if yes"+ ( \event@GroupMemberRemove {} -> do+ return+ ( groupMemberRemove_user_email event+ == "johnsmith@gmail.com"+ )+ )+ ( \GroupMemberRemove {} -> do+ return ()+ )++groupMemberRemoveIfRuleNo :: Rule+groupMemberRemoveIfRuleNo =+ matchIf+ "groupMemberRemove rule-if no"+ ( \event@GroupMemberRemove {} -> do+ return+ ( groupMemberRemove_user_email event+ == "johnsmith@hotmail.com"+ )+ )+ ( \GroupMemberRemove {} -> do+ return ()+ )++pushRule :: Rule+pushRule =+ match+ "push rule"+ ( \Push {} -> do+ return ()+ )++pushIfRuleYes :: Rule+pushIfRuleYes =+ matchIf+ "push rule-if yes"+ ( \event@Push {} -> do+ return (push_checkout_sha event == "da1560886d4f094c3e6c9ef40349f7d38b5d27d7")+ )+ ( \Push {} -> do+ return ()+ )++pushIfRuleNo :: Rule+pushIfRuleNo =+ matchIf+ "push rule-if no"+ ( \event@Push {} -> do+ return (push_checkout_sha event == "")+ )+ ( \Push {} -> do+ return ()+ )++tagPushRule :: Rule+tagPushRule =+ match+ "tagPush rule"+ ( \TagPush {} -> do+ return ()+ )++tagPushIfRuleYes :: Rule+tagPushIfRuleYes =+ matchIf+ "tagPush rule-if yes"+ ( \event@TagPush {} -> do+ return (tagPush_ref event == "refs/tags/v1.0.0")+ )+ ( \TagPush {} -> do+ return ()+ )++tagPushIfRuleNo :: Rule+tagPushIfRuleNo =+ matchIf+ "tagPush rule-if no"+ ( \event@TagPush {} -> do+ return (tagPush_ref event == "refs/tags/v2.0.0")+ )+ ( \TagPush {} -> do+ return ()+ )++projectCreatedHaskell :: ProjectCreate+projectCreatedHaskell =+ ProjectCreate+ { projectCreate_created_at = "2012-07-21T07:30:54Z",+ projectCreate_updated_at = "2012-07-21T07:38:22Z",+ projectCreate_action = "project_create",+ projectCreate_name = "StoreCloud",+ projectCreate_owner_email = "johnsmith@gmail.com",+ projectCreate_owner_name = "John Smith",+ projectCreate_path = "storecloud",+ projectCreate_path_with_namespace = "jsmith/storecloud",+ projectCreate_project_id = 74,+ projectCreate_project_visibility = Private+ }++projectDestroyedHaskell :: ProjectDestroy+projectDestroyedHaskell =+ ProjectDestroy+ { projectDestroy_created_at = "2012-07-21T07:30:58Z",+ projectDestroy_updated_at = "2012-07-21T07:38:22Z",+ projectDestroy_action = "project_destroy",+ projectDestroy_name = "Underscore",+ projectDestroy_owner_email = "johnsmith@gmail.com",+ projectDestroy_owner_name = "John Smith",+ projectDestroy_path = "underscore",+ projectDestroy_path_with_namespace = "jsmith/underscore",+ projectDestroy_project_id = 73,+ projectDestroy_project_visibility = Internal+ }++projectRenamedHaskell :: ProjectRename+projectRenamedHaskell =+ ProjectRename+ { projectRename_created_at = "2012-07-21T07:30:58Z",+ projectRename_updated_at = "2012-07-21T07:38:22Z",+ projectRename_event_name = "project_rename",+ projectRename_name = "Underscore",+ projectRename_path = "underscore",+ projectRename_path_with_namespace = "jsmith/underscore",+ projectRename_project_id = 73,+ projectRename_owner_name = "John Smith",+ projectRename_owner_email = "johnsmith@gmail.com",+ projectRename_project_visibility = Internal,+ projectRename_old_path_with_namespace = "jsmith/overscore"+ }++projectTransferredHaskell :: ProjectTransfer+projectTransferredHaskell =+ ProjectTransfer+ { projectTransfer_created_at = "2012-07-21T07:30:58Z",+ projectTransfer_updated_at = "2012-07-21T07:38:22Z",+ projectTransfer_event_name = "project_transfer",+ projectTransfer_name = "Underscore",+ projectTransfer_path = "underscore",+ projectTransfer_path_with_namespace = "scores/underscore",+ projectTransfer_project_id = 73,+ projectTransfer_owner_name = "John Smith",+ projectTransfer_owner_email = "johnsmith@gmail.com",+ projectTransfer_project_visibility = Internal,+ projectTransfer_old_path_with_namespace = "jsmith/overscore"+ }++projectUpdatedHaskell :: ProjectUpdate+projectUpdatedHaskell =+ ProjectUpdate+ { projectUpdate_created_at = "2012-07-21T07:30:54Z",+ projectUpdate_updated_at = "2012-07-21T07:38:22Z",+ projectUpdate_event_name = "project_update",+ projectUpdate_name = "StoreCloud",+ projectUpdate_owner_email = "johnsmith@gmail.com",+ projectUpdate_owner_name = "John Smith",+ projectUpdate_path = "storecloud",+ projectUpdate_path_with_namespace = "jsmith/storecloud",+ projectUpdate_project_id = 74,+ projectUpdate_project_visibility = Private+ }++userAddedToTeamHaskell :: UserAddToTeam+userAddedToTeamHaskell =+ UserAddToTeam+ { userAddTeam_created_at = "2012-07-21T07:30:56Z",+ userAddTeam_updated_at = "2012-07-21T07:38:22Z",+ userAddTeam_event_name = "user_add_to_team",+ userAddTeam_access_level = "Maintainer",+ userAddTeam_project_id = 74,+ userAddTeam_project_name = "StoreCloud",+ userAddTeam_project_path = "storecloud",+ userAddTeam_project_path_with_namespace = "jsmith/storecloud",+ userAddTeam_user_email = "johnsmith@gmail.com",+ userAddTeam_user_name = "John Smith",+ userAddTeam_user_username = "johnsmith",+ userAddTeam_user_id = 41,+ userAddTeam_project_visibility = Private+ }++userUpdatedForTeamHaskell :: UserUpdateForTeam+userUpdatedForTeamHaskell =+ UserUpdateForTeam+ { userUpdateTeam_created_at = "2012-07-21T07:30:56Z",+ userUpdateTeam_updated_at = "2012-07-21T07:38:22Z",+ userUpdateTeam_event_name = "user_update_for_team",+ userUpdateTeam_access_level = "Maintainer",+ userUpdateTeam_project_id = 74,+ userUpdateTeam_project_name = "StoreCloud",+ userUpdateTeam_project_path = "storecloud",+ userUpdateTeam_project_path_with_namespace = "jsmith/storecloud",+ userUpdateTeam_user_email = "johnsmith@gmail.com",+ userUpdateTeam_user_name = "John Smith",+ userUpdateTeam_user_username = "johnsmith",+ userUpdateTeam_user_id = 41,+ userUpdateTeam_project_visibility = Private+ }++userRemovedFromTeamHaskell :: UserRemoveFromTeam+userRemovedFromTeamHaskell =+ UserRemoveFromTeam+ { userRemoveTeam_created_at = "2012-07-21T07:30:56Z",+ userRemoveTeam_updated_at = "2012-07-21T07:38:22Z",+ userRemoveTeam_event_name = "user_remove_from_team",+ userRemoveTeam_access_level = "Maintainer",+ userRemoveTeam_project_id = 74,+ userRemoveTeam_project_name = "StoreCloud",+ userRemoveTeam_project_path = "storecloud",+ userRemoveTeam_project_path_with_namespace = "jsmith/storecloud",+ userRemoveTeam_user_email = "johnsmith@gmail.com",+ userRemoveTeam_user_name = "John Smith",+ userRemoveTeam_user_username = "johnsmith",+ userRemoveTeam_user_id = 41,+ userRemoveTeam_project_visibility = Private+ }++userCreatedHaskell :: UserCreate+userCreatedHaskell =+ UserCreate+ { userCreate_created_at = "2012-07-21T07:44:07Z",+ userCreate_updated_at = "2012-07-21T07:38:22Z",+ userCreate_email = "js@gitlabhq.com",+ userCreate_event_name = "user_create",+ userCreate_name = "John Smith",+ userCreate_username = "js",+ userCreate_user_id = 41+ }++userRemovedHaskell :: UserRemove+userRemovedHaskell =+ UserRemove+ { userRemove_created_at = "2012-07-21T07:44:07Z",+ userRemove_updated_at = "2012-07-21T07:38:22Z",+ userRemove_email = "js@gitlabhq.com",+ userRemove_event_name = "user_destroy",+ userRemove_name = "John Smith",+ userRemove_username = "js",+ userRemove_user_id = 41+ }++userFailedLoginHaskell :: UserFailedLogin+userFailedLoginHaskell =+ UserFailedLogin+ { userFailedLogin_event_name = "user_failed_login",+ userFailedLogin_created_at = "2017-10-03T06:08:48Z",+ userFailedLogin_updated_at = "2018-01-15T04:52:06Z",+ userFailedLogin_name = "John Smith",+ userFailedLogin_email = "user4@example.com",+ userFailedLogin_user_id = 26,+ userFailedLogin_username = "user4",+ userFailedLogin_state = "blocked"+ }++userRenamedHaskell :: UserRename+userRenamedHaskell =+ UserRename+ { userRename_event_name = "user_rename",+ userRename_created_at = "2017-11-01T11:21:04Z",+ userRename_updated_at = "2017-11-01T14:04:47Z",+ userRename_name = "new-name",+ userRename_email = "best-email@example.tld",+ userRename_user_id = 58,+ userRename_username = "new-exciting-name",+ userRename_old_username = "old-boring-name"+ }++keyCreatedHaskell :: KeyCreate+keyCreatedHaskell =+ KeyCreate+ { keyCreate_event_name = "key_create",+ keyCreate_created_at = "2014-08-18 18:45:16 UTC",+ keyCreate_updated_at = "2012-07-21T07:38:22Z",+ keyCreate_username = "root",+ keyCreate_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC58FwqHUbebw2SdT7SP4FxZ0w+lAO/erhy2ylhlcW/tZ3GY3mBu9VeeiSGoGz8hCx80Zrz+aQv28xfFfKlC8XQFpCWwsnWnQqO2Lv9bS8V1fIHgMxOHIt5Vs+9CAWGCCvUOAurjsUDoE2ALIXLDMKnJxcxD13XjWdK54j6ZXDB4syLF0C2PnAQSVY9X7MfCYwtuFmhQhKaBussAXpaVMRHltie3UYSBUUuZaB3J4cg/7TxlmxcNd+ppPRIpSZAB0NI6aOnqoBCpimscO/VpQRJMVLr3XiSYeT6HBiDXWHnIVPfQc03OGcaFqOit6p8lYKMaP/iUQLm+pgpZqrXZ9vB john@localhost",+ keyCreate_id = 4+ }++keyRemovedHaskell :: KeyRemove+keyRemovedHaskell =+ KeyRemove+ { keyRemove_event_name = "key_destroy",+ keyRemove_created_at = "2014-08-18 18:45:16 UTC",+ keyRemove_updated_at = "2012-07-21T07:38:22Z",+ keyRemove_username = "root",+ keyRemove_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC58FwqHUbebw2SdT7SP4FxZ0w+lAO/erhy2ylhlcW/tZ3GY3mBu9VeeiSGoGz8hCx80Zrz+aQv28xfFfKlC8XQFpCWwsnWnQqO2Lv9bS8V1fIHgMxOHIt5Vs+9CAWGCCvUOAurjsUDoE2ALIXLDMKnJxcxD13XjWdK54j6ZXDB4syLF0C2PnAQSVY9X7MfCYwtuFmhQhKaBussAXpaVMRHltie3UYSBUUuZaB3J4cg/7TxlmxcNd+ppPRIpSZAB0NI6aOnqoBCpimscO/VpQRJMVLr3XiSYeT6HBiDXWHnIVPfQc03OGcaFqOit6p8lYKMaP/iUQLm+pgpZqrXZ9vB john@localhost",+ keyRemove_id = 4+ }++groupCreatedHaskell :: GroupCreate+groupCreatedHaskell =+ GroupCreate+ { groupCreate_created_at = "2012-07-21T07:30:54Z",+ groupCreate_updated_at = "2012-07-21T07:38:22Z",+ groupCreate_event_name = "group_create",+ groupCreate_name = "StoreCloud",+ groupCreate_owner_email = Nothing,+ groupCreate_owner_name = Nothing,+ groupCreate_path = "storecloud",+ groupCreate_group_id = 78+ }++groupRemovedHaskell :: GroupRemove+groupRemovedHaskell =+ GroupRemove+ { groupRemove_created_at = "2012-07-21T07:30:54Z",+ groupRemove_updated_at = "2012-07-21T07:38:22Z",+ groupRemove_event_name = "group_destroy",+ groupRemove_name = "StoreCloud",+ groupRemove_owner_email = Nothing,+ groupRemove_owner_name = Nothing,+ groupRemove_path = "storecloud",+ groupRemove_group_id = 78+ }++groupRenamedHaskell :: GroupRename+groupRenamedHaskell =+ GroupRename+ { groupRename_event_name = "group_rename",+ groupRename_created_at = "2017-10-30T15:09:00Z",+ groupRename_updated_at = "2017-11-01T10:23:52Z",+ groupRename_name = "Better Name",+ groupRename_path = "better-name",+ groupRename_full_path = "parent-group/better-name",+ groupRename_group_id = 64,+ groupRename_owner_name = Nothing,+ groupRename_owner_email = Nothing,+ groupRename_old_path = "old-name",+ groupRename_old_full_path = "parent-group/old-name"+ }++newGroupMemberHaskell :: NewGroupMember+newGroupMemberHaskell =+ NewGroupMember+ { newGroupMember_created_at = "2012-07-21T07:30:56Z",+ newGroupMember_updated_at = "2012-07-21T07:38:22Z",+ newGroupMember_event_name = "user_add_to_group",+ newGroupMember_group_access = "Maintainer",+ newGroupMember_group_id = 78,+ newGroupMember_group_name = "StoreCloud",+ newGroupMember_group_path = "storecloud",+ newGroupMember_user_email = "johnsmith@gmail.com",+ newGroupMember_user_name = "John Smith",+ newGroupMember_user_username = "johnsmith",+ newGroupMember_user_id = 41+ }++groupMemberRemovedHaskell :: GroupMemberRemove+groupMemberRemovedHaskell =+ GroupMemberRemove+ { groupMemberRemove_created_at = "2012-07-21T07:30:56Z",+ groupMemberRemove_updated_at = "2012-07-21T07:38:22Z",+ groupMemberRemove_event_name = "user_remove_from_group",+ groupMemberRemove_group_access = "Maintainer",+ groupMemberRemove_group_id = 78,+ groupMemberRemove_group_name = "StoreCloud",+ groupMemberRemove_group_path = "storecloud",+ groupMemberRemove_user_email = "johnsmith@gmail.com",+ groupMemberRemove_user_name = "John Smith",+ groupMemberRemove_user_username = "johnsmith",+ groupMemberRemove_user_id = 41+ }++groupMemberUpdatedHaskell :: GroupMemberUpdate+groupMemberUpdatedHaskell =+ GroupMemberUpdate+ { groupMemberUpdate_created_at = "2012-07-21T07:30:56Z",+ groupMemberUpdate_updated_at = "2012-07-21T07:38:22Z",+ groupMemberUpdate_event_name = "user_update_for_group",+ groupMemberUpdate_group_access = "Maintainer",+ groupMemberUpdate_group_id = 78,+ groupMemberUpdate_group_name = "StoreCloud",+ groupMemberUpdate_group_path = "storecloud",+ groupMemberUpdate_user_email = "johnsmith@gmail.com",+ groupMemberUpdate_user_name = "John Smith",+ groupMemberUpdate_user_username = "johnsmith",+ groupMemberUpdate_user_id = 41+ }++pushHaskell :: Push+pushHaskell =+ Push+ { push_event_name = "push",+ push_before = "95790bf891e76fee5e1747ab589903a6a1f80f22",+ push_after = "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",+ push_ref = "refs/heads/master",+ push_checkout_sha = "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",+ push_user_id = 4,+ push_user_name = "John Smith",+ push_user_email = "john@example.com",+ push_user_avatar = "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",+ push_project_id = 15,+ push_project = ProjectEvent {projectEvent_name = "Diaspora", projectEvent_description = "", projectEvent_web_url = "http://example.com/mike/diaspora", projectEvent_avatar_url = Nothing, projectEvent_git_ssh_url = "git@example.com:mike/diaspora.git", projectEvent_git_http_url = "http://example.com/mike/diaspora.git", projectEvent_namespace = "Mike", projectEvent_visibility_level = Private, projectEvent_path_with_namespace = "mike/diaspora", projectEvent_default_branch = "master", projectEvent_homepage = Just "http://example.com/mike/diaspora", projectEvent_url = "git@example.com:mike/diaspora.git", projectEvent_ssh_url = "git@example.com:mike/diaspora.git", projectEvent_http_url = "http://example.com/mike/diaspora.git"},+ push_repository = RepositoryEvent {repositoryEvent_name = "Diaspora", repositoryEvent_url = "git@example.com:mike/diaspora.git", repositoryEvent_description = "", repositoryEvent_homepage = Just "http://example.com/mike/diaspora", repositoryEvent_git_http_url = "http://example.com/mike/diaspora.git", repositoryEvent_git_ssh_url = "git@example.com:mike/diaspora.git", repositoryEvent_visibility_level = Private},+ push_commits = [CommitEvent {commitEvent_id = "c5feabde2d8cd023215af4d2ceeb7a64839fc428", commitEvent_message = "Add simple search to projects in public area", commitEvent_timestamp = "2013-05-13T18:18:08+00:00", commitEvent_url = "https://dev.gitlab.org/gitlab/gitlabhq/commit/c5feabde2d8cd023215af4d2ceeb7a64839fc428", commitEvent_author = CommitAuthorEvent {commitAuthorEvent_name = "Example User", commitAuthorEvent_email = "user@example.com"}}],+ push_total_commits_count = 1+ }++tagPushHaskell :: TagPush+tagPushHaskell =+ TagPush+ { tagPush_event_name = "tag_push",+ tagPush_before = "0000000000000000000000000000000000000000",+ tagPush_after = "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",+ tagPush_ref = "refs/tags/v1.0.0",+ tagPush_checkout_sha = "5937ac0a7beb003549fc5fd26fc247adbce4a52e",+ tagPush_user_id = 1,+ tagPush_user_name = "John Smith",+ tagPush_user_avatar = "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",+ tagPush_project_id = 1,+ tagPush_project = ProjectEvent {projectEvent_name = "Example", projectEvent_description = "", projectEvent_web_url = "http://example.com/jsmith/example", projectEvent_avatar_url = Nothing, projectEvent_git_ssh_url = "git@example.com:jsmith/example.git", projectEvent_git_http_url = "http://example.com/jsmith/example.git", projectEvent_namespace = "Jsmith", projectEvent_visibility_level = Private, projectEvent_path_with_namespace = "jsmith/example", projectEvent_default_branch = "master", projectEvent_homepage = Just "http://example.com/jsmith/example", projectEvent_url = "git@example.com:jsmith/example.git", projectEvent_ssh_url = "git@example.com:jsmith/example.git", projectEvent_http_url = "http://example.com/jsmith/example.git"},+ tagPush_repository = RepositoryEvent {repositoryEvent_name = "Example", repositoryEvent_url = "ssh://git@example.com/jsmith/example.git", repositoryEvent_description = "", repositoryEvent_homepage = Just "http://example.com/jsmith/example", repositoryEvent_git_http_url = "http://example.com/jsmith/example.git", repositoryEvent_git_ssh_url = "git@example.com:jsmith/example.git", repositoryEvent_visibility_level = Private},+ tagPush_commits = [],+ tagPush_total_commits_count = 0+ }
+ tests/Tests.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}++module Main where++import Data.Maybe (fromJust)+import SystemHookTests+import Test.Tasty++main :: IO ()+main = do+ defaultMain+ ( testGroup+ "gitlab system hook tests"+ systemHookTests+ )