gitlab-haskell-0.3.2.0: src/GitLab/Types.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StrictData #-}
-- |
-- 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 (..),
Member (..),
Namespace (..),
Links (..),
Owner (..),
Permissions (..),
ProjectId,
Project (..),
ProjectStats (..),
User (..),
Milestone (..),
MilestoneState (..),
TimeStats (..),
IssueId,
Issue (..),
Pipeline (..),
Commit (..),
CommitTodo (..),
CommitStats (..),
Tag (..),
Release (..),
Diff (..),
Repository (..),
Job (..),
Artifact (..),
Group (..),
GroupShare (..),
Branch (..),
RepositoryFile (..),
MergeRequest (..),
Todo (..),
TodoProject (..),
TodoAction (..),
TodoTarget (..),
TodoState (..),
Version (..),
URL,
EditIssueReq (..),
Discussion (..),
Note (..),
IssueStatistics (..),
IssueStats (..),
IssueCounts (..),
IssueBoard (..),
BoardIssue (..),
BoardIssueLabel (..),
ProjectBoard (..),
Visibility (..),
TestReport (..),
TestSuite (..),
TestCase (..),
)
where
import Control.Monad.Trans.Reader
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 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"
-- | 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
}
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
}
deriving (Generic, Show)
-- | links.
data Links = Links
{ self :: Text,
issues :: Maybe Text,
merge_requests :: Maybe 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
}
deriving (Generic, Show, Eq)
-- | permissions.
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,
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
}
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
}
deriving (Generic, Show)
-- | 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_iid :: Maybe Int,
milestone_created_at :: Maybe UTCTime,
milestone_title :: Text,
milestone_id :: Int,
milestone_updated_at :: Maybe UTCTime,
milestone_web_url :: Maybe URL
}
deriving (Generic, Show, Eq)
instance FromJSON Milestone where
parseJSON = genericParseJSON (defaultOptions {fieldLabelModifier = drop 10})
-- | time stats.
data TimeStats = TimeStats
{ time_estimate :: Int,
total_time_spent :: Int,
human_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 :: 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
}
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,
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 [String]
}
deriving (Generic, Show)
-- | commit stats.
data CommitStats = Stats
{ additions :: Int,
deletions :: Int,
total :: Int
}
deriving (Generic, Show)
-- | 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 (Generic, Show)
-- | Release associated with a tag
data Release = Release
{ release_tag_name :: Text,
release_description :: Text
}
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
}
deriving (Generic, Show)
-- | repositories.
data Repository = Repository
{ repository_id :: Text,
repository_name :: Text,
repository_type :: Text,
repository_path :: Text,
mode :: Text
}
deriving (Generic, Show)
-- | jobs.
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
}
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
}
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
}
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
}
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
}
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 String,
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.
data TodoAction
= TAAssigned
| TAMentioned
| TABuildFailed
| TAMarked
| TAApprovalRequired
| TAUnmergeable
| TADirectlyAddressed
deriving (Show)
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)
-- | URL is a synonym for 'Text'.
type URL = Text
-- | TODO states.
data TodoState
= TSPending
| TSDone
deriving (Show)
instance FromJSON TodoState where
parseJSON (String "pending") = return TSPending
parseJSON (String "done") = return TSDone
parseJSON x = unexpected x
-- | 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
}
deriving (Show)
instance FromJSON Todo where
parseJSON = withObject "Todo" $ \v ->
Todo
<$> v .: "id"
<*> v .: "project"
<*> v .: "author"
<*> v .: "action_name"
<*> ( 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"
-- | version of the GitLab instance.
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)
-- | Discussions https://docs.gitlab.com/ee/api/discussions.html
data Discussion = Discussion
{ discussion_id :: Text,
discussion_individual_note :: Bool,
discussion_notes :: [Note]
}
deriving (Generic, Show)
-- | Notes
data Note = Note
{ note_id :: Int,
-- 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 :: Text,
note_attachment :: Maybe Text,
note_author :: Owner,
-- -- TODO parse these as date type
note_created_at :: Text,
note_updated_at :: Text,
note_system :: Bool,
note_noteable_id :: Maybe Int,
note_noteable_type :: Maybe Text, -- create type e.g. from "Commit"
note_noteable_iid :: Maybe Int,
note_resolvable :: Bool
}
deriving (Generic, Show)
-- | Statistics and an issue
newtype IssueStatistics = IssueStatistics
{ issues_statistics :: IssueStats
}
deriving (Generic, Show)
-- | Issue statistics
newtype IssueStats = IssueStats
{ issues_counts :: IssueCounts
}
deriving (Generic, Show)
-- | A count of all, open and closed issues against a project
data IssueCounts = IssueCounts
{ issues_all :: Int,
issues_closed :: Int,
issues_opened :: Int
}
deriving (Generic, Show)
-- | Project issue boards https://docs.gitlab.com/ee/user/project/issue_board.html
data IssueBoard = IssueBoard
{ board_id :: Int,
board_name :: Text,
board_project :: ProjectBoard,
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 (Generic, 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 (Generic, 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 (Generic, Show, Eq)
-- | A project board
data ProjectBoard = ProjectBoard
{ project_board_id :: Int,
project_board_name :: Text,
project_board_name_with_namespace :: Text,
project_board_path :: Text,
project_board_path_with_namespace :: Text,
project_board_http_url_to_repo :: Text,
project_board_web_url :: Text
}
deriving (Generic, 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
{ total_time :: Double,
total_count :: Int,
success_count :: Int,
failed_count :: Int,
skipped_count :: Int,
error_count :: Int,
test_suites :: [TestSuite]
}
deriving (Generic, 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 (Generic, Show, Eq)
testsuitePrefix :: String -> String
testsuitePrefix "testsuite_name" = "name"
testsuitePrefix "testsuite_total_time" = "total_time"
testsuitePrefix "testsuite_success_count" = "success_count"
testsuitePrefix "testsuite_failed_count" = "failed_count"
testsuitePrefix "testsuite_skipped_count" = "skipped_count"
testsuitePrefix "testsuite_error_count" = "error_count"
testsuitePrefix "testsuite_test_cases" = "test_cases"
testsuitePrefix s = s
-- | 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 (Generic, Show, Eq)
testcasePrefix :: String -> String
testcasePrefix "testcase_status" = "status"
testcasePrefix "testcase_name" = "name"
testcasePrefix "testcase_classname" = "classname"
testcasePrefix "testcase_execution_time" = "execution_time"
testcasePrefix "testcase_system_output" = "system_output"
testcasePrefix "testcase_stack_trace" = "stack_trace"
testcasePrefix s = s
-----------------------------
-- JSON GitLab parsers below
-----------------------------
bodyNoPrefix :: String -> String
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"
bodyNoPrefix "todo_parent_ids" = "parent_ids"
bodyNoPrefix "issue_author" = "author"
bodyNoPrefix "issue_created_at" = "created_at"
bodyNoPrefix "issue_description" = "description"
bodyNoPrefix "issue_due_date" = "due_date"
bodyNoPrefix "issue_id" = "id"
bodyNoPrefix "issue_labels" = "labels"
bodyNoPrefix "issue_project_id" = "project_id"
bodyNoPrefix "issue_state" = "state"
bodyNoPrefix "issue_title" = "title"
bodyNoPrefix "issue_web_url" = "web_url"
bodyNoPrefix "link_events" = "events"
bodyNoPrefix "link_labels" = "labels"
bodyNoPrefix "member_avatar_url" = "avatar_url"
bodyNoPrefix "member_id" = "id"
bodyNoPrefix "member_name" = "name"
bodyNoPrefix "member_state" = "state"
bodyNoPrefix "member_username" = "username"
bodyNoPrefix "member_web_url" = "we_url"
bodyNoPrefix "namespace_id" = "id"
bodyNoPrefix "namespace_name" = "name"
bodyNoPrefix "namespace_path" = "path"
bodyNoPrefix "owner_avatar_url" = "avatar_url"
bodyNoPrefix "owner_id" = "id"
bodyNoPrefix "owner_name" = "name"
bodyNoPrefix "owner_username" = "username"
bodyNoPrefix "owner_web_url" = "web_url"
bodyNoPrefix "pipeline_id" = "id"
bodyNoPrefix "pipeline_status" = "status"
bodyNoPrefix "pipeline_web_url" = "web_url"
bodyNoPrefix "project_avatar_url" = "avatar_url"
bodyNoPrefix "project_created_at" = "created_at"
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"
bodyNoPrefix "repository_path" = "path"
bodyNoPrefix "repository_type" = "type"
bodyNoPrefix "user_avatar_uri" = "avatar_url"
bodyNoPrefix "user_id" = "id"
bodyNoPrefix "user_name" = "name"
bodyNoPrefix "user_state" = "state"
bodyNoPrefix "user_username" = "username"
bodyNoPrefix "user_web_url" = "web_url"
bodyNoPrefix "event_title" = "title"
bodyNoPrefix "event_project_id" = "project_id"
bodyNoPrefix "pipeline_ref" = "ref"
bodyNoPrefix "branch_name" = "name"
bodyNoPrefix "branch_default" = "default"
bodyNoPrefix "branch_commit" = "commit"
bodyNoPrefix "repository_file_file_name" = "file_name"
bodyNoPrefix "repository_file_file_path" = "file_path"
bodyNoPrefix "repository_file_size" = "size"
bodyNoPrefix "repository_file_commit_id" = "commit_id"
bodyNoPrefix "merge_request_id" = "id"
bodyNoPrefix "merge_request_iid" = "iid"
bodyNoPrefix "merge_request_project_id" = "project_id"
bodyNoPrefix "merge_request_title" = "title"
bodyNoPrefix "merge_request_description" = "description"
bodyNoPrefix "merge_request_state" = "state"
bodyNoPrefix "merge_request_merged_by" = "merged_by"
bodyNoPrefix "merge_request_merged_at" = "merged_at"
bodyNoPrefix "merge_request_closed_by" = "closed_by"
bodyNoPrefix "merge_request_closed_at" = "closed_at"
bodyNoPrefix "merge_request_created_at" = "created_at"
bodyNoPrefix "merge_request_updated_at" = "updated_at"
bodyNoPrefix "merge_request_target_branch" = "target_branch"
bodyNoPrefix "merge_request_source_branch" = "source_branch"
bodyNoPrefix "merge_request_upvotes" = "upvotes"
bodyNoPrefix "merge_request_downvotes" = "downvotes"
bodyNoPrefix "merge_request_author" = "author"
bodyNoPrefix "merge_request_assignee" = "assignee"
bodyNoPrefix "merge_request_source_project_id" = "source_project_id"
bodyNoPrefix "merge_request_target_project_id" = "target_project_id"
bodyNoPrefix "merge_request_labels" = "labels"
bodyNoPrefix "merge_request_work_in_progress" = "work_in_progress"
bodyNoPrefix "merge_request_milestone" = "milestone"
bodyNoPrefix "merge_request_merge_when_pipeline_succeeds" = "merge_when_pipeline_succeeds"
bodyNoPrefix "merge_request_merge_status" = "merge_status"
bodyNoPrefix "merge_request_sha" = "sha"
bodyNoPrefix "merge_request_merge_commit_sha" = "merge_commit_sha"
bodyNoPrefix "merge_request_user_notes_count" = "user_notes_count"
bodyNoPrefix "merge_request_discussion_locked" = "discussion_locked"
bodyNoPrefix "merge_request_should_remove_source_branch" = "should_remove_source_branch"
bodyNoPrefix "merge_request_force_remove_source_branch" = "force_remove_source_branch"
bodyNoPrefix "merge_request_allow_collaboration" = "allow_collaboration"
bodyNoPrefix "merge_request_allow_maintainer_to_push" = "allow_maintainer_to_push"
bodyNoPrefix "merge_request_web_url" = "web_url"
bodyNoPrefix "merge_request_time_stats" = "time_stats"
bodyNoPrefix "merge_request_squash" = "squash"
bodyNoPrefix "merge_request_approvals_before_merge" = "approvals_before_merge"
bodyNoPrefix "merge_request_allow_contribution" = "allow_contribution"
bodyNoPrefix "merge_request_changes_count" = "changes_count"
bodyNoPrefix "merge_request_pipeline" = "pipeline"
bodyNoPrefix "merge_request_diverged_commits_count" = "diverged_commits_count"
bodyNoPrefix "merge_request_rebase_in_progress" = "rebase_in_progress"
bodyNoPrefix "merge_request_has_conflicts" = "has_conflicts"
bodyNoPrefix "merge_request_blocking_discussions_resolved" = "blocking_discussions_resolved"
bodyNoPrefix "project_stats" = "statistics"
bodyNoPrefix "commit_stats" = "stats"
bodyNoPrefix "share_id" = "id"
bodyNoPrefix "share_project_id" = "project_id"
bodyNoPrefix "share_group_id" = "group_id"
bodyNoPrefix "share_group_access" = "group_access"
bodyNoPrefix "share_expires_at" = "expires_at"
bodyNoPrefix "group_id" = "id"
bodyNoPrefix "group_name" = "name"
bodyNoPrefix "group_path" = "path"
bodyNoPrefix "group_description" = "description"
bodyNoPrefix "group_visibility" = "visibility"
bodyNoPrefix "group_lfs_enabled" = "lfs_enabled"
bodyNoPrefix "group_avatar_url" = "avatar_url"
bodyNoPrefix "group_web_url" = "web_url"
bodyNoPrefix "group_request_access_enabled" = "request_access_enabled"
bodyNoPrefix "group_full_name" = "full_name"
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"
bodyNoPrefix "discussion_id" = "id"
bodyNoPrefix "discussion_individual_note" = "individual_note"
bodyNoPrefix "discussion_notes" = "notes"
bodyNoPrefix "note_id" = "id"
bodyNoPrefix "note_type" = "type"
bodyNoPrefix "note_body" = "body"
bodyNoPrefix "note_attachment" = "attachment"
bodyNoPrefix "note_author" = "author"
bodyNoPrefix "note_created_at" = "created_at"
bodyNoPrefix "note_updated_at" = "updated_at"
bodyNoPrefix "note_system" = "system"
bodyNoPrefix "note_noteable_id" = "noteable_id"
bodyNoPrefix "note_noteable_type" = "noteable_type"
bodyNoPrefix "note_noteable_iid" = "iid"
bodyNoPrefix "note_resolvable" = "resolvable"
-- TODO field names for Issues data type
bodyNoPrefix s = s
-- TODO refactor bodyNoPrefix function above into smaller
-- String -> String
-- functions like those below.
tagPrefix :: String -> String
tagPrefix "tag_commit" = "commit"
tagPrefix "tag_release" = "release"
tagPrefix "tag_name" = "name"
tagPrefix "tag_target" = "target"
tagPrefix "tag_message" = "message"
tagPrefix "tag_protected" = "protected"
tagPrefix s = s
releasePrefix :: String -> String
releasePrefix "release_tag_name" = "tag_name"
releasePrefix "release_description" = "description"
releasePrefix s = s
issueStatsPrefix :: String -> String
issueStatsPrefix "issues_all" = "all"
issueStatsPrefix "issues_closed" = "closed"
issueStatsPrefix "issues_opened" = "opened"
issueStatsPrefix "issues_statistics" = "statistics"
issueStatsPrefix "issues_counts" = "counts"
issueStatsPrefix s = s
boardsPrefix :: String -> String
boardsPrefix "board_id" = "id"
boardsPrefix "board_name" = "name"
boardsPrefix "board_project" = "project"
boardsPrefix "board_milestone" = "milestone"
boardsPrefix "board_lists" = "lists"
boardsPrefix "board_issue_id" = "id"
boardsPrefix "board_issue_label" = "label"
boardsPrefix "board_issue_position" = "position"
boardsPrefix "board_issue_max_issue_count" = "max_issue_count"
boardsPrefix "board_issue_max_issue_weight" = "max_issue_weight"
boardsPrefix "board_issue_limit_metric" = "limit_metric"
boardsPrefix "board_issue_label_name" = "name"
boardsPrefix "board_issue_label_color" = "color"
boardsPrefix "board_issue_label_description" = "description"
boardsPrefix "project_board_id" = "id"
boardsPrefix "project_board_name" = "name"
boardsPrefix "project_board_name_with_namespace" = "name_with_namespace"
boardsPrefix "project_board_path" = "path"
boardsPrefix "project_board_path_with_namespace" = "path_with_namespace"
boardsPrefix "project_board_http_url_to_repo" = "http_url_to_repo"
boardsPrefix "project_board_web_url" = "web_url"
boardsPrefix s = s
instance FromJSON TimeStats where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Issue where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON User where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Commit where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON CommitTodo where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Tag where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = tagPrefix
}
)
instance FromJSON Release where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = releasePrefix
}
)
instance FromJSON CommitStats where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Pipeline where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Member where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Permissions where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Owner where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Links where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Namespace where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Project where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON ProjectStats where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Repository where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Job where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Artifact where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Group where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON GroupShare where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Branch where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON RepositoryFile where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON MergeRequest where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Diff where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Version where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance ToJSON EditIssueReq where
toEncoding =
genericToEncoding
defaultOptions
{ fieldLabelModifier = drop (T.length "edit_issue_"),
omitNothingFields = True
}
instance FromJSON Discussion where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON Note where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = bodyNoPrefix
}
)
instance FromJSON IssueCounts where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = issueStatsPrefix
}
)
instance FromJSON IssueStats where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = issueStatsPrefix
}
)
instance FromJSON IssueStatistics where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = issueStatsPrefix
}
)
instance FromJSON IssueBoard where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = boardsPrefix
}
)
instance FromJSON BoardIssue where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = boardsPrefix
}
)
instance FromJSON BoardIssueLabel where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = boardsPrefix
}
)
instance FromJSON ProjectBoard where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = boardsPrefix
}
)
instance FromJSON TestReport where
parseJSON =
genericParseJSON defaultOptions
instance FromJSON TestSuite where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = testsuitePrefix
}
)
instance FromJSON TestCase where
parseJSON =
genericParseJSON
( defaultOptions
{ fieldLabelModifier = testcasePrefix
}
)