lint: check for bad white space habits

A little coding hygiene cannot hurt. Add a simple awk script to check
all source files for bad white space habits:

- trailing white space
- trailing new lines at the end of files
- missing new line at the end of files
- spaces followed by tabs

The script outputs color when the terminal supports it. It exits with
a non-zero code when there was at least one white space issue found.
Call the script in the lint step.

Example output of the awk script:

 config/default_styleset:1:# <-- trailing whitespace
 config/default_styleset:3:# <-- trailing whitespace
 doc/aerc.1.scd:78:        Executes an arbitrary command in the background. Aerc will set the <-- trailing whitespace
 doc/aerc.1.scd:234:        <-- trailing whitespace
 doc/aerc.1.scd:237:        <-- trailing whitespace
 worker/types/thread_test.go:74:        //         return ErrSkipThread<-- space(s) followed by tab(s)
 worker/lib/testdata/message/invalid/hexa: trailing new line(s)

Fix issues reported by the script.

NB: The ENDFILE match is a GNU extension. It will be ignored on BSD-awk
and trailing new lines will not be detected. The lint make target is
only invoked on alpine linux which has GNU awk anyway.

NB: Empty cells in scdoc tables require trailing white space... Avoid
this by setting content in these cells. I don't really see a use for
empty cells.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
This commit is contained in:
Robin Jarry 2022-10-16 12:05:25 +02:00
parent b22639ab20
commit ebcd6fcea1
9 changed files with 77 additions and 39 deletions

View file

@ -61,6 +61,7 @@ fmt:
.PHONY: lint .PHONY: lint
lint: lint:
@contrib/check-whitespace `git ls-files` && echo white space ok.
@$(GO) run mvdan.cc/gofumpt -l . | grep ^ \ @$(GO) run mvdan.cc/gofumpt -l . | grep ^ \
&& echo The above files need to be formatted, please run make fmt && exit 1 \ && echo The above files need to be formatted, please run make fmt && exit 1 \
|| echo all files formatted. || echo all files formatted.

51
contrib/check-whitespace Executable file
View file

@ -0,0 +1,51 @@
#!/usr/bin/awk -f
BEGIN {
isatty = system("test -t 1") == "0"
retcode = 0
}
function color(code, s) {
if (isatty) {
return "\033[" code "m" s "\033[0m"
}
return s
}
function red(s) { return color("31", s) }
function green(s) { return color("32", s) }
function magenta(s) { return color("35", s) }
function cyan(s) { return color("36", s) }
function bg_red(s) { return color("41", s) }
function hl_ws(s, pattern) {
gsub(pattern, bg_red("&"), s)
# convert tab characters to 8 spaces to allow coloring
gsub(/\t/, " ", s)
return s
}
/ +\t+/ {
retcode = 1
print magenta(FILENAME) cyan(":") green(FNR) cyan(":") \
hl_ws($0, " +\\t+") red("<-- space(s) followed by tab(s)")
}
/[ \t]+$/ {
retcode = 1
print magenta(FILENAME) cyan(":") green(FNR) cyan(":") \
hl_ws($0, "[ \\t]+$") red("<-- trailing whitespace")
}
ENDFILE {
# will only match on GNU awk, ignored on non-GNU versions
if ($0 ~ /^[ \t]*$/) {
retcode = 1
print magenta(FILENAME) cyan(": ") red("trailing new line(s)")
} else if (RT != "\n") {
retcode = 1
print magenta(FILENAME) cyan(": ") red("no new line at end of file")
}
}
END {
exit retcode
}

View file

