diff options
author | shmel1k <shmel1k@ydb.tech> | 2023-11-26 18:16:14 +0300 |
---|---|---|
committer | shmel1k <shmel1k@ydb.tech> | 2023-11-26 18:43:30 +0300 |
commit | b8cf9e88f4c5c64d9406af533d8948deb050d695 (patch) | |
tree | 218eb61fb3c3b96ec08b4d8cdfef383104a87d63 /contrib/python/Twisted/py2/twisted/application/twist | |
parent | 523f645a83a0ec97a0332dbc3863bb354c92a328 (diff) | |
download | ydb-b8cf9e88f4c5c64d9406af533d8948deb050d695.tar.gz |
add kikimr_configure
Diffstat (limited to 'contrib/python/Twisted/py2/twisted/application/twist')
3 files changed, 340 insertions, 0 deletions
diff --git a/contrib/python/Twisted/py2/twisted/application/twist/__init__.py b/contrib/python/Twisted/py2/twisted/application/twist/__init__.py new file mode 100644 index 0000000000..ea7c5d29ce --- /dev/null +++ b/contrib/python/Twisted/py2/twisted/application/twist/__init__.py @@ -0,0 +1,7 @@ +# -*- test-case-name: twisted.application.twist.test -*- +# Copyright (c) Twisted Matrix Laboratories. +# See LICENSE for details. + +""" +C{twist} command line tool. +""" diff --git a/contrib/python/Twisted/py2/twisted/application/twist/_options.py b/contrib/python/Twisted/py2/twisted/application/twist/_options.py new file mode 100644 index 0000000000..2b7d307515 --- /dev/null +++ b/contrib/python/Twisted/py2/twisted/application/twist/_options.py @@ -0,0 +1,205 @@ +# -*- test-case-name: twisted.application.twist.test.test_options -*- +# Copyright (c) Twisted Matrix Laboratories. +# See LICENSE for details. + +""" +Command line options for C{twist}. +""" + +from sys import stdout, stderr +from textwrap import dedent + +from twisted.copyright import version +from twisted.python.usage import Options, UsageError +from twisted.logger import ( + LogLevel, InvalidLogLevelError, + textFileLogObserver, jsonFileLogObserver, +) +from twisted.plugin import getPlugins + +from ..reactors import installReactor, NoSuchReactor, getReactorTypes +from ..runner._exit import exit, ExitStatus +from ..service import IServiceMaker + +openFile = open + + + +class TwistOptions(Options): + """ + Command line options for C{twist}. + """ + + defaultReactorName = "default" + defaultLogLevel = LogLevel.info + + + def __init__(self): + Options.__init__(self) + + self["reactorName"] = self.defaultReactorName + self["logLevel"] = self.defaultLogLevel + self["logFile"] = stdout + + + def getSynopsis(self): + return "{} plugin [plugin_options]".format( + Options.getSynopsis(self) + ) + + + def opt_version(self): + """ + Print version and exit. + """ + exit(ExitStatus.EX_OK, "{}".format(version)) + + + def opt_reactor(self, name): + """ + The name of the reactor to use. + (options: {options}) + """ + # Actually actually actually install the reactor right at this very + # moment, before any other code (for example, a sub-command plugin) + # runs and accidentally imports and installs the default reactor. + try: + self["reactor"] = self.installReactor(name) + except NoSuchReactor: + raise UsageError("Unknown reactor: {}".format(name)) + else: + self["reactorName"] = name + + opt_reactor.__doc__ = dedent(opt_reactor.__doc__).format( + options=", ".join( + '"{}"'.format(rt.shortName) for rt in getReactorTypes() + ), + ) + + + def installReactor(self, name): + """ + Install the reactor. + """ + if name == self.defaultReactorName: + from twisted.internet import reactor + return reactor + else: + return installReactor(name) + + + def opt_log_level(self, levelName): + """ + Set default log level. + (options: {options}; default: "{default}") + """ + try: + self["logLevel"] = LogLevel.levelWithName(levelName) + except InvalidLogLevelError: + raise UsageError("Invalid log level: {}".format(levelName)) + + opt_log_level.__doc__ = dedent(opt_log_level.__doc__).format( + options=", ".join( + '"{}"'.format(l.name) for l in LogLevel.iterconstants() + ), + default=defaultLogLevel.name, + ) + + + def opt_log_file(self, fileName): + """ + Log to file. ("-" for stdout, "+" for stderr; default: "-") + """ + if fileName == "-": + self["logFile"] = stdout + return + + if fileName == "+": + self["logFile"] = stderr + return + + try: + self["logFile"] = openFile(fileName, "a") + except EnvironmentError as e: + exit( + ExitStatus.EX_IOERR, + "Unable to open log file {!r}: {}".format(fileName, e) + ) + + + def opt_log_format(self, format): + """ + Log file format. + (options: "text", "json"; default: "text" if the log file is a tty, + otherwise "json") + """ + format = format.lower() + + if format == "text": + self["fileLogObserverFactory"] = textFileLogObserver + elif format == "json": + self["fileLogObserverFactory"] = jsonFileLogObserver + else: + raise UsageError("Invalid log format: {}".format(format)) + self["logFormat"] = format + + opt_log_format.__doc__ = dedent(opt_log_format.__doc__) + + + def selectDefaultLogObserver(self): + """ + Set C{fileLogObserverFactory} to the default appropriate for the + chosen C{logFile}. + """ + if "fileLogObserverFactory" not in self: + logFile = self["logFile"] + + if hasattr(logFile, "isatty") and logFile.isatty(): + self["fileLogObserverFactory"] = textFileLogObserver + self["logFormat"] = "text" + else: + self["fileLogObserverFactory"] = jsonFileLogObserver + self["logFormat"] = "json" + + + def parseOptions(self, options=None): + self.selectDefaultLogObserver() + + Options.parseOptions(self, options=options) + + if "reactor" not in self: + self["reactor"] = self.installReactor(self["reactorName"]) + + + @property + def plugins(self): + if "plugins" not in self: + plugins = {} + for plugin in getPlugins(IServiceMaker): + plugins[plugin.tapname] = plugin + self["plugins"] = plugins + + return self["plugins"] + + + @property + def subCommands(self): + plugins = self.plugins + for name in sorted(plugins): + plugin = plugins[name] + yield ( + plugin.tapname, + None, + # Avoid resolving the options attribute right away, in case + # it's a property with a non-trivial getter (eg, one which + # imports modules). + lambda plugin=plugin: plugin.options(), + plugin.description, + ) + + + def postOptions(self): + Options.postOptions(self) + + if self.subCommand is None: + raise UsageError("No plugin specified.") diff --git a/contrib/python/Twisted/py2/twisted/application/twist/_twist.py b/contrib/python/Twisted/py2/twisted/application/twist/_twist.py new file mode 100644 index 0000000000..ec8bc34739 --- /dev/null +++ b/contrib/python/Twisted/py2/twisted/application/twist/_twist.py @@ -0,0 +1,128 @@ +# -*- test-case-name: twisted.application.twist.test.test_twist -*- +# Copyright (c) Twisted Matrix Laboratories. +# See LICENSE for details. + +""" +Run a Twisted application. +""" + +import sys + +from twisted.python.usage import UsageError +from ..service import Application, IService +from ..runner._exit import exit, ExitStatus +from ..runner._runner import Runner +from ._options import TwistOptions +from twisted.application.app import _exitWithSignal +from twisted.internet.interfaces import _ISupportsExitSignalCapturing + + + +class Twist(object): + """ + Run a Twisted application. + """ + + @staticmethod + def options(argv): + """ + Parse command line options. + + @param argv: Command line arguments. + @type argv: L{list} + + @return: The parsed options. + @rtype: L{TwistOptions} + """ + options = TwistOptions() + + try: + options.parseOptions(argv[1:]) + except UsageError as e: + exit(ExitStatus.EX_USAGE, "Error: {}\n\n{}".format(e, options)) + + return options + + + @staticmethod + def service(plugin, options): + """ + Create the application service. + + @param plugin: The name of the plugin that implements the service + application to run. + @type plugin: L{str} + + @param options: Options to pass to the application. + @type options: L{twisted.python.usage.Options} + + @return: The created application service. + @rtype: L{IService} + """ + service = plugin.makeService(options) + application = Application(plugin.tapname) + service.setServiceParent(application) + + return IService(application) + + + @staticmethod + def startService(reactor, service): + """ + Start the application service. + + @param reactor: The reactor to run the service with. + @type reactor: L{twisted.internet.interfaces.IReactorCore} + + @param service: The application service to run. + @type service: L{IService} + """ + service.startService() + + # Ask the reactor to stop the service before shutting down + reactor.addSystemEventTrigger( + "before", "shutdown", service.stopService + ) + + + @staticmethod + def run(twistOptions): + """ + Run the application service. + + @param twistOptions: Command line options to convert to runner + arguments. + @type twistOptions: L{TwistOptions} + """ + runner = Runner( + reactor=twistOptions["reactor"], + defaultLogLevel=twistOptions["logLevel"], + logFile=twistOptions["logFile"], + fileLogObserverFactory=twistOptions["fileLogObserverFactory"], + ) + runner.run() + reactor = twistOptions["reactor"] + if _ISupportsExitSignalCapturing.providedBy(reactor): + if reactor._exitSignal is not None: + _exitWithSignal(reactor._exitSignal) + + + @classmethod + def main(cls, argv=sys.argv): + """ + Executable entry point for L{Twist}. + Processes options and run a twisted reactor with a service. + + @param argv: Command line arguments. + @type argv: L{list} + """ + options = cls.options(argv) + + reactor = options["reactor"] + service = cls.service( + plugin=options.plugins[options.subCommand], + options=options.subOptions, + ) + + cls.startService(reactor, service) + cls.run(options) |