bumpver/src/pycalver/rewrite.py

91 lines
2.2 KiB
Python
Raw Normal View History

2020-09-24 11:16:02 +00:00
# This file is part of the pycalver project
# https://github.com/mbarkhau/pycalver
#
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
# SPDX-License-Identifier: MIT
2020-05-25 07:46:30 +00:00
import typing as typ
2018-09-02 21:48:12 +02:00
import difflib
2020-05-25 07:46:30 +00:00
2019-02-21 15:41:06 +01:00
import pathlib2 as pl
2018-09-03 22:23:51 +02:00
2020-09-19 22:35:48 +00:00
from . import config
from .patterns import Pattern
2020-09-06 20:20:36 +00:00
2020-09-19 22:35:48 +00:00
class NoPatternMatch(Exception):
"""Pattern not found in content.
logger.error is used to show error info about the patterns so
that users can debug what is wrong with them. The class
itself doesn't capture that info. This approach is used so
that all patter issues can be shown, rather than bubbling
all the way up the stack on the very first pattern with no
matches.
"""
2018-09-02 21:48:12 +02:00
2018-11-15 22:16:16 +01:00
def detect_line_sep(content: str) -> str:
r"""Parse line separator from content.
>>> detect_line_sep('\r\n')
'\r\n'
>>> detect_line_sep('\r')
'\r'
>>> detect_line_sep('\n')
'\n'
>>> detect_line_sep('')
'\n'
"""
2018-11-11 15:40:16 +01:00
if "\r\n" in content:
return "\r\n"
elif "\r" in content:
return "\r"
else:
return "\n"
2020-09-06 20:20:36 +00:00
class RewrittenFileData(typ.NamedTuple):
"""Container for line-wise content of rewritten files."""
path : str
line_sep : str
old_lines: typ.List[str]
new_lines: typ.List[str]
2020-09-19 22:35:48 +00:00
PathPatternsItem = typ.Tuple[pl.Path, typ.List[Pattern]]
def iter_path_patterns_items(
file_patterns: config.PatternsByFile,
) -> typ.Iterable[PathPatternsItem]:
for filepath_str, patterns in file_patterns.items():
filepath_obj = pl.Path(filepath_str)
if filepath_obj.exists():
yield (filepath_obj, patterns)
else:
errmsg = f"File does not exist: '{filepath_str}'"
2020-09-06 20:20:36 +00:00
raise IOError(errmsg)
def diff_lines(rfd: RewrittenFileData) -> typ.List[str]:
r"""Generate unified diff.
>>> rfd = RewrittenFileData(
... path = "<path>",
... line_sep = "\n",
... old_lines = ["foo"],
... new_lines = ["bar"],
... )
>>> diff_lines(rfd)
['--- <path>', '+++ <path>', '@@ -1 +1 @@', '-foo', '+bar']
"""
lines = difflib.unified_diff(
2020-09-19 22:35:48 +00:00
a=rfd.old_lines,
b=rfd.new_lines,
lineterm="",
fromfile=rfd.path,
tofile=rfd.path,
)
return list(lines)