| 36 | | def find_management_module(app_name): |
| 37 | | """ |
| 38 | | Determines the path to the management module for the given app_name, |
| 39 | | without actually importing the application or the management module. |
| 40 | | |
| 41 | | Raises ImportError if the management module cannot be found for any reason. |
| 42 | | """ |
| 43 | | # TODO: this method is only called from get_commands() which has already |
| 44 | | # imported the application module at that point. |
| 45 | | |
| 46 | | parts = app_name.split('.') |
| 47 | | parts.append('management') |
| 48 | | parts.reverse() |
| 49 | | part = parts.pop() |
| 50 | | path = None |
| 51 | | |
| 52 | | # When using manage.py, the project module is added to the path, |
| 53 | | # loaded, then removed from the path. This means that |
| 54 | | # testproject.testapp.models can be loaded in future, even if |
| 55 | | # testproject isn't in the path. When looking for the management |
| 56 | | # module, we need look for the case where the project name is part |
| 57 | | # of the app_name but the project directory itself isn't on the path. |
| 58 | | try: |
| 59 | | f, path, descr = imp.find_module(part, path) |
| 60 | | except ImportError as e: |
| 61 | | if os.path.basename(os.getcwd()) != part: |
| 62 | | raise e |
| 63 | | else: |
| 64 | | if f: |
| 65 | | f.close() |
| 66 | | |
| 67 | | while parts: |
| 68 | | part = parts.pop() |
| 69 | | f, path, descr = imp.find_module(part, [path] if path else None) |
| 70 | | if f: |
| 71 | | f.close() |
| 72 | | return path |
| 73 | | |
| 74 | | |
| 121 | | # Find and load the management module for each installed app. |
| 122 | | for app_name in reversed(app_names): |
| 123 | | try: |
| 124 | | path = find_management_module(app_name) |
| 125 | | commands.update({name: app_name for name in find_commands(path)}) |
| 126 | | except ImportError: |
| 127 | | pass # No management module - ignore this app |
| | 78 | app_configs = apps.get_app_configs() |
| | 79 | # Find management commands available for each installed app. |
| | 80 | for app_config in reversed(app_configs): |
| | 81 | path = os.path.join(app_config.path, 'management') |
| | 82 | commands.update({name: app_config.name for name in find_commands(path)}) |