Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions src/Forgejo/API/Issue.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ module Forgejo.API.Issue
) where

import Data.Text (Text)
import Forgejo.Types.CreateIssueOption (CreateIssueApiOption)
import Forgejo.Types.Comment (Comment (..))
import Forgejo.Types.CreateIssueCommentOption
import Forgejo.Types.CreateIssueOption
import Forgejo.Types.Issue (Issue)
import GHC.Generics (Generic)
import Servant (Capture, JSON, PostCreated, ReqBody, type (:-), type (:>))

newtype IssueRoutes route = IssueRoutes
data IssueRoutes route = IssueRoutes
{ createIssueApi
:: route
:- "repos"
Expand All @@ -18,5 +20,16 @@ newtype IssueRoutes route = IssueRoutes
:> ReqBody '[JSON] CreateIssueApiOption
:> PostCreated '[JSON] [Issue]
-- ^ POST /repos/{owner}/{repo}/issues
, createIssueCommentApi
:: route
:- "repos"
:> Capture "owner" Text
:> Capture "repo" Text
:> "issues"
:> Capture "index" Int
:> "comments"
:> ReqBody '[JSON] CreateIssueCommentApiOption
:> PostCreated '[JSON] Comment
-- ^ POST /repos/{owner}/{repo}/issues/{index}/comments
}
deriving stock (Generic)
14 changes: 13 additions & 1 deletion src/Forgejo/Methods/Issue.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
module Forgejo.Methods.Issue
( createIssue
, createIssueComment
) where

import Forgejo.API (ForgejoRoutes (issues))
import Forgejo.API.Issue (IssueRoutes (createIssueApi))
import Forgejo.API.Issue (IssueRoutes (..))
import Forgejo.App (AppM, forgejo)
import Forgejo.Types.Comment (Comment)
import Forgejo.Types.CreateIssueCommentOption
import Forgejo.Types.CreateIssueOption
import Forgejo.Types.Issue (Issue)

Expand All @@ -15,3 +18,12 @@ createIssue :: CreateIssueOption -> AppM [Issue]
createIssue CreateIssueOption{..} = do
fg <- forgejo
createIssueApi (issues fg) cioOwner cioRepo cioApiJson

{- | This function creates a comment on an issue/PR on Forgejo via calling to
endpoint 'createIssueCommentApi' from 'IssueRoutes'. Takes one argument of
type 'CreateIssueCommentOption'.
-}
createIssueComment :: CreateIssueCommentOption -> AppM Comment
createIssueComment CreateIssueCommentOption{..} = do
fg <- forgejo
createIssueCommentApi (issues fg) ciscoOwner ciscoRepo ciscoIndex ciscoApiJson
56 changes: 17 additions & 39 deletions src/Forgejo/Types/CreateIssueCommentOption.hs
Original file line number Diff line number Diff line change
@@ -1,53 +1,31 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

module Forgejo.Types.CreateIssueCommentOption
( CreateIssueCommentOption (..)
, CreateIssueCommentOptionPayload (..)
, CreateIssueCommentApiOption (..)
) where

import Data.Aeson (FromJSON (..), ToJSON (..), genericToJSON, withObject, (.:))
import Data.Aeson (ToJSON (..), genericToJSON)
import Data.Aeson.Types (Options (..), camelTo2, defaultOptions)
import Data.Text (Text)
import Data.Time (UTCTime)
import GHC.Generics (Generic)

arpOptions :: Options
arpOptions = defaultOptions{fieldLabelModifier = camelTo2 '_' . drop 3}

runOptions :: Options
runOptions = defaultOptions{fieldLabelModifier = camelTo2 '_' . drop 3}
cicoOptions :: Options
cicoOptions = defaultOptions{fieldLabelModifier = camelTo2 '_' . drop 4}

data CreateIssueCommentOption = CreateIssueCommentOption
{ body :: Text
, updatedAt :: UTCTime
-- | The actual JSON body sent to Forgejo.
newtype CreateIssueCommentApiOption = CreateIssueCommentApiOption
{ cicoBody :: Text
}
deriving stock (Eq, Generic, Show)

-- Manual instance because Forgejo uses "ScheduleID" (capitalised) as the JSON key.
instance FromJSON CreateIssueCommentOption where
parseJSON = withObject "CreateIssueCommentOption" $ \o ->
CreateIssueCommentOption
<$> o .: "body"
<*> o .: "updated_at"

instance ToJSON CreateIssueCommentOption where
toJSON = genericToJSON runOptions
instance ToJSON CreateIssueCommentApiOption where
toJSON = genericToJSON cicoOptions

data CreateIssueCommentOptionPayload = CreateIssueCommentOptionPayload
{ arpAction :: Text
, arpRun :: CreateIssueCommentOption
, arpPriorStatus :: Text
{- | Wrapper carrying routing info alongside the request body,
mirroring CreateIssueOption's shape.
-}
data CreateIssueCommentOption = CreateIssueCommentOption
{ ciscoOwner :: Text
, ciscoRepo :: Text
, ciscoIndex :: Int
, ciscoApiJson :: CreateIssueCommentApiOption
}
deriving stock (Eq, Generic, Show)

instance FromJSON CreateIssueCommentOptionPayload where
parseJSON = withObject "CreateIssueCommentOptionPayload" $ \o ->
CreateIssueCommentOptionPayload
<$> o .: "action"
<*> o .: "run"
<*> o .: "prior_status"

instance ToJSON CreateIssueCommentOptionPayload where
toJSON = genericToJSON arpOptions