1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-01-19 11:56:13 +01:00

Merge pull request #1474 from dmach/quiet-progressbar

Don't show progressbars when --quiet is specified
This commit is contained in:
Daniel Mach 2024-01-25 09:31:18 +01:00 committed by GitHub
commit 4ca4845f6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 129 additions and 20 deletions

View File

@ -344,13 +344,13 @@ class OscMainCommand(MainCommand):
"-v",
"--verbose",
action="store_true",
help="increase verbosity",
help="increase verbosity (conflicts with --quiet)",
)
self.add_argument(
"-q",
"--quiet",
action="store_true",
help="be quiet, not verbose",
help="be quiet, not verbose (conflicts with --verbose)",
)
self.add_argument(
"--debug",
@ -434,6 +434,7 @@ class OscMainCommand(MainCommand):
override_http_full_debug=args.http_full_debug,
override_no_keyring=args.no_keyring,
override_post_mortem=args.post_mortem,
override_quiet=args.quiet,
override_traceback=args.traceback,
override_verbose=args.verbose,
overrides=overrides,

View File

@ -559,13 +559,25 @@ class Options(OscOptions):
section=True,
) # type: ignore[assignment]
quiet: bool = Field(
default=False,
description=textwrap.dedent(
"""
Reduce amount of printed information to bare minimum.
If enabled, automatically sets ``verbose`` to ``False``.
"""
),
) # type: ignore[assignment]
verbose: bool = Field(
default=False,
description=textwrap.dedent(
"""
Increase amount of printed information to stdout.
Automatically set to ``False`` when ``quiet`` is enabled.
"""
),
get_callback=lambda conf, value: False if conf.quiet else value,
) # type: ignore[assignment]
debug: bool = Field(
@ -582,8 +594,10 @@ class Options(OscOptions):
description=textwrap.dedent(
"""
Print HTTP traffic to stderr.
Automatically set to ``True`` when``http_full_debug`` is enabled.
"""
),
get_callback=lambda conf, value: True if conf.http_full_debug else value,
) # type: ignore[assignment]
http_full_debug: bool = Field(
@ -591,6 +605,7 @@ class Options(OscOptions):
description=textwrap.dedent(
"""
[CAUTION!] Print HTTP traffic incl. authentication data to stderr.
If enabled, automatically sets ``http_debug`` to ``True``.
"""
),
) # type: ignore[assignment]
@ -1782,6 +1797,7 @@ def get_config(override_conffile=None,
override_http_full_debug=None,
override_traceback=None,
override_post_mortem=None,
override_quiet=None,
override_no_keyring=None,
override_verbose=None,
overrides=None
@ -1810,7 +1826,6 @@ def get_config(override_conffile=None,
overrides["http_debug"] = override_http_debug
if override_http_full_debug is not None:
overrides["http_debug"] = override_http_full_debug or overrides["http_debug"]
overrides["http_full_debug"] = override_http_full_debug
if override_traceback is not None:
@ -1822,6 +1837,9 @@ def get_config(override_conffile=None,
if override_no_keyring is not None:
overrides["use_keyring"] = not override_no_keyring
if override_quiet is not None:
overrides["quiet"] = override_quiet
if override_verbose is not None:
overrides["verbose"] = override_verbose

View File

@ -5,6 +5,10 @@
import signal
import sys
from abc import ABC
from abc import abstractmethod
from typing import Optional
try:
import progressbar as pb
@ -13,9 +17,25 @@ except ImportError:
have_pb_module = False
class PBTextMeter:
class TextMeterBase(ABC):
@abstractmethod
def start(self, basename: str, size: Optional[int] = None):
pass
def start(self, basename, size=None):
@abstractmethod
def update(self, amount_read: int):
pass
@abstractmethod
def end(self):
pass
class PBTextMeter(TextMeterBase):
def __init__(self):
self.bar: pb.ProgressBar
def start(self, basename: str, size: Optional[int] = None):
if size is None:
widgets = [f"{basename}: ", pb.AnimatedMarker(), ' ', pb.Timer()]
self.bar = pb.ProgressBar(widgets=widgets, maxval=pb.UnknownLength)
@ -33,7 +53,7 @@ class PBTextMeter:
signal.siginterrupt(signal.SIGWINCH, False)
self.bar.start()
def update(self, amount_read):
def update(self, amount_read: int):
self.bar.update(amount_read)
def end(self):
@ -41,25 +61,27 @@ class PBTextMeter:
class NoPBTextMeter:
def start(self, basename, size=None):
def start(self, basename: str, size: Optional[int] = None):
pass
def update(self, *args, **kwargs):
def update(self, amount_read: int):
pass
def end(self, *args, **kwargs):
def end(self):
pass
def create_text_meter(*args, **kwargs):
use_pb_fallback = kwargs.pop('use_pb_fallback', True)
if have_pb_module or use_pb_fallback:
return TextMeter(*args, **kwargs)
return None
def create_text_meter(*args, **kwargs) -> TextMeterBase:
from .conf import config
# this option is no longer used
kwargs.pop("use_pb_fallback", True)
meter_class = PBTextMeter
if not have_pb_module or config.quiet or not config.show_download_progress or not sys.stdout.isatty():
meter_class = NoPBTextMeter
return meter_class(*args, **kwargs)
if have_pb_module:
TextMeter = PBTextMeter
else:
TextMeter = NoPBTextMeter
# vim: sw=4 et

View File

@ -10,6 +10,7 @@ import copy
import inspect
import sys
import types
from typing import Callable
from typing import get_type_hints
# supported types
@ -76,6 +77,7 @@ class Field(property):
default: Any = NotSet,
description: Optional[str] = None,
exclude: bool = False,
get_callback: Optional[Callable] = None,
**extra,
):
# the default value; it can be a factory function that is lazily evaluated on the first use
@ -106,6 +108,10 @@ class Field(property):
# whether to exclude this field from export
self.exclude = exclude
# optional callback to postprocess returned field value
# it takes (model_instance, value) and returns modified value
self.get_callback = get_callback
# extra fields
self.extra = extra
@ -235,12 +241,18 @@ class Field(property):
def get(self, obj):
try:
return obj._values[self.name]
result = obj._values[self.name]
if self.get_callback is not None:
result = self.get_callback(obj, result)
return result
except KeyError:
pass
try:
return obj._defaults[self.name]
result = obj._defaults[self.name]
if self.get_callback is not None:
result = self.get_callback(obj, result)
return result
except KeyError:
pass

View File

@ -43,6 +43,7 @@ debug = 0
http_debug = 0
http_full_debug = 0
http_retries = 3
quiet = 0
verbose = 0
no_preinstallimage = 0
traceback = 0
@ -218,6 +219,9 @@ class TestExampleConfig(unittest.TestCase):
def test_http_retries(self):
self.assertEqual(self.config["http_retries"], 3)
def test_quiet(self):
self.assertEqual(self.config["quiet"], False)
def test_verbose(self):
self.assertEqual(self.config["verbose"], False)
@ -430,6 +434,33 @@ class TestExampleConfig(unittest.TestCase):
self.assertEqual(self.config["apiurl_aliases"], expected)
class TestOverrides(unittest.TestCase):
def test_verbose(self):
self.options = osc.conf.Options()
self.assertEqual(self.options.quiet, False)
self.assertEqual(self.options.verbose, False)
self.options.quiet = True
self.options.verbose = True
self.assertEqual(self.options.quiet, True)
# ``verbose`` is forced to ``False`` by the ``quiet`` option
self.assertEqual(self.options.verbose, False)
self.options.quiet = False
self.assertEqual(self.options.quiet, False)
self.assertEqual(self.options.verbose, True)
def test_http_debug(self):
self.options = osc.conf.Options()
self.assertEqual(self.options.http_debug, False)
self.assertEqual(self.options.http_full_debug, False)
self.options.http_full_debug = True
# ``http_debug`` forced to ``True`` by the ``http_full_debug`` option
self.assertEqual(self.options.http_debug, True)
self.assertEqual(self.options.http_full_debug, True)
class TestFromParent(unittest.TestCase):
def setUp(self):
self.options = osc.conf.Options()

View File

@ -291,6 +291,31 @@ class Test(unittest.TestCase):
self.assertEqual(c.field, "new-text")
self.assertEqual(c.field2, "text")
def test_get_callback(self):
class Model(BaseModel):
quiet: bool = Field(
default=False,
)
verbose: bool = Field(
default=False,
# return False if ``quiet`` is True; return the actual value otherwise
get_callback=lambda obj, value: False if obj.quiet else value,
)
m = Model()
self.assertEqual(m.quiet, False)
self.assertEqual(m.verbose, False)
m.quiet = True
m.verbose = True
self.assertEqual(m.quiet, True)
self.assertEqual(m.verbose, False)
m.quiet = False
m.verbose = True
self.assertEqual(m.quiet, False)
self.assertEqual(m.verbose, True)
if __name__ == "__main__":
unittest.main()