Browse Source

Add check D005 - no newline at end of file

Change-Id: I160bb7e9b3c904655567caee999ac91366668109
Christian Berendt 4 years ago
parent
commit
5a4341727e
7 changed files with 38 additions and 2 deletions
  1. 1
    1
      CONTRIBUTING.rst
  2. 1
    1
      HACKING.rst
  3. 1
    0
      README.rst
  4. 11
    0
      doc8/checks.py
  5. 2
    0
      doc8/main.py
  6. 5
    0
      doc8/parser.py
  7. 17
    0
      doc8/tests/test_checks.py

+ 1
- 1
CONTRIBUTING.rst View File

@@ -10,4 +10,4 @@ the workflow documented at:
10 10
 
11 11
    http://wiki.openstack.org/GerritWorkflow
12 12
 
13
-Pull requests submitted through GitHub will be ignored.
13
+Pull requests submitted through GitHub will be ignored.

+ 1
- 1
HACKING.rst View File

@@ -1,4 +1,4 @@
1 1
 doc8 Style Commandments
2 2
 ===============================================
3 3
 
4
-Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/
4
+Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/

+ 1
- 0
README.rst View File

@@ -43,6 +43,7 @@ Command line usage
43 43
         - no trailing whitespace - D002
44 44
         - no tabulation for indentation - D003
45 45
         - no carriage returns (use unix newlines) - D004
46
+        - no newline at end of file - D005
46 47
 
47 48
     positional arguments:
48 49
       path                  path to scan for doc files (default: os.getcwd())

+ 11
- 0
doc8/checks.py View File

@@ -73,6 +73,17 @@ class CheckCarriageReturn(LineCheck):
73 73
             yield ('D004', 'Found literal carriage return')
74 74
 
75 75
 
76
+class CheckNewlineEndOfFile(ContentCheck):
77
+    REPORTS = frozenset(["D005"])
78
+
79
+    def __init__(self, cfg):
80
+        super(CheckNewlineEndOfFile, self).__init__(cfg)
81
+
82
+    def report_iter(self, parsed_file):
83
+        if parsed_file.lines and not parsed_file.lines[-1].endswith('\n'):
84
+            yield (len(parsed_file.lines), 'D005', 'No newline at end of file')
85
+
86
+
76 87
 class CheckValidity(ContentCheck):
77 88
     REPORTS = frozenset(["D000"])
78 89
     EXT_MATCHER = re.compile(r"(.*)[.]rst", re.I)

+ 2
- 0
doc8/main.py View File

@@ -27,6 +27,7 @@ What is checked:
27 27
     - no trailing whitespace - D002
28 28
     - no tabulation for indentation - D003
29 29
     - no carriage returns (use unix newlines) - D004
30
+    - no newline at end of file - D005
30 31
 """
31 32
 
32 33
 import argparse
@@ -131,6 +132,7 @@ def fetch_checks(cfg):
131 132
         checks.CheckIndentationNoTab(cfg),
132 133
         checks.CheckCarriageReturn(cfg),
133 134
         checks.CheckMaxLineLength(cfg),
135
+        checks.CheckNewlineEndOfFile(cfg),
134 136
     ]
135 137
     mgr = extension.ExtensionManager(
136 138
         namespace='doc8.extension.check',

+ 5
- 0
doc8/parser.py View File

@@ -96,6 +96,11 @@ class ParsedFile(object):
96 96
                 line = line[0:-1]
97 97
             yield line
98 98
 
99
+    @property
100
+    def lines(self):
101
+        self._read()
102
+        return self._lines
103
+
99 104
     @property
100 105
     def extension(self):
101 106
         return self._extension

+ 17
- 0
doc8/tests/test_checks.py View File

@@ -120,3 +120,20 @@ test
120 120
                 check = checks.CheckMaxLineLength(conf)
121 121
                 errors = list(check.report_iter(parsed_file))
122 122
                 self.assertEqual(expected_errors, len(errors))
123
+
124
+
125
+class TestNewlineEndOfFile(testtools.TestCase):
126
+    def test_newline(self):
127
+        tests = [(1, "testing"),
128
+                 (1, "testing\ntesting"),
129
+                 (0, "testing\n"),
130
+                 (0, "testing\ntesting\n")]
131
+
132
+        for expected_errors, line in tests:
133
+            with tempfile.NamedTemporaryFile() as fh:
134
+                fh.write(line)
135
+                fh.flush()
136
+                parsed_file = parser.ParsedFile(fh.name)
137
+                check = checks.CheckNewlineEndOfFile({})
138
+                errors = list(check.report_iter(parsed_file))
139
+                self.assertEqual(expected_errors, len(errors))

Loading…
Cancel
Save