Skip to content

Commit ad2ba16

Browse files
committed
master protect from lost imports of modules with defined CallSpecs
1 parent 045c202 commit ad2ba16

File tree

13 files changed

+64
-22
lines changed

13 files changed

+64
-22
lines changed

quick-process.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ library
323323
System.Process.Quick.CallSpec.Subcases
324324
System.Process.Quick.CallSpec.Type
325325
System.Process.Quick.CallSpec.Verify
326+
System.Process.Quick.CallSpec.Verify.ImportOverlook
326327
System.Process.Quick.CallSpec.Verify.Sandbox
327328
System.Process.Quick.CallSpec.Verify.TrailingHelp
328329
System.Process.Quick.CallSpec.Verify.Type

quick-process.cabal.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ library
112112
System.Process.Quick.CallSpec.Subcases
113113
System.Process.Quick.CallSpec.Type
114114
System.Process.Quick.CallSpec.Verify
115+
System.Process.Quick.CallSpec.Verify.ImportOverlook
115116
System.Process.Quick.CallSpec.Verify.Sandbox
116117
System.Process.Quick.CallSpec.Verify.TrailingHelp
117118
System.Process.Quick.CallSpec.Verify.Type

src/System/Process/Quick/CallSpec.hs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ import Language.Haskell.TH.Syntax qualified as THS
1515
import System.Directory
1616
import System.Process.Quick.CallArgument
1717
import System.Process.Quick.CallSpec.Type as E
18+
import System.Process.Quick.CallSpec.Verify.ImportOverlook
1819
import System.Process.Quick.Prelude
1920
import Text.Casing
2021
import Text.Regex
22+
import System.Process.Quick.Util
2123

2224
type FoldrConstr l a = (HFoldr (Mapcar (Fun CallArgumentGen (QR a))) [QR a] l [QR a])
2325

