Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

`check-self` is a Go CLI diagnostic tool in the Senzing Garage (experimental) project suite. It verifies the environment where Senzing tools run, performing comprehensive checks on configurations, databases, licenses, and system state.

**Status**: Work-in-progress with semantic versions `0.n.x` - not production-ready.

## Build Commands

```bash
make build # Build for current OS/architecture
make build-all # Build for all 6 platforms (darwin/linux/windows × amd64/arm64)
make clean # Remove build artifacts and caches
```

Binaries output to `target/<os>-<arch>/check-self`.

## Test Commands

```bash
make clean setup test # Run tests (setup creates test database)
make check-coverage # Run tests and verify coverage thresholds
make coverage # Generate coverage report and open in browser

# Run a single test
go test -v -run TestFunctionName ./checkself/

# Run tests with trace logging
SENZING_LOG_LEVEL=TRACE go test ./...
```

Coverage targets: 80%+ overall, minimum 30% per file, 70% for `cmd/` package.

## Lint Commands

```bash
make lint # Run all linters (golangci-lint, govulncheck, cspell)
make fix # Auto-fix ~20 linter issues (gofumpt, wsl, nakedret, etc.)
make golangci-lint # Run golangci-lint only
make govulncheck # Vulnerability scanning
make cspell # Spell check (includes dotfiles)
```

Linter config: `.github/linters/.golangci.yaml` - enables 100+ linters with strict settings.

## Development Setup

```bash
make dependencies-for-development # Install dev tools (golangci-lint, gotestfmt, govulncheck, gofumpt, cspell)
make dependencies # Update and tidy Go dependencies
```

**Prerequisites**: Senzing C library installed at `/opt/senzing/er/lib` with SDK headers at `/opt/senzing/er/sdk/c`.

## Architecture

### Package Structure

- `main.go` - Entry point, calls `cmd.Execute()`
- `cmd/` - Cobra CLI setup with Viper configuration management
- `root.go` - Root command definition, context variables, PreRun hooks
- `context_<os>.go` - Platform-specific context handling
- `checkself/` - Core health-check logic
- `checkself.go` - `BasicCheckSelf` struct and `CheckSelf()` orchestrator
- `check*.go` - Individual health check implementations

### Core Pattern: Chain of Responsibility

The `CheckSelf()` method in `checkself/checkself.go` orchestrates checks:

1. `getTestFunctions()` returns ordered list of check functions
2. Each check follows signature: `(ctx, reportChecks, reportInfo, reportErrors) → (reportChecks, reportInfo, reportErrors, error)`
3. Checks execute sequentially; first error stops the chain
4. Reports accumulate: Information → Checks Performed → Errors → Result

### Check Functions (in execution order)

1. `Prolog` - Output header/separator
2. `ListEnvironmentVariables` - Introspect environment
3. `ListStructVariables` - Dump configuration values
4. `CheckConfigPath` - Validate config directory
5. `CheckResourcePath` - Validate resource directory
6. `CheckSupportPath` - Validate support directory
7. `CheckDatabaseURL` - Validate database connection string
8. `CheckSettings` - Parse and validate Senzing settings JSON
9. `CheckDatabaseSchema` - Verify database schema integrity
10. `CheckSenzingConfiguration` - Validate Senzing config (disabled)
11. `CheckLicense` - Validate license (disabled)

### Key Types

```go
// Main configuration struct - populated via Viper from env/flags/files
type BasicCheckSelf struct {
ConfigPath, DatabaseURL, ResourcePath, SupportPath, Settings string
// ... plus other config fields
}

// Factory pattern for Senzing SDK access
szfactorycreator.CreateCoreAbstractFactory() → senzing.SzAbstractFactory
szAbstractFactory.CreateConfigManager() → senzing.SzConfigManager
szAbstractFactory.CreateProduct() → senzing.SzProduct
```

### Database Support

Supports: SQLite3, MySQL, PostgreSQL, Oracle (godror), MSSQL, DB2. Database URL can come from `DatabaseURL` field or extracted from `Settings` JSON.

## Docker

```bash
make docker-build # Build Docker image
make docker-run # Run container
make docker-test # Integration tests via docker-compose
make docker-build-package # Create RPM/DEB packages
```

## Code Style Notes

- Line length limit: 120 characters
- Uses `gofumpt` for formatting (stricter than `gofmt`)
- WSL linter enforces whitespace conventions
- `exhaustruct` excludes `cobra.Command`, `BasicCheckSelf`, `ProductLicenseResponse`
- Function max complexity: 14 (cyclop), max lines: 65 (funlen)
- Use `wraperror.Errorf()` for error wrapping
3 changes: 3 additions & 0 deletions .claude/commands/senzing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Senzing

- Perform the steps specified by <https://raw.githubusercontent.com/senzing-factory/claude/refs/tags/v1/commands/senzing.md>
3 changes: 3 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"includeCoAuthoredBy": false
}
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
version: 2
updates:
- package-ecosystem: github-actions
cooldown:
default-days: 21
directory: /
schedule:
interval: daily
- package-ecosystem: gomod
cooldown:
default-days: 21
directory: /
schedule:
interval: daily
2 changes: 1 addition & 1 deletion .github/linters/.jscpd.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{}
{}
27 changes: 19 additions & 8 deletions .github/linters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@
- [jscpd configuration]
- Example:

