Skip to content

Commit 4230a90

Browse files
committedSep 29, 2021
Split data types in proper modules
Change-Id: Idea7bda38ab6f913d23205a642b7a77136162cd6
1 parent 1f13d97 commit 4230a90

File tree

9 files changed

+258
-234
lines changed

9 files changed

+258
-234
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist-newstyle/

‎gerrit.cabal

+4-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ library
5454

5555
hs-source-dirs: src
5656
exposed-modules: Gerrit
57-
, Gerrit.Data
58-
, Gerrit.Event
57+
, Gerrit.Data.Review
58+
, Gerrit.Data.Change
59+
, Gerrit.Data.Account
60+
, Gerrit.Data.Event
5961
other-modules: Gerrit.Client
6062

6163
test-suite gerrit-test

‎src/Gerrit.hs

+6-4
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ import Data.Maybe (fromMaybe)
3636
import Data.Text (Text)
3737
import qualified Data.Text as T
3838
import Gerrit.Client
39-
import Gerrit.Data
39+
import Gerrit.Data.Account
40+
import Gerrit.Data.Change
41+
import Gerrit.Data.Review
4042
import Network.HTTP.Client (HttpException)
4143

4244
-- | Return the url of a 'GerritChange'
@@ -84,8 +86,8 @@ postReview ::
8486
postReview change message label value' = gerritPost urlPath review
8587
where
8688
urlPath = "changes/" <> changeId <> "/revisions/" <> revHash <> "/review"
87-
changeId = Gerrit.Data.id change
88-
revHash = fromMaybe "" (Gerrit.Data.current_revision change)
89+
changeId = Gerrit.Data.Change.id change
90+
revHash = fromMaybe "" (Gerrit.Data.Change.current_revision change)
8991
review =
9092
ReviewInput
9193
{ riMessage = Just message,
@@ -97,7 +99,7 @@ hasLabel :: T.Text -> Int -> GerritChange -> Bool
9799
hasLabel label labelValue change = case M.lookup label (labels change) of
98100
Just gerritLabel ->
99101
(> 0) $
100-
length $ filter (\vote -> fromMaybe 0 (value vote) == labelValue) (Gerrit.Data.all gerritLabel)
102+
length $ filter (\vote -> fromMaybe 0 (value vote) == labelValue) (Gerrit.Data.Change.all gerritLabel)
101103
_ -> False
102104

103105
-- | Get user account id

‎src/Gerrit/Data.hs

-224
This file was deleted.

‎src/Gerrit/Data/Account.hs

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{-# LANGUAGE DerivingStrategies #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
4+
module Gerrit.Data.Account
5+
( GerritAccountId (..),
6+
GerritAccount (..),
7+
GerritAccountQuery (..),
8+
userQueryText,
9+
)
10+
where
11+
12+
import Control.Monad (mzero)
13+
import Data.Aeson
14+
import Data.Text (Text)
15+
import qualified Data.Text as T
16+
17+
-- https://gerrit-review.googlesource.com/Documentation/user-search-accounts.html#_search_operators
18+
data GerritAccountQuery
19+
= CanSee Text
20+
| Email Text
21+
| Name Text
22+
| Username Text
23+
| IsActive
24+
| IsInactive
25+
26+
userQueryText :: GerritAccountQuery -> Text
27+
userQueryText guq = case guq of
28+
CanSee change -> "cansee:" <> change
29+
Email email -> "email:" <> email
30+
Name name -> "name:" <> escapeChar name
31+
Username username -> "username:" <> username
32+
IsActive -> "is:active"
33+
IsInactive -> "is:inactive"
34+
where
35+
escapeChar = T.replace "'" " "
36+
37+
data GerritAccountId = GerritAccountId
38+
{ gerritAccountId' :: Int,
39+
gerritAccountHasMore' :: Maybe Bool
40+
}
41+
deriving (Eq, Show)
42+
43+
instance FromJSON GerritAccountId where
44+
parseJSON (Object v) = GerritAccountId <$> v .: "_account_id" <*> v .:? "_more_accounts"
45+
parseJSON _ = mzero
46+
47+
data GerritAccount = GerritAccount
48+
{ gerritAccountId :: Int,
49+
gerritAccountName :: Text,
50+
gerritAccountUsername :: Maybe Text,
51+
gerritAccountEmail :: Maybe Text,
52+
gerritAccountHasMore :: Maybe Bool
53+
}
54+
deriving (Eq, Show)
55+
56+
instance FromJSON GerritAccount where
57+
parseJSON (Object v) =
58+
GerritAccount
59+
<$> v .: "_account_id"
60+
<*> v .: "name"
61+
<*> v .:? "username"
62+
<*> v .:? "email"
63+
<*> v .:? "_more_accounts"
64+
parseJSON _ = mzero

‎src/Gerrit/Data/Change.hs

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
{-# LANGUAGE DeriveAnyClass #-}
2+
{-# LANGUAGE DeriveGeneric #-}
3+
{-# LANGUAGE DerivingStrategies #-}
4+
{-# LANGUAGE OverloadedStrings #-}
5+
6+
module Gerrit.Data.Change
7+
( GerritQuery (..),
8+
GerritChangeStatus (..),
9+
GerritChange (..),
10+
GerritRevision (..),
11+
GerritDetailedLabelVote (..),
12+
GerritDetailedLabel (..),
13+
14+
-- * Convenient functions
15+
queryText,
16+
)
17+
where
18+
19+
import Data.Aeson
20+
import qualified Data.Map as M
21+
import Data.Text (Text)
22+
import qualified Data.Text as T
23+
import GHC.Generics (Generic)
24+
25+
aesonOptions :: Options
26+
aesonOptions = defaultOptions {fieldLabelModifier = recordToJson}
27+
where
28+
recordToJson "number" = "_number"
29+
recordToJson "account_id" = "_account_id"
30+
recordToJson n = n
31+
32+
-- https://gerrit-review.googlesource.com/Documentation/user-search.html
33+
data GerritQuery
34+
= Status GerritChangeStatus
35+
| Owner Text
36+
| CommitMessage Text
37+
| Project Text
38+
| ChangeId Text
39+
40+
-- | Convert a GerritQuery object to the search terms
41+
queryText :: GerritQuery -> Text
42+
queryText (Status stat) = "status:" <> T.toLower (T.pack $ show stat)
43+
queryText (Owner owner) = "owner:" <> owner
44+
queryText (CommitMessage message) = "message:" <> message
45+
queryText (Project project') = "project:" <> project'
46+
queryText (ChangeId changeId) = "change:" <> changeId
47+
48+
data GerritChangeStatus = NEW | MERGED | ABANDONED | DRAFT
49+
deriving (Eq, Show, Generic, FromJSON)
50+
51+
-- https://gerrit-review.googlesource.com/Documentation/json.html
52+
data GerritRevisionKind = REWORK | TRIVIAL_REBASE | MERGE_FIRST_PARENT_UPDATE | NO_CODE_CHANGE | NO_CHANGE
53+
deriving (Eq, Show, Generic, FromJSON)
54+
55+
data GerritRevision = GerritRevision
56+
{ ref :: Text,
57+
kind :: GerritRevisionKind
58+
}
59+
deriving (Show, Generic, FromJSON)
60+
61+
data GerritDetailedLabelVote = GerritDetailedLabelVote
62+
{ value :: Maybe Int,
63+
account_id :: Int
64+
}
65+
deriving (Show, Generic)
66+
67+
instance FromJSON GerritDetailedLabelVote where
68+
parseJSON = genericParseJSON aesonOptions
69+
70+
data GerritDetailedLabel = GerritDetailedLabel
71+
{ all :: [GerritDetailedLabelVote],
72+
default_value :: Int
73+
}
74+
deriving (Show, Generic, FromJSON)
75+
76+
data GerritChange = GerritChange
77+
{ id :: Text,
78+
project :: Text,
79+
branch :: Text,
80+
subject :: Text,
81+
status :: GerritChangeStatus,
82+
mergeable :: Maybe Bool,
83+
revisions :: M.Map Text (Maybe GerritRevision),
84+
current_revision :: Maybe Text,
85+
number :: Int,
86+
labels :: M.Map Text GerritDetailedLabel
87+
}
88+
deriving (Show, Generic)
89+
90+
instance FromJSON GerritChange where
91+
parseJSON = genericParseJSON aesonOptions

‎src/Gerrit/Event.hs ‎src/Gerrit/Data/Event.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{-# LANGUAGE RecordWildCards #-}
44

55
-- | Gerrit stream event data type
6-
module Gerrit.Event
6+
module Gerrit.Data.Event
77
( -- * Main event data types
88
EventType (..),
99
Event (..),

‎src/Gerrit/Data/Review.hs

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
{-# LANGUAGE DeriveAnyClass #-}
2+
{-# LANGUAGE DeriveGeneric #-}
3+
{-# LANGUAGE DerivingStrategies #-}
4+
{-# LANGUAGE OverloadedStrings #-}
5+
6+
-- | This module contains the gerrit data type
7+
module Gerrit.Data.Review
8+
( GerritVersion (..),
9+
GerritLabel (..),
10+
GerritReviewAccount (..),
11+
GerritLabelVote (..),
12+
ReviewResult (..),
13+
ReviewInput (..),
14+
)
15+
where
16+
17+
import Data.Aeson
18+
import Data.Char (isUpper, toLower)
19+
import qualified Data.Map as M
20+
import Data.Text (Text)
21+
import GHC.Generics (Generic)
22+
23+
newtype GerritVersion = GerritVersion Text
24+
deriving (Show, Generic)
25+
deriving anyclass (FromJSON)
26+
27+
data GerritLabelVote = REJECTED | APPROVED | DISLIKED | RECOMMENDED
28+
deriving (Eq, Show, Ord, Generic)
29+
30+
-- We use a custom parseJSON to decode Label Vote as lowercase
31+
instance FromJSON GerritLabelVote where
32+
parseJSON = genericParseJSON defaultOptions {fieldLabelModifier = map toLower}
33+
34+
instance FromJSONKey GerritLabelVote where
35+
fromJSONKey = genericFromJSONKey defaultJSONKeyOptions {keyModifier = map toLower}
36+
37+
-- | Modify record attribute to match json schema
38+
-- Remove the prefix and use snakecase
39+
customParseJSON :: String -> Options
40+
customParseJSON prefix = defaultOptions {fieldLabelModifier = recordToJson}
41+
where
42+
recordToJson = updateCase . drop (length prefix)
43+
updateCase [] = []
44+
updateCase (x : xs) = toLower x : updateCase' xs
45+
updateCase' [] = []
46+
updateCase' (x : xs)
47+
| isUpper x = '_' : toLower x : updateCase' xs
48+
| otherwise = x : updateCase' xs
49+
50+
-- https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html
51+
data ReviewResult = ReviewResult
52+
{ rrLabels :: Maybe (M.Map Text Int),
53+
rrReady :: Maybe Int
54+
}
55+
deriving (Eq, Show, Ord, Generic)
56+
57+
instance FromJSON ReviewResult where
58+
parseJSON = genericParseJSON $ customParseJSON "rr"
59+
60+
instance ToJSON ReviewResult where
61+
toJSON = genericToJSON $ customParseJSON "rr"
62+
63+
data ReviewInput = ReviewInput
64+
{ riMessage :: Maybe Text,
65+
riLabels :: Maybe (M.Map Text Int)
66+
}
67+
deriving (Eq, Show, Ord, Generic)
68+
69+
instance FromJSON ReviewInput where
70+
parseJSON = genericParseJSON $ customParseJSON "ri"
71+
72+
instance ToJSON ReviewInput where
73+
toJSON = genericToJSON $ (customParseJSON "ri") {omitNothingFields = True}
74+
75+
newtype GerritReviewAccount = GerritReviewAccount
76+
{ unused_account_id :: Int
77+
}
78+
deriving (Show, Generic)
79+
80+
-- We use a cusom parseJSON to decode `_account_id` as `account_id`
81+
instance FromJSON GerritReviewAccount where
82+
parseJSON = genericParseJSON defaultOptions
83+
84+
newtype GerritLabel
85+
= GerritLabel (M.Map GerritLabelVote GerritReviewAccount)
86+
deriving (Show, Generic)
87+
deriving anyclass (FromJSON)

‎test/Spec.hs

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import Data.ByteString.Lazy (ByteString)
88
import qualified Data.ByteString.Lazy as BSL
99
import Data.Maybe (fromJust)
1010
import Gerrit
11-
import Gerrit.Data as Gerrit
12-
import qualified Gerrit.Event as Event
11+
import Gerrit.Data.Change
12+
import qualified Gerrit.Data.Event as Event
13+
import Gerrit.Data.Review
1314
import System.Directory (listDirectory)
1415
import Test.Tasty
1516
import Test.Tasty.HUnit
@@ -74,7 +75,7 @@ encodingTests dataFiles client =
7475
]
7576
where
7677
prettyEncode obj = encode obj <> "\n"
77-
reviewInput = Gerrit.ReviewInput (Just "Thanks!") Nothing
78+
reviewInput = ReviewInput (Just "Thanks!") Nothing
7879
getRaw :: FilePath -> ByteString
7980
getRaw fp = fromJust $ lookup fp dataFiles
8081
isReviewResult :: Maybe ReviewResult -> Bool

0 commit comments

Comments
 (0)
Please sign in to comment.