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

Multiline support #98

Closed
wants to merge 3 commits into from
Closed

Conversation

achary
Copy link

@achary achary commented May 17, 2021

About

This is a PR covering feature idea from #83.

I've noticed some work started on dm/multiline branch, but I wasn't sure what the status of that was, (looked stalled to me).
Using a bit of spare time, here is my proposed extension to support the feature.

Implementation is based on the idea that when line-ending characters are detected in search phrase, then separate MultilinePatch class handles the file patching. For that, a Python's builtin re regex utils with re.MULTILINE flag are used.
The code for per-line search & replace like existed till now, is left unaffected, as I've been extending the code, rather modifying it.

All tests pass. The features used in extra test cases do correspond to what has been proposed in #83 description.

Implications

Since the patching for such case is file-based and not line-based (like the rest of the code), the UI information about the diff does not display numbers.

@achary achary force-pushed the multiline-support branch from 42081a5 to 23e2549 Compare May 17, 2021 21:24
@@ -275,7 +333,7 @@ def compute_change_request_for_file(self, file: tbump.config.File) -> ChangeRequ

to_search = None
if file.search:
to_search = file.search.format(current_version=re.escape(current_version))
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one looked like redundant to me, as well as blocked using the current_version later on in regex expressions correctly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right. Could you make a separate commit/PR so we can see if this is true?

@@ -21,6 +21,10 @@ def test_file_bumper_simple(test_repo: Path) -> None:
assert file_contains(test_repo / "glob-one.c", 'version_one = "1.2.41-alpha-2"')
assert file_contains(test_repo / "glob-two.v", 'version_two = "1.2.41-alpha-2"')

# one occurence is bumped up, others remain unchanged
assert file_contains(test_repo / "Cargo.toml", 'version = "1.2.41-alpha-2"')
Copy link
Author

@achary achary May 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To simplify my life, I did not created a separate test for checking multi-line replacement results. So I've re-used this one here to check that at least one line has been bumped, and at least one did not.

I'm aware this is not 100% accurate nor sufficiently strict assertion. It rather should be:

  • exactly first occurrence of version string has been changed, and
  • two other occurrences remain unchanged

Again, saving time here. Feel free to extend this check to more strict if you like.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we really need a separate test. The goal of a test suite is to have exactly one test failing if there's a bug somewhere, so it would be better to have a dedicated test for the multiline case.

And of course, the test should check the entire contents of the replaced file :)

@achary achary marked this pull request as ready for review May 17, 2021 21:33
new_line = old_line.replace(old_string, new_string)
patch = Patch(
self.working_path, str(expanded_src), i, old_line, new_line
# Checking for multi-line search phrase
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need a better architecture here. They are a lot of duplication between the two branches of the if "\\n" in search.

Ideally, we should just have something like his:

patcher = make_patcher(search)
patcher.patch()

where the make_patch function would be responsible for building either a MultilinePatch or a Path instance.

Also, there's some duplication between those two classes, which I think we could fix by implementing the following clas diagram:

tbump-multi

... maybe without BasePatch inheriting from Action, but rather Action containing a BasePatch instance?

Anyway, feel free to contact me if you want to discuss this further.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will come back to this PR when I can allocate some extra time.

@achary
Copy link
Author

achary commented Jan 25, 2023

Closing as it looks like not gonna land anytime soon.

@achary achary closed this Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants