8
8
from io import BytesIO
9
9
10
10
from pkg_resources import resource_stream
11
- from typing import Any , Dict , List , Mapping , Text , Union
11
+ from typing import Any , Dict , List , Mapping , Text , Union , Tuple
12
+
12
13
13
14
class JavascriptException (Exception ):
14
15
pass
@@ -21,45 +22,50 @@ class JavascriptException(Exception):
21
22
localdata = threading .local ()
22
23
23
24
have_node_slim = False
24
-
25
+ # minimum acceptable version of nodejs engine
26
+ minimum_node_version_str = '0.10.26'
25
27
26
28
def check_js_threshold_version (working_alias ):
27
- # type: (str) -> bool
28
- """ parse node version: 'v4.2.6\n ' -> ['4', '2', '6'],
29
- https://github.com/nodejs/node/blob/master/CHANGELOG.md#nodejs-changelog"""
30
-
31
- # try:
32
- v1 , v2 , v3 = [int (v ) for v in subprocess .check_output (
33
- [working_alias , "-v" ]).decode ('ascii' ).strip ().strip ('v' ).split ('.' )]
34
- # except Exception as e:
35
- # _logger.debug(str(e))
36
- # _logger.debug("Calling subprocess failed")
37
- # return True
38
-
39
- if v1 == 0 :
40
- if v2 == 10 and v3 <= 25 or v2 < 10 :
41
- return False
42
- return True
29
+ # type: (str) -> Tuple[bool, str]
30
+
31
+ """Checks if the nodeJS engine version on the system
32
+ with the allowed minimum version.
33
+ https://github.com/nodejs/node/blob/master/CHANGELOG.md#nodejs-changelog
34
+ """
35
+ # parse nodejs version into int Tuple: 'v4.2.6\n' -> [4, 2, 6]
36
+ current_version_str = subprocess .check_output (
37
+ [working_alias , "-v" ]).decode ('ascii' )
38
+
39
+ current_version = [int (v ) for v in current_version_str .strip ().strip ('v' ).split ('.' )]
40
+ minimum_node_version = [int (v ) for v in minimum_node_version_str .split ('.' )]
41
+
42
+ if current_version >= minimum_node_version :
43
+ return True
44
+ else :
45
+ return False
46
+
43
47
44
48
def new_js_proc ():
45
49
# type: () -> subprocess.Popen
46
50
47
51
res = resource_stream (__name__ , 'cwlNodeEngine.js' )
48
52
nodecode = res .read ()
49
53
54
+ required_node_version , docker = (False ,)* 2
50
55
nodejs = None
51
56
trynodes = ("nodejs" , "node" )
52
- working_alias = None
53
57
for n in trynodes :
54
58
try :
55
59
if subprocess .check_output ([n , "--eval" , "process.stdout.write('t')" ]) != "t" :
56
- working_alias = n
57
60
continue
58
- nodejs = subprocess .Popen ([n , "--eval" , nodecode ],
59
- stdin = subprocess .PIPE ,
60
- stdout = subprocess .PIPE ,
61
- stderr = subprocess .PIPE )
62
- break
61
+ else :
62
+ nodejs = subprocess .Popen ([n , "--eval" , nodecode ],
63
+ stdin = subprocess .PIPE ,
64
+ stdout = subprocess .PIPE ,
65
+ stderr = subprocess .PIPE )
66
+
67
+ required_node_version = check_js_threshold_version (n )
68
+ break
63
69
except subprocess .CalledProcessError :
64
70
pass
65
71
except OSError as e :
@@ -68,15 +74,7 @@ def new_js_proc():
68
74
else :
69
75
raise
70
76
71
- """ check nodejs version, if it is below certain threshold version,
72
- raise Runtime Exception. Such a test won't be required for docker nodejs"""
73
- if nodejs is not None :
74
- if check_js_threshold_version (working_alias ) is False :
75
- raise JavascriptException (u"cwltool requires updated version of Node.js engine. "
76
- "Try updating: https://docs.npmjs.com/getting-started/installing-node" )
77
-
78
-
79
- if nodejs is None :
77
+ if nodejs is None or nodejs is not None and required_node_version is False :
80
78
try :
81
79
nodeimg = "node:slim"
82
80
global have_node_slim
@@ -91,6 +89,7 @@ def new_js_proc():
91
89
"--sig-proxy=true" , "--interactive" ,
92
90
"--rm" , nodeimg , "node" , "--eval" , nodecode ],
93
91
stdin = subprocess .PIPE , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
92
+ docker = True
94
93
except OSError as e :
95
94
if e .errno == errno .ENOENT :
96
95
pass
@@ -99,12 +98,19 @@ def new_js_proc():
99
98
except subprocess .CalledProcessError :
100
99
pass
101
100
101
+ # docker failed and nodejs not on system
102
102
if nodejs is None :
103
103
raise JavascriptException (
104
104
u"cwltool requires Node.js engine to evaluate Javascript "
105
105
"expressions, but couldn't find it. Tried %s, docker run "
106
106
"node:slim" % u", " .join (trynodes ))
107
107
108
+ # docker failed, but nodejs is installed on system but the version is below the required version
109
+ if docker is False and required_node_version is False :
110
+ raise JavascriptException (
111
+ u'cwltool requires minimum v{} version of Node.js engine.' .format (minimum_node_version_str ),
112
+ u'Try updating: https://docs.npmjs.com/getting-started/installing-node' )
113
+
108
114
return nodejs
109
115
110
116
@@ -115,7 +121,7 @@ def execjs(js, jslib, timeout=None, debug=False): # type: (Union[Mapping, Text]
115
121
116
122
nodejs = localdata .proc
117
123
118
- fn = u"\" use strict\" ;\n %s\n (function()%s)()" % \
124
+ fn = u"\" use strict\" ;\n %s\n (function()%s)()" % \
119
125
(jslib , js if isinstance (js , basestring ) and len (js ) > 1 and js [0 ] == '{' else ("{return (%s);}" % js ))
120
126
121
127
killed = []
@@ -182,7 +188,7 @@ def stdfmt(data): # type: (unicode) -> unicode
182
188
nodejs .poll ()
183
189
184
190
if debug :
185
- info = u"returncode was: %s\n script was:\n %s\n stdout was: %s\n stderr was: %s\n " % \
191
+ info = u"returncode was: %s\n script was:\n %s\n stdout was: %s\n stderr was: %s\n " % \
186
192
(nodejs .returncode , fn_linenum (), stdfmt (stdoutdata ), stdfmt (stderrdata ))
187
193
else :
188
194
info = stdfmt (stderrdata )
0 commit comments