11
11
import argparse
12
12
import subprocess
13
13
import tempfile
14
+ from typing import TextIO
14
15
from unittest import TestCase
15
16
from collections import namedtuple
16
17
@@ -120,7 +121,11 @@ def run_k6(script: Script, duration: str | None, verbose: bool) -> None:
120
121
print (line )
121
122
122
123
123
- def extract_scripts (text : str , lang : str = JS ) -> list [Script ]:
124
+ def extract_scripts (
125
+ text : str , lang : str = JS , index_env : dict [str , str ] | None = None
126
+ ) -> list [Script ]:
127
+ index_env = index_env or {}
128
+
124
129
# A somewhat complicated regex in order to make parsing of the code block
125
130
# easier. Essentially, takes this:
126
131
#
@@ -185,6 +190,13 @@ def extract_scripts(text: str, lang: str = JS) -> list[Script]:
185
190
args .append (opt .removeprefix (ARG ))
186
191
187
192
script_text = "\n " .join (lines [1 :])
193
+ for key , value in index_env .items ():
194
+ # Replace instances of '{{< param "FOO_BAR" >}}' with '1234', assuming
195
+ # the env value of FOO_BAR=1234.
196
+ script_text = re .sub (
197
+ r"{{ *< *param *\"" + key + '" *> *}}' , value , script_text
198
+ )
199
+
188
200
scripts .append (
189
201
Script (
190
202
text = script_text ,
@@ -198,6 +210,26 @@ def extract_scripts(text: str, lang: str = JS) -> list[Script]:
198
210
return scripts
199
211
200
212
213
+ def read_front_matter_env (f : TextIO ) -> dict [str , str ]:
214
+ # Read a Front Matter .md file with environment variables.
215
+ # The variables are actually in a YAML dictionary, but since
216
+ # I want to avoid 3rd party library, I will just try to parse
217
+ # them line-by-line.
218
+ result = {}
219
+ for line in f .readlines ():
220
+ if ":" not in line :
221
+ continue
222
+
223
+ parts = line .strip ().split (":" )
224
+ key , value = parts [0 ].strip (), parts [1 ].strip ()
225
+
226
+ # Look for YAML keys with ALL_CAPS_NAMES
227
+ if re .match (r"[A-Z0-9_]" , key ) and value :
228
+ result [key ] = value
229
+
230
+ return result
231
+
232
+
201
233
def main () -> None :
202
234
parser = argparse .ArgumentParser (
203
235
description = "Run k6 scripts within Markdown files."
@@ -215,6 +247,12 @@ def main() -> None:
215
247
default = None ,
216
248
help = "Override script(s) duration. Is not applied to browser tests." ,
217
249
)
250
+ parser .add_argument (
251
+ "--index-file" ,
252
+ type = argparse .FileType (),
253
+ default = None ,
254
+ help = "Path to Front Matter _index.md file containing environment variables." ,
255
+ )
218
256
parser .add_argument (
219
257
"--verbose" ,
220
258
"-v" ,
@@ -223,8 +261,13 @@ def main() -> None:
223
261
action = "store_true" ,
224
262
)
225
263
args = parser .parse_args ()
264
+ index_env = read_front_matter_env (args .index_file )
226
265
227
266
print ("Starting md-k6 script." )
267
+ print ("Front Matter variables:" )
268
+ for key , value in index_env .items ():
269
+ print (f" { key } ={ value } " )
270
+
228
271
print ("Reading from file:" , args .file .name )
229
272
230
273
lang = args .lang
@@ -234,7 +277,7 @@ def main() -> None:
234
277
print (f"Skipping entire file ({ SKIP_ALL } )." )
235
278
return
236
279
237
- scripts = extract_scripts (text , lang )
280
+ scripts = extract_scripts (text , lang , index_env )
238
281
239
282
if ":" in args .blocks :
240
283
range_parts = args .blocks .split (":" )
@@ -290,6 +333,17 @@ def testExtractScriptSimple(self):
290
333
self .assertEqual (len (scripts ), 1 )
291
334
self .assertEqual (scripts [0 ].text , "hello, world!" )
292
335
336
+ def testExtractScriptIndexEnv (self ):
337
+ text = """
338
+ ```javascript
339
+ {{< param "FOO_BAR" >}} {{ < param "FOO_BAR" > }}
340
+ ```
341
+ """
342
+ scripts = extract_scripts (text , JS , {"FOO_BAR" : "testing" })
343
+
344
+ self .assertEqual (len (scripts ), 1 )
345
+ self .assertEqual (scripts [0 ].text , "testing testing" )
346
+
293
347
def testExtractScriptOptions (self ):
294
348
text = """
295
349
<!-- md-k6:nofail,env.A=B,env.C=X- -->
0 commit comments