zephyr/scripts/build/subfolder_list.py
Jamie McCrae ec7044437e treewide: Disable automatic argparse argument shortening
Disables allowing the python argparse library from automatically
shortening command line arguments, this prevents issues whereby
a new command is added and code that wrongly uses the shortened
command of an existing argument which is the same as the new
command being added will silently change script behaviour.

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2023-01-26 20:12:36 +09:00

120 lines
3.6 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
"""Write subfolder list to a file
This script will walk the specified directory and write the file specified with
the list of all sub-directories found. If the output file already exists, the
file will only be updated in case sub-directories have been added or removed
since the previous invocation.
"""
import os
import argparse
def parse_args():
"""Parse command line arguments and options"""
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
allow_abbrev=False)
parser.add_argument('-d', '--directory', required=True,
help='Directory to walk for sub-directory discovery')
parser.add_argument('-c', '--create-links', required=False,
help='Create links for each directory found in \
directory given')
parser.add_argument('-o', '--out-file', required=True,
help='File to write containing a list of all \
directories found')
parser.add_argument('-t', '--trigger-file', required=False,
help='Trigger file to be be touched to re-run CMake')
args = parser.parse_args()
return args
def get_subfolder_list(directory, create_links=None):
"""Return subfolder list of a directory"""
dirlist = []
if create_links is not None:
if not os.path.exists(create_links):
os.makedirs(create_links)
symbase = os.path.basename(directory)
symlink = create_links + os.path.sep + symbase
if not os.path.exists(symlink):
os.symlink(directory, symlink)
dirlist.append(symlink)
else:
dirlist.append(directory)
for root, dirs, _ in os.walk(directory, topdown=True):
dirs.sort()
for subdir in dirs:
if create_links is not None:
targetdirectory = os.path.join(root, subdir)
reldir = os.path.relpath(targetdirectory, directory)
linkname = symbase + '_' + reldir.replace(os.path.sep, '_')
symlink = create_links + os.path.sep + linkname
if not os.path.exists(symlink):
os.symlink(targetdirectory, symlink)
dirlist.append(symlink)
else:
dirlist.append(os.path.join(root, subdir))
return dirlist
def gen_out_file(out_file, dirs):
"""Generate file with the list of directories
File won't be updated if it already exists and has the same content
"""
dirs_nl = "\n".join(dirs) + "\n"
if os.path.exists(out_file):
with open(out_file, 'r', encoding="utf-8") as out_file_fo:
out_file_dirs = out_file_fo.read()
if out_file_dirs == dirs_nl:
return
with open(out_file, 'w', encoding="utf-8") as out_file_fo:
out_file_fo.writelines(dirs_nl)
def touch(trigger):
"""Touch the trigger file
If no trigger file is provided then do a return.
"""
if trigger is None:
return
if os.path.exists(trigger):
os.utime(trigger, None)
else:
with open(trigger, 'w') as trigger_fo:
trigger_fo.write("")
def main():
"""Parse command line arguments and take respective actions"""
args = parse_args()
dirs = get_subfolder_list(args.directory, args.create_links)
gen_out_file(args.out_file, dirs)
# Always touch trigger file to ensure json files are updated
touch(args.trigger_file)
if __name__ == "__main__":
main()