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:
commit
4ca4845f6c
@ -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,
|
||||
|
20
osc/conf.py
20
osc/conf.py
@ -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
|
||||
|
||||
|
52
osc/meter.py
52
osc/meter.py
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user