1515 - Support sequential markdown code block execution, leveraging [info strings](https://spec.commonmark.org/0.30/#info-string).
1616"""
1717
18+ def eprint (* args , ** kwargs ):
19+ print (* args , file = sys .stderr , ** kwargs )
20+
1821class ASTNode (object ):
1922
2023 _STACKQL_SHELL_INVOCATION : str = 'stackql-shell'
@@ -120,6 +123,7 @@ def parse_markdown_file(self, file_path: str, lang=None) -> MdAST:
120123class Expectation (object ):
121124
122125 _STDOUT_TABLE_CONTAINS_DATA : str = 'stdout-table-contains-data'
126+ _STDOUT_CONTAINS_ALL : str = 'stdout-contains-all'
123127
124128 def __init__ (self , node : ASTNode ):
125129 self ._node : ASTNode = node
@@ -142,7 +146,11 @@ def _contains_nonempty_table(self, s: str) -> bool:
142146
143147 def passes_stdout (self , actual_stdout : str ) -> bool :
144148 if self ._node .has_annotation (self ._STDOUT_TABLE_CONTAINS_DATA ):
149+ eprint (f'running expectation check: { self ._STDOUT_TABLE_CONTAINS_DATA } ' )
145150 return self ._contains_nonempty_table (actual_stdout )
151+ if self ._node .has_annotation (self ._STDOUT_CONTAINS_ALL ):
152+ eprint (f'running expectation check: { self ._STDOUT_CONTAINS_ALL } ' )
153+ return self ._node .get_text () in actual_stdout
146154 return True
147155
148156 def passes_stderr (self , actual_stderr : str ) -> bool :
@@ -240,7 +248,6 @@ def orchestrate(self, file_path: str) -> WorkloadDTO:
240248
241249class WalkthroughResult :
242250
243-
244251 def __init__ (self , stdout_str :str , stderr_str :str , rc :int ) -> None :
245252 self .stdout :str = stdout_str
246253 self .stderr :str = stderr_str
@@ -251,7 +258,7 @@ class SimpleRunner(object):
251258 def __init__ (self , workload : WorkloadDTO ):
252259 self ._workload = workload
253260
254- def run (self ) -> Tuple [ bytes , bytes ] :
261+ def run (self ) -> WalkthroughResult :
255262 bash_path = shutil .which ('bash' )
256263 pr : subprocess .Popen = subprocess .Popen (
257264 self ._workload .get_setup (),
@@ -282,13 +289,16 @@ def __init__(self):
282289 md_parser = MdParser ()
283290 self ._orchestrator : MdOrchestrator = MdOrchestrator (md_parser )
284291
285- def run_all (self , walkthrough_inodes : List [str ], recursive = True ) -> List [WalkthroughResult ]:
292+ def run_all (self , walkthrough_inodes : List [str ], recursive = True , skip_readme = True ) -> List [WalkthroughResult ]:
286293 results : List [WalkthroughResult ] = []
287294 for inode_path in walkthrough_inodes :
288295 is_dir = os .path .isdir (inode_path )
289296 if is_dir :
290297 for root , dirs , files in os .walk (inode_path ):
291298 for file in files :
299+ if skip_readme and file == 'README.md' :
300+ eprint (f'Skipping README.md' )
301+ continue
292302 file_path = os .path .join (root , file )
293303 print (f'File path: { file_path } ' )
294304 workload : WorkloadDTO = self ._orchestrator .orchestrate (file_path )
@@ -302,6 +312,9 @@ def run_all(self, walkthrough_inodes: List[str], recursive=True) -> List[Walkthr
302312 continue
303313 is_file = os .path .isfile (inode_path )
304314 if is_file :
315+ if skip_readme and file == 'README.md' :
316+ eprint (f'Skipping README.md' )
317+ continue
305318 file_path = inode_path
306319 workload : WorkloadDTO = self ._orchestrator .orchestrate (file_path )
307320 e2e : SimpleRunner = SimpleRunner (workload )
@@ -311,7 +324,7 @@ def run_all(self, walkthrough_inodes: List[str], recursive=True) -> List[Walkthr
311324 raise FileNotFoundError (f'Path not tractable: { inode_path } ' )
312325 return results
313326
314- def main ():
327+ def main ():
315328 runner : AllWalkthroughsRunner = AllWalkthroughsRunner ()
316329 results : List [WalkthroughResult ] = runner .run_all ([os .path .join (_REPOSITORY_ROOT_PATH , 'docs' , 'walkthroughs' )])
317330 for result in results :
0 commit comments