def run_from_argv(self, argv): """ Set up any environment changes requested (e.g., Python path and Django settings), then run this command. If the command raises a ``CommandError``, intercept it and print it sensibly to stderr. If the ``--traceback`` option is present or the raised ``Exception`` is not ``CommandError``, raise it. """ self._called_from_command_line = True parser = self.create_parser(argv[0], argv[1]) if self.is_subcommand: options, args = parser.parse_known_args(argv[2:]) cmd_options = vars(options) # pass unknown args to the subcommand args = list(args) else: options = parser.parse_args(argv[2:]) cmd_options = vars(options) # Move positional args out of options to mimic legacy optparse args = cmd_options.pop('args', ()) base.handle_default_options(options) try: self.execute(*args, **cmd_options) except Exception as e: if options.traceback or not isinstance(e, base.CommandError): raise self.stderr.write('%s: %s' % (e.__class__.__name__, e)) sys.exit(1)
def run_from_argv(self, argv): if len(argv) <= 2 or argv[2] in ['-h', '--help']: stdout = OutputWrapper(sys.stdout) stdout.write(self.usage(argv[1])) sys.exit(1) subcommand_class = self._get_subcommand_class(argv[2]) parser = self.create_parser(argv[0], argv[2], subcommand_class) if hasattr(self, 'use_argparse') and self.use_argparse: subcommand_class.add_arguments(parser) options = parser.parse_args(argv[3:]) cmd_options = vars(options) args = cmd_options.pop('args', ()) else: options, args = parser.parse_args(argv[3:]) handle_default_options(options) try: subcommand_class.execute(*args, **options.__dict__) except Exception as e: if not isinstance(e, CommandError): if hasattr(settings, 'SENTRY_DSN'): dsn = settings.SENTRY_DSN elif hasattr(settings, 'RAVEN_CONFIG'): dsn = settings.RAVEN_CONFIG.get('dsn') else: raise sentry = Client(dsn) if not sentry.is_enabled(): raise sentry.get_ident(sentry.captureException()) self._write_error_in_stderr(e)
def run_from_argv(self, argv): """ Set up any environment changes requested (e.g., Python path and Django settings), then run this command. Customize this method to setup our own requirements """ parser = self.create_parser(argv[0], argv[1]) options, args = parser.parse_args(argv[2:]) handle_default_options(options) handle_custom_options(options) try: self.execute(*args, **options.__dict__) except Exception as e: logger.error( 'Command exception :%s(%s)' % (e.__class__.__name__, e), exc_info = sys.exc_info(), extra={ 'data':{ 'command': sys.argv[1], 'args':sys.argv } } )
def run_from_argv(self, argv): parser = self.create_parser(argv[0], argv[1]) options, args = parser.parse_args(argv[2:]) handle_default_options(options) if not options.settings:# or not options.settings.endswith(settings.ENV_NAME): raise ImproperlyConfigured("Settings file has to be specified" " explicitly when deploying") stderr = getattr(options, 'stderr', sys.stderr) try: if len(args) > 0 and args[0] == 'update': self.update(argv[0:2]+args) elif len(args) > 0 and args[0] == 'prepare': self.prepare() elif len(args) > 0 and args[0] == 'updatebackends': self._update(argv[0:2]+['--backends', 'update']+args[1:]) elif len(args) > 0 and args[0] == 'updatefast': self._update(argv[0:2]+['update']+args[1:]) elif len(args) > 0 and args[0] == 'preparefast': self.clean_upload() self.prepare_upload() else: appcfg.main(argv[1:2] + args + [PROJECT_DIR]) except Exception, e: if getattr(options, 'traceback', False): traceback.print_exc() else: stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) sys.exit(1)
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ parser = LaxOptionParser(usage="%prog subcommand [options] [args]", version=pinax.get_version(), option_list=BaseCommand.option_list) try: options, args = parser.parse_args(self.argv) handle_default_options(options) except: pass try: subcommand = self.argv[1] except IndexError: sys.stderr.write("Type '%s help' for usage.\n" % self.prog_name) sys.exit(1) if subcommand == "help": if len(args) > 2: self.fetch_command(args[2]).print_help(self.prog_name, args[2]) else: parser.print_lax_help() sys.stderr.write(self.main_help_text() + "\n") sys.exit(1) elif self.argv[1:] == ["--version"]: pass elif self.argv[1:] in [["--help"], ["-h"]]: parser.print_lax_help() sys.stderr.write(self.main_help_text() + "\n") else: self.fetch_command(subcommand).run_from_argv(self.argv)
def check_options(self): # django switched to argparse in version 1.8 if DJANGO_VERSION >= (1, 8): parser = base.CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False) parser.add_argument('--settings') parser.add_argument('--pythonpath') parser.add_argument(CONFIGURATION_ARGUMENT, help=CONFIGURATION_ARGUMENT_HELP) parser.add_argument('args', nargs='*') # catch-all try: options, args = parser.parse_known_args(self.argv[2:]) if options.configuration: os.environ[self.namevar] = options.configuration base.handle_default_options(options) except base.CommandError: pass # Ignore any option errors at this point. # django < 1.7 did use optparse else: from django.core.management import LaxOptionParser parser = LaxOptionParser(option_list=configuration_options, add_help_option=False) try: options, args = parser.parse_args(self.argv) if options.configuration: os.environ[self.namevar] = options.configuration except: pass # Ignore any option errors at this point.
def run_from_argv(self, argv): if len(argv) <= 2 or argv[2] in ['-h', '--help']: print self.usage(argv[1]) sys.exit(1) subcommand_class = self._get_subcommand_class(argv[2]) parser = self.create_parser(argv[0], argv[2], subcommand_class) if hasattr(self, 'use_argparse') and self.use_argparse: subcommand_class.add_arguments(parser) options = parser.parse_args(argv[3:]) cmd_options = vars(options) args = cmd_options.pop('args', ()) else: options, args = parser.parse_args(argv[3:]) handle_default_options(options) try: subcommand_class.execute(*args, **options.__dict__) except Exception as e: if not isinstance(e, CommandError): if hasattr(settings, 'SENTRY_DSN'): dsn = settings.SENTRY_DSN elif hasattr(settings, 'RAVEN_CONFIG'): dsn = settings.RAVEN_CONFIG.get('dsn') else: raise sentry = Client(dsn) # Force sync transport to avoid race condition with the process exiting for url in sentry.servers: parsed = urlparse.urlparse(url) transport = sentry._registry.get_transport(parsed) transport.async = False sentry.get_ident(sentry.captureException()) self._write_error_in_stderr(e)
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ try: subcommand = self.argv[1] except IndexError: subcommand = 'help' # Display help if no arguments were given. # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False) parser.add_argument('--settings') parser.add_argument('--pythonpath') parser.add_argument('args', nargs='*') # catch-all try: options, args = parser.parse_known_args(self.argv[2:]) handle_default_options(options) except CommandError: pass # Ignore any option errors at this point. no_settings_commands = [ 'help', 'version', '--help', '--version', '-h', 'compilemessages', 'makemessages', 'startapp', 'startproject', ] try: settings.INSTALLED_APPS except ImproperlyConfigured as exc: self.settings_exception = exc # A handful of built-in management commands work without settings. # Load the default settings -- where INSTALLED_APPS is empty. if subcommand in no_settings_commands: settings.configure() if settings.configured: django.setup() self.autocomplete() if subcommand == 'help': if '--commands' in args: sys.stdout.write(self.main_help_text(commands_only=True) + '\n') elif len(options.args) < 1: sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(options.args[0]).print_help(self.prog_name, options.args[0]) # Special-cases: We want 'django-admin --version' and # 'django-admin --help' to work, for backwards compatibility. elif subcommand == 'version' or self.argv[1:] == ['--version']: sys.stdout.write(django.get_version() + '\n') elif self.argv[1:] in (['--help'], ['-h']): sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(subcommand).run_from_argv(self.argv)
def run_from_argv(self, argv): """ Set up any environment changes requested (e.g., Python path and Django settings), then run this command. """ parser = self.create_parser(argv[0], argv[1]) self.arguments = parser.parse_args(argv[2:]) handle_default_options(self.arguments) options = vars(self.arguments) self.execute(**options)
def run_from_argv(self, argv): parser = self.create_parser(argv[0], argv[1]) default_args = getattr(settings, 'DEVSERVER_ARGS', None) if default_args: options, args = parser.parse_args(default_args) else: options = None options, args = parser.parse_args(argv[2:], options) handle_default_options(options) self.execute(*args, **options.__dict__)
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = LaxOptionParser(usage="%prog subcommand [options] [args]", version=django.get_version(), option_list=BaseCommand.option_list) try: options, args = parser.parse_args(self.argv) handle_default_options(options) except: pass # Ignore any option errors at this point. try: subcommand = self.argv[1] except IndexError: sys.stderr.write("Type '%s help' for usage.\n" % self.prog_name) sys.exit(1) if subcommand == 'help': if len(args) > 2: self.fetch_command(args[2]).print_help(self.prog_name, args[2]) else: parser.print_lax_help() sys.stderr.write(self.main_help_text() + '\n') sys.exit(1) # Special-cases: We want 'manage.py --version' and # 'manage.py --help' to work, for backwards compatibility. elif self.argv[1:] == ['--version']: # LaxOptionParser already takes care of printing the version. pass elif self.argv[1:] == ['--help']: parser.print_lax_help() sys.stderr.write(self.main_help_text() + '\n') else: from django.db import connections, DEFAULT_DB_ALIAS db = options.__dict__.get('database', DEFAULT_DB_ALIAS) mysql_workaround = subcommand == "syncdb" and settings.DATABASES[db]['ENGINE'] == "mysql" if mysql_workaround: connection = connections[db] cursor = connection.cursor() cursor.execute("SET FOREIGN_KEY_CHECKS = 0") self.fetch_command(subcommand).run_from_argv(self.argv) if mysql_workaround: cursor = connection.cursor() cursor.execute("SET FOREIGN_KEY_CHECKS = 1")
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = LaxOptionParser(usage="%prog subcommand [options] [args]", version=get_version(), option_list=BaseCommand.option_list) try: options, args = parser.parse_args(self.argv) handle_default_options(options) except: # Needed because parser.parse_args can raise SystemExit pass # Ignore any option errors at this point. try: settings.INSTALLED_APPS except ImproperlyConfigured: # Some commands are supposed to work without configured settings pass else: django.setup() self.autocomplete() try: subcommand = self.argv[1] except IndexError: subcommand = 'help' # Display help if no arguments were given. if subcommand == 'help': if len(args) <= 2: parser.print_lax_help() sys.stdout.write(self.main_help_text() + '\n') elif args[2] == '--commands': sys.stdout.write(self.main_help_text(commands_only=True) + '\n') else: self.fetch_command(args[2]).print_help(self.prog_name, args[2]) elif subcommand == 'version': sys.stdout.write(parser.get_version() + '\n') # Special-cases: We want 'django-admin.py --version' and # 'django-admin.py --help' to work, for backwards compatibility. elif self.argv[1:] == ['--version']: # LaxOptionParser already takes care of printing the version. pass elif self.argv[1:] in (['--help'], ['-h']): parser.print_lax_help() sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(subcommand).run_from_argv(self.argv)
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = LaxOptionParser(usage="%prog subcommand [options] [args]", version=get_version(), option_list=BaseCommand.option_list) self.autocomplete() try: # 预处理某些选项, 这些不属于子命令 # %prog subcommand [options] [args] 分析脚本的参数, 为的是提取出 # x.py subcommand --setting xxx 中的 --setting xxx, 必须提前处理 # 在 BaseCommand 中就有 --settings 和 --pythonpath 选项. options, args = parser.parse_args(self.argv) handle_default_options(options) except: pass # Ignore any option errors at this point. try: # argv[0] 是脚本名, argv[1] 是子命令 subcommand = self.argv[1] 命令 except IndexError: subcommand = 'help' # Display help if no arguments were given. if subcommand == 'help': if len(args) <= 2: # 直接返回 x.py 对应的帮助文档 parser.print_lax_help() sys.stdout.write(self.main_help_text() + '\n') elif args[2] == '--commands': # 只返回所有的命令 sys.stdout.write(self.main_help_text(commands_only=True) + '\n') else: self.fetch_command(args[2]).print_help(self.prog_name, args[2]) elif subcommand == 'version': sys.stdout.write(parser.get_version() + '\n') # Special-cases: We want 'django-admin.py --version' and # 'django-admin.py --help' to work, for backwards compatibility. 向后兼容 elif self.argv[1:] == ['--version']: # LaxOptionParser already takes care of printing the version. pass elif self.argv[1:] in (['--help'], ['-h']): parser.print_lax_help() sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(subcommand).run_from_argv(self.argv) # 所有的命令调用都从 run_from_argv()
def _execute_command(command, command_name, stdout, stderr, argv): parser = command.create_parser("manage.py", command_name) options, argss = parser.parse_args(argv.split()) handle_default_options(options) options.__dict__["stdout"] = stdout options.__dict__["stderr"] = stderr options.__dict__['interactive'] = False #import debugger; debugger.pdb().set_trace() try: return command.execute(*argss, **options.__dict__) except SystemExit, e: pass
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. Taken from django execute method, but enabling all active plugins before execution. """ # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = django_management.LaxOptionParser(usage="%prog subcommand [options] [args]", version=django_management.get_version(), option_list=BaseCommand.option_list) try: options, args = parser.parse_args(self.argv) handle_default_options(options) except: pass # Ignore any option errors at this point. try: subcommand = self.argv[1] except IndexError: sys.stderr.write("Type '%s help' for usage.\n" % self.prog_name) sys.exit(1) if subcommand == 'help': if len(args) > 2: self.fetch_command(args[2]).print_help(self.prog_name, args[2]) else: parser.print_lax_help() sys.stderr.write(self.main_help_text() + '\n') sys.exit(1) # Special-cases: We want 'django-admin.py --version' and # 'django-admin.py --help' to work, for backwards compatibility. elif self.argv[1:] == ['--version']: # LaxOptionParser already takes care of printing the version. pass elif self.argv[1:] == ['--help']: parser.print_lax_help() sys.stderr.write(self.main_help_text() + '\n') else: command = self.fetch_command(subcommand) if subcommand not in ['migrate', 'syncdb', 'startproject', 'dbshell', 'rebuild_db', 'restore_config', 'schemamigration', 'datamigration', 'backupdb', 'startplugin']: # This is override fragment of Django execute method # only works if models have been created (not with syncdb, startproject neither migrate) from merengue.pluggable import enable_active_plugins enable_active_plugins() command.run_from_argv(self.argv)
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = LaxOptionParser(usage="%prog subcommand [options] [args]", version=django.get_version(), option_list=BaseCommand.option_list) try: configglue_parser = settings.__CONFIGGLUE_PARSER__ parser, options, args = schemaconfigglue(configglue_parser, op=parser, argv=self.argv) # remove schema-related options from the argv list self.argv = args utils.update_settings(configglue_parser, settings) except AttributeError: # no __CONFIGGLUE_PARSER__ found, fall back to standard django # options parsing options, args = parser.parse_args(self.argv) handle_default_options(options) except: # Ignore any option errors at this point. args = self.argv try: subcommand = self.argv[1] except IndexError: sys.stderr.write("Type '%s help' for usage.\n" % self.prog_name) sys.exit(1) if subcommand == 'help': if len(args) > 2: self.fetch_command(args[2]).print_help(self.prog_name, args[2]) else: parser.print_lax_help() sys.stderr.write(self.main_help_text() + '\n') sys.exit(1) # Special-cases: We want 'django-admin.py --version' and # 'django-admin.py --help' to work, for backwards compatibility. elif self.argv[1:] == ['--version']: # LaxOptionParser already takes care of printing the version. pass elif self.argv[1:] == ['--help']: parser.print_lax_help() sys.stderr.write(self.main_help_text() + '\n') else: self.fetch_command(subcommand).run_from_argv(self.argv)
def _handle_argv(self, subcommand, argv): """The universal Django command arguments parser.""" parser = subcommand.create_parser(argv[0], argv[1]) if hasattr(subcommand, 'use_argparse') and subcommand.use_argparse: options = parser.parse_args(argv[2:]) cmd_options = vars(options) # Move positional args out of options to mimic legacy optparse args = cmd_options.pop('args', ()) else: options, args = parser.parse_args(argv[2:]) cmd_options = vars(options) handle_default_options(options) return args, cmd_options
def run_from_argv(self, argv): parser = self.create_parser(argv[0], argv[1]) options = parser.parse_args(argv[2:]) handle_default_options(options) try: self.execute(**options.__dict__) except Exception as e: if options.traceback or not isinstance(e, CommandError): raise # self.stderr is not guaranteed to be set here stderr = getattr(self, 'stderr', OutputWrapper(sys.stderr, self.style.ERROR)) stderr.write('%s: %s' % (e.__class__.__name__, e)) sys.exit(1)
def check_options(self): parser = base.CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False) parser.add_argument('--settings') parser.add_argument('--pythonpath') parser.add_argument(CONFIGURATION_ARGUMENT, help=CONFIGURATION_ARGUMENT_HELP) parser.add_argument('args', nargs='*') # catch-all try: options, args = parser.parse_known_args(self.argv[2:]) if options.configuration: os.environ[self.namevar] = options.configuration base.handle_default_options(options) except base.CommandError: pass # Ignore any option errors at this point.
def run_from_argv(self, argv): """Set up any environment changes requested (e.g., Python path and Django settings), then run this command. """ if len(argv) > 2 and not argv[2].startswith('-') and argv[2] in self.commands.keys(): subcommand = self.commands[argv[2]] klass = self.get_subcommand(subcommand) parser = OptionParser(prog=argv[0], usage=klass.usage(u'{0} {1}'.format(argv[1], subcommand)), version=klass.get_version(), option_list=klass.option_list) options, args = parser.parse_args(argv[3:]) args = [subcommand] + args else: parser = self.create_parser(argv[0], argv[1]) options, args = parser.parse_args(argv[2:]) handle_default_options(options) self.execute(*args, **options.__dict__)
def command_echo(self, params): keys = commands.keys() cmd = self.raw_input cmd = next(k for k in keys if cmd.startswith(k)) if cmd: argv = ['telnetsrv', cmd] + params cmd = commands[cmd]['cmd'] try: parser = cmd.create_parser(argv[0], argv[1]) options, args = parser.parse_args(argv[2:]) handle_default_options(options) try: cmd.execute(stdout=self, *args, **options.__dict__) except Exception as e: self.writeerror(str(e)) self.write("\n") except Exception, e: self.writeerror(str(e))
def run_from_argv(self, argv): argv.pop(1) parser = OptionParser() parser.add_option('--schema', default='public') schema_opt = [] for arg in argv: if '--schema' in arg: schema_opt.append(argv.pop(argv.index(arg))) break options, args = parser.parse_args(schema_opt) self.schema = options.__dict__.get('schema', 'public') self.cmd = argv[1] parser = self.create_parser(argv[0], argv[1]) options, args = parser.parse_args(argv[2:]) handle_default_options(options) self.execute(*args, **options.__dict__)
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = LaxOptionParser( usage="%prog subcommand [options] [args]", version=get_version(), option_list=BaseCommand.option_list ) self.autocomplete() try: options, args = parser.parse_args(self.argv) handle_default_options(options) except: pass # Ignore any option errors at this point. try: subcommand = self.argv[1] except IndexError: subcommand = "help" # Display help if no arguments were given. if subcommand == "help": if len(args) <= 2: parser.print_lax_help() sys.stdout.write(self.main_help_text() + "\n") elif args[2] == "--commands": sys.stdout.write(self.main_help_text(commands_only=True) + "\n") else: self.fetch_command(args[2]).print_help(self.prog_name, args[2]) elif subcommand == "version": sys.stdout.write(parser.get_version() + "\n") # Special-cases: We want 'django-admin.py --version' and # 'django-admin.py --help' to work, for backwards compatibility. elif self.argv[1:] == ["--version"]: # LaxOptionParser already takes care of printing the version. pass elif self.argv[1:] in (["--help"], ["-h"]): parser.print_lax_help() sys.stdout.write(self.main_help_text() + "\n") else: self.fetch_command(subcommand).run_from_argv(self.argv)
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = LaxOptionParser(usage="%prog subcommand [options] [args]", version=get_version(), option_list=BaseCommand.option_list) self.autocomplete() try: options, args = parser.parse_args(self.argv) handle_default_options(options) except: pass # Ignore any option errors at this point. try: subcommand = self.argv[1] except IndexError: sys.stderr.write("Type '%s help' for usage.\n" % self.prog_name) sys.exit(1) if subcommand == 'help': if len(args) > 2: self.fetch_command(args[2]).print_help(self.prog_name, args[2]) else: parser.print_lax_help() sys.stderr.write(self.main_help_text() + '\n') sys.exit(1) # Special-cases: We want 'django-admin.py --version' and # 'django-admin.py --help' to work, for backwards compatibility. elif self.argv[1:] == ['--version']: # LaxOptionParser already takes care of printing the version. pass elif self.argv[1:] == ['--help']: parser.print_lax_help() sys.stderr.write(self.main_help_text() + '\n') else: self.fetch_command(subcommand).run_from_argv(self.argv)
def execute_command(command, *args): try: app_name = get_commands()[command] except KeyError: raise ImmediateHttpResponse('Error getting management command details') if isinstance(app_name, BaseCommand): # If the command is already loaded, use it directly. klass = app_name else: klass = load_command_class(app_name, command) command_args = list(args) parser = klass.create_parser(app_name, command) options, arguments = parser.parse_args(command_args) handle_default_options(options) options = options.__dict__ command_result = StringIO() options.update({ 'interactive': False, 'stdout': command_result }) result = None try: klass.execute(*arguments, **options) command_result.seek(0) result = command_result.read() except Exception, e: logger.error( 'Command: %s, args: %s, kwargs: %s. Error: %s', command, ', '.join(arguments), str(e) )
def run_from_argv(self, argv): """ Set up any environment changes requested (e.g., Python path and Django settings), then run this command. If the command raises a ``CommandError``, intercept it and print it sensibly to stderr. """ signal_pre_run.send(self, argv=argv) parser = self.create_parser(argv[0], argv[1]) options, args = parser.parse_args(argv[2:]) handle_default_options(options) try: result = self.execute(*args, **options.__dict__) except SystemExit as e: signal_post_run.send(self, status=e.code) raise except BaseException: result = self.handle_execute_exc(options) if result is None: result = 1 status = result or 0 signal_post_run.send(self, status=status) sys.exit(status)
def run_from_argv(self, argv): if len(argv) <= 2 or argv[2] in ['-h', '--help']: print self.usage(argv[1]) sys.exit(1) subcommand_class = self._get_subcommand_class(argv[2]) parser = self.create_parser(argv[0], argv[2], subcommand_class) options, args = parser.parse_args(argv[3:]) handle_default_options(options) try: subcommand_class.execute(*args, **options.__dict__) except Exception as e: if not isinstance(e, CommandError): if hasattr(settings, 'SENTRY_DSN'): dsn = settings.SENTRY_DSN elif hasattr(settings, 'RAVEN_CONFIG'): dsn = settings.RAVEN_CONFIG.get('dsn') else: raise sentry = Client(dsn) sentry.get_ident(sentry.captureException()) self._write_error_in_stderr(e)
def run(self, hook, errorHandler=None): t1 = datetime.now() self.status = self.STATUS_ENUM_INPROGRESS # set status "in progress" self.save() # --- RUN --- # if errorHandler: errorHandler.flush() params = [it.strip() for it in self.common_params.split(" ")] try: obj = hook() parser = obj.create_parser("./manage.py", self.common) options, args = parser.parse_args(params) # workaround - since django 1.8 settings and pythonpath is not # set by parse_args options.settings = None options.pythonpath = None handle_default_options(options) obj.execute(*args, **options.__dict__) self.status = self.STATUS_ENUM_DONE # set status "done" except Exception as e: self.exit_result = traceback.format_exc() self.status = self.STATUS_ENUM_ERROR # set status "error" logger.exception(e) # Get all errors from logger if errorHandler: for er in errorHandler.flush(): self.exit_result += er.getMessage() + "\n" # --- END RUN --- # t0 = datetime.now() t2 = t0 - t1 self.time_long = t2.seconds + t2.microseconds / 1000000.0 self.date_run = t0 self.save()
def run_from_argv(self, argv): """ Set up any environment changes requested (e.g., Python path and Django settings), then run this command. If the command raises a ``CommandError``, intercept it and print it sensibly to stderr. """ parser = self.create_parser(argv[0], argv[1]) args = parser.parse_args(argv[2:]) handle_default_options(args) try: self.execute(args) except Exception as e: # self.stderr is not guaranteed to be set here try: fallback_stderr = OutputWrapper(sys.stderr, self.style.ERROR) except: fallback_stderr = self.stdout stderr = getattr(self, 'stderr', fallback_stderr) if args.traceback: stderr.write(traceback.format_exc()) else: stderr.write('%s: %s' % (e.__class__.__name__, e)) sys.exit(1)
def execute(self): """ Given the command-line arguments, figure out which subcommand is being run, create a parser appropriate to that command, and run it. 1、命令行参数解析 2、 """ try: # 如果在调用django-admin 的时候没有给出任何的 命令 & 选项 # 那么slef.argv 列表只有一项 它就是slef.argv[0] 它的值为django-admin # 所以这种情况下正好会报 IndexError subcommand = self.argv[1] except IndexError: # 如果没有给出任何命令的情况下 把subcommand设置为help # 也就是说不给出命令的情况下 就当做是看django-admin的帮助. subcommand = 'help' # Display help if no arguments were given. # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. # django 在标准库的argparser上作出了一些自定义 # CommandParser 继承了argparser.ArgumentParser # CommandParser 位于 jango.core.management.base 这个包中. # usage & add_help 都是argparser.ArgumentParser.__init__中的参数 # CommandParser.__init__(self, cmd, **kwargs): 由这里可以看了cmd=None parser = CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False) parser.add_argument('--settings') parser.add_argument('--pythonpath') parser.add_argument('args', nargs='*') # catch-all try: options, args = parser.parse_known_args(self.argv[2:]) handle_default_options(options) except CommandError: pass # Ignore any option errors at this point. try: # settings 是在django.conf包中LazySettings类的实例 # 这里有个问题,就是在LazySettings类的代码中没有找到INSTALLED_APPS 的定义 # settings.INSTALLED_APPS 像这样的语句又有什么意义呢?难道它这样干就单单是为了引发异常? settings.INSTALLED_APPS except ImproperlyConfigured as exc: self.settings_exception = exc if settings.configured: # Start the auto-reloading dev server even if the code is broken. # The hardcoded condition is a code smell but we can't rely on a # flag on the command class because we haven't located it yet. if subcommand == 'runserver' and '--noreload' not in self.argv: try: autoreload.check_errors(django.setup)() except Exception: # The exception will be raised later in the child process # started by the autoreloader. Pretend it didn't happen by # loading an empty list of applications. apps.all_models = defaultdict(OrderedDict) apps.app_configs = OrderedDict() apps.apps_ready = apps.models_ready = apps.ready = True # Remove options not compatible with the built-in runserver # (e.g. options for the contrib.staticfiles' runserver). # Changes here require manually testing as described in # #27522. _parser = self.fetch_command('runserver').create_parser( 'django', 'runserver') _options, _args = _parser.parse_known_args(self.argv[2:]) for _arg in _args: self.argv.remove(_arg) # In all other cases, django.setup() is required to succeed. else: django.setup() self.autocomplete() if subcommand == 'help': if '--commands' in args: sys.stdout.write( self.main_help_text(commands_only=True) + '\n') elif len(options.args) < 1: sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(options.args[0]).print_help( self.prog_name, options.args[0]) # Special-cases: We want 'django-admin --version' and # 'django-admin --help' to work, for backwards compatibility. elif subcommand == 'version' or self.argv[1:] == ['--version']: sys.stdout.write(django.get_version() + '\n') elif self.argv[1:] in (['--help'], ['-h']): sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(subcommand).run_from_argv(self.argv)
def execute(self): """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ try: subcommand = self.argv[1] except IndexError: subcommand = 'help' # Display help if no arguments were given. # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False) parser.add_argument('--settings') parser.add_argument('--pythonpath') parser.add_argument('args', nargs='*') # catch-all try: options, args = parser.parse_known_args(self.argv[2:]) handle_default_options(options) except CommandError: pass # Ignore any option errors at this point. try: settings.INSTALLED_APPS except ImproperlyConfigured as exc: self.settings_exception = exc if settings.configured: # Start the auto-reloading dev server even if the code is broken. # The hardcoded condition is a code smell but we can't rely on a # flag on the command class because we haven't located it yet. if subcommand == 'runserver' and '--noreload' not in self.argv: try: autoreload.check_errors(django.setup)() except Exception: # The exception will be raised later in the child process # started by the autoreloader. Pretend it didn't happen by # loading an empty list of applications. apps.all_models = defaultdict(OrderedDict) apps.app_configs = OrderedDict() apps.apps_ready = apps.models_ready = apps.ready = True # Remove options not compatible with the built-in runserver # (e.g. options for the contrib.staticfiles' runserver). # Changes here require manually testing as described in # #27522. _parser = self.fetch_command('runserver').create_parser('django', 'runserver') _options, _args = _parser.parse_known_args(self.argv[2:]) for _arg in _args: self.argv.remove(_arg) # In all other cases, django.setup() is required to succeed. else: django.setup() self.autocomplete() if subcommand == 'help': if '--commands' in args: sys.stdout.write(self.main_help_text(commands_only=True) + '\n') elif len(options.args) < 1: sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(options.args[0]).print_help(self.prog_name, options.args[0]) # Special-cases: We want 'django-admin --version' and # 'django-admin --help' to work, for backwards compatibility. elif subcommand == 'version' or self.argv[1:] == ['--version']: sys.stdout.write(django.get_version() + '\n') elif self.argv[1:] in (['--help'], ['-h']): sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(subcommand).run_from_argv(self.argv)
def execute(self): """ Given the command-line arguments, figure out which subcommand is being run, create a parser appropriate to that command, and run it. """ # 1 Subcommand: 子程序名, 默认为help, 见上面定义 try: subcommand = self.argv[1] except IndexError: subcommand = 'help' # Display help if no arguments were given. # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. # 2 处理和解析参数 parser = CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False) parser.add_argument('--settings') parser.add_argument('--pythonpath') parser.add_argument('args', nargs='*') # catch-all try: options, args = parser.parse_known_args(self.argv[2:]) handle_default_options(options) except CommandError: pass # Ignore any option errors at this point. MY(1.0, '解析后的参数:', '\n\toptions:', options, '\n\targs:', args) # 3 LazySetting对象, __getattr__/__setattr__方法,完成INSTALLED_APPS赋值 # 懒加载. try: settings.INSTALLED_APPS except ImproperlyConfigured as exc: self.settings_exception = exc # django.setup() # 4.1 配置日志 # 4.2 加载自定义模块 # 4.3 加载model模块 if settings.configured: # Start the auto-reloading dev server even if the code is broken. # The hardcoded condition is a code smell but we can't rely on a # flag on the command class because we haven't located it yet. # a 重新导入所有配置信息 if subcommand == 'runserver' and '--noreload' not in self.argv: try: autoreload.check_errors(django.setup)() except Exception: # The exception will be raised later in the child process # started by the autoreloader. Pretend it didn't happen by # loading an empty list of applications. apps.all_models = defaultdict(OrderedDict) apps.app_configs = OrderedDict() apps.apps_ready = apps.models_ready = apps.ready = True # Remove options not compatible with the built-in runserver # (e.g. options for the contrib.staticfiles' runserver). # Changes here require manually testing as described in # #27522. _parser = self.fetch_command('runserver').create_parser( 'django', 'runserver') _options, _args = _parser.parse_known_args(self.argv[2:]) for _arg in _args: self.argv.remove(_arg) # In all other cases, django.setup() is required to succeed. # b 配置日志, 加载自定义模块, models模块, 使用Application else: django.setup() self.autocomplete() # 5 fetch_command, 返回不同的Command对象, 根据不同的参数运行不同的后台任务, # 5.1 调用各个 BaseCommand 子类的方法来完成对应的业务, 例如: # runserver.py.Command # flush.py.Command # and so on # 5.2 不同Command流程(handle相当于钩子): # run_from_argv, 进行参数解析和配置, 调用execute # execute, 设置环境变量,运行handle, 在父类实现大部分逻辑; # handle, 进入run, 由各个子类rewrite, (主要处理逻辑) # run_from_argv, 处理善后 if subcommand == 'help': if '--commands' in args: sys.stdout.write( self.main_help_text(commands_only=True) + '\n') elif len(options.args) < 1: sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(options.args[0]).print_help( self.prog_name, options.args[0]) elif subcommand == 'version' or self.argv[1:] == ['--version']: # Special-cases: We want 'django-admin --version' and # 'django-admin --help' to work, for backwards compatibility. sys.stdout.write(django.get_version() + '\n') elif self.argv[1:] in (['--help'], ['-h']): sys.stdout.write(self.main_help_text() + '\n') else: MY(1, '\n\tShell subcommand:', subcommand, ' Argv:', self.argv) # 执行一个django-admin命令, 当然也可以自定义该命令 # 该函数: django.core.management.base self.fetch_command(subcommand).run_from_argv(self.argv)
def initialize( skip_update=False, settings=None, debug=False, debug_database=False, no_input=False, pythonpath=None, ): # noqa: max-complexity=12 """ This should be called before starting the Kolibri app, it initializes Kolibri plugins and sets up Django. """ check_debian_user(no_input) setup_logging(debug=debug, debug_database=debug_database) default_options = DefaultDjangoOptions(settings, pythonpath) handle_default_options(default_options) # Do this here so that we can fix any issues with our configuration file before # we attempt to set up django. autoremove_unavailable_plugins() # Check if there is an options.ini file exist inside the KOLIBRI_HOME folder check_default_options_exist() version = get_version() updated = version_updated(kolibri.__version__, version) if updated: check_plugin_config_file_location(version) # Reset the enabled plugins to the defaults # This needs to be run before dbbackup because # dbbackup relies on settings.INSTALLED_APPS enable_new_default_plugins() _setup_django() if updated and not skip_update: conditional_backup(kolibri.__version__, version) if version: logger.info( "Version was {old}, new version: {new}".format( old=version, new=kolibri.__version__ ) ) else: logger.info("New install, version: {new}".format(new=kolibri.__version__)) update(version, kolibri.__version__) check_content_directory_exists_and_writable() if not skip_update: # Run any plugin specific updates here in case they were missed by # our Kolibri version based update logic. run_plugin_updates() check_django_stack_ready() try: check_database_is_migrated() except DatabaseNotMigrated: try: _migrate_databases() except Exception as e: logging.error( "The database was not fully migrated. Tried to " "migrate the database and an error occurred: " "{}".format(e) ) raise except DatabaseInaccessible as e: logging.error( "Tried to check that the database was accessible " "and an error occurred: {}".format(e) ) raise import_tasks_module_from_django_apps()
def django_init(self): """ Checks for the required data and initializes the application. """ # manage.py os.environ.setdefault("DJANGO_SETTINGS_MODULE", SETTINGS) # django.core.management.execute_from_command_line(argv=ARGS) """ A simple method that runs a ManagementUtility. """ from django.core.management import ManagementUtility utility = ManagementUtility(ARGS) # utility.execute() """ Given the command-line arguments, this figures out which subcommand is being run, creates a parser appropriate to that command, and runs it. """ from django.core.management import LaxOptionParser # For backwards compatibility: get_version() used to be in this module. from django import get_version from django.core.management.base import BaseCommand, handle_default_options # Preprocess options to extract --settings and --pythonpath. # These options could affect the commands that are available, so they # must be processed early. parser = LaxOptionParser(usage="%prog subcommand [options] [args]", version=get_version(), option_list=BaseCommand.option_list) utility.autocomplete() try: options, args = parser.parse_args(utility.argv) handle_default_options(options) except: pass # Ignore any option errors at this point. subcommand = utility.argv[1] klass = utility.fetch_command(subcommand) # klass.run_from_argv(utility.argv) """ Set up any environment changes requested (e.g., Python path and Django settings), then run this command. If the command raises a ``CommandError``, intercept it and print it sensibly to stderr. If the ``--traceback`` option is present or the raised ``Exception`` is not ``CommandError``, raise it. """ from django.core.management.base import CommandError parser = klass.create_parser(utility.argv[0], utility.argv[1]) options, args = parser.parse_args(utility.argv[2:]) handle_default_options(options) options = options.__dict__ # klass.execute(*args, **options.__dict__) """ Try to execute this command, performing model validation if needed (as controlled by the attribute ``klass.requires_model_validation``, except if force-skipped). """ from django.core.management.base import OutputWrapper klass.stdout = OutputWrapper(options.get('stdout', sys.stdout)) klass.stderr = OutputWrapper(options.get('stderr', sys.stderr), klass.style.ERROR) #klass.can_import_settings = True from django.conf import settings saved_locale = None #klass.leave_locale_alone = False # Only mess with locales if we can assume we have a working # settings file, because django.utils.translation requires settings # (The final saying about whether the i18n machinery is active will be # found in the value of the USE_I18N setting) #klass.can_import_settings = True # Switch to US English, because django-admin.py creates database # content like permissions, and those shouldn't contain any # translations. from django.utils import translation saved_locale = translation.get_language() translation.activate('en-us') try: # Validation is called explicitly each time the server is reloaded. #klass.requires_model_validation = False addrport = args[0] print 'addrport %s' % addrport args = args[1:] # klass.handle(addrport='', *args, **options) import re from django.core.management.commands.runserver import naiveip_re, DEFAULT_PORT from django.conf import settings if not settings.DEBUG and not settings.ALLOWED_HOSTS: raise CommandError('You must set settings.ALLOWED_HOSTS if DEBUG is False.') klass.use_ipv6 = options.get('use_ipv6') if klass.use_ipv6 and not socket.has_ipv6: raise CommandError('Your Python does not support IPv6.') if args: raise CommandError('Usage is runserver %s' % klass.args) klass._raw_ipv6 = False if not addrport: klass.addr = '' klass.port = DEFAULT_PORT else: m = re.match(naiveip_re, addrport) if m is None: raise CommandError('"%s" is not a valid port number ' 'or address:port pair.' % addrport) klass.addr, _ipv4, _ipv6, _fqdn, klass.port = m.groups() if not klass.port.isdigit(): raise CommandError("%r is not a valid port number." % klass.port) if klass.addr: if _ipv6: klass.addr = klass.addr[1:-1] klass.use_ipv6 = True klass._raw_ipv6 = True elif klass.use_ipv6 and not _fqdn: raise CommandError('"%s" is not a valid IPv6 address.' % klass.addr) if not klass.addr: klass.addr = '::1' if klass.use_ipv6 else '127.0.0.1' klass._raw_ipv6 = bool(klass.use_ipv6) # klass.run(*args, **options) """ Runs the server, using the autoreloader if needed """ #from django.utils import autoreload use_reloader = options.get('use_reloader') if use_reloader: # use queue and threading to start httpd # skip for now print 'reloader bypassed for Windows service' pass # klass.inner_run(*args, **options) import errno import socket from django.utils import six from django.utils.six.moves import socketserver from django.core.servers.basehttp import WSGIServer, WSGIRequestHandler from datetime import datetime from django.conf import settings from django.utils import translation threading = options.get('use_threading') shutdown_message = options.get('shutdown_message', '') quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' klass.stdout.write("Validating models...\n\n") klass.validate(display_num_errors=True) klass.stdout.write(( "%(started_at)s\n" "Django version %(version)s, using settings %(settings)r\n" "Starting development server at http://%(addr)s:%(port)s/\n" "Quit the server with %(quit_command)s.\n" ) % { "started_at": datetime.now().strftime('%B %d, %Y - %X'), "version": klass.get_version(), "settings": settings.SETTINGS_MODULE, "addr": '[%s]' % klass.addr if klass._raw_ipv6 else klass.addr, "port": klass.port, "quit_command": quit_command, }) # django.core.management.base forces the locale to en-us. We should # set it up correctly for the first request (particularly important # in the "--noreload" case). translation.activate(settings.LANGUAGE_CODE) try: handler = klass.get_handler(*args, **options) # run(addr=klass.addr, port=int(klass.port), wsgi_handler=handler, # ipv6=klass.use_ipv6, threading=threading) server_address = (klass.addr, int(klass.port)) if threading: httpd_cls = type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {}) else: httpd_cls = WSGIServer httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=klass.use_ipv6) httpd.set_app(handler) except socket.error as e: # Use helpful error messages instead of ugly tracebacks. ERRORS = { errno.EACCES: "You don't have permission to access that port.", errno.EADDRINUSE: "That port is already in use.", errno.EADDRNOTAVAIL: "That IP address can't be assigned-to.", } try: error_text = ERRORS[e.errno] except KeyError: error_text = str(e) klass.stderr.write("Error: %s" % error_text) # Need to use an OS exit because sys.exit doesn't work in a thread os._exit(1) finally: if saved_locale is not None: translation.activate(saved_locale) return httpd