@@ -10,7 +10,8 @@ module Language.PureScript.Docs.Types
12import Control.Arrow (first, (***))
12import Control.Arrow (first, (***))
13−import Control.Applicative ((<$>), (<*>))
13+import Control.Applicative ((<$>), (<*>), pure)
14+import Control.Monad (when)
14import Data.Functor ((<$))
15import Data.Functor ((<$))
15import Data.Maybe (mapMaybe)
16import Data.Maybe (mapMaybe)
16import Data.Version
17import Data.Version
@@ -22,7 +23,7 @@ import Data.Text (Text)
22import Data.ByteString.Lazy (ByteString)
23import Data.ByteString.Lazy (ByteString)
23import qualified Data.Text as T
24import qualified Data.Text as T
25−import Web.Bower.PackageMeta hiding (Version)
26+import Web.Bower.PackageMeta hiding (Version, displayError)
27import qualified Language.PureScript as P
28import qualified Language.PureScript as P
@@ -43,6 +44,9 @@ data Package a = Package
43 , pkgResolvedDependencies :: [(PackageName, Version)]
44 , pkgResolvedDependencies :: [(PackageName, Version)]
44 , pkgGithub :: (GithubUser, GithubRepo)
45 , pkgGithub :: (GithubUser, GithubRepo)
45 , pkgUploader :: a
46 , pkgUploader :: a
47+ , pkgCompilerVersion :: Version
48+ -- ^ The version of the PureScript compiler which was used to generate
49+ -- this data. We store this in order to reject packages which are too old.
47 deriving (Show, Eq, Ord)
51 deriving (Show, Eq, Ord)
@@ -62,6 +66,7 @@ verifyPackage verifiedUser Package{..} =
62 pkgResolvedDependencies
66 pkgResolvedDependencies
64 verifiedUser
68 verifiedUser
66packageName :: Package a -> PackageName
71packageName :: Package a -> PackageName
67packageName = bowerName . pkgMeta
72packageName = bowerName . pkgMeta
@@ -170,7 +175,10 @@ newtype GithubRepo
170 deriving (Show, Eq, Ord)
175 deriving (Show, Eq, Ord)
172data PackageError
177data PackageError
178+ = CompilerTooOld Version Version
179+ -- ^ Minimum allowable version for generating data with the current
180+ -- parser, and actual version used.
173− = ErrorInPackageMeta BowerError
181+ | ErrorInPackageMeta BowerError
174 | InvalidVersion
182 | InvalidVersion
175 | InvalidDeclarationType String
183 | InvalidDeclarationType String
176 | InvalidChildDeclarationType String
184 | InvalidChildDeclarationType String
@@ -204,14 +212,21 @@ ignorePackage (FromDep _ x) = x
204----------------------
212----------------------
205-- Parsing
213-- Parsing
207−parseUploadedPackage :: ByteString -> Either (ParseError PackageError) UploadedPackage
215+parseUploadedPackage :: Version -> ByteString -> Either (ParseError PackageError) UploadedPackage
208−parseUploadedPackage = parse asUploadedPackage
216+parseUploadedPackage minVersion = parse $ asUploadedPackage minVersion
210−parseVerifiedPackage :: ByteString -> Either (ParseError PackageError) VerifiedPackage
218+parseVerifiedPackage :: Version -> ByteString -> Either (ParseError PackageError) VerifiedPackage
211−parseVerifiedPackage = parse asVerifiedPackage
219+parseVerifiedPackage minVersion = parse $ asVerifiedPackage minVersion
221+asPackage :: Version -> (forall e. Parse e a) -> Parse PackageError (Package a)
222+asPackage minimumVersion uploader = do
223+ -- If the compilerVersion key is missing, we can be sure that it was produced
224+ -- with 0.7.0.0, since that is the only released version that included the
225+ -- psc-publish tool before this key was added.
226+ compilerVersion <- keyOrDefault "compilerVersion" (Version [0,7,0,0] []) asVersion
227+ when (compilerVersion < minimumVersion)
228+ (throwCustomError $ CompilerTooOld minimumVersion compilerVersion)
213−asPackage :: (forall e. Parse e a) -> Parse PackageError (Package a)
215 Package <$> key "packageMeta" asPackageMeta .! ErrorInPackageMeta
230 Package <$> key "packageMeta" asPackageMeta .! ErrorInPackageMeta
216 <*> key "version" asVersion
231 <*> key "version" asVersion
217 <*> key "versionTag" asString
232 <*> key "versionTag" asString
@@ -220,9 +235,10 @@ asPackage uploader =
220 <*> key "resolvedDependencies" asResolvedDependencies
235 <*> key "resolvedDependencies" asResolvedDependencies
221 <*> key "github" asGithub
236 <*> key "github" asGithub
222 <*> key "uploader" uploader
237 <*> key "uploader" uploader
238+ <*> pure compilerVersion
224−asUploadedPackage :: Parse PackageError UploadedPackage
240+asUploadedPackage :: Version -> Parse PackageError UploadedPackage
225−asUploadedPackage = asPackage asNotYetKnown
241+asUploadedPackage minVersion = asPackage minVersion asNotYetKnown
227asNotYetKnown :: Parse e NotYetKnown
243asNotYetKnown :: Parse e NotYetKnown
228asNotYetKnown = NotYetKnown <$ asNull
244asNotYetKnown = NotYetKnown <$ asNull
@@ -230,32 +246,42 @@ asNotYetKnown = NotYetKnown <$ asNull
230instance A.FromJSON NotYetKnown where
246instance A.FromJSON NotYetKnown where
231 parseJSON = toAesonParser' asNotYetKnown
247 parseJSON = toAesonParser' asNotYetKnown
233−asVerifiedPackage :: Parse PackageError VerifiedPackage
249+asVerifiedPackage :: Version -> Parse PackageError VerifiedPackage
234−asVerifiedPackage = asPackage asGithubUser
250+asVerifiedPackage minVersion = asPackage minVersion asGithubUser
236displayPackageError :: PackageError -> Text
252displayPackageError :: PackageError -> Text
237displayPackageError e = case e of
253displayPackageError e = case e of
254+ CompilerTooOld minV usedV ->
255+ "Expecting data produced by at least version " <> T.pack (showVersion minV)
256+ <> " of the compiler, but it appears that " <> T.pack (showVersion usedV)
258+ ErrorInPackageMeta err ->
238− ErrorInPackageMeta err -> "Error in package metadata: " <> showBowerError err
259+ "Error in package metadata: " <> showBowerError err
239− InvalidVersion -> "Invalid version"
260+ InvalidVersion ->
262+ InvalidDeclarationType str ->
240− InvalidDeclarationType str -> "Invalid declaration type: \"" <> T.pack str <> "\""
263+ "Invalid declaration type: \"" <> T.pack str <> "\""
264+ InvalidChildDeclarationType str ->
241− InvalidChildDeclarationType str -> "Invalid child declaration type: \"" <> T.pack str <> "\""
265+ "Invalid child declaration type: \"" <> T.pack str <> "\""
242− InvalidFixity -> "Invalid fixity"
266+ InvalidFixity ->
243− InvalidKind str -> "Invalid kind: \"" <> T.pack str <> "\""
269+ "Invalid kind: \"" <> T.pack str <> "\""
270+ InvalidDataDeclType str ->
244− InvalidDataDeclType str -> "Invalid data declaration type: \"" <> T.pack str <> "\""
271+ "Invalid data declaration type: \"" <> T.pack str <> "\""
246 (<>) = T.append
273 (<>) = T.append
275+instance A.FromJSON a => A.FromJSON (Package a) where
276+ parseJSON = toAesonParser displayPackageError
277+ (asPackage (Version [0,0,0,0] []) fromAesonParser)
248asGithubUser :: Parse e GithubUser
279asGithubUser :: Parse e GithubUser
249asGithubUser = GithubUser <$> asString
280asGithubUser = GithubUser <$> asString
251instance A.FromJSON GithubUser where
282instance A.FromJSON GithubUser where
252 parseJSON = toAesonParser' asGithubUser
283 parseJSON = toAesonParser' asGithubUser
254−instance A.FromJSON a => A.FromJSON (Package a) where
255− -- TODO: actual error display
256− parseJSON = toAesonParser (T.pack . show)
257− (asPackage fromAesonParser)
259asVersion :: Parse PackageError Version
285asVersion :: Parse PackageError Version
260asVersion = withString (maybe (Left InvalidVersion) Right . parseVersion')
286asVersion = withString (maybe (Left InvalidVersion) Right . parseVersion')
@@ -408,6 +434,7 @@ instance A.ToJSON a => A.ToJSON (Package a) where
408 pkgResolvedDependencies
434 pkgResolvedDependencies
409 , "github" .= pkgGithub
435 , "github" .= pkgGithub
410 , "uploader" .= pkgUploader
436 , "uploader" .= pkgUploader
437+ , "compilerVersion" .= showVersion P.version
413instance A.ToJSON NotYetKnown where
440instance A.ToJSON NotYetKnown where