on master help sign in
merge upstream to add the haskell-scripting flag support.
commit1581b24b52f3547327b8ad436c1d1c8df169dc7a authorHugh JF Chen <hugh.jf.chen@gmail.com> dateThu 23 Apr 2020, 09:32 (7 years ago) parente6323316c8e781
12 files changed+311−97
.travis.yml+46−36 ci/DevOps/local/test/build/build.sh+3−3 ci/DevOps/local/test/build/nix/default.nix+115 project-m36.cabal+17−7 src/lib/ProjectM36/AtomFunction.hs+6−1 src/lib/ProjectM36/DatabaseContextFunction.hs+5 src/lib/ProjectM36/RelationalExpression.hs+12−1 src/lib/ProjectM36/ScriptSession.hs+25−11 src/lib/ProjectM36/Transaction/Persist.hs+40−18 test/TransactionGraph/Persist.hs+11−4 test/TutorialD/Interpreter/AtomFunctionScript.hs+18−10 test/TutorialD/Interpreter/DatabaseContextFunctionScript.hs+13−6
.travis.yml+46−36
@@ -1,54 +1,64 @@
11# For more information, see https://github.com/ChrisPenner/haskell-stack-travis-ci
22language: c
3−sudo: true
4−
5−dist: bionic
3+sudo: false
64
75git:
86 submodules: false # whether to recursively clone submodules
97
10−#cache:
11−# directories:
12−# - $HOME/.ghc
13−# - $HOME/.cabal
14−# - $HOME/.stack
15−# - .stack-work
16−# timeout: 1000
17−
18−#matrix:
19−# fast_finish: true
20−# include:
21−# - env: CACHE_NAME=8.2.2 STACK_YAML=stack.ghc8.2.yaml
22−# compiler: ": #stack 8.2.2"
23−#
24−# - env: CACHE_NAME=osx-8.2.2 STACK_YAML=stack.ghc8.2.yaml
25−# os: osx
26−# osx_image: xcode7.3
27−# compiler: ": #stack 8.2.2"
28−#
29−# - env: CACHE_NAME=8.4.4 STACK_YAML=stack.ghc8.4.yaml
30−# compiler: ": #stack 8.4.4"
31−#
32−# - env: CACHE_NAME=8.6.5 STACK_YAML=stack.ghc8.6.yaml
33−# compiler: ": #stack 8.6.5"
34−#
35−# - env: CACHE_NAME=osx-8.6.5 STACK_YAML=stack.ghc8.6.yaml
36−# os: osx
37−# osx_image: xcode11
38−# compiler: ": #stack 8.6.5"
8+cache:
9+ directories:
10+ - $HOME/.ghc
11+ - $HOME/.cabal
12+ - $HOME/.stack
13+ - .stack-work
14+ timeout: 1000
15+
16+matrix:
17+ fast_finish: true
18+ include:
19+ - env: CACHE_NAME=8.2.2 STACK_YAML=stack.ghc8.2.yaml
20+ compiler: ": #stack 8.2.2"
21+
22+ - env: CACHE_NAME=osx-8.2.2 STACK_YAML=stack.ghc8.2.yaml
23+ os: osx
24+ osx_image: xcode7.3
25+ compiler: ": #stack 8.2.2"
26+
27+ - env: CACHE_NAME=8.4.4 STACK_YAML=stack.ghc8.4.yaml
28+ compiler: ": #stack 8.4.4"
29+
30+ - env: CACHE_NAME=8.6.5 STACK_YAML=stack.ghc8.6.yaml
31+ compiler: ": #stack 8.6.5"
32+
33+ - env: CACHE_NAME=osx-8.6.5 STACK_YAML=stack.ghc8.6.yaml
34+ os: osx
35+ osx_image: xcode11
36+ compiler: ": #stack 8.6.5"
3937
4038before_script:
4139 - unset CC
42− - sudo apt-get update
43− - sudo apt-get -y upgrade
44− - sudo apt-get -y install git curl
40+ - export PATH=$HOME/.local/bin:/opt/ghc/$GHC_VERSION/bin:$PATH
41+ - ./.travis/install-ghr.sh
42+ - ./.travis/install-stack.sh
4543
4644# Here starts the actual work to be performed for the package under test;
4745# any command which exits with a non-zero exit code causes the build to fail.
4846script:
4947 - |
5048 # Run tests
51− ./ci/DevOps/local/test/cb.sh
49+ set -e
50+ ./.travis/install-dependencies.sh
51+ stack --no-terminal --jobs=2 --system-ghc test
52+ - |
53+ #Run HLint
54+ if [[ "$(uname)" = "Linux" ]]; then
55+ curl -sL https://raw.github.com/ndmitchell/hlint/master/misc/travis.sh | sh -s lint src test examples --cpp-define VERSION_project_m36=HLINT
56+ fi
57+ - |
58+ #Run Haddock
59+ if [[ "$(uname)" = "Linux" ]]; then
60+ stack --no-install-ghc --system-ghc --no-haddock-deps haddock
61+ fi
5262
5363after_success:
5464 - |
ci/DevOps/local/test/build/build.sh+3−3
@@ -21,9 +21,9 @@ if [ -f ${SCRIPT_ABS_PATH}/nix/project-m36.nix ]; then
2121 [ -x ~/.emacs.d/bin/doom ] && echo "((nil . ((dante-target . \"project-m36\"))))" > ${SCRIPT_ABS_PATH}/../../../../.dir-locals.el && nix-shell --run "~/.emacs.d/bin/doom env > /dev/null 2>&1" ${SCRIPT_ABS_PATH}/nix/shell.nix
2222 nix-shell ${SCRIPT_ABS_PATH}/nix/shell.nix
2323 else
24− nix-shell --run "cd ${SCRIPT_ABS_PATH}/../../../../.. ; cabal new-update ; cabal new-clean ; cabal new-test" ${SCRIPT_ABS_PATH}/nix/shell.nix
25− nix-shell --run "cd ${SCRIPT_ABS_PATH}/../../../../.. ; cabal new-clean" ${SCRIPT_ABS_PATH}/nix/shell.nix
26− nix-build -A project-m36-docker ${SCRIPT_ABS_PATH}/nix/default.nix
24+ #nix-shell --run "cd ${SCRIPT_ABS_PATH}/../../../../.. ; cabal new-update ; cabal new-clean ; cabal new-test" ${SCRIPT_ABS_PATH}/nix/shell.nix
25+ #nix-shell --run "cd ${SCRIPT_ABS_PATH}/../../../../.. ; cabal new-clean" ${SCRIPT_ABS_PATH}/nix/shell.nix
26+ nix-build -A project-m36-server-docker -A project-m36-websocket-server-docker -A project-m36-tutd-docker ${SCRIPT_ABS_PATH}/nix/default.nix
2727 fi
2828else
2929 info "No ${SCRIPT_ABS_PATH}/nix/project-m36.nix found, skip building"
ci/DevOps/local/test/build/nix/default.nix+115
@@ -238,6 +238,117 @@ divert 258 DIVERT # Divert pseudo-protocol
238238 '';
239239 };
240240
241+ overrideCabal = drv: f: (drv.override (args: args // {
242+ mkDerivation = drv: (args.mkDerivation drv).override f;
243+ })) // {
244+ overrideScope = scope: overrideCabal (drv.overrideScope scope) f;
245+ };
246+
247+ static-project-m36-server = drv: overrideCabal drv (drv: {
248+ postFixup = "rm -rf $out/lib $out/nix-support $out/share/doc $out/bin/Example* $out/bin/tutd $out/bin/bigrel $out/bin/handles $out/bin/project-m36-websocket-server";
249+ });
250+
251+ static-project-m36-websocket-server = drv: overrideCabal drv (drv: {
252+ postFixup = "rm -rf $out/lib $out/nix-support $out/share/doc $out/bin/Example* $out/bin/tutd $out/bin/bigrel $out/bin/handles $out/bin/project-m36-server";
253+ });
254+
255+ static-project-m36-tutd = drv: overrideCabal drv (drv: {
256+ postFixup = "rm -rf $out/lib $out/nix-support $out/share/doc $out/bin/Example* $out/bin/project-m36-server $out/bin/bigrel $out/bin/handles $out/bin/project-m36-websocket-server";
257+ });
258+
259+ static-project-m36-example = drv: overrideCabal drv (drv: {
260+ postFixup = "rm -fr $out/lib $out/nix-support $out/share/doc $out/bin/tutd $out/bin/bigrel $out/bin/handles $out/bin/project-m36-server $out/bin/project-m36-websocket-server";
261+ });
262+
263+ project-m36-server-docker = pkgs.dockerTools.buildImage {
264+ name = "project-m36-server";
265+ tag = project-m36.version;
266+
267+ contents = [ (static-project-m36-server static-project-m36)
268+ project-m36-env ];
269+ config = {
270+ Env = [
271+ "PARA1="
272+ "PARA2="
273+ ];
274+ User = "project-m36";
275+ Cmd = [ "${static-project-m36}/bin/project-m36-server" ];
276+ ExposedPorts = {
277+ "5432/tcp" = {};
278+ };
279+ WorkingDir = "/data";
280+ Volumes = {
281+ "/data" = {};
282+ };
283+ };
284+};
285+
286+ project-m36-websocket-server-docker = pkgs.dockerTools.buildImage {
287+ name = "project-m36-websocket";
288+ tag = project-m36.version;
289+
290+ contents = [ (static-project-m36-websocket-server static-project-m36)
291+ project-m36-env ];
292+ config = {
293+ Env = [
294+ "PARA1="
295+ "PARA2="
296+ ];
297+ User = "project-m36";
298+ Cmd = [ "${static-project-m36}/bin/project-m36-websocket-server" ];
299+ ExposedPorts = {
300+ "5432/tcp" = {};
301+ };
302+ WorkingDir = "/data";
303+ Volumes = {
304+ "/data" = {};
305+ };
306+ };
307+};
308+ project-m36-tutd-docker = pkgs.dockerTools.buildImage {
309+ name = "project-m36-tutd";
310+ tag = project-m36.version;
311+
312+ contents = [ (static-project-m36-tutd static-project-m36)
313+ project-m36-env ];
314+ config = {
315+ Env = [
316+ "PARA1="
317+ "PARA2="
318+ ];
319+ User = "project-m36";
320+ Cmd = [ "${static-project-m36}/bin/tutd" ];
321+ ExposedPorts = {
322+ "5432/tcp" = {};
323+ };
324+ WorkingDir = "/data";
325+ Volumes = {
326+ "/data" = {};
327+ };
328+ };
329+};
330+ project-m36-example-docker = pkgs.dockerTools.buildImage {
331+ name = "project-m36-example";
332+ tag = project-m36.version;
333+
334+ contents = [ (static-project-m36-example static-project-m36)
335+ project-m36-env ];
336+ config = {
337+ Env = [
338+ "PARA1="
339+ "PARA2="
340+ ];
341+ User = "project-m36";
342+ Cmd = [ "${static-project-m36}/bin/Example-SimpleClient" ];
343+ ExposedPorts = {
344+ "5432/tcp" = {};
345+ };
346+ WorkingDir = "/data";
347+ Volumes = {
348+ "/data" = {};
349+ };
350+ };
351+};
241352 project-m36-docker = pkgs.dockerTools.buildImage {
242353 name = "project-m36";
243354 tag = project-m36.version;
@@ -264,4 +375,8 @@ in {
264375 inherit project-m36;
265376 inherit static-project-m36;
266377 inherit project-m36-docker;
378+ inherit project-m36-server-docker;
379+ inherit project-m36-websocket-server-docker;
380+ inherit project-m36-tutd-docker;
381+ inherit project-m36-example-docker;
267382}
project-m36.cabal+17−7
@@ -28,8 +28,19 @@ Flag stack
2828 Manual: True
2929 Default: False
3030
31+Flag haskell-scripting
32+ Description: enables Haskell scripting which links against GHC as a library
33+ Manual: True
34+ Default: True
35+
3136Library
32− Build-Depends: base>=4.8 && < 4.13, ghc >= 8.2 && < 8.7, ghc-paths, mtl, containers, unordered-containers, hashable, haskeline, directory, MonadRandom, random-shuffle, uuid >= 1.3.12, cassava >= 0.4.5.1 && < 0.6, text, bytestring, deepseq, deepseq-generics, vector, parallel, monad-parallel, exceptions, transformers, gnuplot, binary, filepath, zlib, directory, vector-binary-instances, temporary, stm, time, hashable-time, old-locale, rset, attoparsec, either, base64-bytestring, data-interval, extended-reals, network-transport, aeson >= 1.1, path-pieces, conduit, resourcet, http-api-data, semigroups, QuickCheck, quickcheck-instances, distributed-process-client-server >= 0.2.3, distributed-process >= 0.7.4, distributed-process-extras >= 0.3.2, distributed-process-async >= 0.2.4.1, network-transport-tcp >= 0.6.0, network-transport, list-t, stm-containers >= 0.2.15, foldl, optparse-applicative, Glob, cryptohash-sha256
37+ Build-Depends: base>=4.8 && < 4.13, ghc-paths, mtl, containers, unordered-containers, hashable, haskeline, directory, MonadRandom, random-shuffle, uuid >= 1.3.12, cassava >= 0.4.5.1 && < 0.6, text, bytestring, deepseq, deepseq-generics, vector, parallel, monad-parallel, exceptions, transformers, gnuplot, binary, filepath, zlib, directory, vector-binary-instances, temporary, stm, time, hashable-time, old-locale, rset, attoparsec, either, base64-bytestring, data-interval, extended-reals, network-transport, aeson >= 1.1, path-pieces, conduit, resourcet, http-api-data, semigroups, QuickCheck, quickcheck-instances, distributed-process-client-server >= 0.2.3, distributed-process >= 0.7.4, distributed-process-extras >= 0.3.2, distributed-process-async >= 0.2.4.1, network-transport-tcp >= 0.6.0, network-transport, list-t, stm-containers >= 0.2.15, foldl, optparse-applicative, Glob, cryptohash-sha256
38+ if flag(haskell-scripting)
39+ Build-Depends: ghc >= 8.2 && < 8.7
40+ CPP-Options: -DPM36_HASKELL_SCRIPTING
41+ if impl(ghc>= 8) && flag(haskell-scripting)
42+ build-depends:
43+ ghc-boot, ghci
3344 if impl(ghc>= 8.6)
3445 Build-Depends: deferred-folds
3546 Exposed-Modules: ProjectM36.Error,
@@ -118,15 +129,13 @@ Library
118129 Hs-Source-Dirs: ./src/lib
119130 Default-Language: Haskell2010
120131 Default-Extensions: OverloadedStrings, CPP
121− if impl(ghc>= 8)
122− build-depends:
123− ghc-boot, ghci
124− if !flag(stack)
132+ if !flag(stack)
125133 Build-Depends: deferred-folds
126134
127135Executable tutd
136+ if flag(haskell-scripting)
137+ Build-Depends: ghc >= 8.2 && < 8.7
128138 Build-Depends: base >=4.8 && <5.0,
129− ghc >= 7.8 && < 8.7,
130139 ghc-paths,
131140 project-m36,
132141 containers,
@@ -189,8 +198,9 @@ Executable tutd
189198 Default-Extensions: OverloadedStrings
190199
191200Executable project-m36-server
201+ if flag(haskell-scripting)
202+ Build-Depends: ghc >= 8.2 && < 8.7
192203 Build-Depends: base,
193− ghc >= 7.8 && < 8.7,
194204 ghc-paths,
195205 project-m36,
196206 binary,
src/lib/ProjectM36/AtomFunction.hs+6−1
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12module ProjectM36.AtomFunction where
23import ProjectM36.Base
34import ProjectM36.Error
@@ -72,7 +73,11 @@ createScriptedAtomFunction funcName argsType retType = AddAtomFunction funcName
7273 retType]])
7374
7475loadAtomFunctions :: ModName -> FuncName -> FilePath -> IO (Either LoadSymbolError [AtomFunction])
76+#ifdef PM36_HASKELL_SCRIPTING
7577loadAtomFunctions = loadFunction
78+#else
79+loadAtomFunctions _ _ _ = pure (Left LoadSymbolError)
80+#endif
7681
7782atomFunctionsAsRelation :: AtomFunctions -> Either RelationalError Relation
7883atomFunctionsAsRelation funcs = mkRelationFromList attrs tups
@@ -81,4 +86,4 @@ atomFunctionsAsRelation funcs = mkRelationFromList attrs tups
8186 Attribute "arguments" TextAtomType]
8287 atomFuncToTuple aFunc = [TextAtom (atomFuncName aFunc),
8388 TextAtom (atomFuncTypeToText aFunc)]
84− atomFuncTypeToText aFunc = T.intercalate " -> " (map prettyAtomType (atomFuncType aFunc))
89+ atomFuncTypeToText aFunc = T.intercalate " -> " (map prettyAtomType (atomFuncType aFunc))
src/lib/ProjectM36/DatabaseContextFunction.hs+5
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12module ProjectM36.DatabaseContextFunction where
23--implements functions which operate as: [Atom] -> DatabaseContextExpr -> Either RelationalError DatabaseContextExpr
34import ProjectM36.Base
@@ -61,7 +62,11 @@ createScriptedDatabaseContextFunction :: DatabaseContextFunctionName -> [TypeCon
6162createScriptedDatabaseContextFunction funcName argsIn retArg = AddDatabaseContextFunction funcName (argsIn ++ [databaseContextFunctionReturnType retArg])
6263
6364loadDatabaseContextFunctions :: ModName -> FuncName -> FilePath -> IO (Either LoadSymbolError [DatabaseContextFunction])
65+#ifdef PM36_HASKELL_SCRIPTING
6466loadDatabaseContextFunctions = loadFunction
67+#else
68+loadDatabaseContextFunctions _ _ _ = pure (Left LoadSymbolError)
69+#endif
6570
6671databaseContextFunctionsAsRelation :: DatabaseContextFunctions -> Either RelationalError Relation
6772databaseContextFunctionsAsRelation dbcFuncs = mkRelationFromList attrs tups
src/lib/ProjectM36/RelationalExpression.hs+12−1
@@ -17,7 +17,6 @@ import qualified Data.Map as M
1717import qualified Data.HashSet as HS
1818import qualified Data.Set as S
1919import Control.Monad.State hiding (join)
20−import Control.Exception
2120import Data.Maybe
2221import Data.Either
2322import Data.Char (isUpper)
@@ -27,8 +26,13 @@ import qualified ProjectM36.TypeConstructorDef as TCD
2726import Control.Monad.Trans.Except
2827import Control.Monad.Trans.Reader
2928import Test.QuickCheck
29+
30+#ifdef PM36_HASKELL_SCRIPTING
3031import GHC
32+import Control.Exception
3133import GHC.Paths
34+#endif
35+
3236
3337data DatabaseContextExprDetails = CountUpdatedTuples
3438
@@ -520,6 +524,12 @@ evalDatabaseContextExpr (ExecuteDatabaseContextFunction funcName atomArgExprs) =
520524 Right newContext -> putStateContext newContext >> pure (Right ())
521525
522526evalDatabaseContextIOExpr :: Maybe ScriptSession -> DatabaseContext -> DatabaseContextIOExpr -> IO (Either RelationalError DatabaseContext)
527+#if !defined(PM36_HASKELL_SCRIPTING)
528+evalDatabaseContextIOExpr _ _ AddAtomFunction{} = pure (Left (ScriptError ScriptCompilationDisabledError))
529+evalDatabaseContextIOExpr _ _ AddDatabaseContextFunction{} = pure (Left (ScriptError ScriptCompilationDisabledError))
530+evalDatabaseContextIOExpr _ _ LoadAtomFunctions{} = pure (Left (ScriptError ScriptCompilationDisabledError))
531+evalDatabaseContextIOExpr _ _ LoadDatabaseContextFunctions{} = pure (Left (ScriptError ScriptCompilationDisabledError))
532+#else
523533evalDatabaseContextIOExpr mScriptSession currentContext (AddAtomFunction funcName funcType script) =
524534 case mScriptSession of
525535 Nothing -> pure (Left (ScriptError ScriptCompilationDisabledError))
@@ -605,6 +615,7 @@ evalDatabaseContextIOExpr _ currentContext (LoadDatabaseContextFunctions modName
605615 Right dbcListFunc -> let newContext = currentContext { dbcFunctions = mergedFuncs }
606616 mergedFuncs = HS.union (dbcFunctions currentContext) (HS.fromList dbcListFunc)
607617 in pure (Right newContext)
618+#endif
608619
609620evalDatabaseContextIOExpr _ currentContext (CreateArbitraryRelation relVarName attrExprs range) =
610621 --Define
src/lib/ProjectM36/ScriptSession.hs+25−11
@@ -1,8 +1,12 @@
1−{-# LANGUAGE MagicHash, UnboxedTuples, KindSignatures, DataKinds #-}
1+{-# LANGUAGE UnboxedTuples, KindSignatures, DataKinds #-}
2+#ifdef PM36_HASKELL_SCRIPTING
3+{-# LANGUAGE MagicHash #-}
4+#endif
25module ProjectM36.ScriptSession where
36
7+#ifdef PM36_HASKELL_SCRIPTING
48import ProjectM36.Error
5−
9+import GHC
610import Control.Exception
711import Control.Monad
812import System.IO.Error
@@ -13,8 +17,6 @@ import System.FilePath
1317import System.Info (os, arch)
1418import Data.Text (Text, unpack)
1519import Data.Maybe
16−
17−import GHC
1820import GHC.Paths (libdir)
1921#if __GLASGOW_HASKELL__ >= 800
2022import GHC.LanguageExtensions
@@ -36,22 +38,38 @@ import Type
3638import Type hiding (pprTyThing)
3739#else
3840#endif
39−
4041import GHC.Exts (addrToAny#)
4142import GHC.Ptr (Ptr(..))
4243import Encoding
44+#endif
45+
4346
4447data ScriptSession = ScriptSession {
48+#ifdef PM36_HASKELL_SCRIPTING
4549 hscEnv :: HscEnv,
4650 atomFunctionBodyType :: Type,
4751 dbcFunctionBodyType :: Type
52+#endif
4853 }
4954
50−newtype ScriptSessionError = ScriptSessionLoadError GhcException
55+#ifdef PM36_HASKELL_SCRIPTING
56+data ScriptSessionError = ScriptSessionLoadError GhcException
57+ | ScriptingDisabled
5158 deriving (Show)
59+#else
60+data ScriptSessionError = ScriptingDisabled
61+ deriving (Show)
62+#endif
63+
64+data LoadSymbolError = LoadSymbolError
65+type ModName = String
66+type FuncName = String
5267
5368-- | Configure a GHC environment/session which we will use for all script compilation.
5469initScriptSession :: [String] -> IO (Either ScriptSessionError ScriptSession)
70+#if !defined(PM36_HASKELL_SCRIPTING)
71+initScriptSession _ = pure (Left ScriptingDisabled)
72+#else
5573initScriptSession ghcPkgPaths = do
5674 --for the sake of convenience, for developers' builds, include the local cabal sandbox package database and the cabal new-build package database
5775 eHomeDir <- tryJust (guard . isDoesNotExistError) getHomeDirectory
@@ -223,11 +241,6 @@ mangleSymbol pkg module' valsym =
223241 maybe "" (\p -> zEncodeString p ++ "_") pkg ++
224242 zEncodeString module' ++ "_" ++ zEncodeString valsym ++ "_closure"
225243
226−type ModName = String
227−type FuncName = String
228−
229−data LoadSymbolError = LoadSymbolError
230−
231244loadFunction :: ModName -> FuncName -> FilePath -> IO (Either LoadSymbolError a)
232245loadFunction modName funcName objPath = do
233246#if __GLASGOW_HASKELL__ >= 802
@@ -252,3 +265,4 @@ prefixUnderscore =
252265 ("darwin",_) -> "_"
253266 ("cygwin",_) -> "_"
254267 _ -> ""
268+#endif
src/lib/ProjectM36/Transaction/Persist.hs+40−18
@@ -1,3 +1,4 @@
1+{-# LANGUAGE TypeApplications #-}
12module ProjectM36.Transaction.Persist where
23import ProjectM36.Base
34import ProjectM36.Error
@@ -15,13 +16,17 @@ import qualified Data.Text as T
1516import Control.Monad
1617import ProjectM36.ScriptSession
1718import ProjectM36.AtomFunctions.Basic (precompiledAtomFunctions)
18−import Control.Exception
19−import GHC
20−import GHC.Paths
19+
2120import Codec.Compression.GZip
2221import qualified Data.ByteString as BS
2322import qualified Data.ByteString.Lazy as BSL
2423
24+#ifdef PM36_HASKELL_SCRIPTING
25+import GHC
26+import Control.Exception
27+import GHC.Paths
28+#endif
29+
2530getDirectoryNames :: FilePath -> IO [FilePath]
2631getDirectoryNames path =
2732 filter (\ n -> n `notElem` ["..", "."]) <$> getDirectoryContents path
@@ -128,33 +133,40 @@ readAtomFuncs transDir mScriptSession = do
128133 pure (HS.union precompiledAtomFunctions (HS.fromList funcs))
129134
130135loadAtomFunc :: AtomFunctions -> Maybe ScriptSession -> AtomFunctionName -> [AtomType] -> Maybe AtomFunctionBodyScript -> IO AtomFunction
131−loadAtomFunc precompiledFuncs mScriptSession funcName funcType mFuncScript = case mFuncScript of
136+loadAtomFunc precompiledFuncs _mScriptSession funcName _funcType mFuncScript = case mFuncScript of
132137 --handle pre-compiled case- pull it from the precompiled list
133138 Nothing -> case atomFunctionForName funcName precompiledFuncs of
134139 --WARNING: possible landmine here if we remove a precompiled atom function in the future, then the transaction cannot be restored
135140 Left _ -> error ("expected precompiled atom function: " ++ T.unpack funcName)
136141 Right realFunc -> pure realFunc
137142 --handle a real Haskell scripted function- compile and load
138− Just funcScript ->
139− case mScriptSession of
143+ Just _funcScript ->
144+#ifdef PM36_HASKELL_SCRIPTING
145+ case _mScriptSession of
140146 Nothing -> error "attempted to read serialized AtomFunction without scripting enabled"
141147 Just scriptSession -> do
142148 --risk of GHC exception during compilation here
143149 eCompiledScript <- runGhc (Just libdir) $ do
144150 setSession (hscEnv scriptSession)
145− compileScript (atomFunctionBodyType scriptSession) funcScript
151+ compileScript (atomFunctionBodyType scriptSession) _funcScript
146152 case eCompiledScript of
147153 Left err -> throwIO err
148154 Right compiledScript -> pure AtomFunction { atomFuncName = funcName,
149− atomFuncType = funcType,
150− atomFuncBody = AtomFunctionBody (Just funcScript) compiledScript }
155+ atomFuncType = _funcType,
156+ atomFuncBody = AtomFunctionBody (Just _funcScript) compiledScript }
157+#else
158+ error "Haskell scripting is disabled"
159+#endif
151160
152161--if the script session is enabled, compile the script, otherwise, hard error!
153162
154163readAtomFunc :: FilePath -> AtomFunctionName -> Maybe ScriptSession -> AtomFunctions -> IO AtomFunction
164+#if !defined(PM36_HASKELL_SCRIPTING)
165+readAtomFunc _ _ _ _ = error "Haskell scripting is disabled"
166+#else
155167readAtomFunc transDir funcName mScriptSession precompiledFuncs = do
156168 let atomFuncPath = atomFuncsPath transDir
157− (funcType, mFuncScript) <- B.decodeFile atomFuncPath
169+ (funcType, mFuncScript) <- B.decodeFile @([AtomType],Maybe T.Text) atomFuncPath
158170 case mFuncScript of
159171 --handle pre-compiled case- pull it from the precompiled list
160172 Nothing -> case atomFunctionForName funcName precompiledFuncs of
@@ -162,7 +174,8 @@ readAtomFunc transDir funcName mScriptSession precompiledFuncs = do
162174 Left _ -> error ("expected precompiled atom function: " ++ T.unpack funcName)
163175 Right realFunc -> pure realFunc
164176 --handle a real Haskell scripted function- compile and load
165− Just funcScript ->
177+ Just funcScript ->
178+
166179 case mScriptSession of
167180 Nothing -> error "attempted to read serialized AtomFunction without scripting enabled"
168181 Just scriptSession -> do
@@ -175,6 +188,7 @@ readAtomFunc transDir funcName mScriptSession precompiledFuncs = do
175188 Right compiledScript -> pure AtomFunction { atomFuncName = funcName,
176189 atomFuncType = funcType,
177190 atomFuncBody = AtomFunctionBody (Just funcScript) compiledScript }
191+#endif
178192
179193
180194writeDBCFuncs :: DiskSync -> FilePath -> DatabaseContextFunctions -> IO ()
@@ -193,26 +207,34 @@ readDBCFuncs transDir mScriptSession = do
193207 let funcs = mapM ((\name -> readDBCFunc transDir name mScriptSession precompiledDatabaseContextFunctions) . T.pack) funcNames
194208 HS.union basicDatabaseContextFunctions . HS.fromList <$> funcs
195209
196−readDBCFunc :: FilePath -> DatabaseContextFunctionName -> Maybe ScriptSession -> DatabaseContextFunctions -> IO DatabaseContextFunction
210+readDBCFunc :: FilePath -> DatabaseContextFunctionName -> Maybe ScriptSession -> DatabaseContextFunctions -> IO DatabaseContextFunction
211+#if !defined(PM36_HASKELL_SCRIPTING)
212+readDBCFunc transDir funcName _ precompiledFuncs = do
213+#else
197214readDBCFunc transDir funcName mScriptSession precompiledFuncs = do
215+#endif
198216 let dbcFuncPath = dbcFuncsDir transDir </> T.unpack funcName
199− (funcType, mFuncScript) <- B.decodeFile dbcFuncPath
217+ (_funcType, mFuncScript) <- B.decodeFile @([AtomType], Maybe T.Text) dbcFuncPath
200218 case mFuncScript of
201219 Nothing -> case databaseContextFunctionForName funcName precompiledFuncs of
202220 Left _ -> error ("expected precompiled dbc function: " ++ T.unpack funcName)
203221 Right realFunc -> pure realFunc --return precompiled function
204− Just funcScript ->
222+ Just _funcScript ->
223+#ifdef PM36_HASKELL_SCRIPTING
205224 case mScriptSession of
206225 Nothing -> error "attempted to read serialized AtomFunction without scripting enabled"
207226 Just scriptSession -> do
208227 eCompiledScript <- runGhc (Just libdir) $ do
209228 setSession (hscEnv scriptSession)
210− compileScript (dbcFunctionBodyType scriptSession) funcScript
229+ compileScript (dbcFunctionBodyType scriptSession) _funcScript
211230 case eCompiledScript of
212231 Left err -> throwIO err
213232 Right compiledScript -> pure DatabaseContextFunction { dbcFuncName = funcName,
214− dbcFuncType = funcType,
215− dbcFuncBody = DatabaseContextFunctionBody (Just funcScript) compiledScript}
233+ dbcFuncType = _funcType,
234+ dbcFuncBody = DatabaseContextFunctionBody (Just _funcScript) compiledScript}
235+#else
236+ error "Haskell scripting is disabled"
237+#endif
216238
217239writeIncDep :: DiskSync -> FilePath -> (IncDepName, InclusionDependency) -> IO ()
218240writeIncDep sync transDir (incDepName, incDep) =
@@ -252,4 +274,4 @@ readTypeConstructorMapping path = do
252274 let atPath = typeConsPath path
253275 B.decodeFile atPath
254276
255−
277+
test/TransactionGraph/Persist.hs+11−4
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12import Test.HUnit
23import ProjectM36.Base
34import ProjectM36.Persist (DiskSync(NoDiskSync))
@@ -5,8 +6,6 @@ import ProjectM36.TransactionGraph.Persist
56import ProjectM36.TransactionGraph
67import ProjectM36.Transaction
78import ProjectM36.DateExamples
8−import ProjectM36.Client
9−import ProjectM36.Relation
109import System.IO.Temp
1110import System.Exit
1211import Data.Either
@@ -17,6 +16,10 @@ import qualified Data.Map as M
1716import qualified Data.Set as S
1817import Data.Time.Clock
1918import Data.Time.Calendar
19+#ifdef PM36_HASKELL_SCRIPTING
20+import ProjectM36.Client
21+import ProjectM36.Relation
22+#endif
2023
2124main :: IO ()
2225main = do
@@ -75,7 +78,10 @@ testDBSimplePersistence = TestCase $ withSystemTempDirectory "m36testdb" $ \temp
7578
7679--only Haskell-scripted dbc and atom functions can be serialized
7780testFunctionPersistence :: Test
78−testFunctionPersistence = TestCase $
81+#if !defined(PM36_HASKELL_SCRIPTING)
82+testFunctionPersistence = TestCase $ pure ()
83+#else
84+testFunctionPersistence = TestCase $
7985 withSystemTempDirectory "m36testdb" $ \tempdir -> do
8086 let dbdir = tempdir </> "dbdir"
8187 connInfo = InProcessConnectionInfo (MinimalPersistence dbdir) emptyNotificationCallback []
@@ -96,10 +102,11 @@ testFunctionPersistence = TestCase $
96102 res <- executeRelationalExpr sess2 conn2 (MakeRelationFromExprs Nothing [TupleExpr (M.singleton "a" (FunctionAtomExpr "testdisk" [NakedAtomExpr (IntAtom 3)] ()))])
97103 let expectedRel = mkRelationFromList (attributesFromList [Attribute "a" IntAtomType]) [[IntAtom 3]]
98104 assertEqual "testdisk dbc function run" expectedRel res
99−
105+
100106assertIOEither :: (Show a) => IO (Either a b) -> IO b
101107assertIOEither x = do
102108 ret <- x
103109 case ret of
104110 Left err -> assertFailure (show err) >> undefined
105111 Right val -> pure val
112+#endif
test/TutorialD/Interpreter/AtomFunctionScript.hs+18−10
@@ -1,25 +1,32 @@
1−import TutorialD.Interpreter.TestBase
1+{-# LANGUAGE CPP #-}
22import System.Exit
33import Test.HUnit
4+#ifdef PM36_HASKELL_SCRIPTING
5+import TutorialD.Interpreter.TestBase
46import ProjectM36.Client
57import ProjectM36.Relation
68import ProjectM36.DataTypes.Maybe
79import qualified Data.Vector as V
810import qualified Data.Map as M
11+#endif
912
1013{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
1114main :: IO ()
1215main = do
13− tcounts <- runTestTT (TestList [testBasicAtomFunction,
14− testExceptionAtomFunction,
15− testErrorAtomFunction,
16− testNoArgumentAtomFunction,
17− testArgumentTypeMismatch,
18− testPolymorphicReturnType,
19− testScriptedTypeVariable
20− ])
16+ tcounts <- runTestTT (TestList [
17+#ifdef PM36_HASKELL_SCRIPTING
18+ testBasicAtomFunction,
19+ testExceptionAtomFunction,
20+ testErrorAtomFunction,
21+ testNoArgumentAtomFunction,
22+ testArgumentTypeMismatch,
23+ testPolymorphicReturnType,
24+ testScriptedTypeVariable
25+#endif
26+ ])
2127 if errors tcounts + failures tcounts > 0 then exitFailure else exitSuccess
2228
29+#ifdef PM36_HASKELL_SCRIPTING
2330--add an atom function and run it
2431testBasicAtomFunction :: Test
2532testBasicAtomFunction = TestCase $ do
@@ -111,4 +118,5 @@ testScriptedTypeVariable = TestCase $ do
111118 result <- executeRelationalExpr sess conn (MakeRelationFromExprs (Just (map NakedAttributeExpr attrs)) tupleExprs)
112119
113120 assertEqual "id function equality" expectedResult result
114−
121+
122+#endif
test/TutorialD/Interpreter/DatabaseContextFunctionScript.hs+13−6
@@ -1,19 +1,26 @@
1−import TutorialD.Interpreter.TestBase
1+{-# LANGUAGE CPP #-}
22import System.Exit
33import Test.HUnit
4+#ifdef PM36_HASKELL_SCRIPTING
5+import TutorialD.Interpreter.TestBase
46import ProjectM36.Client
57import ProjectM36.Relation
68import qualified Data.Text as T
9+#endif
710
811main :: IO ()
912main = do
10− tcounts <- runTestTT (TestList [testBasicDBCFunction,
11− testErrorDBCFunction,
12− testExceptionDBCFunction,
13− testDBCFunctionWithAtomArguments
13+ tcounts <- runTestTT (TestList [
14+#ifdef PM36_HASKELL_SCRIPTING
15+ testBasicDBCFunction,
16+ testErrorDBCFunction,
17+ testExceptionDBCFunction,
18+ testDBCFunctionWithAtomArguments
19+#endif
1420 ])
1521 if errors tcounts + failures tcounts > 0 then exitFailure else exitSuccess
1622
23+#ifdef PM36_HASKELL_SCRIPTING
1724testBasicDBCFunction :: Test
1825testBasicDBCFunction = TestCase $ do
1926 (sess, conn) <- dateExamplesConnection emptyNotificationCallback
@@ -55,4 +62,4 @@ testDBCFunctionWithAtomArguments = TestCase $ do
5562 assertEqual "person relation" expectedPerson result
5663 expectTutorialDErr sess conn (T.isPrefixOf "AtomTypeMismatchError") "execute multiArgFunc(\"fail\", \"fail\")"
5764
58−
65+#endif