@@ -8,10 +8,11 @@ import Prelude hiding (userError)
8import Data.Maybe
8import Data.Maybe
9import Data.Char (isSpace)
9import Data.Char (isSpace)
10import Data.String (fromString)
10import Data.String (fromString)
11−import Data.List (stripPrefix, isSuffixOf, (\\))
11+import Data.List (stripPrefix, isSuffixOf, (\\), nubBy)
12import Data.List.Split (splitOn)
12import Data.List.Split (splitOn)
13import Data.List.NonEmpty (NonEmpty(..))
13import Data.List.NonEmpty (NonEmpty(..))
14import Data.Version
14import Data.Version
15+import Data.Function (on)
15import Safe (headMay)
16import Safe (headMay)
17import qualified Data.ByteString.Lazy.Char8 as BL
18import qualified Data.ByteString.Lazy.Char8 as BL
@@ -196,18 +197,35 @@ getResolvedDependencies :: [PackageName] -> PrepareM [(PackageName, Version)]
196getResolvedDependencies declaredDeps = do
197getResolvedDependencies declaredDeps = do
197 depsBS <- fromString <$> readProcess' "bower" ["list", "--json", "--offline"] ""
198 depsBS <- fromString <$> readProcess' "bower" ["list", "--json", "--offline"] ""
199− deps <- catchLeft (parse asBowerResolvedDependencies depsBS)
200+ -- Check for undeclared dependencies
200− (internalError . JSONError FromBowerList)
201+ toplevels <- catchJSON (parse asToplevelDependencies depsBS)
202+ warnUndeclared declaredDeps toplevels
202− warnUndeclared declaredDeps (map fst deps)
204+ deps <- catchJSON (parse asResolvedDependencies depsBS)
203 handleDeps deps
205 handleDeps deps
206− asBowerResolvedDependencies ::
208+ catchJSON = flip catchLeft (internalError . JSONError FromBowerList)
210+-- | Extracts all dependencies and their versions from
211+-- `bower list --json --offline`
207− Parse BowerError [(PackageName, DependencyStatus)]
212+asResolvedDependencies :: Parse BowerError [(PackageName, DependencyStatus)]
208− asBowerResolvedDependencies =
213+asResolvedDependencies = nubBy ((==) `on` fst) <$> go
216+ fmap (fromMaybe []) $
217+ keyMay "dependencies" $
218+ (++) <$> eachInObjectWithKey (parsePackageName . T.unpack)
220+ <*> (concatMap snd <$> eachInObject asResolvedDependencies)
222+-- | Extracts only the top level dependency names from the output of
223+-- `bower list --json --offline`
224+asToplevelDependencies :: Parse BowerError [PackageName]
225+asToplevelDependencies =
209− key "dependencies"
227+ key "dependencies" $
210− (eachInObjectWithKey (parsePackageName . T.unpack) asDependencyStatus)
228+ eachInObjectWithKey (parsePackageName . T.unpack) (return ())
212asDependencyStatus :: Parse e DependencyStatus
230asDependencyStatus :: Parse e DependencyStatus
213asDependencyStatus = do
231asDependencyStatus = do