#!/usr/bin/python # Copyright Istio Authors. All Rights Reserved. # # 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 argparse import sys import re import os import yaml linenum = 0 snipnum = 0 section = "" current_snip = None multiline_cmd = False output_started = False snippets = [] boilerplates = [] # Should be ordered to avoid non-deterministic results in `gencheck_istio` HEADER = """#!/bin/bash # shellcheck disable=SC2034,SC2153,SC2155,SC2164 # Copyright Istio Authors. All Rights Reserved. # # 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. #################################################################################################### # WARNING: THIS IS AN AUTO-GENERATED FILE, DO NOT EDIT. PLEASE MODIFY THE ORIGINAL MARKDOWN FILE: # %s #################################################################################################### """ startsnip = re.compile(r"^(\s*){{< text (syntax=)?\"?(\w+)\"? .*>}}$") boilerplate = re.compile(r"^\s*{{< boilerplate\s*\"?([a-zA-Z0-9-]+)\"? >}}$") snippetid = re.compile(r"snip_id=(\w+)") githubfile = re.compile(r"^(.*)(?}}", github_url) line = line.replace("istioctl install", "istioctl install --set values.pilot.env.PILOT_ENABLE_CONFIG_DISTRIBUTION_TRACKING=true") match = sectionhead.match(line) if match: snipnum = 0 section = invalidchar.sub('', match.group(1).strip().replace(" ", "_")).lower() continue match = startsnip.match(line) if match: snipnum += 1 indent = match.group(1) kind = match.group(3) match = snippetid.search(line) if match: if match.group(1) == "none": continue id = snipprefix + "_" + match.group(1) else: id = "%s_%s_%d" % (snipprefix, section, snipnum) if kind == "bash": script = "\n%s() {\n" % id else: script = "\n! read -r -d '' %s <<\ENDSNIP\n" % id current_snip = {"start": linenum, "id": id, "kind": kind, "indent": indent, "script": ["", script]} snippets.append(current_snip) continue match = boilerplate.match(line) if match: name = match.group(1) if not os.path.isfile(f'{boilerplatedir}/{name}.sh'): print(f"--> boilerplate {name} does not have snippets") continue if not name in boilerplates: boilerplates.append(name) continue if current_snip != None: if current_snip["indent"] and line.startswith(current_snip["indent"]): _, line = line.split(current_snip["indent"], 1) if "{{< /text >}}" in line: if current_snip["kind"] == "bash" and not output_started: script = "}\n" else: script = "ENDSNIP\n" current_snip["script"].append(script) current_snip = None multiline_cmd = False output_started = False else: if current_snip["kind"] == "bash": if line.startswith("$ "): line = line[2:] else: if multiline_cmd: if line == "EOF\n": multiline_cmd = False elif not current_snip["script"][-1].endswith("\\\n"): # command output if not output_started: current_snip["script"].append("}\n\n! read -r -d '' %s_out <<\ENDSNIP\n" % id) output_started = True while True: match = githubfile.match(line) if not match: break line = match.group(1) + match.group(2) + match.group(3) + "\n" match = execit.match(line) if match: msg = "ERROR: 'kubectl exec -it' will not work in test environment. Please remove -it from .md line: " + str(linenum) line = line + ">>> %s\n" % msg print(" " + msg) if heredoc.search(line): multiline_cmd = True line = line.replace("{{< istio_version >}}", istio_version) line = line.replace("{{< istio_full_version >}}", istio_full_version) line = line.replace("{{< istio_previous_version >}}", istio_previous_version) line = line.replace("{{< istio_full_version_revision >}}", istio_full_version_revision) line = line.replace("{{< istio_previous_version_revision >}}", istio_previous_version_revision) line = line.replace("{{< k8s_gateway_api_version >}}", k8s_gateway_api_version) current_snip["script"].append(line) if len(boilerplates) > 0: if boilerplatedir is None: print("boilerplate snippet directory is not defined. Use -b option to specify it") sys.exit(1) if len(snippets) == 0 and len(boilerplates) == 0: print("--> no snippet or boilerplate. skipping..") sys.exit(0) with open(os.path.join(snipdir, snipfile), 'w', encoding='utf-8') as f: f.write(HEADER % markdown.split("content/en/")[1] if "content/en/" in markdown else markdown) # There is an assumption here that boilerplate snippets generated # would be named .sh. See scripts/gen_snip.sh # for generating all snippets. There is some coupling between the two. for bp in boilerplates: boilerplate_snippets = f'{boilerplatedir}/{bp}.sh' source_line = f'source "{boilerplate_snippets}"\n' f.write(source_line) for snippet in snippets: lines = snippet["script"] for line in lines: f.write(line)