summaryrefslogtreecommitdiffstats
path: root/tools/lint/file-whitespace
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/lint/file-whitespace.yml160
-rw-r--r--tools/lint/file-whitespace/__init__.py124
2 files changed, 284 insertions, 0 deletions
diff --git a/tools/lint/file-whitespace.yml b/tools/lint/file-whitespace.yml
new file mode 100644
index 0000000000..97fe39de07
--- /dev/null
+++ b/tools/lint/file-whitespace.yml
@@ -0,0 +1,160 @@
+---
+file-whitespace:
+ description: File content sanity check
+ include:
+ - .
+ - tools/lint/python/black_requirements.txt
+ - tools/lint/python/ruff_requirements.txt
+ - tools/lint/rst/requirements.txt
+ - tools/lint/tox/tox_requirements.txt
+ - tools/lint/spell/codespell_requirements.txt
+ - tools/tryselect/selectors/chooser/requirements.txt
+ exclude:
+ - accessible/tests/crashtests
+ - accessible/tests/mochitest
+ - browser/locales/en-US/chrome/browser/uiDensity.properties
+ - build/pgo/blueprint
+ - build/pgo/js-input
+ - devtools/client/debugger/test
+ - devtools/client/inspector/markup/test
+ - devtools/client/inspector/rules/test
+ - devtools/client/inspector/test
+ # Excluded because tests were failing unexpectedly
+ - devtools/client/styleeditor/test/sync_with_csp.css
+ - devtools/client/webconsole/test/browser/test-message-categories-css-parser.css
+ - devtools/shared/webconsole/test/chrome/test_object_actor_native_getters.html
+ - docshell/base/crashtests
+ - docshell/test
+ - dom/base/crashtests
+ - dom/base/test
+ - dom/canvas/crashtests
+ - dom/canvas/test
+ - dom/events/crashtests
+ - dom/events/test
+ - dom/file/tests/file_mozfiledataurl_inner.html
+ - dom/html/crashtests
+ - dom/html/reftests
+ - dom/html/test
+ - dom/jsurl/crashtests/344996-1.xhtml
+ - dom/jsurl/test
+ - dom/media/mediasource/test/crashtests/926665.html
+ - dom/media/test
+ - dom/media/tests
+ - dom/media/webaudio/test
+ - dom/media/webrtc/transport/nricectx.cpp
+ - dom/media/webspeech/synth/test
+ - dom/plugins/test
+ - dom/smil/crashtests
+ - dom/smil/test
+ - dom/security/test
+ - dom/svg/crashtests
+ - dom/svg/test
+ - dom/webauthn/winwebauthn/webauthn.h
+ - dom/tests/mochitest
+ - dom/xml/crashtests
+ - dom/xml/test
+ - dom/xslt/crashtests
+ - dom/xslt/tests
+ - dom/xul/crashtests
+ - dom/xul/test
+ - editor/composer/test
+ - editor/composer/crashtests/removing-editable-xslt.html
+ - editor/libeditor/tests
+ - editor/libeditor/crashtests
+ - editor/reftests
+ - extensions/universalchardet
+ - gfx/tests/crashtests
+ - gfx/vr/nsFxrCommandLineHandler.cpp
+ - image/test/crashtests
+ - image/test/mochitest
+ - image/test/reftest
+ - intl/lwbrk/crashtests
+ - intl/uconv/crashtests
+ - intl/uconv/tests
+ - intl/strres/tests/unit/397093.properties
+ - intl/strres/tests/unit/strres.properties
+ - js/xpconnect/crashtests
+ - js/xpconnect/tests
+ - js/src/frontend/BytecodeEmitter.cpp
+ - js/src/frontend/SharedContext.h
+ - layout/base/crashtests
+ - layout/base/tests
+ - layout/forms/crashtests
+ - layout/forms/test
+ - layout/generic/crashtests
+ - layout/generic/test
+ - layout/inspector/tests
+ - layout/mathml/tests
+ - layout/painting/crashtests/1405881-1.html
+ - layout/painting/crashtests/1407470-1.html
+ - layout/reftests
+ - layout/style/crashtests
+ - layout/style/test
+ - layout/svg/crashtests
+ - layout/tables/test/test_bug337124.html
+ - layout/tables/crashtests
+ - layout/xul/crashtests
+ - layout/xul/reftest
+ - layout/xul/test
+ - layout/xul/tree
+ - modules/libjar/zipwriter/test/unit/data/test_bug399727.html
+ - netwerk/test/crashtests
+ - netwerk/test/mochitests/test1.css
+ - netwerk/test/mochitests/test2.css
+ - parser/htmlparser/tests
+ - parser/html/java/named-character-references.html
+ - testing/perfdocs/generated/
+ - testing/talos/talos/pageloader/chrome/pageloader.xhtml
+ - testing/talos/talos/tests
+ - testing/web-platform/mozilla/tests/editor
+ - testing/web-platform/mozilla/tests/focus
+ - testing/web-platform/tests
+ - testing/web-platform/tests/conformance-checkers
+ - testing/web-platform/tests/content-security-policy
+ - testing/web-platform/tests/html
+ - testing/web-platform/tests/tools/lint/tests/dummy/broken.html
+ - testing/web-platform/tests/tools/lint/tests/dummy/broken_ignored.html
+ - toolkit/content/tests/chrome
+ - tools/jprof/README.html
+ - tools/lint/eslint
+ - tools/lint/test/test_clang_format.py
+ - view/crashtests
+ - widget/cocoa/crashtests
+ - widget/nsFilePickerProxy.cpp
+ - widget/tests
+ - widget/windows/tests/TestUrisToValidate.h
+ - xpcom/reflect/xptcall/porting.html
+ - xpcom/tests/test.properties
+ - xpcom/tests/unit/data/bug121341.properties
+ # Excluded below files because tests were failing unexpectedly
+ - dom/bindings/test/test_barewordGetsWindow.html
+ - devtools/client/styleeditor/test/sourcemap-css/sourcemaps.css
+ - devtools/client/styleeditor/test/sourcemap-css/contained.css
+ - devtools/client/styleeditor/test/sourcemap-css/test-stylus.css
+ - dom/bindings/test/file_barewordGetsWindow_frame1.html
+ - dom/bindings/test/file_barewordGetsWindow_frame2.html
+ - devtools/perfdocs/index.rst
+ - python/mozperftest/perfdocs/running.rst
+ - python/mozperftest/perfdocs/vision.rst
+ - python/mozperftest/perfdocs/writing.rst
+ extensions:
+ - .c
+ - .cc
+ - .cpp
+ - .css
+ - .dtd
+ - .idl
+ - .ftl
+ - .h
+ - .html
+ - .md
+ - .properties
+ - .py
+ - .rs
+ - .rst
+ - .webidl
+ - .xhtml
+ support-files:
+ - 'tools/lint/file-whitespace/**'
+ type: external
+ payload: file-whitespace:lint
diff --git a/tools/lint/file-whitespace/__init__.py b/tools/lint/file-whitespace/__init__.py
new file mode 100644
index 0000000000..ab7a6944b7
--- /dev/null
+++ b/tools/lint/file-whitespace/__init__.py
@@ -0,0 +1,124 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from mozlint import result
+from mozlint.pathutils import expand_exclusions
+
+results = []
+
+
+def lint(paths, config, fix=None, **lintargs):
+ files = list(expand_exclusions(paths, config, lintargs["root"]))
+ log = lintargs["log"]
+ fixed = 0
+
+ for f in files:
+ with open(f, "rb") as open_file:
+ hasFix = False
+ content_to_write = []
+
+ try:
+ lines = open_file.readlines()
+ # Check for Empty spaces or newline character at end of file
+ if lines[:].__len__() != 0 and lines[-1:][0].strip().__len__() == 0:
+ # return file pointer to first
+ open_file.seek(0)
+ if fix:
+ fixed += 1
+ # fix Empty lines at end of file
+ for i, line in reversed(list(enumerate(open_file))):
+ # determine if line is empty
+ if line.strip() != b"":
+ with open(f, "wb") as write_file:
+ # determine if file's last line have \n, if not then add a \n
+ if not lines[i].endswith(b"\n"):
+ lines[i] = lines[i] + b"\n"
+ # write content to file
+ for e in lines[: i + 1]:
+ write_file.write(e)
+ # end the loop
+ break
+ else:
+ res = {
+ "path": f,
+ "message": "Empty Lines at end of file",
+ "level": "error",
+ "lineno": open_file.readlines()[:].__len__(),
+ }
+ results.append(result.from_config(config, **res))
+ except Exception as ex:
+ log.debug("Error: " + str(ex) + ", in file: " + f)
+
+ # return file pointer to first
+ open_file.seek(0)
+
+ lines = open_file.readlines()
+ # Detect missing newline at the end of the file
+ if lines[:].__len__() != 0 and not lines[-1].endswith(b"\n"):
+ if fix:
+ fixed += 1
+ with open(f, "wb") as write_file:
+ # add a newline character at end of file
+ lines[-1] = lines[-1] + b"\n"
+ # write content to file
+ for e in lines:
+ write_file.write(e)
+ else:
+ res = {
+ "path": f,
+ "message": "File does not end with newline character",
+ "level": "error",
+ "lineno": lines.__len__(),
+ }
+ results.append(result.from_config(config, **res))
+
+ # return file pointer to first
+ open_file.seek(0)
+
+ for i, line in enumerate(open_file):
+ if line.endswith(b" \n"):
+ # We found a trailing whitespace
+ if fix:
+ # We want to fix it, strip the trailing spaces
+ content_to_write.append(line.rstrip() + b"\n")
+ fixed += 1
+ hasFix = True
+ else:
+ res = {
+ "path": f,
+ "message": "Trailing whitespace",
+ "level": "error",
+ "lineno": i + 1,
+ }
+ results.append(result.from_config(config, **res))
+ else:
+ if fix:
+ content_to_write.append(line)
+ if hasFix:
+ # Only update the file when we found a change to make
+ with open(f, "wb") as open_file_to_write:
+ open_file_to_write.write(b"".join(content_to_write))
+
+ # We are still using the same fp, let's return to the first
+ # line
+ open_file.seek(0)
+ # Open it as once as we just need to know if there is
+ # at least one \r\n
+ content = open_file.read()
+
+ if b"\r\n" in content:
+ if fix:
+ fixed += 1
+ content = content.replace(b"\r\n", b"\n")
+ with open(f, "wb") as open_file_to_write:
+ open_file_to_write.write(content)
+ else:
+ res = {
+ "path": f,
+ "message": "Windows line return",
+ "level": "error",
+ }
+ results.append(result.from_config(config, **res))
+
+ return {"results": results, "fixed": fixed}