@@ -72,10 +74,13 @@ genCallSpec ::
7274
[VerificationMethod] -> String -> HList l -> Q [Dec]
7375
genCallSpec verMethods progName l = do
7476
runIO . whenNothingM_ (findExecutable progName) . fail $ "Program " <> show progName <> " is not found"
75-
maybe err (g . mkName') (programNameToHsIdentifier progName)
77+
pkgName <- loc_module <$> location
78+
addCompiledCallSpec (ConT . mkName . joinNe pkgName '.' $ toList csBaseName)
79+
go $ mkName' csBaseName
7680
where
77-
err = fail $ "Call spec name is bad: " <> show progName <> " " <> show l
78-
g recName = do
81+
csBaseName = maybe err id (programNameToHsIdentifier progName)
82+
err = error $ "Call spec name is bad: " <> show progName <> " " <> show l
83+
go recName = do
7984
(a, w) <- runWriterT . unQR $ sequence
8085
[ genCallArgsRecord recName l
8186
, genCallSpecInstance verMethods recName progName l

src/System/Process/Quick/CallSpec/Verify.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Data.Map qualified as M
55
import Data.Multimap.Table (row, rowKeys, rowKeysSet)
66
import Data.Set (findMin)
77
import Data.Text.Lazy qualified as LT
8-
import Data.Typeable ( TypeRep )
8+
import System.Process.Quick.CallSpec.Verify.ImportOverlook
99
import Language.Haskell.TH.Syntax
1010
import System.Process.Quick.CallSpec
1111
import System.Process.Quick.CallSpec.Verify.Sandbox
@@ -115,7 +115,10 @@ discoverAndVerifyCallSpecs activeVerMethods iterations = do
115115
outArgLocators <- extractInstanceType <$> reifyInstances ''RefinedOutArgLocator [VarT (mkName "c")]
116116
when (outArgLocators == []) $ putStrLn "Discovered 0 OutArg locators!!!"
117117
ts <- extractInstanceType <$> reifyInstances ''CallSpec [VarT (mkName "a")]
118-
when (ts == []) $ putStrLn "Discovered 0 types with CallSpec instance!!!"
118+
when (ts == []) $ fail "Discovered 0 types with CallSpec instance!!!"
119+
overlookedCss <- verifyFoundCsCoverCompiledOnes ts
120+
when (overlookedCss /= mempty) . fail . toString . displayT . renderOneLine $
121+
"Overlooked CallSpecs: " <> pretty overlookedCss
119122
!r <- [| void $ runStateT (
120123
fmap concat
121124
(sequence $(ListE <$> (mapM (genCsVerification
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module System.Process.Quick.CallSpec.Verify.ImportOverlook
2+
( addCompiledCallSpec
3+
, verifyFoundCsCoverCompiledOnes
4+
) where
5+
6+
import Data.Set ( (\\), insert )
7+
import Language.Haskell.TH ( Type, Name, nameModule, nameBase, mkName )
8+
import System.Process.Quick.Prelude hiding (Type)
9+
import System.Process.Quick.Util
10+
11+
erasePackage :: Type -> Type
12+
erasePackage t = gmapT go t
13+
where
14+
go :: forall x. (Data x) => x -> x
15+
go x | Just Refl <- eqT @x @Name =
16+
mkName $ joinNe (fromMaybe "" $ nameModule x) '.' (nameBase x)
17+
| otherwise = x
18+
19+
compiledCallSpecs :: IORef (Set Type)
20+
compiledCallSpecs = unsafePerformIO $ newIORef mempty
21+
22+
addCompiledCallSpec :: MonadIO m => Type -> m ()
23+
addCompiledCallSpec xt = atomicModifyIORef'_ compiledCallSpecs $ $(tw "/") . insert (erasePackage xt)
24+
25+
verifyFoundCsCoverCompiledOnes :: MonadIO m => [Type] -> m (Set Type)
26+
verifyFoundCsCoverCompiledOnes found =
27+
(\\ fromList found') <$> readIORef compiledCallSpecs
28+
where
29+
found' = erasePackage <$> found

src/System/Process/Quick/CallSpec/Verify/Sandbox.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
module System.Process.Quick.CallSpec.Verify.Sandbox where
22

3-
import Control.Monad.Writer.Strict (execWriterT, WriterT)
43
import Data.Conduit (runConduitRes, (.|))
54
import Data.Conduit.Find as F
65
import Data.Conduit.List qualified as DCL

src/System/Process/Quick/CallSpec/Verify/Type.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
module System.Process.Quick.CallSpec.Verify.Type where
33

44
import Data.Multimap.Table ( Table )
5-
import Data.Typeable ( TypeRep )
65
import Generic.Data ( gmappend, gmempty )
76
import Prelude (show)
87
import System.Process.Quick.CallEffect (CallEffect)

src/System/Process/Quick/Predicate/InDir.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import System.Process.Quick.Predicate
55
import System.Process.Quick.Predicate.InFile ( genFilePathBy )
66
import System.Process.Quick.Prelude
77
import Text.Regex.TDFA ((=~))
8-
import Type.Reflection ((:~:)(Refl))
98

109
data InDir deriving (Data, Show, Eq, Generic)
1110

src/System/Process/Quick/Predicate/InFile.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
module System.Process.Quick.Predicate.InFile where
22

3-
import Control.Monad.Writer.Strict
43
import System.Process.Quick.Predicate
54
import System.Process.Quick.Prelude
65
import System.Process.Quick.TdfaToSbvRegex as P
76
import System.Process.Quick.Sbv.Arbitrary
87
import System.Process.Quick.CallArgument (NeList)
98
import Text.Regex.TDFA ((=~))
109
import Type.Reflection qualified as R
11-
import Type.Reflection ((:~:)(Refl))
1210

1311

1412
data InFile (ext :: Symbol) deriving (Data, Show, Eq, Generic)

src/System/Process/Quick/Prelude.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
{-# OPTIONS_HADDOCK hide #-}
22
module System.Process.Quick.Prelude (module M, liftIO1) where
33

4+
import Control.Monad.Writer.Strict as M (MonadWriter (tell), WriterT, execWriterT)
45
import Control.Exception.Safe as M (MonadMask, MonadCatch, bracket, tryIO, try, tryAny, throw)
56
import Control.Lens as M (Lens', at, (^.), (.~), (%~), _1, _2)
67
import Control.Monad.Time as M (MonadTime(..))
78
import Data.Char as M (isAlphaNum, isAlpha, isLetter, isLower, toLower)
8-
import Data.Data as M (Data, gmapM)
9+
import Data.Data as M (Data, gmapM, gmapT)
910
import Data.Generics.Labels as M ()
1011
import Data.HList as M (typeRep)
1112
import Data.List as M (isSuffixOf)
1213
import Data.Set as M (member)
1314
import Data.Time.Clock as M (NominalDiffTime, diffUTCTime)
14-
import Data.Typeable as M (eqT)
15+
import Data.Typeable as M (TypeRep, eqT, (:~:) (Refl))
1516
import Debug.TraceEmbrace as M (tr, tw)
1617
import Generic.Random as M (genericArbitraryU)
1718
import GHC.TypeLits as M (Symbol, KnownSymbol (..), symbolVal)
1819
import Refined as M (Refined, unrefine, refine, Predicate (..), throwRefineOtherException)
1920
import Relude as M hiding (Predicate)
2021
import Relude.Extra as M (toPairs)
2122
import System.Exit as M (ExitCode (..))
23+
import System.IO.Unsafe as M (unsafePerformIO)
2224
import System.Process as M (ProcessHandle, CreateProcess (..), readCreateProcess, readCreateProcessWithExitCode)
2325
import System.Process.Quick.Pretty as M
2426
import Test.QuickCheck as M (Gen, Arbitrary (..), generate, chooseInt, sized, elements, listOf)

0 commit comments

Comments
 (0)