-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- supersedes the `--list` option - provides much more capability - Can output in YAML, JSON, and default - Can specify one or more items to display - Can use dotted-notation to pull items from nested data structures.
- Loading branch information
Showing
12 changed files
with
807 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
"""Functions for displaying information about the version.""" | ||
import dataclasses | ||
from io import StringIO | ||
from pprint import pprint | ||
from typing import Any, Optional | ||
|
||
from bumpversion.bump import get_next_version | ||
from bumpversion.config import Config | ||
from bumpversion.exceptions import BadInputError | ||
from bumpversion.ui import print_error, print_info | ||
from bumpversion.utils import get_context | ||
|
||
|
||
def output_default(value: dict) -> None: | ||
"""Output the value with key=value or just value if there is only one item.""" | ||
if len(value) == 1: | ||
print_info(list(value.values())[0]) | ||
else: | ||
buffer = StringIO() | ||
pprint(value, stream=buffer) # noqa: T203 | ||
print_info(buffer.getvalue()) | ||
|
||
|
||
def output_yaml(value: dict) -> None: | ||
"""Output the value as yaml.""" | ||
from bumpversion.yaml_dump import dump | ||
|
||
print_info(dump(value)) | ||
|
||
|
||
def output_json(value: dict) -> None: | ||
"""Output the value as json.""" | ||
import json | ||
|
||
def default_encoder(obj: Any) -> str: | ||
if dataclasses.is_dataclass(obj): | ||
return str(obj) | ||
elif isinstance(obj, type): | ||
return obj.__name__ | ||
raise TypeError(f"Object of type {type(obj), str(obj)} is not JSON serializable") | ||
|
||
print_info(json.dumps(value, sort_keys=True, indent=2, default=default_encoder)) | ||
|
||
|
||
OUTPUTTERS = { | ||
"yaml": output_yaml, | ||
"json": output_json, | ||
"default": output_default, | ||
} | ||
|
||
|
||
def resolve_name(obj: Any, name: str, default: Any = None, err_on_missing: bool = False) -> Any: | ||
""" | ||
Get a key or attr ``name`` from obj or default value. | ||
Copied and modified from Django Template variable resolutions | ||
Resolution methods: | ||
- Mapping key lookup | ||
- Attribute lookup | ||
- Sequence index | ||
Args: | ||
obj: The object to access | ||
name: A dotted name to the value, such as ``mykey.0.name`` | ||
default: If the name cannot be resolved from the object, return this value | ||
err_on_missing: Raise a `BadInputError` if the name cannot be resolved | ||
Returns: | ||
The value at the resolved name or the default value. | ||
Raises: | ||
BadInputError: If we cannot resolve the name and `err_on_missing` is `True` | ||
# noqa: DAR401 | ||
""" | ||
lookups = name.split(".") | ||
current = obj | ||
try: # catch-all for unexpected failures | ||
for bit in lookups: | ||
try: # dictionary lookup | ||
current = current[bit] | ||
# ValueError/IndexError are for numpy.array lookup on | ||
# numpy < 1.9 and 1.9+ respectively | ||
except (TypeError, AttributeError, KeyError, ValueError, IndexError): | ||
try: # attribute lookup | ||
current = getattr(current, bit) | ||
except (TypeError, AttributeError): | ||
# Reraise if the exception was raised by a @property | ||
if bit in dir(current): | ||
raise | ||
try: # list-index lookup | ||
current = current[int(bit)] | ||
except ( | ||
IndexError, # list index out of range | ||
ValueError, # invalid literal for int() | ||
KeyError, # current is a dict without `int(bit)` key | ||
TypeError, | ||
): # un-subscript-able object | ||
return default | ||
return current | ||
except Exception as e: # noqa: BLE001 # pragma: no cover | ||
if err_on_missing: | ||
raise BadInputError(f"Could not resolve '{name}'") from e | ||
else: | ||
return default | ||
|
||
|
||
def log_list(config: Config, version_part: Optional[str], new_version: Optional[str]) -> None: | ||
"""Output configuration with new version.""" | ||
ctx = get_context(config) | ||
if version_part: | ||
version = config.version_config.parse(config.current_version) | ||
next_version = get_next_version(version, config, version_part, new_version) | ||
next_version_str = config.version_config.serialize(next_version, ctx) | ||
|
||
print_info(f"new_version={next_version_str}") | ||
|
||
for key, value in config.dict(exclude={"scm_info", "parts"}).items(): | ||
print_info(f"{key}={value}") | ||
|
||
|
||
def do_show(*args, config: Config, format_: str = "default") -> None: | ||
"""Show current version or configuration information.""" | ||
config_dict = config.dict() | ||
|
||
try: | ||
if "all" in args or not args: | ||
show_items = config_dict | ||
else: | ||
show_items = {key: resolve_name(config_dict, key) for key in args} | ||
|
||
OUTPUTTERS.get(format_, OUTPUTTERS["default"])(show_items) | ||
except BadInputError as e: | ||
print_error(e.message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
"""Utilities for user interface.""" | ||
from click import UsageError, echo | ||
|
||
|
||
def print_info(msg: str) -> None: | ||
"""Echo a message to the console.""" | ||
echo(msg) | ||
|
||
|
||
def print_error(msg: str) -> None: | ||
"""Raise an error and exit.""" | ||
raise UsageError(msg) |
Oops, something went wrong.