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 allow_abbrev=False) 23 24 parser.add_argument('-d', '--directory', required=True, 25 help='Directory to walk for sub-directory discovery') 26 parser.add_argument('-c', '--create-links', required=False, 27 help='Create links for each directory found in \ 28 directory given') 29 parser.add_argument('-o', '--out-file', required=True, 30 help='File to write containing a list of all \ 31 directories found') 32 parser.add_argument('-t', '--trigger-file', required=False, 33 help='Trigger file to be touched to re-run CMake') 34 35 args = parser.parse_args() 36 37 return args 38 39 40def get_subfolder_list(directory, create_links=None): 41 """Return subfolder list of a directory""" 42 dirlist = [] 43 44 if create_links is not None: 45 if not os.path.exists(create_links): 46 os.makedirs(create_links) 47 symbase = os.path.basename(directory) 48 symlink = create_links + os.path.sep + symbase 49 if not os.path.exists(symlink): 50 os.symlink(directory, symlink) 51 dirlist.append(symlink) 52 else: 53 dirlist.append(directory) 54 55 for root, dirs, _ in os.walk(directory, topdown=True): 56 dirs.sort() 57 for subdir in dirs: 58 if create_links is not None: 59 targetdirectory = os.path.join(root, subdir) 60 reldir = os.path.relpath(targetdirectory, directory) 61 linkname = symbase + '_' + reldir.replace(os.path.sep, '_') 62 symlink = create_links + os.path.sep + linkname 63 if not os.path.exists(symlink): 64 os.symlink(targetdirectory, symlink) 65 dirlist.append(symlink) 66 else: 67 dirlist.append(os.path.join(root, subdir)) 68 69 return dirlist 70 71 72def gen_out_file(out_file, dirs): 73 """Generate file with the list of directories 74 75 File won't be updated if it already exists and has the same content 76 77 """ 78 dirs_nl = "\n".join(dirs) + "\n" 79 80 if os.path.exists(out_file): 81 with open(out_file, 'r', encoding="utf-8") as out_file_fo: 82 out_file_dirs = out_file_fo.read() 83 84 if out_file_dirs == dirs_nl: 85 return 86 87 with open(out_file, 'w', encoding="utf-8") as out_file_fo: 88 out_file_fo.writelines(dirs_nl) 89 90 91def touch(trigger): 92 """Touch the trigger file 93 94 If no trigger file is provided then do a return. 95 96 """ 97 if trigger is None: 98 return 99 100 if os.path.exists(trigger): 101 os.utime(trigger, None) 102 else: 103 with open(trigger, 'w') as trigger_fo: 104 trigger_fo.write("") 105 106 107def main(): 108 """Parse command line arguments and take respective actions""" 109 args = parse_args() 110 111 dirs = get_subfolder_list(args.directory, args.create_links) 112 gen_out_file(args.out_file, dirs) 113 114 # Always touch trigger file to ensure json files are updated 115 touch(args.trigger_file) 116 117 118if __name__ == "__main__": 119 main() 120