```json
{
"ignore": [
"**/*.go,**/go-test*.yaml"
],
```json
{
"ignore": ["**/*.go,**/go-test*.yaml"],
"threshold": 10
}
```
}
```

## .yaml-lint.yml

Expand All @@ -40,10 +38,23 @@
- [yaml-lint]
- [yaml-lint configuration]

[.checkov.yaml]: .checkov.yaml
## bearer.yml

- [bearer.yml]
- Used by [bearer.yaml]
- [bearer]
- [bearer repository]
- [bearer configuration]

[.checkov.yaml]: .checkov.yaml
[.golangci.yaml]: .golangci.yaml
[.jscpd.json]: .jscpd.json
[.yaml-lint.yml]: .yaml-lint.yml
[bearer configuration]: https://docs.bearer.com/reference/config/
[bearer repository]: https://github.com/Bearer/bearer/tree/main
[bearer.yaml]: ../workflows/README.md#beareryaml
[bearer.yml]: bearer.yml
[bearer]: https://docs.bearer.com/
[checkov configuration]: https://www.checkov.io/2.Basics/CLI%20Command%20Reference.html
[checkov]: https://www.checkov.io/
[golangci linters]: https://golangci-lint.run/usage/linters/
Expand Down
14 changes: 13 additions & 1 deletion .github/renovate.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":disableDependencyDashboard",
"docker:pinDigests"
],
"enabledManagers": ["dockerfile", "docker-compose"],
"extends": ["config:recommended", ":disableDependencyDashboard", "docker:pinDigests"]
"schedule": ["on sunday"],
"prCreation": "not-pending",
"packageRules": [
{
"matchUpdateTypes": ["major", "minor", "patch"],
"minimumReleaseAge": "21 days"
}
]
}
9 changes: 6 additions & 3 deletions .github/workflows/bearer.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
name: bearer
name: Bearer

on:
push:
branches-ignore: [main]
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

permissions: {}

jobs:
rule_check:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Checkout repository
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/claude-pr-review.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
name: Claude PR Review

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

on:
pull_request:
types: [opened, synchronize]

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

permissions: {}

jobs:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/dependabot-approve-and-merge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ on:
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

permissions: {}

jobs:
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/docker-build-container.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ name: Docker build container

on:
pull_request:
branches:
- main
branches: [main]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

permissions: {}

jobs:
docker-build-container:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Get repository name
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/go-proxy-pull.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ jobs:
permissions:
contents: write
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Pull new module version
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/go-test-darwin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ name: Go test darwin

on: [pull_request, workflow_dispatch]

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

env:
SENZING_LOG_LEVEL: TRACE
SENZING_TOOLS_DATABASE_URL: sqlite3://na:na@nowhere/tmp/sqlite/G2C.db
Expand All @@ -20,6 +24,7 @@ jobs:
go: ["1.24"]
os: [macos-latest]
senzingsdk-version: [production-v4, staging-v4]
timeout-minutes: 30

steps:
- name: Checkout repository
Expand Down Expand Up @@ -63,13 +68,13 @@ jobs:
go test -exec "${GITHUB_WORKSPACE}/bin/macos_exec_dyld.sh" -json -v -p 1 -coverprofile="./cover-${{ matrix.senzingsdk-version }}.out" -covermode=atomic -coverpkg=./... ./... 2>&1 | tee "/tmp/gotest-${{ matrix.senzingsdk-version }}.log" | gotestfmt

- name: Store coverage file
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: "cover-${{ matrix.senzingsdk-version }}.out"
path: "./cover-${{ matrix.senzingsdk-version }}.out"

- name: Upload test log
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
if: always()
with:
name: "test-log-${{ matrix.senzingsdk-version }}"
Expand Down
10 changes: 8 additions & 2 deletions .github/workflows/go-test-linux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ name: Go test linux

on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "15 7 * * *"

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

env:
SENZING_LOG_LEVEL: TRACE
SENZING_TOOLS_DATABASE_URL: sqlite3://na:na@nowhere/tmp/sqlite/G2C.db
Expand All @@ -27,6 +32,7 @@ jobs:
go: ["1.24"]
os: [ubuntu-latest]
senzingsdk-version: [production-v4, staging-v4]
timeout-minutes: 30

steps:
- name: Checkout repository
Expand Down Expand Up @@ -67,13 +73,13 @@ jobs:
go test -json -v -p 1 -coverprofile="./cover-${{ matrix.senzingsdk-version }}.out" -covermode=atomic -coverpkg=./... ./... 2>&1 | tee "/tmp/gotest-${{ matrix.senzingsdk-version }}.log" | gotestfmt

- name: Store coverage file
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: "cover-${{ matrix.senzingsdk-version }}.out"
path: "./cover-${{ matrix.senzingsdk-version }}.out"

- name: Upload test log
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
if: always()
with:
name: "test-log-${{ matrix.senzingsdk-version }}"
Expand Down
Loading
Loading