From 0e2ffb5d7d3e623c7084c5fdeb35599b634d6291 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Vavrus=CC=8Ca?= <mvavrusa@cloudflare.com>
Date: Wed, 22 Nov 2017 18:57:39 -0800
Subject: [PATCH] Added luacheck for linting Lua files and static analysis

This is super useful for checking things like misusing undefined
variables or modifying globals, especially in modules when it's
not immediately visible which variables are in the global
namespace and which are not.

I added several exceptions for files in daemon/lua and tests,
as for example sandbox module needs to legitimately modify
global namespace.

There's a lot of things failing, so I didn't make it part of the
standard `make check`, but we should eventually enable it to
improve code quality and spot problems with CI.
---
 .luacheckrc   | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++
 Makefile      |  2 ++
 doc/build.rst |  3 ++
 3 files changed, 81 insertions(+)
 create mode 100644 .luacheckrc

diff --git a/.luacheckrc b/.luacheckrc
new file mode 100644
index 000000000..2e2f2775e
--- /dev/null
+++ b/.luacheckrc
@@ -0,0 +1,76 @@
+std = 'luajit'
+new_read_globals = {
+	'help',
+	'quit',
+	'hostname',
+	'moduledir',
+	'user',
+	'verbose',
+	'resolve',
+	'tojson',
+	'todname',
+	'map',
+	'net',
+	'cache',
+	'modules',
+	'trust_anchors',
+	'worker',
+	'event',
+	'_hint_root_file',
+	-- Sandbox declarations
+	'kB',
+	'MB',
+	'GB',
+	'sec',
+	'second',
+	'minute',
+	'min',
+	'hour',
+	'day',
+	'panic',
+	'warn',
+	'log',
+	'mode',
+	'trust_anchors',
+	'reorder_RR',
+	'option',
+	'env',
+	'kres',
+	'trustanchor',
+	'libknot_SONAME',
+	'libzscanner_SONAME',
+	'table_print',
+	'__engine',
+	'_ENV',
+	'_SANDBOX',
+}
+
+new_globals = {
+	-- Modules are allowed to be set and accessed from global namespace
+	'policy',
+	'view',
+	'stats',
+	'http',
+}
+
+-- Luacheck < 0.18 doesn't support new_read_globals
+for _, v in ipairs(new_read_globals) do
+	table.insert(new_globals, v)
+end
+
+-- Ignore test files
+exclude_files = {
+	'modules/policy/lua-aho-corasick', -- Vendored
+}
+
+-- Ignore some pedantic checks
+ignore = {
+	'4.1/err', -- Shadowing err
+	'4.1/.',   -- Shadowing one letter variables
+}
+
+-- Sandbox can set global variables
+files['daemon/lua'].ignore = {'111', '121', '122'}
+-- Tests and scripts can use global variables
+files['scripts'].ignore = {'111', '112', '113'}
+files['tests'].ignore = {'111', '112', '113'}
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 144721c0c..58093eb87 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,8 @@ check: all tests
 clean: contrib-clean lib-clean daemon-clean client-clean modules-clean \
 	tests-clean doc-clean bench-clean
 doc: doc-html
+lint:
+	luacheck --codes .
 .PHONY: all install check clean doc info
 
 # Options
diff --git a/doc/build.rst b/doc/build.rst
index 3427645a3..e9dde5381 100644
--- a/doc/build.rst
+++ b/doc/build.rst
@@ -62,6 +62,7 @@ There are also *optional* packages that enable specific functionality in Knot DN
    "libprotobuf_ 3.0+", "``modules/dnstap``", "Protocol Buffers support for dnstap_."
    "`libprotobuf-c`_ 1.0+", "``modules/dnstap``", "C bindings for Protobuf."
    "libfstrm_ 0.2+", "``modules/dnstap``", "Frame Streams data transport protocol."
+   "luacheck_", "``lint``", "Syntax and static analysis checker for Lua."
 
 .. [#] Requires C99, ``__attribute__((cleanup))`` and ``-MMD -MP`` for dependency file generation. GCC, Clang and ICC are supported.
 .. [#] You can use variables ``<dependency>_CFLAGS`` and ``<dependency>_LIBS`` to configure dependencies manually (i.e. ``libknot_CFLAGS`` and ``libknot_LIBS``).
@@ -252,6 +253,7 @@ The project can be built with code coverage tracking using the ``COVERAGE=1`` va
 Running unit and integration tests
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+The linter requires luacheck_ and is executed by ``make lint``.
 The unit tests require cmocka_ and are executed by ``make check``.
 Tests for the dnstap module need go and are executed by ``make ckeck-dnstap``.
 
@@ -319,5 +321,6 @@ You can hack on the container by changing the container entrypoint to shell like
 .. _libprotobuf: https://developers.google.com/protocol-buffers/
 .. _libprotobuf-c: https://github.com/protobuf-c/protobuf-c/wiki
 .. _libfstrm: https://github.com/farsightsec/fstrm
+.. _luacheck: http://luacheck.readthedocs.io
 
 .. _DESTDIR: https://www.gnu.org/prep/standards/html_node/DESTDIR.html
-- 
GitLab