Merge "Allow ParseOptions to compose multiple option parsers easily" into main am: f0e5c7e321

Original change: https://android-review.googlesource.com/c/platform/build/+/2828702

Change-Id: I761ceb28e2990de48c86e8e63c6d11990fe3658c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2023-11-15 19:12:04 +00:00
committed by Automerger Merge Worker

View File

@@ -39,18 +39,23 @@ import tempfile
import threading import threading
import time import time
import zipfile import zipfile
from typing import Iterable, Callable
from dataclasses import dataclass from dataclasses import dataclass
from genericpath import isdir
from hashlib import sha1, sha256 from hashlib import sha1, sha256
import images import images
import rangelib
import sparse_img import sparse_img
from blockimgdiff import BlockImageDiff from blockimgdiff import BlockImageDiff
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@dataclass
class OptionHandler:
extra_long_opts: Iterable[str]
handler: Callable
class Options(object): class Options(object):
def __init__(self): def __init__(self):
@@ -2793,12 +2798,19 @@ def Usage(docstring):
def ParseOptions(argv, def ParseOptions(argv,
docstring, docstring,
extra_opts="", extra_long_opts=(), extra_opts="", extra_long_opts=(),
extra_option_handler=None): extra_option_handler: Iterable[OptionHandler] = None):
"""Parse the options in argv and return any arguments that aren't """Parse the options in argv and return any arguments that aren't
flags. docstring is the calling module's docstring, to be displayed flags. docstring is the calling module's docstring, to be displayed
for errors and -h. extra_opts and extra_long_opts are for flags for errors and -h. extra_opts and extra_long_opts are for flags
defined by the caller, which are processed by passing them to defined by the caller, which are processed by passing them to
extra_option_handler.""" extra_option_handler."""
extra_long_opts = list(extra_long_opts)
if not isinstance(extra_option_handler, Iterable):
extra_option_handler = [extra_option_handler]
for handler in extra_option_handler:
if isinstance(handler, OptionHandler):
extra_long_opts.extend(handler.extra_long_opts)
try: try:
opts, args = getopt.getopt( opts, args = getopt.getopt(
@@ -2860,8 +2872,19 @@ def ParseOptions(argv,
elif o in ("--logfile",): elif o in ("--logfile",):
OPTIONS.logfile = a OPTIONS.logfile = a
else: else:
if extra_option_handler is None or not extra_option_handler(o, a): if extra_option_handler is None:
assert False, "unknown option \"%s\"" % (o,) raise ValueError("unknown option \"%s\"" % (o,))
success = False
for handler in extra_option_handler:
if isinstance(handler, OptionHandler):
if handler.handler(o, a):
success = True
break
elif handler(o, a):
success = True
if not success:
raise ValueError("unknown option \"%s\"" % (o,))
if OPTIONS.search_path: if OPTIONS.search_path:
os.environ["PATH"] = (os.path.join(OPTIONS.search_path, "bin") + os.environ["PATH"] = (os.path.join(OPTIONS.search_path, "bin") +