module CircleCI.Project (
getProjectsInfo
, ProjectInfo (..)
, BranchBuildInfo (..)
, BuildInfo (..)
, BuildStatus (..)
, module CircleCI.Common.Types
, module CircleCI.Common.Run
) where
import CircleCI.Common.URL
import CircleCI.Common.Types
import CircleCI.Common.HTTPS
import CircleCI.Common.Run
import Control.Monad ( mzero )
import Control.Monad.Except ( runExceptT )
import Control.Monad.Reader ( ask )
import Control.Monad.IO.Class ( liftIO )
import Data.Aeson
import Data.Aeson.Types
import Data.HashMap.Strict
import qualified Data.Proxy as P
import Data.Text ( Text )
import Data.Time.Clock ( UTCTime )
import Network.HTTP.Client ( Manager )
import Servant.API
import Servant.Client
getProjectsInfo :: CircleCIResponse [ProjectInfo]
getProjectsInfo = do
AccountAPIToken token <- ask
liftIO . runExceptT $ do
manager <- httpsManager
servantGetProjectsInfo (Just token)
manager
apiBaseUrl
data ProjectInfo = ProjectInfo {
language :: Text
, repositoryName :: Text
, repositoryUrl :: Text
, branches :: [BranchBuildInfo]
, defaultBranch :: Text
, isOpenSource :: Bool
, followed :: Bool
, gitHubUserName :: Text
, slackChannel :: Maybe Text
, slackWebhookUrl :: Maybe Text
, slackNotifyPreferenses :: Maybe Text
, slackSubdomain :: Maybe Text
, slackAPIToken :: Maybe Text
, hipchatNotifyPreferenses :: Maybe Text
, hipchatNotify :: Maybe Text
, hipchatAPIToken :: Maybe Text
, hipchatRoom :: Maybe Text
, ircServer :: Maybe Text
, ircKeyword :: Maybe Text
, ircChannel :: Maybe Text
, ircUsername :: Maybe Text
, ircPassword :: Maybe Text
, ircNotifyPreferenses :: Maybe Text
} deriving (Show)
instance FromJSON ProjectInfo where
parseJSON (Object o) = ProjectInfo
<$> o .: "language"
<*> o .: "reponame"
<*> o .: "vcs_url"
<*> (o .: "branches" >>= toBranchesBuildInfo)
<*> o .: "default_branch"
<*> o .: "oss"
<*> o .: "followed"
<*> o .: "username"
<*> o .:? "slack_channel"
<*> o .:? "slack_webhook_url"
<*> o .:? "slack_notify_prefs"
<*> o .:? "slack_subdomain"
<*> o .:? "slack_api_token"
<*> o .:? "hipchat_notify_prefs"
<*> o .:? "hipchat_notify"
<*> o .:? "hipchat_api_token"
<*> o .:? "hipchat_room"
<*> o .:? "irc_server"
<*> o .:? "irc_keyword"
<*> o .:? "irc_channel"
<*> o .:? "irc_username"
<*> o .:? "irc_password"
<*> o .:? "irc_notify_prefs"
parseJSON _ = mzero
toBranchesBuildInfo :: HashMap Text RawBranchBuildInfo -> Parser [BranchBuildInfo]
toBranchesBuildInfo rawBranchesBuildInfo = return
[BranchBuildInfo { branchName = aBranchName
, lastSuccessBuild = rawLastSuccessBuild rawBranchesBuild
, lastFailedBuild = rawLastFailedBuild rawBranchesBuild
, pusherLogins = rawPusherLogins rawBranchesBuild
, recentBuilds = rawRecentBuilds rawBranchesBuild
, runningBuilds = rawRunningBuilds rawBranchesBuild
}
| (aBranchName, rawBranchesBuild) <- toList rawBranchesBuildInfo]
data RawBranchBuildInfo = RawBranchBuildInfo {
rawLastSuccessBuild :: Maybe BuildInfo
, rawLastFailedBuild :: Maybe BuildInfo
, rawPusherLogins :: [Text]
, rawRecentBuilds :: Maybe [BuildInfo]
, rawRunningBuilds :: Maybe [BuildInfo]
} deriving (Eq, Show)
instance FromJSON RawBranchBuildInfo where
parseJSON (Object o) = RawBranchBuildInfo
<$> o .:? "last_success"
<*> o .:? "last_non_success"
<*> o .: "pusher_logins"
<*> o .:? "recent_builds"
<*> o .:? "running_builds"
parseJSON _ = mzero
data BranchBuildInfo = BranchBuildInfo {
branchName :: Text
, lastSuccessBuild :: Maybe BuildInfo
, lastFailedBuild :: Maybe BuildInfo
, pusherLogins :: [Text]
, recentBuilds :: Maybe [BuildInfo]
, runningBuilds :: Maybe [BuildInfo]
} deriving (Eq, Show)
data BuildInfo = BuildInfo {
status :: BuildStatus
, number :: Int
, commit :: Text
, pushDate :: UTCTime
, addingDate :: UTCTime
} deriving (Eq, Show)
instance FromJSON BuildInfo where
parseJSON (Object o) = BuildInfo
<$> (o .: "status" >>= toBuildStatus)
<*> o .: "build_num"
<*> o .: "vcs_revision"
<*> o .: "pushed_at"
<*> o .: "added_at"
parseJSON _ = mzero
toBuildStatus :: Text -> Parser BuildStatus
toBuildStatus "running" = return BuildRunning
toBuildStatus "success" = return BuildSuccess
toBuildStatus "failed" = return BuildFailed
toBuildStatus "canceled" = return BuildCanceled
toBuildStatus "no_tests" = return NoTests
toBuildStatus _ = return BuildSuccess
data BuildStatus = BuildRunning
| BuildSuccess
| BuildFailed
| BuildCanceled
| NoTests
deriving (Eq, Show)
type ProjectsInfoAPI = GetProjectsInfoCall
type GetProjectsInfoCall =
"projects"
:> QueryParam "circle-token" Token
:> Get '[JSON] [ProjectInfo]
servantGetProjectsInfo :: Maybe Token
-> Manager
-> BaseUrl
-> ClientM [ProjectInfo]
servantGetProjectsInfo = client projectsInfoAPI
projectsInfoAPI :: P.Proxy ProjectsInfoAPI
projectsInfoAPI = P.Proxy