1#!/usr/bin/env python3 2# SPDX-License-Identifier: Apache-2.0 3 4"""Write subfolder list to a file 5 6This script will walk the specified directory and write the file specified with 7the list of all sub-directories found. If the output file already exists, the 8file will only be updated in case sub-directories have been added or removed 9since the previous invocation. 10 11""" 12 13import os 14import argparse 15 16 17def parse_args(): 18 """Parse command line arguments and options""" 19 parser = argparse.ArgumentParser( 20 description=__doc__, 21 formatter_class=argparse.RawDescriptionHelpFormatter) 22 23 parser.add_argument('-d', '--directory', required=True, 24 help='Directory to walk for sub-directory discovery') 25 parser.add_argument('-c', '--create-links', required=False, 26 help='Create links for each directory found in \ 27 directory given') 28 parser.add_argument('-o', '--out-file', required=True, 29 help='File to write containing a list of all \ 30 directories found') 31 parser.add_argument('-t', '--trigger-file', required=False, 32 help='Trigger file to be be touched to re-run CMake') 33 34 args = parser.parse_args() 35 36 return args 37 38 39def get_subfolder_list(directory, create_links=None): 40 """Return subfolder list of a directory""" 41 dirlist = [] 42 43 if create_links is not None: 44 if not os.path.exists(create_links): 45 os.makedirs(create_links) 46 symbase = os.path.basename(directory) 47 symlink = create_links + os.path.sep + symbase 48 if not os.path.exists(symlink): 49 os.symlink(directory, symlink) 50 dirlist.append(symlink) 51 else: 52 dirlist.append(directory) 53 54 for root, dirs, _ in os.walk(directory, topdown=True): 55 dirs.sort() 56 for subdir in dirs: 57 if create_links is not None: 58 targetdirectory = os.path.join(root, subdir) 59 reldir = os.path.relpath(targetdirectory, directory) 60 linkname = symbase + '_' + reldir.replace(os.path.sep, '_') 61 symlink = create_links + os.path.sep + linkname 62 if not os.path.exists(symlink): 63 os.symlink(targetdirectory, symlink) 64 dirlist.append(symlink) 65 else: 66 dirlist.append(os.path.join(root, subdir)) 67 68 return dirlist 69 70 71def gen_out_file(out_file, dirs): 72 """Generate file with the list of directories 73 74 File won't be updated if it already exists and has the same content 75 76 """ 77 dirs_nl = "\n".join(dirs) + "\n" 78 79 if os.path.exists(out_file): 80 with open(out_file, 'r', encoding="utf-8") as out_file_fo: 81 out_file_dirs = out_file_fo.read() 82 83 if out_file_dirs == dirs_nl: 84 return 85 86 with open(out_file, 'w', encoding="utf-8") as out_file_fo: 87 out_file_fo.writelines(dirs_nl) 88 89 90def touch(trigger): 91 """Touch the trigger file 92 93 If no trigger file is provided then do a return. 94 95 """ 96 if trigger is None: 97 return 98 99 if os.path.exists(trigger): 100 os.utime(trigger, None) 101 else: 102 with open(trigger, 'w') as trigger_fo: 103 trigger_fo.write("") 104 105 106def main(): 107 """Parse command line arguments and take respective actions""" 108 args = parse_args() 109 110 dirs = get_subfolder_list(args.directory, args.create_links) 111 gen_out_file(args.out_file, dirs) 112 113 # Always touch trigger file to ensure json files are updated 114 touch(args.trigger_file) 115 116 117if __name__ == "__main__": 118 main() 119