aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/Twisted/py2/twisted/application/twist
diff options
context:
space:
mode:
authorshmel1k <shmel1k@ydb.tech>2023-11-26 18:16:14 +0300
committershmel1k <shmel1k@ydb.tech>2023-11-26 18:43:30 +0300
commitb8cf9e88f4c5c64d9406af533d8948deb050d695 (patch)
tree218eb61fb3c3b96ec08b4d8cdfef383104a87d63 /contrib/python/Twisted/py2/twisted/application/twist
parent523f645a83a0ec97a0332dbc3863bb354c92a328 (diff)
downloadydb-b8cf9e88f4c5c64d9406af533d8948deb050d695.tar.gz
add kikimr_configure
Diffstat (limited to 'contrib/python/Twisted/py2/twisted/application/twist')
-rw-r--r--contrib/python/Twisted/py2/twisted/application/twist/__init__.py7
-rw-r--r--contrib/python/Twisted/py2/twisted/application/twist/_options.py205
-rw-r--r--contrib/python/Twisted/py2/twisted/application/twist/_twist.py128
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)