@ -867,63 +867,63 @@ following special keys are supported:
| semicolon | semicolon
: ; : ;
| tab | tab
: : Tab
| enter | enter
: : Enter
| up | up
: : Up arrow
| c-up | c-up
: Ctrl+Up : Ctrl+Up
| a-up | a-up
: Alt+Up : Alt+Up
| down | down
: : Down arrow
| c-down | c-down
: Ctrl+Down : Ctrl+Down
| a-down | a-down
: Alt+Down : Alt+Down
| right | right
: : Right arrow
| c-right | c-right
: Ctrl+Right : Ctrl+Right
| a-right | a-right
: Alt+Right : Alt+Right
| left | left
: : Left arrow
| c-left | c-left
: Ctrl+Left : Ctrl+Left
| a-left | a-left
: Alt+Left : Alt+Left
| pgup | pgup
: : Page Up
| c-pgup | c-pgup
: Ctrl+PageUp : Ctrl+PageUp
| a-pgup | a-pgup
: Alt+PageUp : Alt+PageUp
| pgdn | pgdn
: : Page Down
| c-pgdn | c-pgdn
: Ctrl+PageDn : Ctrl+PageDn
| a-pgdn | a-pgdn
: Alt+PageDn : Alt+PageDn
| home | home
: : Home
| end | end
: : End
| insert | insert
: : Insert
| delete | delete
: : Delete
| exit | exit
: : Exit
| cancel | cancel
: : Cancel
| print | print
: : Print screen
| pause | pause
: : Pause
| backtab | backtab
: : Shift+Tab
| c-space | c-space
: Ctrl+Space : Ctrl+Space
| a-space | a-space

View file

@ -83,8 +83,7 @@ styling.
[[ *Style Object* [[ *Style Object*
:[ *Description* :[ *Description*
| default | default
: The default style object used for normal ui elements while not : The default style object used for normal ui elements while not using specialized configuration.
using specialized configuration.
| error | error
: The style used to show errors. : The style used to show errors.
| warning | warning
@ -158,8 +157,7 @@ For example, the following wildcards can be made using this syntax.
| \*.fg=blue | \*.fg=blue
: Set the foreground color of all style objects to blue. : Set the foreground color of all style objects to blue.
| \*list.bg=hotpink | \*list.bg=hotpink
: Set the background color of all style objects that end in list : Set the background color of all style objects that end in list to hotpink.
to hotpink.
## Selected modifier ## Selected modifier
Selected modifier can be applied to any style object. The style provided for Selected modifier can be applied to any style object. The style provided for

View file

@ -237,10 +237,8 @@ message list, the message in the message viewer, etc).
Seen Seen
Message has been read Message has been read
Answered Answered
Message has been answered Message has been answered
Flagged Flagged
Message is flagged for urgent/special attention Message is flagged for urgent/special attention

View file

@ -24,5 +24,3 @@ Content-Type: text/html; charset=utf-8
<ObJECT> <ObJECT>
--Nextpart_1Q2YJhd197991794467076Pgfa-- --Nextpart_1Q2YJhd197991794467076Pgfa--

View file

@ -135,18 +135,13 @@ func (w *worker) handleMessage(msg types.WorkerMessage) error {
case *types.CheckMail: case *types.CheckMail:
go w.handleCheckMail(msg) go w.handleCheckMail(msg)
return nil return nil
// not implemented, they are generally not used // not implemented, they are generally not used
// in a notmuch based workflow // in a notmuch based workflow
// case *types.DeleteMessages: // case *types.DeleteMessages:
// case *types.CopyMessages: // case *types.CopyMessages:
// return w.handleCopyMessages(msg)
// case *types.AppendMessage: // case *types.AppendMessage:
// return w.handleAppendMessage(msg)
// case *types.CreateDirectory: // case *types.CreateDirectory:
// return w.handleCreateDirectory(msg)
// case *types.RemoveDirectory: // case *types.RemoveDirectory:
// return w.handleRemoveDirectory(msg)
} }
return errUnsupported return errUnsupported
} }

View file

@ -70,9 +70,6 @@ func TestNewWalk(t *testing.T) {
var prefix []string var prefix []string
lastLevel := 0 lastLevel := 0
tree.Walk(func(t *Thread, lvl int, e error) error { tree.Walk(func(t *Thread, lvl int, e error) error {
// if t.Uid%2 != 0 {
// return ErrSkipThread
// }
if e != nil { if e != nil {
fmt.Printf("ERROR: %v\n", e) fmt.Printf("ERROR: %v\n", e)
} }