Skip to content

Commit 314384a

Browse files
committed
Initial commit: SPOCP implementation with adaptive indexing
- Implements SPOCP (S-Expression-Based Object Comparison Protocol) draft-hedberg-spocp-sexp-00 - Features: - Full S-expression parsing and matching - Adaptive indexing engine (automatic optimization) - Tag-based indexing for large rulesets - Pattern matching: wildcards, prefixes, suffixes, sets, ranges - 96.8% test coverage on main package - Architecture: - AdaptiveEngine: Recommended default, automatically enables indexing - Engine: Low-level control for advanced use cases - Clean API: spocp.New() as primary constructor - Compliance: - 8 Architectural Decision Records (ADRs) - >70% test coverage requirement (ADR-02) - Modern Go idioms (any vs interface{}) - Documentation: - Comprehensive README with examples - API reference and quick reference guides - Adaptive engine and engine selection guides - ADR compliance tracking - CI/CD: - GitHub Actions for testing (Go 1.23.x, 1.24.x, 1.25.x) - Linting with golangci-lint - Format checking with gofmt - Automated releases on version tags
0 parents  commit 314384a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+9071
-0
lines changed

.github/workflows/ci.yml

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
test:
14+
name: Test
15+
runs-on: ubuntu-latest
16+
strategy:
17+
matrix:
18+
go-version: ['1.23.x', '1.24.x', '1.25.x']
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Set up Go
25+
uses: actions/setup-go@v5
26+
with:
27+
go-version: ${{ matrix.go-version }}
28+
29+
- name: Download dependencies
30+
run: go mod download
31+
32+
- name: Verify dependencies
33+
run: go mod verify
34+
35+
- name: Run tests
36+
run: go test -v -race -coverprofile=coverage.out ./...
37+
38+
- name: Check coverage
39+
run: |
40+
go tool cover -func=coverage.out
41+
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
42+
echo "Total coverage: ${COVERAGE}%"
43+
# Ensure coverage is above 70% (ADR-02)
44+
if (( $(echo "$COVERAGE < 70" | bc -l) )); then
45+
echo "Coverage ${COVERAGE}% is below 70% threshold"
46+
exit 1
47+
fi
48+
49+
- name: Upload coverage to Codecov
50+
uses: codecov/codecov-action@v4
51+
if: matrix.go-version == '1.25.x'
52+
with:
53+
files: ./coverage.out
54+
flags: unittests
55+
name: codecov-umbrella
56+
env:
57+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
58+
59+
lint:
60+
name: Lint
61+
runs-on: ubuntu-latest
62+
63+
steps:
64+
- name: Checkout code
65+
uses: actions/checkout@v4
66+
67+
- name: Set up Go
68+
uses: actions/setup-go@v5
69+
with:
70+
go-version: '1.25.x'
71+
72+
- name: golangci-lint
73+
uses: golangci/golangci-lint-action@v4
74+
with:
75+
version: latest
76+
args: --timeout=5m
77+
78+
format:
79+
name: Format Check
80+
runs-on: ubuntu-latest
81+
82+
steps:
83+
- name: Checkout code
84+
uses: actions/checkout@v4
85+
86+
- name: Set up Go
87+
uses: actions/setup-go@v5
88+
with:
89+
go-version: '1.25.x'
90+
91+
- name: Check formatting
92+
run: |
93+
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
94+
echo "The following files are not formatted:"
95+
gofmt -s -l .
96+
exit 1
97+
fi
98+
99+
- name: Verify go.mod and go.sum
100+
run: |
101+
go mod tidy
102+
git diff --exit-code go.mod go.sum
103+
104+
build:
105+
name: Build
106+
runs-on: ubuntu-latest
107+
108+
steps:
109+
- name: Checkout code
110+
uses: actions/checkout@v4
111+
112+
- name: Set up Go
113+
uses: actions/setup-go@v5
114+
with:
115+
go-version: '1.25.x'
116+
117+
- name: Build
118+
run: go build -v ./...
119+
120+
- name: Build examples
121+
run: |
122+
for example in examples/*.go; do
123+
if [ -f "$example" ]; then
124+
go build -v "$example"
125+
fi
126+
done
127+
128+
- name: Build commands
129+
run: |
130+
for cmd in cmd/*; do
131+
if [ -d "$cmd" ]; then
132+
go build -v "./$cmd"
133+
fi
134+
done

.github/workflows/release.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
name: Create Release
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
22+
- name: Set up Go
23+
uses: actions/setup-go@v5
24+
with:
25+
go-version: '1.25.x'
26+
27+
- name: Run tests
28+
run: go test -v ./...
29+
30+
- name: Generate changelog
31+
id: changelog
32+
run: |
33+
echo "## What's Changed" > RELEASE_NOTES.md
34+
git log $(git describe --tags --abbrev=0 HEAD^)..HEAD --pretty=format:"* %s (%h)" >> RELEASE_NOTES.md || echo "* Initial release" >> RELEASE_NOTES.md
35+
36+
- name: Create Release
37+
uses: softprops/action-gh-release@v1
38+
with:
39+
body_path: RELEASE_NOTES.md
40+
draft: false
41+
prerelease: false
42+
env:
43+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Binaries for programs and plugins
2+
*.exe
3+
*.exe~
4+
*.dll
5+
*.so
6+
*.dylib
7+
bin/
8+
9+
# Test binary, built with `go test -c`
10+
*.test
11+
12+
# Output of the go coverage tool
13+
*.out
14+
coverage.html
15+
coverage.out
16+
17+
# Dependency directories
18+
vendor/
19+
20+
# Go workspace file
21+
go.work
22+
23+
# IDEs
24+
.idea/
25+
.vscode/
26+
*.swp
27+
*.swo
28+
*~
29+
30+
# OS
31+
.DS_Store
32+
Thumbs.db
33+
34+
# Temporary files
35+
*.tmp
36+
*.log

.golangci.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# golangci-lint configuration
2+
# https://golangci-lint.run/usage/configuration/
3+
4+
run:
5+
timeout: 5m
6+
tests: true
7+
modules-download-mode: readonly
8+
9+
linters:
10+
enable:
11+
- errcheck # Check for unchecked errors
12+
- gosimple # Simplify code
13+
- govet # Vet examines Go source code
14+
- ineffassign # Detect ineffectual assignments
15+
- staticcheck # Static analysis checks
16+
- unused # Find unused code
17+
- gofmt # Check formatting
18+
- goimports # Check imports
19+
- misspell # Find commonly misspelled words
20+
- revive # Drop-in replacement for golint
21+
- stylecheck # Replacement for golint
22+
- unconvert # Remove unnecessary type conversions
23+
- unparam # Find unused function parameters
24+
- gosec # Security checks
25+
- bodyclose # Check HTTP response bodies are closed
26+
- noctx # Find HTTP requests without context
27+
28+
linters-settings:
29+
errcheck:
30+
check-blank: true
31+
check-type-assertions: true
32+
33+
govet:
34+
enable-all: true
35+
disable:
36+
- shadow # Shadow variables are sometimes intentional
37+
38+
revive:
39+
rules:
40+
- name: exported
41+
severity: warning
42+
disabled: false
43+
- name: var-naming
44+
severity: warning
45+
disabled: false
46+
- name: package-comments
47+
severity: warning
48+
disabled: false
49+
50+
stylecheck:
51+
checks: ["all"]
52+
53+
issues:
54+
exclude-rules:
55+
# Exclude some linters from running on tests files
56+
- path: _test\.go
57+
linters:
58+
- gosec
59+
- errcheck
60+
61+
max-issues-per-linter: 0
62+
max-same-issues: 0

0 commit comments

Comments
 (0)