Skip to content

Commit dbec6d2

Browse files
committed
MAJOR: add aspell as aditional check for spelling errors
1 parent f74106a commit dbec6d2

File tree

5 files changed

+128
-1
lines changed

5 files changed

+128
-1
lines changed

.github/workflows/actions.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ jobs:
3232
runs-on: ubuntu-latest
3333
needs: ["go_build"]
3434
steps:
35+
- name: Install Aspell
36+
run: sudo apt-get update && sudo apt-get install -y aspell
3537
- uses: actions/checkout@v4
3638
- name: Set up Go
3739
uses: actions/setup-go@v4
@@ -51,6 +53,8 @@ jobs:
5153
runs-on: ubuntu-latest
5254
needs: ["go_build"]
5355
steps:
56+
- name: Install Aspell
57+
run: sudo apt-get update && sudo apt-get install -y aspell
5458
- uses: actions/checkout@v4
5559
with:
5660
fetch-depth: 0

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
FROM golang:alpine as builder
1+
FROM golang:alpine AS builder
22
RUN mkdir /build
33
ADD . /build/
44
WORKDIR /build
55
RUN go build -o check
66

77
FROM alpine:latest
8+
RUN apk --no-cache add aspell
89
COPY --from=builder /build/check /check
910
WORKDIR /
1011
ENTRYPOINT ["/check"]

aspell.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"log"
7+
"os"
8+
"os/exec"
9+
"slices"
10+
"strings"
11+
)
12+
13+
type Aspell []string
14+
15+
func (a Aspell) Check(subject string) error {
16+
var words []string
17+
var badWords []string
18+
19+
data, err := checkWithAspellExec(subject)
20+
if data != "" {
21+
words = strings.Split(data, "\n")
22+
}
23+
if err != nil {
24+
return err
25+
}
26+
27+
for _, word := range words {
28+
if len(word) < 1 {
29+
continue
30+
}
31+
if !slices.Contains(a, word) {
32+
badWords = append(badWords, word)
33+
}
34+
}
35+
36+
if len(badWords) > 0 {
37+
return fmt.Errorf("aspell: %s", badWords)
38+
}
39+
return nil
40+
}
41+
42+
func (a Aspell) CheckSubjects(subjects []string) error {
43+
var response string
44+
for _, subject := range subjects {
45+
if err := a.Check(subject); err != nil {
46+
response += fmt.Sprintf("%s\n", err)
47+
}
48+
}
49+
if len(response) > 0 {
50+
return fmt.Errorf("%s", response)
51+
}
52+
return nil
53+
}
54+
55+
func LoadAspellExceptions(filename string) (Aspell, error) {
56+
var words []string
57+
58+
var data []byte
59+
var err error
60+
if data, err = os.ReadFile(filename); err != nil {
61+
log.Printf("warning: aspell exceptions file not found (%s)", err)
62+
}
63+
words = strings.Split(string(data), "\n")
64+
65+
return words, nil
66+
}
67+
68+
func checkWithAspellExec(subject string) (string, error) {
69+
cmd := exec.Command("aspell", "--list")
70+
cmd.Stdin = strings.NewReader(subject)
71+
72+
var stdout, stderr bytes.Buffer
73+
cmd.Stdout = &stdout
74+
cmd.Stderr = &stderr
75+
err := cmd.Run()
76+
if err != nil {
77+
log.Printf("aspell error: %s, stderr: %s", err, stderr.String())
78+
return "", err
79+
}
80+
81+
log.Printf("aspell output: stdout: %s, stderr: %s", stdout.String(), stderr.String())
82+
return stdout.String() + stderr.String(), nil
83+
}

aspell_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package main
2+
3+
import "testing"
4+
5+
func Test_checkWithAspell(t *testing.T) {
6+
aspell := Aspell{"config"}
7+
tests := []struct {
8+
name string
9+
subject string
10+
wantErr bool
11+
}{
12+
{"OK", "BUG/MEDIUM: config: add default location of path to the configuration file", false},
13+
{"error - flie", "BUG/MEDIUM: config: add default location of path to the configuration flie", true},
14+
{"error - locatoin", "CLEANUP/MEDIUM: config: add default locatoin of path to the configuration file", true},
15+
{"error - locatoin+flie", "CLEANUP/MEDIUM: config: add default locatoin of path to the configuration flie", true},
16+
}
17+
for _, tt := range tests {
18+
t.Run(tt.name, func(t *testing.T) {
19+
err := aspell.Check(tt.subject)
20+
if tt.wantErr && err == nil {
21+
t.Errorf("checkWithAspell() error = %v, wantErr %v", err, tt.wantErr)
22+
}
23+
if !tt.wantErr && err != nil {
24+
t.Errorf("checkWithAspell() error = %v, wantErr %v", err, tt.wantErr)
25+
}
26+
})
27+
}
28+
}

check.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,11 @@ func main() {
401401
repoPath = os.Args[1]
402402
}
403403

404+
aspellExceptions, err := LoadAspellExceptions(path.Join(repoPath, ".aspell-exceptions"))
405+
if err != nil {
406+
log.Fatalf("error reading aspell exceptions: %s", err)
407+
}
408+
404409
commitPolicy, err := LoadCommitPolicy(path.Join(repoPath, ".check-commit.yml"))
405410
if err != nil {
406411
log.Fatalf("error reading configuration: %s", err)
@@ -425,5 +430,11 @@ func main() {
425430
log.Fatalf("%s\n", commitPolicy.HelpText)
426431
}
427432

433+
err = aspellExceptions.CheckSubjects(subjects)
434+
if err != nil {
435+
log.Printf("encountered one or more commit message spelling errors\n")
436+
log.Fatalf("%s\n", err)
437+
}
438+
428439
log.Printf("check completed without errors\n")
429440
}

0 commit comments

Comments
 (0)