Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Return SCM information in show command #291

Merged
merged 2 commits into from
Feb 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions bumpversion/scm/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
self.config = config
self._latest_tag_info: Optional[LatestTagInfo] = None

def __repr__(self) -> str:
"""Return a string representation of the SCMTool."""
return self.__str__()

Check warning on line 32 in bumpversion/scm/git.py

View check run for this annotation

Codecov / codecov/patch

bumpversion/scm/git.py#L32

Added line #L32 was not covered by tests

def __str__(self) -> str:
"""A string representation of the object."""
return "Git"

def is_available(self) -> bool:
"""Is the VCS implementation usable?"""
try:
Expand Down
8 changes: 8 additions & 0 deletions bumpversion/scm/hg.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
self.config = config
self._latest_tag_info: Optional[LatestTagInfo] = None

def __repr__(self) -> str:
"""Return a string representation of the SCMTool."""
return self.__str__()

Check warning on line 28 in bumpversion/scm/hg.py

View check run for this annotation

Codecov / codecov/patch

bumpversion/scm/hg.py#L28

Added line #L28 was not covered by tests

def __str__(self) -> str:
"""A string representation of the object."""
return "Mercurial"

Check warning on line 32 in bumpversion/scm/hg.py

View check run for this annotation

Codecov / codecov/patch

bumpversion/scm/hg.py#L32

Added line #L32 was not covered by tests

def is_available(self) -> bool:
"""Is the VCS implementation usable?"""
try:
Expand Down
17 changes: 17 additions & 0 deletions bumpversion/scm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ class DefaultSCMTool:
def __init__(self, config: SCMConfig):
self.config = config

def __repr__(self) -> str:
"""Return a string representation of the SCMTool."""
return self.__str__()

def __str__(self) -> str:
"""A string representation of the object."""
return "None"

def is_available(self) -> bool:
"""Return whether the SCM tool is available."""
return True
Expand Down Expand Up @@ -151,6 +159,15 @@ def __init__(self, config: SCMConfig):
self.tool: SCMTool = DefaultSCMTool(config)
self._set_from_scm_tool()

def __repr__(self) -> str:
"""Return a string representation of the SCMInfo."""
import pprint
from io import StringIO

str_io = StringIO()
pprint.pprint(self.as_dict(), stream=str_io)
return str_io.getvalue().rstrip()

def as_dict(self) -> dict[str, Any]:
"""Return the information as a dict."""
return {
Expand Down
11 changes: 7 additions & 4 deletions bumpversion/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
from io import StringIO
from pathlib import Path
from pprint import pprint
from typing import Any, Optional
from typing import Any, Optional, Union

from bumpversion.bump import get_next_version
from bumpversion.config import Config
from bumpversion.context import get_context
from bumpversion.exceptions import BadInputError
from bumpversion.scm.models import SCMInfo
from bumpversion.ui import print_error, print_info
from bumpversion.utils import recursive_sort_dict

Expand All @@ -35,14 +36,16 @@ def output_json(value: dict) -> None:
"""Output the value as json."""
import json

def default_encoder(obj: Any) -> str:
def default_encoder(obj: Any) -> Union[str, dict]:
if dataclasses.is_dataclass(obj):
return str(obj)
elif isinstance(obj, type):
return obj.__name__
elif isinstance(obj, Path):
return str(obj)
raise TypeError(f"Object of type {type(obj), str(obj)} is not JSON serializable")
elif isinstance(obj, SCMInfo):
return obj.as_dict()
return str(obj)

print_info(json.dumps(value, sort_keys=True, indent=2, default=default_encoder))

Expand Down Expand Up @@ -124,7 +127,7 @@ def do_show(
"""Show current version or configuration information."""
if current_version:
config.current_version = current_version
config_dict = config.model_dump(exclude={"scm_info"})
config_dict = config.model_dump()
ctx = get_context(config)

if increment:
Expand Down
12 changes: 11 additions & 1 deletion bumpversion/yaml_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from textwrap import indent
from typing import Any, Callable, Union

from bumpversion.scm.models import SCMInfo

DumperFunc = Callable[[Any], str]


Expand Down Expand Up @@ -90,7 +92,7 @@ def format_dict(val: dict) -> str:

for key, value in sorted(val.items()):
rendered_value = dump(value).strip()
if isinstance(value, (dict, list, tuple)):
if isinstance(value, (dict, list, tuple, SCMInfo)):
rendered_value = f"\n{indent(rendered_value, INDENT)}"
else:
rendered_value = f" {rendered_value}"
Expand Down Expand Up @@ -146,3 +148,11 @@ def format_datetime(val: datetime.datetime) -> str:


YAML_DUMPERS.add_dumper(datetime.datetime, format_datetime)


def format_scminfo(val: SCMInfo) -> str:
"""Return a string representation of a value."""
return format_dict(val.as_dict())


YAML_DUMPERS.add_dumper(SCMInfo, format_scminfo)
9 changes: 9 additions & 0 deletions tests/fixtures/basic_cfg_expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@
'pre_commit_hooks': [],
'regex': False,
'replace': '{new_version}',
'scm_info': {'branch_name': None,
'commit_sha': None,
'current_tag': None,
'current_version': None,
'dirty': None,
'distance_to_latest_tag': 0,
'repository_root': None,
'short_branch_name': None,
'tool': None},
'search': '{current_version}',
'serialize': ('{major}.{minor}.{patch}-{release}', '{major}.{minor}.{patch}'),
'setup_hooks': [],
Expand Down
10 changes: 10 additions & 0 deletions tests/fixtures/basic_cfg_expected.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ pre_commit_hooks:

regex: false
replace: "{new_version}"
scm_info:
branch_name: null
commit_sha: null
current_tag: null
current_version: null
dirty: null
distance_to_latest_tag: 0
repository_root: null
short_branch_name: null
tool: "None"
search: "{current_version}"
serialize:
- "{major}.{minor}.{patch}-{release}"
Expand Down
11 changes: 11 additions & 0 deletions tests/fixtures/basic_cfg_expected_full.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@
"pre_commit_hooks": [],
"regex": false,
"replace": "{new_version}",
"scm_info": {
"branch_name": null,
"commit_sha": null,
"current_tag": null,
"current_version": null,
"dirty": null,
"distance_to_latest_tag": 0,
"repository_root": null,
"short_branch_name": null,
"tool": "None"
},
"search": "{current_version}",
"serialize": [
"{major}.{minor}.{patch}-{release}",
Expand Down
Loading
Loading