# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import collections import os import re from pathlib import Path import marko Directive = collections.namedtuple('Directive', 'name args kwargs') TerraformExample = collections.namedtuple( 'TerraformExample', 'name code module files fixtures type directive readme_path header index') YamlExample = collections.namedtuple('YamlExample', 'body module schema directive') File = collections.namedtuple('File', 'path content') def get_tftest_directive(s): """Scan a code block and return a Directive object if there are any tftest directives""" regexp = rf"^ *# *(tftest\S*)(.*)$" if match := re.search(regexp, s, re.M): name, body = match.groups() args = [] kwargs = {} for arg in body.split(): if '=' in arg: l, r = arg.split('=', 1) kwargs[l] = r else: args.append(arg) return Directive(name, args, kwargs) return None def get_readme_examples(readme_path, fabric_root): """Find all code examples tagged for testing in a README file.""" readme_path = readme_path.resolve() fabric_root = fabric_root.resolve() doc = marko.parse(readme_path.read_text()) module = readme_path.parent path = module.relative_to(fabric_root) files = collections.defaultdict(dict) fixtures = {} examples = [] # first pass: collect all examples tagged with tftest-file or tftest-fixture last_header = None for child in doc.children: if isinstance(child, marko.block.FencedCode): code = child.children[0].children directive = get_tftest_directive(code) if directive is None: continue if directive.name == 'tftest-file': name, filepath = directive.kwargs['id'], directive.kwargs['path'] files[last_header][name] = File(filepath, code) if directive.name == 'tftest-fixture': name = directive.kwargs['id'] fixtures[name] = code elif isinstance(child, marko.block.Heading): last_header = child.children[0].children # second pass: collect all examples tagged with tftest last_header = None index = 0 for child in doc.children: if isinstance(child, marko.block.FencedCode): index += 1 code = child.children[0].children directive = get_tftest_directive(code) if directive is None: continue if child.lang in ('hcl', 'tfvars'): name = f'{path}:{last_header}' if index > 1: name += f' {index}' example_id = f'terraform:{path}:{last_header}:{index}' marks = [] if 'serial' in directive.args: marks.append('serial') example = TerraformExample(name, code, path, files[last_header], fixtures, child.lang, directive, readme_path, last_header, index) examples.append((example, example_id, marks, last_header, index)) elif child.lang == "yaml": schema = directive.kwargs.get('schema') if directive.name == "tftest-file" and schema: schema = module / 'schemas' / schema example = YamlExample(code, module, schema, directive) yaml_path = directive.kwargs['path'] example_id = f'yaml:{path}:{last_header}:{yaml_path}:{index}' examples.append((example, example_id, [], last_header, index)) elif isinstance(child, marko.block.Heading): last_header = child.children[0].children index = 0 return examples