1# Copyright (C) 2008 Canonical Ltd 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 2 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software 15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 17"""Custom module finder for entire package""" 18 19import modulefinder 20import os 21import sys 22 23 24class CustomModuleFinder(modulefinder.ModuleFinder): 25 """Custom module finder for processing python packages, 26 e.g. brz plugins packages. 27 28 :param path: list of directories to search for modules; 29 if not specified, python standard library only is used. 30 """ 31 32 def __init__(self, path=None, debug=0, excludes=[], replace_paths=[]): 33 if path is None: 34 path = [os.path.dirname(os.__file__)] # only python std lib 35 modulefinder.ModuleFinder.__init__( 36 self, path, debug, excludes, replace_paths) 37 38 def run_package(self, package_path): 39 """Recursively process each module in package with run_script method. 40 41 :param package_path: path to package directory. 42 """ 43 stack = [package_path] 44 while stack: 45 curdir = stack.pop(0) 46 py = os.listdir(curdir) 47 for i in py: 48 full = os.path.join(curdir, i) 49 if os.path.isdir(full): 50 init = os.path.join(full, '__init__.py') 51 if os.path.isfile(init): 52 stack.append(full) 53 continue 54 if not i.endswith('.py'): 55 continue 56 if i == 'setup.py': # skip 57 continue 58 self.run_script(full) 59 60 def get_result(self): 61 """Return 2-tuple: (list of packages, list of modules)""" 62 keys = sorted(self.modules.keys()) 63 mods = [] 64 packs = [] 65 for key in keys: 66 m = self.modules[key] 67 if not m.__file__: # skip builtins 68 continue 69 if m.__path__: 70 packs.append(key) 71 elif key != '__main__': 72 mods.append(key) 73 return (packs, mods) 74 75 76if __name__ == '__main__': 77 package = sys.argv[1] 78 79 mf = CustomModuleFinder() 80 mf.run_package(package) 81 82 packs, mods = mf.get_result() 83 84 print('Packages:') 85 print(packs) 86 87 print('Modules:') 88 print(mods) 89