1#!/usr/bin/env python 2# 3# Copyright (C) 2023 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from typing import List 18from glob import glob 19from pathlib import Path 20from os.path import join, relpath 21import argparse 22 23class FileLister: 24 def __init__(self, args) -> None: 25 self.out_file = args.out_file 26 27 self.folder_dir = args.dir 28 self.extensions = [e if e.startswith(".") else "." + e for e in args.extensions] 29 self.root = args.root 30 self.files_list = list() 31 32 def get_files(self) -> None: 33 """Get all files directory in the input directory including the files in the subdirectories 34 35 Recursively finds all files in the input directory. 36 Set file_list as a list of file directory strings, 37 which do not include directories but only files. 38 List is sorted in alphabetical order of the file directories. 39 40 Args: 41 dir: Directory to get the files. String. 42 43 Raises: 44 FileNotFoundError: An error occurred accessing the non-existing directory 45 """ 46 47 if not dir_exists(self.folder_dir): 48 raise FileNotFoundError(f"Directory {self.folder_dir} does not exist") 49 50 if self.folder_dir[:-2] != "**": 51 self.folder_dir = join(self.folder_dir, "**") 52 53 self.files_list = list() 54 for file in sorted(glob(self.folder_dir, recursive=True)): 55 if Path(file).is_file(): 56 if self.root: 57 file = join(self.root, relpath(file, self.folder_dir[:-2])) 58 self.files_list.append(file) 59 60 61 def list(self) -> None: 62 self.get_files() 63 self.files_list = [f for f in self.files_list if not self.extensions or Path(f).suffix in self.extensions] 64 self.write() 65 66 def write(self) -> None: 67 if self.out_file == "": 68 pprint(self.files_list) 69 else: 70 write_lines(self.out_file, self.files_list) 71 72### 73# Helper functions 74### 75def pprint(l: List[str]) -> None: 76 for line in l: 77 print(line) 78 79def dir_exists(dir: str) -> bool: 80 return Path(dir).exists() 81 82def write_lines(out_file: str, lines: List[str]) -> None: 83 with open(out_file, "w+") as f: 84 f.writelines(line + '\n' for line in lines) 85 86if __name__ == '__main__': 87 parser = argparse.ArgumentParser() 88 parser.add_argument('dir', action='store', type=str, 89 help="directory to list all subdirectory files") 90 parser.add_argument('--out', dest='out_file', 91 action='store', default="", type=str, 92 help="optional directory to write subdirectory files. If not set, will print to console") 93 parser.add_argument('--root', dest='root', 94 action='store', default="", type=str, 95 help="optional directory to replace the root directories of output.") 96 parser.add_argument('--extensions', nargs='*', default=list(), dest='extensions', 97 help="Extensions to include in the output. If not set, all files are included") 98 99 args = parser.parse_args() 100 101 file_lister = FileLister(args) 102 file_lister.list() 103