gitlab-haskell-1.0.0.0: src/GitLab/Types.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TemplateHaskell #-}
-- |
-- Module : GitLab.Types
-- Description : Haskell records corresponding to JSON data from GitLab API calls
-- Copyright : (c) Rob Stewart, Heriot-Watt University, 2019
-- License : BSD3
-- Maintainer : robstewart57@gmail.com
-- Stability : stable
module GitLab.Types
( GitLab,
GitLabState (..),
GitLabServerConfig (..),
defaultGitLabServer,
ArchiveFormat (..),
AccessLevel (..),
SearchIn (..),
Scope (..),
SortBy (..),
OrderBy (..),
Member (..),
SamlIdentity (..),
Identity (..),
Namespace (..),
Links (..),
Owner (..),
Permissions (..),
ProjectId,
Project (..),
Statistics (..),
User (..),
Milestone (..),
MilestoneState (..),
TimeStats (..),
IssueId,
Issue (..),
Epic (..),
Pipeline (..),
Commit (..),
CommitTodo (..),
CommitStats (..),
Contributor (..),
Tag (..),
Release (..),
Diff (..),
Repository (..),
Job (..),
Artifact (..),
Group (..),
GroupShare (..),
Branch (..),
RepositoryFile (..),
RepositoryFileBlame (..),
RepositoryFileSimple (..),
MergeRequest (..),
Todo (..),
TodoProject (..),
TodoAction (..),
TodoTarget (..),
TodoTargetType (..),
TodoType (..),
TodoState (..),
Version (..),
URL,
EditIssueReq (..),
Discussion (..),
CommitNote (..),
Note (..),
CommandsChanges (..),
IssueStatistics (..),
IssueStats (..),
IssueCounts (..),
IssueBoard (..),
BoardIssue (..),
BoardIssueLabel (..),
Visibility (..),
TestReport (..),
TestSuite (..),
TestCase (..),
TimeEstimate (..),
TaskCompletionStatus (..),
References (..),
Change (..),
DiffRefs (..),
DetailedStatus (..),
License (..),
ExpirationPolicy (..),
RepositoryStorage (..),
Starrer (..),
ProjectAvatar (..),
Email (..),
Key (..),
UserPrefs (..),
UserStatus (..),
UserCount (..),
Event (..),
EventActionName (..),
EventTargetType (..),
PushData (..),
)
where
import Control.Monad.Trans.Reader
import Data.Aeson
import Data.Aeson.TH
import Data.Aeson.Types
import Data.Text (Text)
import qualified Data.Text as T
import Data.Time.Clock
import Network.HTTP.Conduit
-- | type synonym for all GitLab actions.
type GitLab a = ReaderT GitLabState IO a
-- | state used by GitLab actions, used internally.
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,
-- | write system hook events to files in the system temporary
-- directory.
debugSystemHooks :: Bool
}
-- | default settings, the 'url' and 'token' values will need to be overwritten.
defaultGitLabServer :: GitLabServerConfig
defaultGitLabServer =
GitLabServerConfig
{ url = "https://gitlab.com",
token = "",
timeout = 15000000, -- 15 seconds
retries = 5,
debugSystemHooks = False
}
-- https://docs.gitlab.com/ee/api/repositories.html#get-file-archive
-- tar.gz, tar.bz2, tbz, tbz2, tb2, bz2, tar, and zip
-- | archive format for file archives of repositories.
-- See 'GitLab.API.Repositories.getFileArchive' in 'GitLab.API.Repositories'.
data ArchiveFormat
= -- | ".tar.gz"
TarGz
| -- | ".tar.bz2"
TarBz2
| -- | ".tbz"
Tbz
| -- | ".tbz2"
Tbz2
| -- | ".tb2"
Tb2
| -- | ".bz2"
Bz2
| -- | ".tar"
Tar
| -- | ".zip"
Zip
instance Show ArchiveFormat where
show TarGz = ".tar.gz"
show TarBz2 = ".tar.bz2"
show Tbz = ".tbz"
show Tbz2 = ".tbz2"
show Tb2 = ".tb2"
show Bz2 = ".bz2"
show Tar = ".tar"
show Zip = ".zip"
-- | the access levels for project members. See <https://docs.gitlab.com/ee/user/permissions.html#project-members-permissions>
data AccessLevel
= Guest
| Reporter
| Developer
| Maintainer
| Owner
deriving (Eq)
instance Show AccessLevel where
show Guest = "10"
show Reporter = "20"
show Developer = "30"
show Maintainer = "40"
show Owner = "50"
-- | Where to filter a search within
data SearchIn
= JustTitle
| JustDescription
| TitleAndDescription
instance Show SearchIn where
show JustTitle = "title"
show JustDescription = "description"
show TitleAndDescription = "title,description"
-- | Scope of search results
data Scope
= CreatedByMe
| AssignedToMe
| All
instance Show Scope where
show CreatedByMe = "created_by_me"
show AssignedToMe = "assigned_to_me"
show All = "all"
-- | Sort objects in ascending or descending order
data SortBy
= Ascending
| Descending
instance Show SortBy where
show Ascending = "asc"
show Descending = "desc"
-- | Ordering search results
data OrderBy
= CreatedAt
| UpdatedAt
| Priority
| DueDate
| RelativePosition
| LabelPriority
| MilestoneDue
| Popularity
| Weight
instance Show OrderBy where
show CreatedAt = "created_at"
show UpdatedAt = "updated_at"
show Priority = "priority"
show DueDate = "due_date"
show RelativePosition = "relative_position"
show LabelPriority = "label_priority"
show MilestoneDue = "milestone_due"
show Popularity = "popularity"
show Weight = "weight"
-- | member of a project.
data Member = Member
{ member_id :: Int,
member_name :: Maybe Text,
member_email :: Maybe Text, --- TODO type for email address e.g. zhang@example.com
member_username :: Maybe Text,
member_state :: Maybe Text,
member_avatar_uri :: Maybe Text,
member_web_url :: Maybe Text,
member_access_level :: Maybe Int,
member_group_saml_identity :: Maybe SamlIdentity,
member_expires_at :: Maybe Text,
member_invited :: Maybe Bool,
member_override :: Maybe Bool,
member_avatar_url :: Maybe Text, -- TODO type for URL
member_approved :: Maybe Bool,
member_membership_type :: Maybe Text, -- TODO type for "group_member"
member_last_activity_on :: Maybe Text, -- TODO type for "2021-01-27"
member_created_at :: Maybe UTCTime,
member_removable :: Maybe Bool,
member_membership_state :: Maybe Text -- type for "active"
}
deriving (Show, Eq)
-- TODO merge Identity and SamlIdentity into a single type.
-- | identity
data Identity = Identity
{ identity_extern_uid :: Text,
identity_provider :: Text,
identity_provider_id :: Maybe Int
}
deriving (Show, Eq)
-- | SAML identity
data SamlIdentity = SamlIdentity
{ saml_identity_extern_uid :: Text,
saml_identity_provider :: Text,
saml_identity_saml_provider_id :: Maybe Int
}
deriving (Show, Eq)
-- | namespaces.
data Namespace = Namespace
{ namespace_id :: Int,
namespace_name :: Text,
namespace_path :: Text,
namespace_kind :: Text,
namespace_full_path :: Maybe Text,
namespace_avatar_url :: Maybe Text,
namespace_web_url :: Maybe Text,
namespace_parent_id :: Maybe Int
}
deriving (Show, Eq)
-- | links.
data Links = Links
{ links_self :: Text,
links_issues :: Maybe Text,
links_notes :: Maybe Text,
links_award_emoji :: Maybe Text,
links_project :: Maybe Text,
links_merge_requests :: Maybe Text,
links_repo_branches :: Maybe Text,
links_labels :: Maybe Text,
links_events :: Maybe Text,
links_members :: Maybe Text
}
deriving (Show, Eq)
-- | owners.
data Owner = Ownwer
{ owner_id :: Int,
owner_name :: Text,
owner_username :: Maybe Text,
owner_email :: Maybe Text,
owner_state :: Maybe Text,
owner_avatar_url :: Maybe Text,
owner_web_url :: Maybe Text,
owner_created_at :: Maybe UTCTime
}
deriving (Show, Eq)
-- | permissions.
data Permissions = Permissions
{ permissions_project_access :: Maybe Value,
permissions_group_access :: Maybe Value
}
deriving (Show, Eq)
-- | projects.
data Project = Project
{ project_id :: Int,
project_description :: Maybe Text,
project_name :: Text,
project_name_with_namespace :: Text,
project_path :: Text,
project_path_with_namespace :: Text,
project_created_at :: Maybe UTCTime,
project_default_branch :: Maybe Text,
project_tag_list :: Maybe [Text], -- GitLab Docs: "deprecated, use `topics` instead"
project_topics :: Maybe [Text],
project_ssh_url_to_repo :: Maybe Text,
project_http_url_to_repo :: Maybe Text,
project_web_url :: Text,
project_readme_url :: Maybe Text, -- check
project_avatar_url :: Maybe Text,
project_license_url :: Maybe Text,
project_license :: Maybe License,
project_star_count :: Maybe Int,
project_runners_token :: Maybe Text, -- "b8547b1dc37721d05889db52fa2f02"
project_ci_default_git_depth :: Maybe Int,
project_ci_forward_deployment_enabled :: Maybe Bool,
project_forks_count :: Maybe Int,
project_last_activity_at :: Maybe UTCTime,
project_namespace :: Maybe Namespace,
project_archived :: Maybe Bool,
project_visibility :: Maybe Text,
project_owner :: Maybe Owner,
project_resolve_outdated_diff_discussions :: Maybe Bool,
project_container_registry_enabled :: Maybe Bool,
project_container_registry_access_level :: Maybe Text, -- TODO
project_container_expiration_policy :: Maybe ExpirationPolicy,
-- type for "disabled"
project_issues_enabled :: Maybe Bool,
project_merge_requests_enabled :: Maybe Bool,
project_wiki_enabled :: Maybe Bool,
project_jobs_enabled :: Maybe Bool,
project_snippets_enabled :: Maybe Bool,
project_can_create_merge_request_in :: Maybe Bool,
project_issues_access_level :: Maybe Text, -- TODO a type for "enabled"
project_repository_access_level :: Maybe Text, -- TODO a type for "enabled"
project_merge_requests_access_level :: Maybe Text, -- TODO a type for "enabled"
project_forking_access_level :: Maybe Text, -- TODO a type for "enabled"
project_analytics_access_level :: Maybe Text, -- TODO a type for "enabled"
project_wiki_access_level :: Maybe Text, -- TODO a type for "enabled"
project_builds_access_level :: Maybe Text, -- TODO a type for "enabled"
project_snippets_access_level :: Maybe Text, -- TODO a type for "enabled"
project_pages_access_level :: Maybe Text, -- TODO a type for "enabled"
project_emails_disabled :: Maybe Bool, -- check
project_shared_runners_enabled :: Maybe Bool,
project_lfs_enabled :: Maybe Bool,
project_creator_id :: Maybe Int,
project_forked_from_project :: Maybe Project,
project_import_status :: Maybe String,
project_open_issues_count :: Maybe Int,
project_public_jobs :: Maybe Bool,
project_build_timeout :: Maybe Int,
project_auto_cancel_pending_pipelines :: Maybe Text, -- TODO a type for "enabled"
project_ci_config_path :: Maybe Text, -- check null
project_shared_with_groups :: Maybe [GroupShare],
project_only_allow_merge_if_pipeline_succeeds :: Maybe Bool,
project_allow_merge_on_skipped_pipeline :: Maybe Bool,
project_restrict_user_defined_variables :: Maybe Bool,
project_request_access_enabled :: Maybe Bool,
project_only_allow_merge_if_all_discussions_are_resolved :: Maybe Bool,
project_remove_source_branch_after_merge :: Maybe Bool,
project_printing_merge_request_link_enabled :: Maybe Bool,
project_printing_merge_requests_link_enabled :: Maybe Bool,
project_merge_method :: Maybe Text, -- TODO type for "merge"
project_squash_option :: Maybe Text, -- TODO type for "default_on"
project_autoclose_referenced_issues :: Maybe Bool,
project_suggestion_commit_message :: Maybe Text,
project_marked_for_deletion_at :: Maybe Text, -- TODO "2020-04-03"
project_marked_for_deletion_on :: Maybe Text, -- TODO "2020-04-03"
project_compliance_frameworks :: Maybe [Text],
project_statistics :: Maybe Statistics,
project_permissions :: Maybe Permissions,
project_container_registry_image_prefix :: Maybe Text,
project__links :: Maybe Links,
project_mirror :: Maybe Bool,
project_mirror_overwrites_diverged_branches :: Maybe Bool,
project_mirror_trigger_builds :: Maybe Bool,
project_auto_devops_deploy_strategy :: Maybe Text,
project_auto_devops_enabled :: Maybe Bool,
project_service_desk_enabled :: Maybe Bool,
project_approvals_before_merge :: Maybe Int,
project_mirror_user_id :: Maybe Int,
project_packages_enabled :: Maybe Bool,
project_empty_repo :: Maybe Bool,
project_only_mirror_protected_branches :: Maybe Bool,
project_repository_storage :: Maybe Text -- TODO type for "default"
}
deriving (Show, Eq)
-- | Licenses.
data License = License
{ license_key :: Maybe Text,
license_name :: Maybe Text,
license_nickname :: Maybe Text,
license_html_url :: Maybe Text,
license_source_url :: Maybe Text
}
deriving (Show, Eq)
-- | Expiration policies.
data ExpirationPolicy = ExpirationPolicy
{ expiration_policy_cadence :: Maybe Text,
expiration_policy_enabled :: Maybe Bool,
expiration_policy_keep_n :: Maybe Int,
expiration_policy_older_than :: Maybe Text,
expiration_policy_name_regex :: Maybe Text,
expiration_policy_name_regex_delete :: Maybe Value, -- TODO
expiration_policy_name_regex_keep :: Maybe Value, -- TODO
expiration_policy_next_run_at :: Maybe UTCTime
}
deriving (Show, Eq)
-- | Information about repository storage.
data RepositoryStorage = RepositoryStorage
{ repository_storage_project_id :: Int,
repository_storage_disk_path :: Maybe Text,
repository_storage_created_at :: Maybe UTCTime,
repository_storage_repository_storage :: Maybe Text
}
deriving (Show, Eq)
-- | project statistics.
data Statistics = Statistics
{ statistics_commit_count :: Maybe Int,
statistics_storage_size :: Int,
statistics_repository_size :: Int,
statistics_wiki_size :: Maybe Int,
statistics_lfs_objects_size :: Maybe Int,
statistics_job_artifacts_size :: Maybe Int,
statistics_packages_size :: Maybe Int,
statistics_uploads_size :: Maybe Int,
statistics_snippets_size :: Maybe Int,
statistics_pipeline_artifacts_size :: Maybe Int
}
deriving (Show, Eq)
-- | registered users.
data User = User
{ user_id :: Int,
user_username :: Text,
user_bio :: Maybe Text,
user_two_factor_enabled :: Maybe Bool,
user_last_sign_in_at :: Maybe UTCTime,
user_current_sign_in_at :: Maybe UTCTime,
user_last_activity_on :: Maybe Text, -- test current-user has '2012-05-23'
user_skype :: Maybe Text,
user_twitter :: Maybe Text,
user_website_url :: Maybe Text,
user_theme_id :: Maybe Int,
user_color_scheme_id :: Maybe Int,
user_external :: Maybe Bool,
user_private_profile :: Maybe Bool,
user_projects_limit :: Maybe Int,
user_can_create_group :: Maybe Bool,
user_can_create_project :: Maybe Bool,
user_public_email :: Maybe Text,
user_organization :: Maybe Text,
user_job_title :: Maybe Text,
user_linkedin :: Maybe Text,
user_confirmed_at :: Maybe UTCTime,
user_identities :: Maybe [Identity],
user_name :: Text,
user_email :: Maybe Text,
user_followers :: Maybe Int,
user_bot :: Maybe Bool,
user_following :: Maybe Int,
user_state :: Text,
user_avatar_url :: Maybe Text,
user_web_url :: Maybe Text,
user_discussion_locked :: Maybe Bool, -- only for author of 'TODO' type
user_created_at :: Maybe UTCTime
}
deriving (Show, Eq)
-- | milestone state.
data MilestoneState
= MSActive
| MSClosed
deriving (Show, Eq)
instance FromJSON MilestoneState where
parseJSON (String "active") = return MSActive
parseJSON (String "closed") = return MSClosed
parseJSON x = unexpected x
-- | milestones.
data Milestone = Milestone
{ milestone_project_id :: Maybe Int,
milestone_group_id :: Maybe Int,
milestone_description :: Maybe Text,
milestone_state :: Maybe MilestoneState,
milestone_due_date :: Maybe Text,
milestone_start_date :: Maybe Text,
milestone_iid :: Maybe Int,
milestone_created_at :: Maybe UTCTime,
milestone_closed_at :: Maybe UTCTime,
milestone_title :: Text,
milestone_id :: Int,
milestone_updated_at :: Maybe UTCTime,
milestone_web_url :: Maybe URL
}
deriving (Show, Eq)
-- instance FromJSON Milestone where
-- parseJSON = genericParseJSON (defaultOptions {fieldLabelModifier = drop 10})
-- | time stats.
data TimeStats = TimeStats
{ time_stats_time_estimate :: Int,
time_stats_total_time_spent :: Int,
time_stats_human_time_estimate :: Maybe Int,
time_stats_human_total_time_spent :: Maybe Int
}
deriving (Show, Eq)
-- | alias for project id
type ProjectId = Int
-- | alias for issue id
type IssueId = Int
-- | project issues.
data Issue = Issue
{ issue_state :: Text,
issue_description :: Maybe Text,
issue_health_status :: Maybe Text, -- TODO type for "on_track"
issue_author :: Maybe User,
issue_milestone :: Maybe Milestone,
issue_project_id :: Maybe ProjectId,
issue_assignees :: Maybe [User],
issue_assignee :: Maybe User,
issue_updated_at :: Maybe UTCTime,
issue_closed_at :: Maybe Text,
issue_closed_by :: Maybe User,
issue_id :: IssueId,
issue_title :: Text,
issue_created_at :: Maybe UTCTime,
issue_iid :: Int,
-- TODO: what is the difference between the two below?
issue_type :: Maybe Text, -- type for this e.g. "ISSUE"
issue_issue_type :: Maybe Text, -- type for this e.g. "issue"
issue_labels :: Maybe [Text],
issue_upvotes :: Int,
issue_downvotes :: Int,
issue_merge_requests_count :: Maybe Int,
issue_user_notes_count :: Maybe Int,
issue_due_date :: Maybe Text,
issue_web_url :: Text,
issue_references :: Maybe References,
issue_confidential :: Maybe Bool,
issue_weight :: Maybe Text, -- Int?
issue_epic :: Maybe Epic, -- Int?
issue_discussion_locked :: Maybe Bool,
issue_time_stats :: Maybe TimeStats,
issue_has_tasks :: Maybe Bool,
issue_task_status :: Maybe Text,
issue__links :: Maybe Links,
issue_task_completion_status :: Maybe TaskCompletionStatus,
issue_blocking_issues_count :: Maybe Int,
issue_subscribed :: Maybe Bool,
issue_service_desk_reply_to :: Maybe Text
}
deriving (Show, Eq)
-- | GitLab epic.
data Epic = Epic
{ epic_id :: Int,
epic_iid :: Int,
epic_title :: Text,
epic_url :: Text,
epic_group_id :: Int
}
deriving (Show, Eq)
-- | project pipelines
data Pipeline = Pipeline
{ pipeline_id :: Int,
pipeline_iid :: Maybe Int,
pipeline_project_id :: Maybe Int,
pipeline_sha :: Text,
pipeline_ref :: Text,
pipeline_status :: Text,
pipeline_web_url :: Maybe Text,
pipeline_before_sha :: Maybe Text,
pipeline_tag :: Maybe Bool,
pipeline_yaml_errors :: Maybe Text,
pipeline_user :: Maybe User,
pipeline_created_at :: Maybe UTCTime,
pipeline_updated_at :: Maybe UTCTime,
pipeline_started_at :: Maybe UTCTime,
pipeline_finished_at :: Maybe UTCTime,
pipelined_committed_at :: Maybe UTCTime,
pipeline_duration :: Maybe Int,
pipeline_queued_duration :: Maybe Double,
pipeline_coverage :: Maybe Text,
pipeline_detailed_status :: Maybe DetailedStatus
}
deriving (Show, Eq)
-- | project pipelines
data DetailedStatus = DetailedStatus
{ detailed_status_icon :: Maybe Text, -- "status_pending"
detailed_status_text :: Maybe Text,
detailed_status_label :: Maybe Text,
detailed_status_group :: Maybe Text,
detailed_status_tooltip :: Maybe Text,
detailed_status_has_details :: Maybe Bool,
detailed_status_details_path :: Maybe Text,
detailed_status_illustration :: Maybe Text,
detailed_status_favicon :: Maybe Text
}
deriving (Show, Eq)
-- | code commits.
data Commit = Commit
{ commit_id :: Text,
commit_short_id :: Text,
commit_title :: Text,
commit_author_name :: Text,
commit_author_email :: Text,
commit_authored_date :: Maybe Text, -- ZonedTime ?
commit_committer_name :: Maybe Text,
commit_committer_email :: Maybe Text,
commit_committed_date :: Maybe Text, -- ZonedTime ?
commit_created_at :: Maybe Text, -- ZonedTime ?
commit_message :: Text,
commit_parent_ids :: Maybe [String],
commit_last_pipeline :: Maybe Pipeline,
commit_stats :: Maybe CommitStats,
commit_status :: Maybe Text,
commit_web_url :: Maybe Text
}
deriving (Show, Eq)
-- | summary of a code commit for TODOs.
data CommitTodo = CommitTodo
{ commit_todo_id :: Text,
commit_todo_short_id :: Text,
commit_todo_created_at :: UTCTime,
commit_todo_parent_ids :: Maybe [String]
}
deriving (Show, Eq)
-- | repository contributors.
data Contributor = Contributor
{ contributor_name :: Text,
contributor_email :: Text,
contributor_commits :: Int,
contributor_additions :: Int,
contributor_deletions :: Int
}
deriving (Show, Eq)
-- | commit stats.
data CommitStats = CommitStats
{ commitstats_additions :: Int,
commitstats_deletions :: Int,
commitstats_total :: Int
}
deriving (Show, Eq)
-- | tags.
data Tag = Tag
{ tag_commit :: Commit,
tag_release :: Maybe Release,
tag_name :: Text,
tag_target :: Text,
tag_message :: Maybe Text,
tag_protected :: Bool
}
deriving (Show, Eq)
-- | Release associated with a tag
data Release = Release
{ release_tag_name :: Text,
release_description :: Text
}
deriving (Show, Eq)
-- | diff between two commits.
data Diff = Diff
{ diff_diff :: Text,
diff_new_path :: Text,
diff_old_path :: Text,
diff_a_mode :: Maybe Text,
diff_b_mode :: Maybe Text,
diff_new_file :: Bool,
diff_renamed_file :: Bool,
diff_deleted_file :: Bool
}
deriving (Show, Eq)
-- | repositories.
data Repository = Repository
{ repository_id :: Text,
repository_name :: Text,
repository_type :: Text,
repository_path :: Text,
repository_mode :: Text
}
deriving (Show, Eq)
-- | artifacts.
data Artifact = Artifact
{ artifact_file_type :: Maybe Text,
artifact_size :: Int,
artifact_filename :: Text,
artifact_file_format :: Maybe Text
}
deriving (Show, Eq)
-- | groups.
data Group = Group
{ group_id :: Int,
group_name :: Text,
group_path :: Maybe Text,
group_description :: Maybe Text,
group_visibility :: Maybe Text,
group_share_with_group_lock :: Maybe Bool,
group_require_two_factor_authentication :: Maybe Bool,
group_two_factor_grace_period :: Maybe Int,
group_project_creation_level :: Maybe Text, -- TODO type for "developer"
group_auto_devops_enabled :: Maybe Bool,
group_subgroup_creation_level :: Maybe Text, -- TODO type for "owner"
group_emails_disabled :: Maybe Bool,
group_mentions_disabled :: Maybe Bool,
group_default_branch_protection :: Maybe Int,
group_lfs_enabled :: Maybe Bool,
group_avatar_url :: Maybe Text,
group_web_url :: Maybe Text,
group_request_access_enabled :: Maybe Bool,
group_full_name :: Maybe Text,
group_full_path :: Maybe Text,
group_runners_token :: Maybe Text,
group_file_template_project_id :: Maybe Int,
group_parent_id :: Maybe Int,
group_created_at :: Maybe UTCTime,
group_statistics :: Maybe Statistics,
group_shared_with_groups :: Maybe [GroupShare],
group_prevent_sharing_groups_outside_hierarchy :: Maybe Bool
}
deriving (Show, Eq)
-- | response to sharing a project with a group.
data GroupShare = GroupShare
{ groupshare_id :: Maybe Int,
groupshare_project_id :: Maybe Int,
groupshare_group_id :: Int,
groupshare_group_name :: Maybe Text,
groupshare_group_full_path :: Maybe Text,
groupshare_group_access_level :: Int, -- TODO change this to 'AccessLevel'
groupshare_expires_at :: Maybe Text
}
deriving (Show, Eq)
-- | code branches.
data Branch = Branch
{ branch_name :: Text,
branch_merged :: Bool,
branch_protected :: Bool,
branch_default :: Bool,
branch_developers_can_push :: Bool,
branch_developers_can_merge :: Bool,
branch_can_push :: Bool,
branch_web_url :: Maybe Text,
branch_commit :: Commit
}
deriving (Show, Eq)
-- | files in a repository.
data RepositoryFile = RepositoryFile
{ repository_file_file_name :: Text,
repository_file_file_path :: Text,
repository_file_size :: Int,
repository_file_encoding :: Text,
repository_file_content :: Text,
repository_file_content_sha256 :: Text,
repository_file_ref :: Text,
repository_file_blob_id :: Text,
repository_file_commit_id :: Text,
repository_file_last_commit_id :: Text,
repository_file_execute_filemode :: Maybe Bool
}
deriving (Show, Eq)
-- | files in a repository.
data RepositoryFileSimple = RepositoryFileSimple
{ repository_file_simple_file_path :: Text,
repository_file_simple_branch :: Text
}
deriving (Show, Eq)
-- | files in a repository.
data RepositoryFileBlame = RepositoryFileBlame
{ repository_file_blame_commit :: Commit,
repository_file_blame_lines :: [Text]
}
deriving (Show, Eq)
-- | 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, -- TODO make a type e.g. 'reopened'
merge_request_created_at :: UTCTime,
merge_request_updated_at :: UTCTime,
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_assignees :: Maybe [User],
merge_request_reviewers :: Maybe [User],
merge_request_source_project_id :: Int,
merge_request_target_project_id :: Int,
merge_request_labels :: [Text],
merge_request_draft :: Maybe Bool,
merge_request_work_in_progress :: Bool,
merge_request_milestone :: Maybe Milestone,
merge_request_merge_when_pipeline_succeeds :: Bool,
merge_request_merge_status :: Text, -- create type e.g. for "can_be_merged"
merge_request_merge_error :: Maybe Text,
merge_request_sha :: Maybe Text,
merge_request_merge_commit_sha :: Maybe Text,
merge_request_squash_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 :: Maybe Text,
merge_request_time_stats :: Maybe TimeStats,
merge_request_squash :: Maybe Bool,
merge_request_subscribed :: Maybe Bool,
merge_request_changes_count :: Maybe String,
merge_request_merged_by :: Maybe User,
merge_request_merged_at :: Maybe UTCTime,
merge_request_closed_by :: Maybe User,
merge_request_closed_at :: Maybe UTCTime,
merge_request_latest_build_started_at :: Maybe UTCTime,
merge_request_latest_build_finished_at :: Maybe UTCTime,
merge_request_first_deployed_to_production_at :: Maybe UTCTime,
merge_request_pipeline :: Maybe Pipeline,
merge_request_head_pipeline :: Maybe Pipeline,
merge_request_diverged_commits_count :: Maybe Int,
merge_request_rebase_in_progress :: Maybe Bool,
merge_request_first_contribution :: Maybe Bool,
merge_request_has_conflicts :: Maybe Bool,
merge_request_blocking_discussions_resolved :: Maybe Bool,
merge_request_approvals_before_merge :: Maybe Int,
merge_request_mirror :: Maybe Bool,
merge_request_task_completion_status :: Maybe TaskCompletionStatus,
merge_request_reference :: Maybe Text,
merge_request_references :: Maybe References,
merge_request_changes :: Maybe [Change],
merge_request_overflow :: Maybe Bool,
merge_request_diff_refs :: Maybe DiffRefs
}
deriving (Show, Eq)
-- | monitors a task completion status.
data TaskCompletionStatus = TaskCompletionStatus
{ task_completion_status_count :: Int,
task_completion_status_completed_count :: Maybe Int
}
deriving (Show, Eq)
-- | references.
data References = References
{ references_short :: Text,
references_relative :: Text,
references_full :: Text
}
deriving (Show, Eq)
-- | Change between commits.
data Change = Change
{ change_old_path :: Text,
change_new_path :: Text,
change_a_mode :: Text, -- find type for "100644"
change_b_mode :: Text, -- find type for "100644"
change_diff :: Text, -- find type for "--- a/VERSION\\ +++ b/VERSION\\ @@ -1 +1 @@\\ -1.9.7\\ +1.9.8"
change_new_file :: Bool,
change_renamed_file :: Bool,
change_deleted_file :: Bool
}
deriving (Show, Eq)
-- | diff references.
data DiffRefs = DiffRefs
{ diff_refs_base_sha :: Text,
diff_refs_head_sha :: Text,
diff_refs_start_sha :: Text
}
deriving (Show, Eq)
{- TODO for MergeRequest
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"changes": [
{
"old_path": "VERSION",
"new_path": "VERSION",
"a_mode": "100644",
"b_mode": "100644",
"diff": "--- a/VERSION\\ +++ b/VERSION\\ @@ -1 +1 @@\\ -1.9.7\\ +1.9.8",
"new_file": false,
"renamed_file": false,
"deleted_file": false
}
"overflow": false
"diff_refs": {
"base_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00",
"head_sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f",
"start_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00"
},
-}
-- | TODO action.
data TodoAction
= TAAssigned
| TAMentioned
| TABuildFailed
| TAMarked
| TAApprovalRequired
| TAUnmergeable
| TADirectlyAddressed
deriving (Show, Eq)
instance FromJSON TodoAction where
parseJSON (String "assigned") = return TAAssigned
parseJSON (String "mentioned") = return TAMentioned
parseJSON (String "build_failed") = return TABuildFailed
parseJSON (String "marked") = return TAMarked
parseJSON (String "approval_required") = return TAApprovalRequired
parseJSON (String "unmergeable") = return TAUnmergeable
parseJSON (String "directly_addressed") = return TADirectlyAddressed
parseJSON x = unexpected x
-- | TODO targets.
data TodoTarget
= TTIssue Issue
| TTMergeRequest MergeRequest
| TTCommit CommitTodo
deriving (Show, Eq)
-- | URL is a synonym for 'Text'.
type URL = Text
-- | TODO states.
data TodoState
= TSPending
| TSDone
deriving (Show, Eq)
-- | A project TODO.
data TodoProject = TodoProject
{ todo_project_id :: Int,
todo_project_description :: Maybe Text,
todo_project_name :: Text,
todo_project_name_with_namespace :: Text,
todo_project_path :: Text,
todo_project_path_with_namespace :: Text,
todo_project_created_at :: Maybe UTCTime
}
deriving (Show, Eq)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "todo_project_"), omitNothingFields = True} ''TodoProject)
-- | TODOs.
data Todo = Todo
{ todo_id :: Int,
todo_project :: TodoProject,
todo_author :: User,
todo_action_name :: TodoAction,
todo_target_type :: TodoTargetType,
todo_target :: TodoTarget,
todo_target_url :: URL,
todo_body :: Text,
todo_state :: TodoState,
todo_created_at :: UTCTime,
todo_updated_at :: Maybe UTCTime
}
deriving (Show, Eq)
-- | Target type of a TODO.
data TodoTargetType
= MergeRequestTarget
| IssueTarget
| CommitTarget
deriving (Show, Eq)
-- | Type of a TODO.
data TodoType
= TodoTypeIssue
| TodoTypeMergeRequest
| TodoTypeCommit
| TodoTypeEpic
| TodoTypeDesign
| TodoTypeAlert
instance Show TodoType where
show TodoTypeIssue = "Issue"
show TodoTypeMergeRequest = "MergeRequest"
show TodoTypeCommit = "Commit"
show TodoTypeEpic = "Epic"
show TodoTypeDesign = "DesignManagement::Design"
show TodoTypeAlert = "AlertManagement::Alert"
-- | version of the GitLab instance.
data Version = Version
{ version_version :: Text,
version_revision :: Text
}
deriving (Show, Eq)
-- | 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 UTCTime,
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 (Show)
-- | Discussions https://docs.gitlab.com/ee/api/discussions.html
data Discussion = Discussion
{ discussion_id :: Text,
discussion_individual_note :: Bool,
discussion_notes :: [Note]
}
deriving (Show, Eq)
-- | Note attached to a commit.
data CommitNote = CommitNote
{ commitnote_note :: Text,
commitnote_author :: User
}
deriving (Show, Eq)
-- | Notes
data Note = Note
{ note_id :: Int,
note_title :: Maybe Text, -- for snippets
note_file_name :: Maybe Text, -- for snippets
-- https://docs.gitlab.com/ee/api/discussions.html#list-project-commit-discussion-items
note_type :: Maybe Text, -- TODO create type for this, e.g. from "DiscussionNote"
note_body :: Maybe Text,
note_attachment :: Maybe Text,
note_author :: Owner,
note_created_at :: UTCTime,
note_updated_at :: Maybe UTCTime,
note_system :: Maybe Bool,
note_noteable_id :: Maybe Int,
note_noteable_type :: Maybe Text, -- create type e.g. from "Commit"
note_noteable_iid :: Maybe Int,
note_commands_changes :: Maybe CommandsChanges,
note_resolved :: Maybe Bool,
note_resolvable :: Maybe Bool,
note_confidential :: Maybe Bool,
note_resolved_by :: Maybe User -- TODO check
}
deriving (Show, Eq)
-- | has a change been promoted to an epic.
newtype CommandsChanges = CommanandsChanges
{ commands_changes_promote_to_epic :: Bool
}
deriving (Show, Eq)
-- | Statistics and an issue
newtype IssueStatistics = IssueStatistics
{ issue_statistics_stats :: IssueStats
}
deriving (Show, Eq)
-- | Issue statistics
newtype IssueStats = IssueStats
{ issue_stats_issue_counts :: IssueCounts
}
deriving (Show, Eq)
-- | A count of all, open and closed issues against a project
data IssueCounts = IssueCounts
{ issue_counts__all :: Int,
issue_counts_closed :: Int,
issue_counts_opened :: Int
}
deriving (Show, Eq)
-- | Project issue boards https://docs.gitlab.com/ee/user/project/issue_board.html
data IssueBoard = IssueBoard
{ board_id :: Int,
board_name :: Text,
board_project :: Project,
board_milestone :: Maybe Milestone,
board_lists :: [BoardIssue],
board_group :: Maybe Text, -- not sure, documentation doesn't indicate type
board_assignee :: Maybe Owner,
board_labels :: Maybe [BoardIssueLabel],
board_weight :: Maybe Int
}
deriving (Show, Eq)
-- | Issues associated with a project issue board
data BoardIssue = BoardIssue
{ board_issue_id :: Int,
board_issue_label :: BoardIssueLabel,
board_issue_position :: Int,
board_issue_max_issue_count :: Int,
board_issue_max_issue_weight :: Int,
-- TODO, the docs don't say what type this should be
board_issue_limit_metric :: Maybe Int
}
deriving (Show, Eq)
-- | Label of an issues for a project issue board
data BoardIssueLabel = BoardIssueLabel
{ board_issue_label_id :: Maybe Int,
board_issue_label_name :: Text,
board_issue_label_color :: Text, -- parse into type from e.g. "#F0AD4E"
board_issue_label_description :: Maybe Text
}
deriving (Show, Eq)
-- | Project visibility.
data Visibility
= Public
| Private
| Internal
deriving (Show, Eq)
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)
-- | Unit test reports for a CI pipeline https://docs.gitlab.com/ee/ci/unit_test_reports.html
data TestReport = TestReport
{ test_report_total_time :: Double,
test_report_total_count :: Int,
test_report_success_count :: Int,
test_report_failed_count :: Int,
test_report_skipped_count :: Int,
test_report_error_count :: Int,
test_report_test_suites :: [TestSuite]
}
deriving (Show, Eq)
-- | Testsuites associated with a test report
data TestSuite = TestSuite
{ testsuite_name :: Text,
testsuite_total_time :: Double,
testsuite_success_count :: Int,
testsuite_failed_count :: Int,
testsuite_skipped_count :: Int,
testsuite_error_count :: Int,
testsuite_test_cases :: [TestCase]
}
deriving (Show, Eq)
-- | Test case associated with a testsuite
data TestCase = TestCase
{ testcase_status :: Text, -- could turn this into a type e.g. for "success"
testcase_name :: Text,
testcase_classname :: Text,
testcase_execution_time :: Double,
testcase_system_output :: Maybe Text,
testcase_stack_trace :: Maybe Text
}
deriving (Show, Eq)
-- | Estimated humand and total time spent.
data TimeEstimate = TimeEstimate
{ time_estimate_human_time_estimate :: Maybe Text,
time_estimate_human_total_time_spent :: Maybe Text,
time_estimate_time_estimate :: Maybe Int,
time_estimate_total_time_spent :: Maybe Int
}
deriving (Show, Eq)
-- | Email information.
data Email = Email
{ email_id :: Int,
email_email :: Text,
email_confirmed_at :: Maybe UTCTime
}
deriving (Show, Eq)
-- | User preferences.
data UserPrefs = UserPrefs
{ user_prefs_id :: Int,
user_prefs_user_id :: Int,
user_prefs_view_diffs_file_by_file :: Bool,
user_prefs_show_whitespace_in_diffs :: Bool
}
deriving (Show, Eq)
-- | SSH key information.
data Key = Key
{ key_id :: Maybe Int,
key_title :: Maybe Text,
key_key :: Text,
key_created_at :: Maybe UTCTime,
key_expires_at :: Maybe UTCTime
}
deriving (Show, Eq)
-- | User status.
data UserStatus = UserStatus
{ user_status_emoji :: Maybe Text, -- TODO type for "coffee"
user_status_availability :: Maybe Text, -- TODO type for "busy"
user_status_message :: Maybe Text,
user_status_message_html :: Maybe Text, -- TODO type for HTML content
user_status_clear_status_at :: Maybe UTCTime
}
deriving (Show, Eq)
-- | Tracks counts for a user's activity.
data UserCount = UserCount
{ user_count_merge_requests :: Int, -- TODO type for "coffee"
user_count_assigned_issues :: Int, -- TODO type for "busy"
user_count_assigned_merge_requests :: Int,
user_count_review_requested_merge_requests :: Int, -- TODO type for HTML content
user_count_todos :: Int
}
deriving (Show, Eq)
-- TODO this data type could be improved to remove redundant Maybe
-- values. E.g. the push_data field will only be populated for the
-- "pushed" action_name, but would be Nothing for all action_name
-- values. Same for 'commented on' and the existence of a 'event_note'
-- field value.
-- | Events https://docs.gitlab.com/ee/api/events.html
data Event = Event
{ event_id :: Int,
event_title :: Maybe Text,
event_project_id :: Int,
event_action_name :: EventActionName,
event_target_id :: Maybe Int,
event_target_iid :: Maybe Int,
event_target_type :: Maybe EventTargetType,
event_author_id :: Int,
event_target_title :: Maybe Text,
event_created_at :: Maybe UTCTime,
event_author :: User,
event_author_username :: Text,
event_push_data :: Maybe PushData,
event_note :: Maybe Note
}
deriving (Show, Eq)
-- | Information about a git push.
data PushData = PushData
{ push_data_commit_count :: Int,
push_data_action :: EventActionName,
push_data_ref_type :: Text, -- TODO type for "branch"
push_data_commit_from :: Text, -- sha hash
push_data_commit_to :: Text, -- sha hash
push_data_ref :: Text,
push_data_commit_title :: Text
}
deriving (Show, Eq)
-- | Tracks whether an action is open, closed, pushed or commented on.
data EventActionName
= ANOpened
| ANClosed
| ANPushed
| ANCommentedOn
deriving (Show, Eq)
instance ToJSON EventActionName where
toJSON ANOpened = String "opened"
toJSON ANClosed = String "closed"
toJSON ANPushed = String "pushed"
toJSON ANCommentedOn = String "commented on"
instance FromJSON EventActionName where
parseJSON (String "opened") = return ANOpened
parseJSON (String "closed") = return ANClosed
parseJSON (String "pushed") = return ANPushed
parseJSON (String "commented on") = return ANCommentedOn
parseJSON x = unexpected x
-- | Associates an event with a particular target.
data EventTargetType
= ETTIssue
| ETTMilestone
| ETTMergeRequest
| ETTNote
| ETTProject
| ETTSnippet
| ETTUser
deriving (Show, Eq)
instance ToJSON EventTargetType where
toJSON ETTIssue = String "Issue"
toJSON ETTMilestone = String "Milestone"
toJSON ETTMergeRequest = String "MergeRequest"
toJSON ETTNote = String "Note"
toJSON ETTProject = String "Project"
toJSON ETTSnippet = String "Snippet"
toJSON ETTUser = String "User"
instance FromJSON EventTargetType where
parseJSON (String "Issue") = return ETTIssue
parseJSON (String "Milestone") = return ETTMilestone
parseJSON (String "MergeRequest") = return ETTMergeRequest
parseJSON (String "Note") = return ETTNote
parseJSON (String "Project") = return ETTProject
parseJSON (String "Snippet") = return ETTSnippet
parseJSON (String "User") = return ETTUser
parseJSON x = unexpected x
-- | Events https://docs.gitlab.com/ee/api/events.html
data Job = Job
{ job_commit :: Commit,
job_coverage :: Maybe Text, -- ??
job_allow_failure :: Bool,
job_created_at :: UTCTime,
job_started_at :: Maybe UTCTime,
job_finished_at :: Maybe UTCTime,
job_duration :: Maybe Double,
job_queued_duration :: Double,
job_artifacts_file :: Maybe Artifact,
job_artifacts :: Maybe [Artifact],
job_artifacts_expire_at :: Maybe UTCTime,
job_tag_list :: Maybe [Text],
job_id :: Int,
job_name :: Text,
job_pipeline :: Maybe Pipeline,
job_ref :: Text,
job_stage :: Maybe Text,
job_status :: Text, -- TODO type for "failed" and others
job_failure_reason :: Maybe Text, -- TODO type for "script_failure" and others
job_tag :: Bool,
job_web_url :: Text, -- TODO type for URL like "https://example.com/foo/bar/-/jobs/7"
job_user :: Maybe User,
job_downstream_pipeline :: Maybe Pipeline
}
deriving (Show, Eq)
-----------------------------
-- JSON GitLab parsers below
-----------------------------
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "time_stats_"), omitNothingFields = True} ''TimeStats)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "user_"), omitNothingFields = True} ''User)
instance ToJSON MilestoneState where
toJSON MSActive = String "active"
toJSON MSClosed = String "closed"
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "milestone_"), omitNothingFields = True} ''Milestone)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "references_"), omitNothingFields = True} ''References)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "epic_"), omitNothingFields = True} ''Epic)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "links_"), omitNothingFields = True} ''Links)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "task_completion_status_"), omitNothingFields = True} ''TaskCompletionStatus)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "issue_"), omitNothingFields = True} ''Issue)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "detailed_status_"), omitNothingFields = True} ''DetailedStatus)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "pipeline_"), omitNothingFields = True} ''Pipeline)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "commitstats_"), omitNothingFields = True} ''CommitStats)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "commit_"), omitNothingFields = True} ''Commit)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "release_"), omitNothingFields = True} ''Release)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "tag_"), omitNothingFields = True} ''Tag)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "contributor_"), omitNothingFields = True} ''Contributor)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "saml_identity_"), omitNothingFields = True} ''SamlIdentity)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "identity_"), omitNothingFields = True} ''Identity)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "member_"), omitNothingFields = True} ''Member)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "permissions_"), omitNothingFields = True} ''Permissions)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "owner_"), omitNothingFields = True} ''Owner)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "namespace_"), omitNothingFields = True} ''Namespace)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "expiration_policy_"), omitNothingFields = True} ''ExpirationPolicy)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "license_"), omitNothingFields = True} ''License)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "groupshare_"), omitNothingFields = True} ''GroupShare)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "statistics_"), omitNothingFields = True} ''Statistics)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "project_"), omitNothingFields = True} ''Project)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "repository_"), omitNothingFields = True} ''Repository)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "artifact_"), omitNothingFields = True} ''Artifact)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "job_"), omitNothingFields = True} ''Job)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "branch_"), omitNothingFields = True} ''Branch)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "repository_file_"), omitNothingFields = True} ''RepositoryFile)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "repository_file_simple_"), omitNothingFields = True} ''RepositoryFileSimple)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "repository_file_blame_"), omitNothingFields = True} ''RepositoryFileBlame)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "change_"), omitNothingFields = True} ''Change)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "diff_refs_"), omitNothingFields = True} ''DiffRefs)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "merge_request_"), omitNothingFields = True} ''MergeRequest)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "diff_"), omitNothingFields = True} ''Diff)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "version_"), omitNothingFields = True} ''Version)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "edit_issue_"), omitNothingFields = True} ''EditIssueReq)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "commands_changes_"), omitNothingFields = True} ''CommandsChanges)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "note_"), omitNothingFields = True} ''Note)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "discussion_"), omitNothingFields = True} ''Discussion)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "issue_counts_"), omitNothingFields = True} ''IssueCounts)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "issue_stats_"), omitNothingFields = True} ''IssueStats)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "issue_statistics_"), omitNothingFields = True} ''IssueStatistics)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "board_issue_label_"), omitNothingFields = True} ''BoardIssueLabel)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "board_issue_"), omitNothingFields = True} ''BoardIssue)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "board_"), omitNothingFields = True} ''IssueBoard)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "testcase_"), omitNothingFields = True} ''TestCase)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "testsuite_"), omitNothingFields = True} ''TestSuite)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "test_report_"), omitNothingFields = True} ''TestReport)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "time_estimate_"), omitNothingFields = True} ''TimeEstimate)
instance ToJSON TodoAction where
toJSON TAAssigned = String "assigned"
toJSON TAMentioned = String "mentioned"
toJSON TABuildFailed = String "build_build"
toJSON TAMarked = String "marked"
toJSON TAApprovalRequired = String "approval_required"
toJSON TAUnmergeable = String "unmergeable"
toJSON TADirectlyAddressed = String "directly_addressed"
instance FromJSON TodoState where
parseJSON (String "pending") = return TSPending
parseJSON (String "done") = return TSDone
parseJSON x = unexpected x
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "commit_todo_"), omitNothingFields = True} ''CommitTodo)
instance FromJSON TodoTargetType where
parseJSON (String "MergeRequest") = return MergeRequestTarget
parseJSON (String "Issue") = return IssueTarget
parseJSON (String "Commit") = return CommitTarget
parseJSON x = unexpected x
instance FromJSON Todo where
parseJSON = withObject "Todo" $ \v ->
Todo
<$> v .: "id"
<*> v .: "project"
<*> v .: "author"
<*> v .: "action_name"
<*> v .: "target_type"
<*> ( v .: "target_type" >>= \case
"MergeRequest" -> TTMergeRequest <$> v .: "target"
"Issue" -> TTIssue <$> v .: "target"
"Commit" -> TTCommit <$> v .: "target"
(_ :: Text) -> fail ""
)
<*> v .: "target_url"
<*> v .: "body"
<*> v .: "state"
<*> v .: "created_at"
<*> v .:? "updated_at"
$(deriveToJSON defaultOptions {fieldLabelModifier = drop (T.length "todo_"), omitNothingFields = True} ''Todo)
instance ToJSON TodoTargetType where
toJSON MergeRequestTarget = String "MergeRequest"
toJSON IssueTarget = String "Issue"
toJSON CommitTarget = String "Commit"
instance ToJSON TodoState where
toJSON TSPending = String "pending"
toJSON TSDone = String "done"
instance ToJSON TodoTarget where
toJSON (TTIssue x) = toJSON x
toJSON (TTMergeRequest x) = toJSON x
toJSON (TTCommit x) = toJSON x
-- | User who is the starrer of a project.
data Starrer = Starrer
{ starrer_starred_since :: UTCTime,
starrer_user :: User
}
deriving (Show, Eq)
-- | Avatar for a project.
newtype ProjectAvatar = ProjectAvatar
{ project_avatar_avatar_url :: Text
}
deriving (Show, Eq)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "repository_storage_"), omitNothingFields = True} ''RepositoryStorage)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "starrer_"), omitNothingFields = True} ''Starrer)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "project_avatar_"), omitNothingFields = True} ''ProjectAvatar)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "group_"), omitNothingFields = True} ''Group)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "commitnote_"), omitNothingFields = True} ''CommitNote)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "email_"), omitNothingFields = True} ''Email)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "key_"), omitNothingFields = True} ''Key)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "user_prefs_"), omitNothingFields = True} ''UserPrefs)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "user_status_"), omitNothingFields = True} ''UserStatus)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "user_count_"), omitNothingFields = True} ''UserCount)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "event_"), omitNothingFields = True} ''Event)
$(deriveJSON defaultOptions {fieldLabelModifier = drop (T.length "push_data_"), omitNothingFields = True} ''PushData)