mirror of
https://github.com/ditkrg/todo-to-issue-action.git
synced 2026-01-23 06:16:43 +00:00
fix: handle CRLF and mixed line-ending files
Regardless of the OS on which the app is running, respect the original line endings of the file when writing back the issue URL. In the case of a mixed line-ending file (e.g. both Windows-style CRLF and Unix-style LF), the issue URL comment line will use the line ending style of the TODO comment line above it. Partially addresses GitHub issue #245
This commit is contained in:
parent
c10ca453d9
commit
ad4d65c8b8
42
main.py
42
main.py
@ -73,18 +73,56 @@ def process_diff(diff, client=Client(), insert_issue_urls=False, parser=TodoPars
|
|||||||
line_number = raw_issue.start_line - 1
|
line_number = raw_issue.start_line - 1
|
||||||
with open(raw_issue.file_name, 'r') as issue_file:
|
with open(raw_issue.file_name, 'r') as issue_file:
|
||||||
file_lines = issue_file.readlines()
|
file_lines = issue_file.readlines()
|
||||||
|
|
||||||
|
# Get style of newlines used in this file, so that we
|
||||||
|
# use the same type when writing the file back out.
|
||||||
|
# Note:
|
||||||
|
# - if only one newline type is detected, then
|
||||||
|
# 'newlines' will be a string with that value
|
||||||
|
# - if no newlines are detected, 'newlines' will
|
||||||
|
# be 'None' and the platform-dependent default
|
||||||
|
# will be used when terminating lines on write
|
||||||
|
# - if multiple newline types are detected (e.g.
|
||||||
|
# a mix of Windows- and Unix-style newlines in
|
||||||
|
# the same file), then that is handled within
|
||||||
|
# the following if block...
|
||||||
|
newline_style = issue_file.newlines
|
||||||
|
|
||||||
|
if isinstance(issue_file.newlines, tuple):
|
||||||
|
# A tuple being returned indicates that a mix of
|
||||||
|
# line ending styles was found in the file. In
|
||||||
|
# order to not perturb the file any more than
|
||||||
|
# intended (i.e. inserting the issue URL comment(s))
|
||||||
|
# we'll reread the file and keep the line endings.
|
||||||
|
# On write, we'll tell writelines to not introduce
|
||||||
|
# any explicit line endings. This modification
|
||||||
|
# of the read and write behavior is handled by
|
||||||
|
# passing '' to the newline argument of open().
|
||||||
|
# Note: the line ending of the issue URLs line(s)
|
||||||
|
# itself will be that of the TODO line above it
|
||||||
|
# and is handled later in this function.
|
||||||
|
newline_style = ''
|
||||||
|
|
||||||
|
# reread the file without stripping off line endings
|
||||||
|
with open(raw_issue.file_name, 'r',
|
||||||
|
newline=newline_style) as issue_file_reread:
|
||||||
|
file_lines = issue_file_reread.readlines()
|
||||||
|
else:
|
||||||
|
newline_style = issue_file.newlines
|
||||||
if line_number < len(file_lines):
|
if line_number < len(file_lines):
|
||||||
# Duplicate the line to retain the comment syntax.
|
# Duplicate the line to retain the comment syntax.
|
||||||
old_line = file_lines[line_number]
|
old_line = file_lines[line_number]
|
||||||
remove = fr'(?i:{re.escape(raw_issue.identifier)}).*{re.escape(raw_issue.title)}.*?(\r|\r\n|\n)?$'
|
remove = fr'(?i:{re.escape(raw_issue.identifier)}).*{re.escape(raw_issue.title)}.*?(\r|\r\n|\n)?$'
|
||||||
insert = f'Issue URL: {client.get_issue_url(new_issue_number)}'
|
insert = f'Issue URL: {client.get_issue_url(new_issue_number)}'
|
||||||
new_line = re.sub('^.*'+remove, raw_issue.prefix + insert, old_line)
|
# note that the '\1' capture group is the line ending character sequence and
|
||||||
|
# will only be non-empty in the case of a mixed line-endings file
|
||||||
|
new_line = re.sub('^.*'+remove, fr'{raw_issue.prefix + insert}\1', old_line)
|
||||||
# make sure the above operation worked as intended
|
# make sure the above operation worked as intended
|
||||||
if new_line != old_line:
|
if new_line != old_line:
|
||||||
# Check if the URL line already exists, if so abort.
|
# Check if the URL line already exists, if so abort.
|
||||||
if line_number == len(file_lines) - 1 or file_lines[line_number + 1] != new_line:
|
if line_number == len(file_lines) - 1 or file_lines[line_number + 1] != new_line:
|
||||||
file_lines.insert(line_number + 1, new_line)
|
file_lines.insert(line_number + 1, new_line)
|
||||||
with open(raw_issue.file_name, 'w') as issue_file:
|
with open(raw_issue.file_name, 'w', newline=newline_style) as issue_file:
|
||||||
issue_file.writelines(file_lines)
|
issue_file.writelines(file_lines)
|
||||||
print('Issue URL successfully inserted', file=output)
|
print('Issue URL successfully inserted', file=output)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user