#!/usr/bin/env python import os import sys from django.core.management import ManagementUtility from pycharm_run_utils import import_system_module from teamcity import teamcity_presence_env_var inspect = import_system_module("inspect") project_directory = sys.argv.pop() #ensure project directory is given priority when looking for settings files sys.path.insert(0, project_directory) #import settings to prevent circular dependencies later on import django.db try: from django.conf import settings apps = settings.INSTALLED_APPS except: pass from django.core import management try: # setup environment # this stuff was done earlier by setup_environ() which was removed in 1.4 sys.path.append(os.path.join(project_directory, os.pardir)) project_name = os.path.basename(os.path.normpath(project_directory)) __import__(project_name) except ImportError: # project has custom structure (project directory is not importable) pass finally: sys.path.pop() manage_file = os.getenv('PYCHARM_DJANGO_MANAGE_MODULE') if not manage_file: manage_file = 'manage' try: __import__(manage_file) except ImportError as e: print ("Failed to import" + str(manage_file) + " in ["+ ",".join(sys.path) +"] " + str(e)) settings_file = os.getenv('DJANGO_SETTINGS_MODULE') if not settings_file: settings_file = 'settings' import django if django.VERSION >= (1, 7): if not settings.configured: settings.configure() django.setup() def _create_command(): """ Creates PycharmTestCommand that inherits real Command class. Wrapped to method to make it is not called when module loaded but only when django fully initialized (lazy) """ class PycharmTestCommand(ManagementUtility().fetch_command("test").__class__): def get_runner(self): TEST_RUNNER = 'django_test_runner.run_tests' test_path = TEST_RUNNER.split('.') # Allow for Python 2.5 relative paths if len(test_path) > 1: test_module_name = '.'.join(test_path[:-1]) else: test_module_name = '.' test_module = __import__(test_module_name, {}, {}, test_path[-1]) test_runner = getattr(test_module, test_path[-1]) return test_runner def handle(self, *test_labels, **options): # handle south migration in tests commands = management.get_commands() if hasattr(settings, "SOUTH_TESTS_MIGRATE") and not settings.SOUTH_TESTS_MIGRATE: # point at the core syncdb command when creating tests # tests should always be up to date with the most recent model structure commands['syncdb'] = 'django.core' elif 'south' in settings.INSTALLED_APPS: try: from south.management.commands import MigrateAndSyncCommand commands['syncdb'] = MigrateAndSyncCommand() from south.hacks import hacks if hasattr(hacks, "patch_flush_during_test_db_creation"): hacks.patch_flush_during_test_db_creation() except ImportError: commands['syncdb'] = 'django.core' verbosity = int(options.get('verbosity', 1)) interactive = options.get('interactive', True) failfast = options.get('failfast', False) TestRunner = self.get_runner() if not inspect.ismethod(TestRunner): our_options = {"verbosity": int(verbosity), "interactive": interactive, "failfast": failfast} options.update(our_options) failures = TestRunner(test_labels, **options) else: test_runner = TestRunner(verbosity=verbosity, interactive=interactive, failfast=failfast) failures = test_runner.run_tests(test_labels) if failures: sys.exit(bool(failures)) return PycharmTestCommand() class PycharmTestManagementUtility(ManagementUtility): def __init__(self, argv=None): ManagementUtility.__init__(self, argv) def execute(self): from django_test_runner import is_nosetest if is_nosetest(settings): # New way to run django-nose is to install teamcity-runners plugin # there is no easy way to get qname in 2.7 so string is used name = "teamcity.nose_report.TeamcityReport" # emulate TC to enable plugin os.environ.update({teamcity_presence_env_var: "1"}) # NOSE_PLUGINS could be list or tuple. Adding teamcity plugin to it try: settings.NOSE_PLUGINS += [name] except TypeError: settings.NOSE_PLUGINS += (name, ) except AttributeError: settings.NOSE_PLUGINS = [name] # This file is required to init and monkeypatch new runners # noinspection PyUnresolvedReferences import _jb_runner_tools super(PycharmTestManagementUtility, self).execute() else: _create_command().run_from_argv(self.argv) if __name__ == "__main__": try: custom_settings = __import__(settings_file) splitted_settings = settings_file.split('.') if len(splitted_settings) != 1: settings_name = '.'.join(splitted_settings[:-1]) settings_module = __import__(settings_name, globals(), locals(), [splitted_settings[-1]]) custom_settings = getattr(settings_module, splitted_settings[-1]) except ImportError: print ("There is no such settings file " + str(settings_file) + "\n") try: subcommand = sys.argv[1] except IndexError: subcommand = 'help' # Display help if no arguments were given. if subcommand == 'test': utility = PycharmTestManagementUtility(sys.argv) else: utility = ManagementUtility() utility.execute()