1#!/usr/bin/env python3 2# 3# Copyright (c) 2018, Nordic Semiconductor ASA 4# Copyright (c) 2017-2022, Intel Corporation 5# 6# SPDX-License-Identifier: Apache-2.0 7 8# Very quick script to move docs from different places into the doc directory 9# to fix the website and external links 10 11import argparse 12import errno 13import filecmp 14import fnmatch 15import os 16import re 17import shutil 18import sys 19 20# directives to parse for included files 21DIRECTIVES = ["figure","include","image","literalinclude", "graphviz"] 22 23ZEPHYR_BASE = "../" 24ZEPHYR_BUILD = None 25 26def copy_if_different(src, dst): 27 # Copies 'src' as 'dst', but only if dst does not exist or if itx contents 28 # differ from src.This avoids unnecessary # timestamp updates, which 29 # trigger documentation rebuilds. 30 if os.path.exists(dst) and filecmp.cmp(src, dst): 31 return 32 shutil.copyfile(src, dst) 33 34def get_files(all, dest, dir): 35 matches = [] 36 for root, dirnames, filenames in os.walk('%s/%s' %(ZEPHYR_BASE, dir)): 37 if ZEPHYR_BUILD: 38 if os.path.normpath(root).startswith(os.path.normpath(ZEPHYR_BUILD)): 39 # Build folder, skip it 40 continue 41 42 for filename in fnmatch.filter(filenames, '*' if all else '*.rst'): 43 matches.append(os.path.join(root, filename)) 44 for file in matches: 45 frel = file.replace(ZEPHYR_BASE,"").strip("/") 46 dir=os.path.dirname(frel) 47 if not os.path.exists(os.path.join(dest, dir)): 48 os.makedirs(os.path.join(dest, dir)) 49 50 copy_if_different(file, os.path.join(dest, frel)) 51 52 # Inspect only .rst files for directives referencing other files 53 # we'll need to copy (as configured in the DIRECTIVES variable) 54 if not fnmatch.fnmatch(file, "*.rst"): 55 continue 56 57 try: 58 with open(file, encoding="utf-8") as f: 59 content = f.readlines() 60 61 content = [x.strip() for x in content] 62 directives = "|".join(DIRECTIVES) 63 pattern = re.compile("\s*\.\.\s+(%s)::\s+(.*)" %directives) 64 for l in content: 65 m = pattern.match(l) 66 if m: 67 inf = m.group(2) 68 ind = os.path.dirname(inf) 69 if not os.path.exists(os.path.join(dest, dir, ind)): 70 os.makedirs(os.path.join(dest, dir, ind)) 71 72 src = os.path.join(ZEPHYR_BASE, dir, inf) 73 dst = os.path.join(dest, dir, inf) 74 try: 75 copy_if_different(src, dst) 76 77 except FileNotFoundError: 78 sys.stderr.write("File not found: %s\n reference by %s\n" % (inf, file)) 79 80 except UnicodeDecodeError as e: 81 sys.stderr.write( 82 "Malformed {} in {}\n" 83 " Context: {}\n" 84 " Problematic data: {}\n" 85 " Reason: {}\n".format( 86 e.encoding, file, 87 e.object[max(e.start - 40, 0):e.end + 40], 88 e.object[e.start:e.end], 89 e.reason)) 90 91 f.close() 92 93def main(): 94 95 parser = argparse.ArgumentParser(description='Recursively copy .rst files ' 96 'from the origin folder(s) to the ' 97 'destination folder, plus files referenced ' 98 'in those .rst files by a configurable ' 99 'list of directives: {}.'.format(DIRECTIVES)) 100 101 parser.add_argument('-a', '--all', action='store_true', help='Copy all files ' 102 '(recursively) in the specified source folder(s).') 103 parser.add_argument('dest', nargs=1) 104 parser.add_argument('src', nargs='+') 105 args = parser.parse_args() 106 107 dest = args.dest[0] 108 109 for d in args.src: 110 get_files(args.all, dest, d) 111 112if __name__ == "__main__": 113 main() 114