Skip to content

Commit

Permalink
SpaceConsistencyBear: Add blanklines_at_EOF option
Browse files Browse the repository at this point in the history
Add allow_trailing_blanklines option for whether to allow
trailing blanklines at EOF.

Closes coala#1793
  • Loading branch information
khanchi97 committed Dec 17, 2017
1 parent bdbc81e commit 0efd137
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 34 deletions.
105 changes: 72 additions & 33 deletions bears/general/SpaceConsistencyBear.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def run(self,
file,
use_spaces: bool,
allow_trailing_whitespace: bool=False,
allow_trailing_blanklines: bool=False,
indent_size: int=SpacingHelper.DEFAULT_TAB_WIDTH,
enforce_newline_at_EOF: bool=True):
'''
Expand All @@ -29,6 +30,8 @@ def run(self,
of tabs.
:param allow_trailing_whitespace: Whether to allow trailing whitespace
or not.
:param allow_trailing_blanklines: Whether to allow trailing blanklines
at the EOF or not.
:param indent_size: Number of spaces per indentation
level.
:param enforce_newline_at_EOF: Whether to enforce a newline at the
Expand All @@ -38,48 +41,84 @@ def run(self,
result_texts = []
additional_info_texts = []

def get_blanklines_nr_start():

if not allow_trailing_blanklines:
rev_enumerated_zip_obj = zip(reversed(range(1, len(file) + 1)),
reversed(file))
rev_enumerated_tuple = tuple(rev_enumerated_zip_obj)
line_nr_start = -1

for line_number, line in rev_enumerated_tuple:
replacement = line
if replacement.strip() == '':
line_nr_start = line_number
else:
break

return line_nr_start

blanklines_nr_start = get_blanklines_nr_start()
no_blanklines = True

for line_number, line in enumerate(file, start=1):
replacement = line

if enforce_newline_at_EOF:
# Since every line contains at the end at least one \n, only
# the last line could potentially not have one. So we don't
# need to check whether the current line_number is the last
# one.
if replacement[-1] != '\n':
replacement += '\n'
result_texts.append('No newline at EOF.')
additional_info_texts.append(
"A trailing newline character ('\\n') is missing from "
'your file. '
'<http://stackoverflow.com/a/5813359/3212182> gives '
'more information about why you might need one.')

if not allow_trailing_whitespace:
replacement = replacement.rstrip(' \t\n') + '\n'
if replacement != line.rstrip('\n') + '\n':
result_texts.append('Trailing whitespaces.')
if not allow_trailing_blanklines:
if blanklines_nr_start == line_number:

no_blanklines = False
result_texts.append('Trailing blanklines.')
additional_info_texts.append(
'Your source code contains trailing whitespaces. '
'Those usually have no meaning. Please consider '
'Your source code contains trailing blanklines at EOF.'
'Those usually have no meaning. Please consider'
'removing them.')
blanklines_nr_start = None

if no_blanklines:
if enforce_newline_at_EOF:
# Since every line contains at the end at least one \n,
# only the last line could potentially not have one. So we
# don't need to check whether the current line_number is
# the last one.
if replacement[-1] != '\n':
replacement += '\n'
result_texts.append('No newline at EOF.')
additional_info_texts.append(
"A trailing newline character ('\\n') is missing "
'from your file. '
'<http://stackoverflow.com/a/5813359/3212182> '
'gives more information about why you might need '
'one.')

if not allow_trailing_whitespace:
replacement = replacement.rstrip(' \t\n') + '\n'
if replacement != line.rstrip('\n') + '\n':
result_texts.append('Trailing whitespaces.')
additional_info_texts.append(
'Your source code contains trailing whitespaces. '
'Those usually have no meaning. Please consider '
'removing them.')

if use_spaces:
pre_replacement = replacement
replacement = spacing_helper.replace_tabs_with_spaces(
replacement)
if replacement != pre_replacement:
result_texts.append('Tabs used instead of spaces.')
else:
pre_replacement = replacement
replacement = spacing_helper.replace_spaces_with_tabs(
replacement)
if replacement != pre_replacement:
result_texts.append('Spaces used instead of tabs.')
if use_spaces:
pre_replacement = replacement
replacement = spacing_helper.replace_tabs_with_spaces(
replacement)
if replacement != pre_replacement:
result_texts.append('Tabs used instead of spaces.')
else:
pre_replacement = replacement
replacement = spacing_helper.replace_spaces_with_tabs(
replacement)
if replacement != pre_replacement:
result_texts.append('Spaces used instead of tabs.')

if len(result_texts) > 0:
diff = Diff(file)
diff.change_line(line_number, line, replacement)
if no_blanklines:
diff.change_line(line_number, line, replacement)
else:
diff.delete_lines(line_number, len(file))
inconsistencies = ''.join('\n- ' + string
for string in result_texts)
yield Result.from_values(
Expand Down
26 changes: 25 additions & 1 deletion tests/general/SpaceConsistencyBearTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,28 @@ def test_data_sets_tabs(self):
self.section.append(Setting('use_spaces', 'false'))
self.section.append(Setting('allow_trailing_whitespace', 'true'))
self.section.append(Setting('enforce_newline_at_EOF', 'false'))
self.section.append(Setting('allow_trailing_blanklines', 'false'))

self.check_invalidity(self.uut, [' t'])
self.check_validity(self.uut, ['t \n'])
self.check_validity(self.uut, ['\tt\n'])
self.check_validity(self.uut, [])

def test_enforce_newline_at_eof(self):
self.section.append(Setting('use_spaces', 'true'))
self.section.append(Setting('allow_trailing_whitespace', 'true'))
self.section.append(Setting('enforce_newline_at_EOF', 'true'))
self.section.append(Setting('allow_trailing_blanklines', 'true'))

self.check_validity(self.uut,
['hello world \n'],
force_linebreaks=False)
self.check_validity(self.uut,
['def somecode():\n',
" print('funny')\n",
" print('funny end.')\n"],
" print('funny end.')\n",
' \n',
'\n'],
force_linebreaks=False)
self.check_invalidity(self.uut,
[' no hello world'],
Expand All @@ -70,3 +75,22 @@ def test_enforce_newline_at_eof(self):
" print('funny')\n",
" print('the result is not funny...')"],
force_linebreaks=False)

def test_trailing_blanklines(self):
self.section.append(Setting('use_spaces', 'true'))
self.section.append(Setting('allow_trailing_whitespace', 'false'))
self.section.append(Setting('enforce_newline_at_EOF', 'true'))
self.section.append(Setting('allow_trailing_blanklines', 'false'))

self.check_invalidity(self.uut,
['def funny_code():\n',
" print('Is it funny?')\n",
" print('Yeah, funny')\n",
' \n',
'\n'],
force_linebreaks=False)
self.check_validity(self.uut,
['def funny_code():\n',
" print('Is it funny?')\n",
" print('Yeah, funny')\n"],
force_linebreaks=False)

0 comments on commit 0efd137

Please sign in to comment.