Skip to content

Commit b1e39a5

Browse files
committed
ENH Add min-ngless-version to external modules
This way, if a module does require some specific bit of functionality, it can be specified explicit for better error messages closes #143
1 parent b626af8 commit b1e39a5

File tree

7 files changed

+72
-25
lines changed

7 files changed

+72
-25
lines changed

ChangeLog

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Version 1.2.0+
2+
* Add min-ngless-version field for modules
23
* Add early check that block assignments are always to block variables
34
* Use ZStd compression for temporary files from preprocess()
45
* Correctly handle subpaths in samples for collect (fixes #141)

Execs/Main.hs

+1-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{-# LANGUAGE PackageImports #-}
2-
{- Copyright 2013-2020 NGLess Authors
2+
{- Copyright 2013-2021 NGLess Authors
33
- License: MIT
44
-}
55
module Main
@@ -214,26 +214,6 @@ loadScript (CmdArgs.ScriptFilePath fname) =
214214
Left err -> Left (show err)
215215

216216

217-
parseVersion :: Maybe T.Text -> NGLess NGLVersion
218-
parseVersion Nothing = return $ NGLVersion 1 2
219-
parseVersion (Just "1.2") = return $ NGLVersion 1 2
220-
parseVersion (Just "1.1") = return $ NGLVersion 1 1
221-
parseVersion (Just "1.0") = return $ NGLVersion 1 0
222-
parseVersion (Just "0.0") = return $ NGLVersion 0 0
223-
parseVersion (Just "0.5") = return $ NGLVersion 0 5
224-
parseVersion (Just "0.6") = return $ NGLVersion 0 6
225-
parseVersion (Just "0.7") = return $ NGLVersion 0 7
226-
parseVersion (Just "0.8") = return $ NGLVersion 0 8
227-
parseVersion (Just "0.9") = return $ NGLVersion 0 9
228-
parseVersion (Just "0.10") = return $ NGLVersion 0 10
229-
parseVersion (Just "0.11") = return $ NGLVersion 0 11
230-
parseVersion (Just v) = case T.splitOn "." v of
231-
[majV,minV,_] ->
232-
throwScriptError $ concat ["The NGLess version string at the top of the file should only\ncontain a major and a minor version, separated by a dot.\n\n"
233-
,"You probably meant to write:\n\n"
234-
,"ngless \"" , T.unpack majV, ".", T.unpack minV, "\"\n"]
235-
[_, _] -> throwScriptError $ concat ["Version ", T.unpack v, " is not supported (only versions 1.[0-2] and 0.0/0.5-12 are available in this release)."]
236-
_ -> throwScriptError $ concat ["Version ", T.unpack v, " could not be understood. The version string should look like \"1.0\" or similar"]
237217

238218
modeExec :: CmdArgs.NGLessMode -> IO ()
239219
modeExec opts@CmdArgs.DefaultMode{} = do

Modules/example-cmd.ngm/0.0/module.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
version: '0.0.0'
22
name: 'Test tool'
3+
min-ngless-version:
4+
min-version: "1.3"
5+
reason: "The min-ngless-version field is only supported since NGLess 1.3"
36
functions:
47
-
58
nglName: "testing"

NGLess/ExternalModules.hs

+32-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{- Copyright 2015-2019 NGLess Authors
1+
{- Copyright 2015-2021 NGLess Authors
22
- License: MIT
33
-}
44

@@ -178,9 +178,27 @@ instance Aeson.FromJSON Command where
178178
<*> o .:? "additional" .!= []
179179
<*> o .:? "return" .!= CommandReturn NGLVoid "" ""
180180

181+
data ModuleNGLessMinVersion = ModuleNGLessMinVersion
182+
{ nglessMinVersion :: NGLVersion
183+
, nglessMinVersionReason :: T.Text
184+
}
185+
deriving (Eq, Show)
186+
187+
instance Aeson.FromJSON ModuleNGLessMinVersion where
188+
parseJSON = Aeson.withObject "min-ngless-version" $ \o -> do
189+
vtText <- o .: "min-version"
190+
reason <- o .: "reason"
191+
vt <- (Aeson.withText "minimal NGLess version" $ \vt ->
192+
case parseVersion (Just vt) of
193+
Left err -> fail (show err)
194+
Right val -> return val) vtText
195+
return $ ModuleNGLessMinVersion vt reason
196+
197+
181198
data ExternalModule = ExternalModule
182199
{ emInfo :: ModInfo -- ^ module information
183200
, modulePath :: FilePath -- ^ directory where module files are located
201+
, modNGLessMinVersion :: Maybe ModuleNGLessMinVersion -- ^ minimal NGLess version for this module
184202
, initCmd :: Maybe FilePath
185203
, initArgs :: [String]
186204
, emFunctions :: [Command]
@@ -197,6 +215,7 @@ instance Aeson.FromJSON ExternalModule where
197215
init_cmd <- initO' .: "init_cmd"
198216
init_args <- initO' .:? "init_args" .!= []
199217
return (init_cmd, init_args)
218+
modNGLessMinVersion <- o .:? "min-ngless-version"
200219
references <- o .:? "references" .!= []
201220
emFunctions <- o .:? "functions" .!= []
202221
singleCitation <- o .:? "citation"
@@ -406,6 +425,14 @@ asInternalModule em@ExternalModule{..} = do
406425
validateModule :: ExternalModule -> NGLessIO ()
407426
validateModule em@ExternalModule{..} = do
408427
checkSyntax em
428+
whenJust modNGLessMinVersion $ \(ModuleNGLessMinVersion minV reason) -> do
429+
curV <- ngleVersion <$> nglEnvironment
430+
when (minV > curV) $
431+
throwScriptError $ concat
432+
[ "Current NGLess version is too old for loading module '"
433+
, show emInfo, ".\n"
434+
, "Version ", show minV, " is required.\n"
435+
, "Reason: ", T.unpack reason]
409436
whenJust initCmd $ \initCmd' -> do
410437
outputListLno' DebugOutput ("Running initialization for module ":show emInfo:" ":initCmd':" ":initArgs)
411438
env <- nglessEnv modulePath
@@ -533,7 +560,10 @@ checkCompatible modname version mi = do
533560
loadModule :: ModInfo -> NGLessIO Module
534561
loadModule mi
535562
| isGlobalImport mi && name `notElem` knownModules =
536-
throwScriptError ("Module '" ++ T.unpack name ++ "' is not known.\n\t" ++ T.unpack (suggestionMessage name knownModules) ++ "\n\tTo import local modules, use \"local import\"")
563+
throwScriptError (
564+
"Module '" ++ T.unpack name ++ "' is not known.\n\t"
565+
++ T.unpack (suggestionMessage name knownModules)
566+
++ "\n\tTo import local modules, use \"local import\"")
537567
| otherwise = asInternalModule =<< findLoad name version
538568
where
539569
isGlobalImport LocalModInfo{} = False

NGLess/NGLess/NGLEnvironment.hs

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
{- Copyright 2016-2019 NGLess Authors
1+
{- Copyright 2016-2021 NGLess Authors
22
- License: MIT
33
-}
44
module NGLess.NGLEnvironment
55
( NGLVersion(..)
6+
, parseVersion
67
, NGLEnvironment(..)
78
, nglEnvironment
89
, nglConfiguration
@@ -39,6 +40,27 @@ data NGLEnvironment = NGLEnvironment
3940
, ngleConfiguration :: NGLessConfiguration
4041
} deriving (Show, Eq)
4142

43+
parseVersion :: Maybe T.Text -> NGLess NGLVersion
44+
parseVersion Nothing = return $ NGLVersion 1 2
45+
parseVersion (Just "1.3") = return $ NGLVersion 1 3
46+
parseVersion (Just "1.2") = return $ NGLVersion 1 2
47+
parseVersion (Just "1.1") = return $ NGLVersion 1 1
48+
parseVersion (Just "1.0") = return $ NGLVersion 1 0
49+
parseVersion (Just "0.0") = return $ NGLVersion 0 0
50+
parseVersion (Just "0.5") = return $ NGLVersion 0 5
51+
parseVersion (Just "0.6") = return $ NGLVersion 0 6
52+
parseVersion (Just "0.7") = return $ NGLVersion 0 7
53+
parseVersion (Just "0.8") = return $ NGLVersion 0 8
54+
parseVersion (Just "0.9") = return $ NGLVersion 0 9
55+
parseVersion (Just "0.10") = return $ NGLVersion 0 10
56+
parseVersion (Just "0.11") = return $ NGLVersion 0 11
57+
parseVersion (Just v) = case T.splitOn "." v of
58+
[majV,minV,_] ->
59+
throwScriptError $ concat ["The NGLess version string at the top of the file should only\ncontain a major and a minor version, separated by a dot.\n\n"
60+
,"You probably meant to write:\n\n"
61+
,"ngless \"" , T.unpack majV, ".", T.unpack minV, "\"\n"]
62+
[_, _] -> throwScriptError $ concat ["Version ", T.unpack v, " is not supported (only versions 1.[0-2] and 0.0/0.5-12 are available in this release)."]
63+
_ -> throwScriptError $ concat ["Version ", T.unpack v, " could not be understood. The version string should look like \"1.0\" or similar"]
4264
ngle :: IORef NGLEnvironment
4365
{-# NOINLINE ngle #-}
4466
ngle = unsafePerformIO (newIORef $ NGLEnvironment (NGLVersion 0 0) Nothing "" ["bwa"] [] (error "Configuration not set"))

docs/sources/modules.md

+11
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,17 @@ provide a list:
231231
- "Paper 1"
232232
- "Paper 2"
233233

234+
## Minimal NGLess Version
235+
236+
External modules can specify a minimal NGLess version that they need to run.
237+
This is optional, but if it is used, you need to additionally supply a reason
238+
for the requirement (using the aptly-named `reason` field):
239+
240+
min-ngless-version:
241+
min-version: "1.3"
242+
reason: "The min-ngless-version field is only supported since NGLess 1.3"
243+
244+
234245
## Internal Modules
235246

236247
This is very advanced as it requires writing Haskell code which can then

tests/exampleExternalModule/example-cmd.ngl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ngless '1.1'
1+
ngless '1.3'
22
import "example-cmd" version "0.0"
33
import "mocat" version "0.6"
44

0 commit comments

Comments
 (0)