Skip to content

Commit 93c41c3

Browse files
author
Sergey Vilgelm
committed
Add file-header-path option
Use a file to store a long multi-line header instead of putting it to the pylint config.
1 parent d3fe096 commit 93c41c3

File tree

3 files changed

+60
-27
lines changed

3 files changed

+60
-27
lines changed

pylintfileheader/file_header_checker.py

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ class FileHeaderChecker(BaseChecker):
3636
'help': 'The file header that should be on top of a file.',
3737
}
3838
),
39+
(
40+
'file-header-path',
41+
{
42+
'default': None,
43+
'type': 'string',
44+
'metavar': '<file>',
45+
'help': 'The path to the file that contains the header.',
46+
}
47+
),
3948
(
4049
'file-header-ignore-empty-files',
4150
{
@@ -47,27 +56,39 @@ class FileHeaderChecker(BaseChecker):
4756
),
4857
)
4958

50-
def process_module(self, node):
51-
"""Process the astroid node stream."""
52-
if self.config.file_header:
53-
content = None
54-
with node.stream() as stream:
55-
# Explicit decoding required by python 3
56-
content = stream.read().decode('utf-8')
59+
def __init__(self, linter=None):
60+
super(FileHeaderChecker, self).__init__(linter=linter)
61+
self.pattern = None
62+
self.header = None
5763

58-
if self.config.file_header_ignore_empty_files and not content:
59-
return
64+
def open(self):
65+
self.header = self.config.file_header
66+
if not self.header and self.config.file_header_path:
67+
with open(self.config.file_header_path, 'r') as f:
68+
self.header = f.read()
6069

70+
if self.header:
6171
if sys.version_info[0] < 3:
62-
pattern = re.compile(
63-
r'\A' + self.config.file_header, re.LOCALE | re.MULTILINE)
72+
opts = re.LOCALE | re.MULTILINE
6473
else:
65-
# The use of re.LOCALE is discouraged in python 3
66-
pattern = re.compile(
67-
r'\A' + self.config.file_header, re.MULTILINE)
74+
opts = re.MULTILINE
75+
self.pattern = re.compile(r'\A' + self.header, opts)
76+
77+
def process_module(self, node):
78+
"""Process the astroid node stream."""
79+
80+
if self.pattern is None:
81+
return
82+
83+
content = None
84+
with node.stream() as stream:
85+
# Explicit decoding required by python 3
86+
content = stream.read().decode('utf-8')
87+
88+
if self.config.file_header_ignore_empty_files and not content:
89+
return
6890

69-
matches = pattern.findall(content)
91+
matches = self.pattern.findall(content)
7092

71-
if len(matches) != 1:
72-
self.add_message('invalid-file-header', 1,
73-
args=self.config.file_header)
93+
if len(matches) != 1:
94+
self.add_message('invalid-file-header', 1, args=self.header)

pylintfileheadertest/file_header_checker_test.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,6 @@ def test_valid_header_not_at_top_message_added(self):
4343
args='# Valid\n# Header')):
4444
self.checker.process_module(node_mock)
4545

46-
def test_config_empty_no_message_added(self):
47-
"""When the `file-header` option is not set, no message should be added."""
48-
49-
self.checker.config.file_header = None
50-
node_mock = MagicMock()
51-
node_mock.stream.return_value.__enter__.return_value.read.return_value.decode.return_value = '# Invalid\n# Header'
52-
with self.assertNoMessages():
53-
self.checker.process_module(node_mock)
54-
5546
def test_ignore_empty_files(self):
5647
"""When the `file-header-ignore-empty-files` option is set to True."""
5748

@@ -71,3 +62,22 @@ def test_do_not_ignore_empty_files(self):
7162
line=1,
7263
args='# Valid\n# Header')):
7364
self.checker.process_module(node_mock)
65+
66+
67+
class TestFileHeaderCheckerNoConfig(pylint.testutils.CheckerTestCase):
68+
CHECKER_CLASS = FileHeaderChecker
69+
CONFIG = {}
70+
71+
def test_no_message_added(self):
72+
"""When the `file-header` option is not set, no message should be added."""
73+
74+
self.checker.config.file_header = None
75+
node_mock = MagicMock()
76+
node_mock.stream.return_value.__enter__.return_value.read.return_value.decode.return_value = '# Invalid\n# Header'
77+
with self.assertNoMessages():
78+
self.checker.process_module(node_mock)
79+
80+
81+
class TestFileHeaderCheckerPath(TestFileHeaderChecker):
82+
CHECKER_CLASS = FileHeaderChecker
83+
CONFIG = {'file_header_path': 'pylintfileheadertest/header.txt'}

pylintfileheadertest/header.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Valid
2+
# Header

0 commit comments

Comments
 (0)