mirror of
https://github.com/openSUSE/osc.git
synced 2025-01-31 16:56:17 +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",
|
"-v",
|
||||||
"--verbose",
|
"--verbose",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="increase verbosity",
|
help="increase verbosity (conflicts with --quiet)",
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
"-q",
|
"-q",
|
||||||
"--quiet",
|
"--quiet",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="be quiet, not verbose",
|
help="be quiet, not verbose (conflicts with --verbose)",
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
"--debug",
|
"--debug",
|
||||||
@ -434,6 +434,7 @@ class OscMainCommand(MainCommand):
|
|||||||
override_http_full_debug=args.http_full_debug,
|
override_http_full_debug=args.http_full_debug,
|
||||||
override_no_keyring=args.no_keyring,
|
override_no_keyring=args.no_keyring,
|
||||||
override_post_mortem=args.post_mortem,
|
override_post_mortem=args.post_mortem,
|
||||||
|
override_quiet=args.quiet,
|
||||||
override_traceback=args.traceback,
|
override_traceback=args.traceback,
|
||||||
override_verbose=args.verbose,
|
override_verbose=args.verbose,
|
||||||
overrides=overrides,
|
overrides=overrides,
|
||||||
|
20
osc/conf.py
20
osc/conf.py
@ -559,13 +559,25 @@ class Options(OscOptions):
|
|||||||
section=True,
|
section=True,
|
||||||
) # type: ignore[assignment]
|
) # 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(
|
verbose: bool = Field(
|
||||||
default=False,
|
default=False,
|
||||||
description=textwrap.dedent(
|
description=textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
Increase amount of printed information to stdout.
|
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]
|
) # type: ignore[assignment]
|
||||||
|
|
||||||
debug: bool = Field(
|
debug: bool = Field(
|
||||||
@ -582,8 +594,10 @@ class Options(OscOptions):
|
|||||||
description=textwrap.dedent(
|
description=textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
Print HTTP traffic to stderr.
|
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]
|
) # type: ignore[assignment]
|
||||||
|
|
||||||
http_full_debug: bool = Field(
|
http_full_debug: bool = Field(
|
||||||
@ -591,6 +605,7 @@ class Options(OscOptions):
|
|||||||
description=textwrap.dedent(
|
description=textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
[CAUTION!] Print HTTP traffic incl. authentication data to stderr.
|
[CAUTION!] Print HTTP traffic incl. authentication data to stderr.
|
||||||
|
If enabled, automatically sets ``http_debug`` to ``True``.
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
) # type: ignore[assignment]
|
) # type: ignore[assignment]
|
||||||
@ -1782,6 +1797,7 @@ def get_config(override_conffile=None,
|
|||||||
override_http_full_debug=None,
|
override_http_full_debug=None,
|
||||||
override_traceback=None,
|
override_traceback=None,
|
||||||
override_post_mortem=None,
|
override_post_mortem=None,
|
||||||
|
override_quiet=None,
|
||||||
override_no_keyring=None,
|
override_no_keyring=None,
|
||||||
override_verbose=None,
|
override_verbose=None,
|
||||||
overrides=None
|
overrides=None
|
||||||
@ -1810,7 +1826,6 @@ def get_config(override_conffile=None,
|
|||||||
overrides["http_debug"] = override_http_debug
|
overrides["http_debug"] = override_http_debug
|
||||||
|
|
||||||
if override_http_full_debug is not None:
|
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
|
overrides["http_full_debug"] = override_http_full_debug
|
||||||
|
|
||||||
if override_traceback is not None:
|
if override_traceback is not None:
|
||||||
@ -1822,6 +1837,9 @@ def get_config(override_conffile=None,
|
|||||||
if override_no_keyring is not None:
|
if override_no_keyring is not None:
|
||||||
overrides["use_keyring"] = not override_no_keyring
|
overrides["use_keyring"] = not override_no_keyring
|
||||||
|
|
||||||
|
if override_quiet is not None:
|
||||||
|
overrides["quiet"] = override_quiet
|
||||||
|
|
||||||
if override_verbose is not None:
|
if override_verbose is not None:
|
||||||
overrides["verbose"] = override_verbose
|
overrides["verbose"] = override_verbose
|
||||||
|
|
||||||
|
52
osc/meter.py
52
osc/meter.py
@ -5,6 +5,10 @@
|
|||||||
|
|
||||||
|
|
||||||
import signal
|
import signal
|
||||||
|
import sys
|
||||||
|
from abc import ABC
|
||||||
|
from abc import abstractmethod
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import progressbar as pb
|
import progressbar as pb
|
||||||
@ -13,9 +17,25 @@ except ImportError:
|
|||||||
have_pb_module = False
|
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:
|
if size is None:
|
||||||
widgets = [f"{basename}: ", pb.AnimatedMarker(), ' ', pb.Timer()]
|
widgets = [f"{basename}: ", pb.AnimatedMarker(), ' ', pb.Timer()]
|
||||||
self.bar = pb.ProgressBar(widgets=widgets, maxval=pb.UnknownLength)
|
self.bar = pb.ProgressBar(widgets=widgets, maxval=pb.UnknownLength)
|
||||||
@ -33,7 +53,7 @@ class PBTextMeter:
|
|||||||
signal.siginterrupt(signal.SIGWINCH, False)
|
signal.siginterrupt(signal.SIGWINCH, False)
|
||||||
self.bar.start()
|
self.bar.start()
|
||||||
|
|
||||||
def update(self, amount_read):
|
def update(self, amount_read: int):
|
||||||
self.bar.update(amount_read)
|
self.bar.update(amount_read)
|
||||||
|
|
||||||
def end(self):
|
def end(self):
|
||||||
@ -41,25 +61,27 @@ class PBTextMeter:
|
|||||||
|
|
||||||
|
|
||||||
class NoPBTextMeter:
|
class NoPBTextMeter:
|
||||||
def start(self, basename, size=None):
|
def start(self, basename: str, size: Optional[int] = None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def update(self, *args, **kwargs):
|
def update(self, amount_read: int):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def end(self, *args, **kwargs):
|
def end(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def create_text_meter(*args, **kwargs):
|
def create_text_meter(*args, **kwargs) -> TextMeterBase:
|
||||||
use_pb_fallback = kwargs.pop('use_pb_fallback', True)
|
from .conf import config
|
||||||
if have_pb_module or use_pb_fallback:
|
|
||||||
return TextMeter(*args, **kwargs)
|
# this option is no longer used
|
||||||
return None
|
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
|
# vim: sw=4 et
|
||||||
|
@ -10,6 +10,7 @@ import copy
|
|||||||
import inspect
|
import inspect
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
from typing import Callable
|
||||||
from typing import get_type_hints
|
from typing import get_type_hints
|
||||||
|
|
||||||
# supported types
|
# supported types
|
||||||
@ -76,6 +77,7 @@ class Field(property):
|
|||||||
default: Any = NotSet,
|
default: Any = NotSet,
|
||||||
description: Optional[str] = None,
|
description: Optional[str] = None,
|
||||||
exclude: bool = False,
|
exclude: bool = False,
|
||||||
|
get_callback: Optional[Callable] = None,
|
||||||
**extra,
|
**extra,
|
||||||
):
|
):
|
||||||
# the default value; it can be a factory function that is lazily evaluated on the first use
|
# 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
|
# whether to exclude this field from export
|
||||||
self.exclude = exclude
|
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
|
# extra fields
|
||||||
self.extra = extra
|
self.extra = extra
|
||||||
|
|
||||||
@ -235,12 +241,18 @@ class Field(property):
|
|||||||
|
|
||||||
def get(self, obj):
|
def get(self, obj):
|
||||||
try:
|
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:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
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:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ debug = 0
|
|||||||
http_debug = 0
|
http_debug = 0
|
||||||
http_full_debug = 0
|
http_full_debug = 0
|
||||||
http_retries = 3
|
http_retries = 3
|
||||||
|
quiet = 0
|
||||||
verbose = 0
|
verbose = 0
|
||||||
no_preinstallimage = 0
|
no_preinstallimage = 0
|
||||||
traceback = 0
|
traceback = 0
|
||||||
@ -218,6 +219,9 @@ class TestExampleConfig(unittest.TestCase):
|
|||||||
def test_http_retries(self):
|
def test_http_retries(self):
|
||||||
self.assertEqual(self.config["http_retries"], 3)
|
self.assertEqual(self.config["http_retries"], 3)
|
||||||
|
|
||||||
|
def test_quiet(self):
|
||||||
|
self.assertEqual(self.config["quiet"], False)
|
||||||
|
|
||||||
def test_verbose(self):
|
def test_verbose(self):
|
||||||
self.assertEqual(self.config["verbose"], False)
|
self.assertEqual(self.config["verbose"], False)
|
||||||
|
|
||||||
@ -430,6 +434,33 @@ class TestExampleConfig(unittest.TestCase):
|
|||||||
self.assertEqual(self.config["apiurl_aliases"], expected)
|
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):
|
class TestFromParent(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.options = osc.conf.Options()
|
self.options = osc.conf.Options()
|
||||||
|
@ -291,6 +291,31 @@ class Test(unittest.TestCase):
|
|||||||
self.assertEqual(c.field, "new-text")
|
self.assertEqual(c.field, "new-text")
|
||||||
self.assertEqual(c.field2, "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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user