Skip to content

Commit cd2a45a

Browse files
committed
Make binDist search components recursively
1 parent 903031b commit cd2a45a

File tree

2 files changed

+45
-20
lines changed

2 files changed

+45
-20
lines changed

src/Hedgehog/Extras/Internal/Plan.hs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
{-# LANGUAGE DeriveGeneric #-}
22
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE RecordWildCards #-}
4+
{-# LANGUAGE NoFieldSelectors #-}
35

46
module Hedgehog.Extras.Internal.Plan
57
( Plan(..)
68
, Component(..)
79
) where
810

911
import Control.Applicative
12+
import Control.Monad
1013
import Data.Aeson
14+
import qualified Data.Aeson as A
15+
import qualified Data.Aeson.KeyMap as M
1116
import Data.Eq
1217
import Data.Function
1318
import Data.Maybe
@@ -18,6 +23,7 @@ import Text.Show
1823
data Component = Component
1924
{ componentName :: Maybe Text
2025
, binFile :: Maybe Text
26+
, components :: [Component]
2127
}
2228
deriving (Generic, Eq, Show)
2329

@@ -31,6 +37,14 @@ instance FromJSON Plan where
3137
<$> v .: "install-plan"
3238

3339
instance FromJSON Component where
34-
parseJSON = withObject "Plan" $ \v -> Component
35-
<$> v .:? "component-name"
36-
<*> v .:? "bin-file"
40+
parseJSON = withObject "Plan" $ \v -> do
41+
componentName <- v .:? "component-name"
42+
binFile <- v .:? "bin-file"
43+
componentsTuples <- join . maybeToList . fmap M.toAscList <$> v .:? "components"
44+
-- sub-components are an object with components name as a key
45+
components <- forM componentsTuples $ \(subComponentName, subComponent) ->
46+
parseJSON $
47+
A.Object $
48+
M.insert "component-name" (toJSON subComponentName) subComponent
49+
pure Component{..}
50+

src/Hedgehog/Extras/Test/Process.hs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
{-# LANGUAGE DeriveGeneric #-}
2+
{-# LANGUAGE LambdaCase #-}
3+
{-# LANGUAGE NamedFieldPuns #-}
24
{-# LANGUAGE OverloadedStrings #-}
35
{-# LANGUAGE ScopedTypeVariables #-}
46
{-# LANGUAGE TypeApplications #-}
@@ -25,20 +27,21 @@ module Hedgehog.Extras.Test.Process
2527
, defaultExecConfig
2628
) where
2729

28-
import Control.Monad (Monad (..), MonadFail (fail), void, unless)
30+
import Control.Applicative (pure, (<|>))
31+
import Control.Monad (Monad (..), MonadFail (fail), unless, void)
2932
import Control.Monad.Catch (MonadCatch)
3033
import Control.Monad.IO.Class (MonadIO, liftIO)
3134
import Control.Monad.Trans.Resource (MonadResource, ReleaseKey, register)
3235
import Data.Aeson (eitherDecode)
33-
import Data.Bool (Bool (..))
36+
import Data.Bool (Bool (True), otherwise)
3437
import Data.Either (Either (..))
3538
import Data.Eq (Eq (..))
36-
import Data.Function (($), (&), (.))
39+
import Data.Function (($), (.))
3740
import Data.Functor ((<$>))
3841
import Data.Int (Int)
3942
import Data.Maybe (Maybe (..))
4043
import Data.Monoid (Last (..), mempty, (<>))
41-
import Data.String (String)
44+
import Data.String (IsString (..), String)
4245
import GHC.Generics (Generic)
4346
import GHC.Stack (HasCallStack)
4447
import Hedgehog (MonadTest)
@@ -55,6 +58,7 @@ import Text.Show (Show (show))
5558

5659
import qualified Data.ByteString.Lazy as LBS
5760
import qualified Data.List as L
61+
import Data.Text (Text)
5862
import qualified Data.Text as T
5963
import qualified GHC.Stack as GHC
6064
import qualified Hedgehog as H
@@ -308,19 +312,26 @@ binDist pkg binaryEnv = do
308312
<> "\" if you are working with sources. Otherwise define "
309313
<> binaryEnv
310314
<> " and have it point to the executable you want."
311-
contents <- H.evalIO . LBS.readFile $ planJsonFile
312-
313-
case eitherDecode contents of
314-
Right plan -> case L.filter matching (plan & installPlan) of
315-
(component:_) -> case component & binFile of
316-
Just bin -> return $ addExeSuffix (T.unpack bin)
317-
Nothing -> error $ "missing \"bin-file\" key in plan component: " <> show component <> " in the plan in: " <> planJsonFile
318-
[] -> error $ "Cannot find \"component-name\" key with the value \"exe:" <> pkg <> "\" in the plan in: " <> planJsonFile
319-
Left message -> error $ "Cannot decode plan in " <> planJsonFile <> ": " <> message
320-
where matching :: Component -> Bool
321-
matching component = case componentName component of
322-
Just name -> name == "exe:" <> T.pack pkg
323-
Nothing -> False
315+
316+
Plan{installPlan} <- eitherDecode <$> H.evalIO (LBS.readFile planJsonFile)
317+
>>= \case
318+
Left message -> error $ "Cannot decode plan in " <> planJsonFile <> ": " <> message
319+
Right plan -> pure plan
320+
321+
let componentName = "exe:" <> fromString pkg
322+
case findComponent componentName installPlan of
323+
Just Component{binFile=Just binFilePath} -> pure . addExeSuffix $ T.unpack binFilePath
324+
Just component@Component{binFile=Nothing} ->
325+
error $ "missing \"bin-file\" key in plan component: " <> show component <> " in the plan in: " <> planJsonFile
326+
Nothing ->
327+
error $ "Cannot find \"component-name\" key with the value \"exe:" <> pkg <> "\" in the plan in: " <> planJsonFile
328+
where
329+
findComponent :: Text -> [Component] -> Maybe Component
330+
findComponent _ [] = Nothing
331+
findComponent needle (c@Component{componentName, components}:topLevelComponents)
332+
| componentName == Just needle = Just c
333+
| otherwise = findComponent needle topLevelComponents <|> findComponent needle components
334+
324335

325336
-- | Create a 'CreateProcess' describing how to start a process given the Cabal package name
326337
-- corresponding to the executable, an environment variable pointing to the executable,

0 commit comments

Comments
 (0)