114 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
| #!/usr/bin/env python3
 | |
| #
 | |
| # markdown-preprocess - filter *.md.in files, convert to .md
 | |
| #
 | |
| 
 | |
| import glob
 | |
| import os
 | |
| import re
 | |
| import sys
 | |
| 
 | |
| def main():
 | |
|     script_dir = os.path.abspath(os.path.dirname(__file__))
 | |
|     man_dir = os.path.join(script_dir,"../docs/source/markdown")
 | |
| 
 | |
|     try:
 | |
|         os.chdir(man_dir)
 | |
|     except FileNotFoundError:
 | |
|         raise Exception("Please invoke me from the base repo dir")
 | |
| 
 | |
|     # If called with args, process only those files
 | |
|     infiles = [ os.path.basename(x) for x in sys.argv[1:] ]
 | |
|     if len(infiles) == 0:
 | |
|         # Called without args: process all *.md.in files
 | |
|         infiles = glob.glob('*.md.in')
 | |
|     for infile in infiles:
 | |
|         process(infile)
 | |
| 
 | |
| def process(infile):
 | |
|     # Some options are the same between containers and pods; determine
 | |
|     # which description to use from the name of the source man page.
 | |
|     pod_or_container = 'container'
 | |
|     if '-pod-' in infile or '-kube-' in infile:
 | |
|         pod_or_container = 'pod'
 | |
| 
 | |
|     # foo.md.in -> foo.md -- but always write to a tmpfile
 | |
|     outfile = os.path.splitext(infile)[0]
 | |
|     outfile_tmp = outfile + '.tmp.' + str(os.getpid())
 | |
| 
 | |
| #    print("got here: ",infile, " -> ", outfile)
 | |
| 
 | |
|     with open(infile, 'r') as fh_in, open(outfile_tmp, 'w') as fh_out:
 | |
|         for line in fh_in:
 | |
|             # '@@option foo' -> include file options/foo.md
 | |
|             if line.startswith('@@option '):
 | |
|                 _, optionname = line.strip().split(" ")
 | |
|                 optionfile = os.path.join("options", optionname + '.md')
 | |
| 
 | |
|                 # Comment intended to help someone viewing the .md file.
 | |
|                 # Leading newline is important because if two lines are
 | |
|                 # consecutive without a break, sphinx (but not go-md2man)
 | |
|                 # treats them as one line and will unwantedly render the
 | |
|                 # comment in its output.
 | |
|                 fh_out.write("\n[//]: # (BEGIN included file " + optionfile + ")\n")
 | |
|                 with open(optionfile, 'r') as fh_optfile:
 | |
|                     for opt_line in fh_optfile:
 | |
|                         opt_line = replace_type(opt_line, pod_or_container)
 | |
|                         opt_line = opt_line.replace('<<subcommand>>', podman_subcommand(infile))
 | |
|                         opt_line = opt_line.replace('<<fullsubcommand>>', podman_subcommand(infile, 'full'))
 | |
|                         fh_out.write(opt_line)
 | |
|                 fh_out.write("\n[//]: # (END   included file " + optionfile + ")\n")
 | |
|             else:
 | |
|                 fh_out.write(line)
 | |
| 
 | |
|     os.chmod(outfile_tmp, 0o444)
 | |
|     os.rename(outfile_tmp, outfile)
 | |
| 
 | |
| # Given a file path of the form podman-foo-bar.1.md.in, return "foo bar"
 | |
| def podman_subcommand(string: str, full=None) -> str:
 | |
|     # Special case: 'podman-pod-start' becomes just 'start'
 | |
|     if not full:
 | |
|         if string.startswith("podman-pod-"):
 | |
|             string = string[len("podman-pod-"):]
 | |
|     if string.startswith("podman-"):
 | |
|         string = string[len("podman-"):]
 | |
|     if string.endswith(".1.md.in"):
 | |
|         string = string[:-len(".1.md.in")]
 | |
|     return string.replace("-", " ")
 | |
| 
 | |
| # Replace instances of '<<pod|container>>' with the desired one (based on
 | |
| # 'type' which is 'pod' or 'container').
 | |
| def replace_type(line: str, type: str) -> str:
 | |
|     # Internal helper function: determines the desired half of the <a|b> string
 | |
|     def replwith(matchobj):
 | |
|         lhs, rhs = matchobj[0].split('|')
 | |
|         # Strip off '<<' and '>>'
 | |
|         lhs = lhs[2:]
 | |
|         rhs = rhs[:len(rhs)-2]
 | |
| 
 | |
|         # Check both sides for 'pod' followed by (non-"m" or end-of-string).
 | |
|         # The non-m prevents us from triggering on 'podman', which could
 | |
|         # conceivably be present in both sides. And we check for 'pod',
 | |
|         # not 'container', because it's possible to have something like
 | |
|         # <<container in pod|container>>.
 | |
|         if re.match('.*pod([^m]|$)', lhs, re.IGNORECASE):
 | |
|             if re.match('.*pod([^m]|$)', rhs, re.IGNORECASE):
 | |
|                 raise Exception("'%s' matches 'pod' in both left and right sides" % matchobj[0])
 | |
|             # Only left-hand side has "pod"
 | |
|             if type == 'pod':
 | |
|                 return lhs
 | |
|             else:
 | |
|                 return rhs
 | |
|         else:
 | |
|             if not re.match('.*pod([^m]|$)', rhs, re.IGNORECASE):
 | |
|                 raise Exception("'%s' does not match 'pod' in either side" % matchobj[0])
 | |
|             if type == 'pod':
 | |
|                 return rhs
 | |
|             else:
 | |
|                 return lhs
 | |
| 
 | |
|     return re.sub('<<[^\|>]*\|[^\|>]*>>', replwith, line)
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main()
 |