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