@@ -1,10 +1,14 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE RecordWildCards #-}
3module ErrorsWarnings where
4module ErrorsWarnings where
6+import Control.Applicative ((<$>))
5import Data.Aeson.BetterErrors
7import Data.Aeson.BetterErrors
6import Data.Version
8import Data.Version
7import Data.Maybe
9import Data.Maybe
11+import Data.Foldable (foldMap)
8import Data.List (intersperse)
12import Data.List (intersperse)
9import Data.List.NonEmpty (NonEmpty(..))
13import Data.List.NonEmpty (NonEmpty(..))
10import qualified Data.List.NonEmpty as NonEmpty
14import qualified Data.List.NonEmpty as NonEmpty
@@ -31,6 +35,7 @@ data PackageError
31data PackageWarning
35data PackageWarning
32 = ResolutionNotVersion PackageName
36 = ResolutionNotVersion PackageName
33 | UndeclaredDependency PackageName
37 | UndeclaredDependency PackageName
38+ | UnacceptableVersion (PackageName, String)
34 deriving (Show)
39 deriving (Show)
36-- | An error that should be fixed by the user.
41-- | An error that should be fixed by the user.
@@ -247,32 +252,39 @@ displayOtherError e = case e of
247 successivelyIndented
252 successivelyIndented
248 [ "An IO exception occurred:", show exc ]
253 [ "An IO exception occurred:", show exc ]
250−renderWarnings :: [PackageWarning] -> Box
255+data CollectedWarnings = CollectedWarnings
251−renderWarnings =
256+ { resolutionNotVersions :: [PackageName]
252− collectWarnings
257+ , undeclaredDependencies :: [PackageName]
253− [ (getResolutionNotVersion, warnResolutionNotVersions)
258+ , unacceptableVersions :: [(PackageName, String)]
254− , (getUndeclaredDependency, warnUndeclaredDependencies)
259+ }
255− ]
260+ deriving (Show, Eq, Ord)
257− collectWarnings patterns warns =
258− let boxes = mapMaybe (collectWarnings' warns) patterns
261− , indented (vcat (intersperse spacer boxes))
263− in if null boxes then nullBox else result
265− getResolutionNotVersion (ResolutionNotVersion n) = Just n
262+instance Monoid CollectedWarnings where
266− getResolutionNotVersion _ = Nothing
263+ mempty = CollectedWarnings mempty mempty mempty
264+ mappend (CollectedWarnings as bs cs) (CollectedWarnings as' bs' cs') =
265+ CollectedWarnings (as <> as') (bs <> bs') (cs <> cs')
267+collectWarnings :: [PackageWarning] -> CollectedWarnings
268+collectWarnings = foldMap singular
270+ singular w = case w of
271+ ResolutionNotVersion pn -> CollectedWarnings [pn] [] []
268− getUndeclaredDependency (UndeclaredDependency n) = Just n
272+ UndeclaredDependency pn -> CollectedWarnings [] [pn] []
269− getUndeclaredDependency _ = Nothing
273+ UnacceptableVersion t -> CollectedWarnings [] [] [t]
271−collectWarnings' :: [PackageWarning] -> ((PackageWarning -> Maybe a), (NonEmpty a -> Box)) -> Maybe Box
275+renderWarnings :: [PackageWarning] -> Box
272−collectWarnings' warns (pattern, render) =
276+renderWarnings warns =
273− case mapMaybe pattern warns of
277+ let CollectedWarnings{..} = collectWarnings warns
274− [] -> Nothing
278+ go toBox warns' = toBox <$> NonEmpty.nonEmpty warns'
275− (x:xs) -> Just (render (x :| xs))
279+ mboxes = [ go warnResolutionNotVersions resolutionNotVersions
280+ , go warnUndeclaredDependencies undeclaredDependencies
281+ , go warnUnacceptableVersions unacceptableVersions
283+ in case catMaybes mboxes of
285+ boxes -> vcat [ para "Warnings:"
286+ , indented (vcat (intersperse spacer boxes))
277warnResolutionNotVersions :: NonEmpty PackageName -> Box
289warnResolutionNotVersions :: NonEmpty PackageName -> Box
278warnResolutionNotVersions pkgNames =
290warnResolutionNotVersions pkgNames =
@@ -314,5 +326,34 @@ warnUndeclaredDependencies pkgNames =
315 bulletedList runPackageName (NonEmpty.toList pkgNames)
327 bulletedList runPackageName (NonEmpty.toList pkgNames)
329+warnUnacceptableVersions :: NonEmpty (PackageName, String) -> Box
330+warnUnacceptableVersions pkgs =
331+ let singular = NonEmpty.length pkgs == 1
332+ pl a b = if singular then b else a
334+ packages' = pl "packages'" "package's"
335+ packages = pl "packages" "package"
336+ anyOfThese = pl "any of these" "this"
337+ these = pl "these" "this"
338+ versions = pl "versions" "version"
341+ [ "The following installed Bower ", packages', " ", versions, " could "
345+ bulletedList showTuple (NonEmpty.toList pkgs)
349+ ["Links to types in ", anyOfThese, " ", packages, " will not work. In "
350+ , "order to make links work, edit your bower.json to specify an "
351+ , "acceptable version or version range for ", these, " ", packages, ", "
352+ , "and rerun `bower install`."
356+ showTuple (pkgName, tag) = runPackageName pkgName ++ "#" ++ tag
317printWarnings :: [PackageWarning] -> IO ()
358printWarnings :: [PackageWarning] -> IO ()
318printWarnings = printToStderr . renderWarnings
359printWarnings = printToStderr . renderWarnings