@@ -10,17 +10,19 @@ import Control.Arrow (first, (***))
1010import Control.Monad (when )
1111import Control.Monad.Error.Class (catchError )
1212
13- import Data.Monoid ((<>) )
1413import Data.Aeson ((.=) )
1514import Data.Aeson.BetterErrors
1615import Data.ByteString.Lazy (ByteString )
1716import Data.Either (isLeft , isRight )
18- import Data.Maybe (mapMaybe , fromMaybe )
17+ import Data.Maybe (mapMaybe , fromMaybe , maybeToList )
18+ import Data.Monoid ((<>) )
1919import Data.Text (Text )
20+ import Data.Time.Clock (UTCTime )
21+ import qualified Data.Time.Format as TimeFormat
2022import Data.Version
21- import qualified Data.Vector as V
2223import qualified Data.Aeson as A
2324import qualified Data.Text as T
25+ import qualified Data.Vector as V
2426
2527import qualified Language.PureScript as P
2628
@@ -40,6 +42,10 @@ data Package a = Package
4042 { pkgMeta :: PackageMeta
4143 , pkgVersion :: Version
4244 , pkgVersionTag :: Text
45+ -- TODO: When this field was introduced, it was given the Maybe type for the
46+ -- sake of backwards compatibility, as older JSON blobs will not include the
47+ -- field. It should eventually be changed to just UTCTime.
48+ , pkgTagTime :: Maybe UTCTime
4349 , pkgModules :: [Module ]
4450 , pkgBookmarks :: [Bookmark ]
4551 , pkgResolvedDependencies :: [(PackageName , Version )]
@@ -62,6 +68,7 @@ verifyPackage verifiedUser Package{..} =
6268 Package pkgMeta
6369 pkgVersion
6470 pkgVersionTag
71+ pkgTagTime
6572 pkgModules
6673 pkgBookmarks
6774 pkgResolvedDependencies
@@ -72,6 +79,29 @@ verifyPackage verifiedUser Package{..} =
7279packageName :: Package a -> PackageName
7380packageName = bowerName . pkgMeta
7481
82+ -- |
83+ -- The time format used for serializing package tag times in the JSON format.
84+ -- This is the ISO 8601 date format which includes a time and a timezone.
85+ --
86+ jsonTimeFormat :: String
87+ jsonTimeFormat = " %Y-%m-%dT%H:%M:%S%z"
88+
89+ -- |
90+ -- Convenience function for formatting a time in the format expected by this
91+ -- module.
92+ --
93+ formatTime :: UTCTime -> String
94+ formatTime =
95+ TimeFormat. formatTime TimeFormat. defaultTimeLocale jsonTimeFormat
96+
97+ -- |
98+ -- Convenience function for parsing a time in the format expected by this
99+ -- module.
100+ --
101+ parseTime :: String -> Maybe UTCTime
102+ parseTime =
103+ TimeFormat. parseTimeM False TimeFormat. defaultTimeLocale jsonTimeFormat
104+
75105data Module = Module
76106 { modName :: P. ModuleName
77107 , modComments :: Maybe Text
@@ -275,6 +305,7 @@ data PackageError
275305 | InvalidFixity
276306 | InvalidKind Text
277307 | InvalidDataDeclType Text
308+ | InvalidTime
278309 deriving (Show , Eq , Ord )
279310
280311type Bookmark = InPackage (P. ModuleName , Text )
@@ -320,13 +351,18 @@ asPackage minimumVersion uploader = do
320351 Package <$> key " packageMeta" asPackageMeta .! ErrorInPackageMeta
321352 <*> key " version" asVersion
322353 <*> key " versionTag" asText
354+ <*> keyMay " tagTime" (withString parseTimeEither)
323355 <*> key " modules" (eachInArray asModule)
324356 <*> key " bookmarks" asBookmarks .! ErrorInPackageMeta
325357 <*> key " resolvedDependencies" asResolvedDependencies
326358 <*> key " github" asGithub
327359 <*> key " uploader" uploader
328360 <*> pure compilerVersion
329361
362+ parseTimeEither :: String -> Either PackageError UTCTime
363+ parseTimeEither =
364+ maybe (Left InvalidTime ) Right . parseTime
365+
330366asUploadedPackage :: Version -> Parse PackageError UploadedPackage
331367asUploadedPackage minVersion = asPackage minVersion asNotYetKnown
332368
@@ -359,6 +395,8 @@ displayPackageError e = case e of
359395 " Invalid kind: \" " <> str <> " \" "
360396 InvalidDataDeclType str ->
361397 " Invalid data declaration type: \" " <> str <> " \" "
398+ InvalidTime ->
399+ " Invalid time"
362400
363401instance A. FromJSON a => A. FromJSON (Package a ) where
364402 parseJSON = toAesonParser displayPackageError
@@ -550,7 +588,7 @@ asSourceSpan = P.SourceSpan <$> key "name" asString
550588
551589instance A. ToJSON a => A. ToJSON (Package a ) where
552590 toJSON Package {.. } =
553- A. object
591+ A. object $
554592 [ " packageMeta" .= pkgMeta
555593 , " version" .= showVersion pkgVersion
556594 , " versionTag" .= pkgVersionTag
@@ -562,7 +600,8 @@ instance A.ToJSON a => A.ToJSON (Package a) where
562600 , " github" .= pkgGithub
563601 , " uploader" .= pkgUploader
564602 , " compilerVersion" .= showVersion P. version
565- ]
603+ ] ++
604+ fmap (\ t -> " tagTime" .= formatTime t) (maybeToList pkgTagTime)
566605
567606instance A. ToJSON NotYetKnown where
568607 toJSON _ = A. Null
0 commit comments