Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save fboaventura/dbef70213a9d8f4b99a73ff0caeb54c6 to your computer and use it in GitHub Desktop.
Save fboaventura/dbef70213a9d8f4b99a73ff0caeb54c6 to your computer and use it in GitHub Desktop.
A tutorial example of A CLI module using an argparse.Action class instance to find all files in a directory tree
"""a tutorial example of A CLI module using an argparse.Action class instance to find all files in a directory tree
"""
from argparse import Action, ArgumentParser
from sys import argv, stderr, stdout
from os import _exit, scandir
from os.path import exists, isdir
__VERSION__ = "1.0.0"
class TraverseDirectoryTree(Action):
def __call__(self, parser, args, values, option_string=None):
if isdir(values):
value = self._find_all_the_files(values)
setattr(args, self.dest, value)
else:
raise ValueError(
"the path must be a real directory on your machine")
def _find_all_the_files(self, path):
"""a recursive function to take a path on a disk and find all the files in a complicated directory tree
:param str path: a directory path that is on disk
:rtype generator
"""
# call a for to iterate through the output of scandir
# this does a flat ls of the directory contents whether
# each content is a file or a directory or a symbolic link
for n_item in scandir(path):
# have to check if the item in hand is a directory
if n_item.is_dir():
# if it is a directory have to call the function
# with the path of the new item
yield from self._find_all_the_files(n_item.path)
# check if the item is a regular file
elif n_item.is_file():
# if it is a regular file add this to the generator
yield n_item.path
else:
# if the item is neither a directory nor a file then
# something is wierd about this directory
# and you need to know so that you can deal with it
stderr.write("{} cannot be recognized.\n".format(n_item.path))
def main():
"""a main method for the module. takes parameters passed
:rtype int
"""
arguments = ArgumentParser(description="A tool to find all regular files in a complex directory tree",
epilog="Copyright verbalhanglider, version " + __VERSION__)
arguments.add_argument("a_directory", action=TraverseDirectoryTree,
help="An absolute directory path")
parsed_args = arguments.parse_args()
try:
a_generator = parsed_args.a_directory
for a_file in a_generator:
stdout.write("{}\n".format(a_file))
return 0
except KeyboardInterrupt:
return 131
if __name__ == "__main__":
_exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment