fintual-backend-devops-go / harness / help.go
help.go
Raw
package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"strings"
)

type commandHelp struct{ description, flags, effects, example string }

var commandOrder = strings.Fields("init-db claim fixture seed verify capture bench compare equivalence operations plans waits export-errors export-transcript")
var commands = map[string]commandHelp{
	"init-db":           {"Create a dedicated test database.", "db", "Creates an assignment_harness_* database owned by the connecting role. Existing databases must already be owned and marked. Does not migrate or load data.", "harness/harness init-db --db 'dbname=assignment_harness_native'"},
	"claim":             {"Mark an empty test database for harness use.", "db", "Writes the ownership marker after service migrations. Refuses populated, unmarked application tables and databases owned by another role.", "harness/harness claim"},
	"fixture":           {"Load the small contract-test sample.", "db", "REPLACES application data: 3 users, 3 tags, 4 posts (3 published), 3 comments. Requires an owned, marked test database.", "harness/harness fixture"},
	"seed":              {"Load the full synthetic dataset.", "db", "REPLACES application data: 1,000 users, 50 tags, 100,000 posts, 500,000 comments. Requires an owned, marked test database.", "harness/harness seed"},
	"verify":            {"Check HTTP behavior against reviewed captures.", "db url golden", "RESETS the small fixture for each case and performs test writes. Run the target service in compat mode against the same database.", "harness/harness verify --url http://127.0.0.1:18001 --golden fixtures/contract"},
	"capture":           {"Record reference HTTP behavior.", "db url golden", "RESETS test data and OVERWRITES captures. Target the original Django reference; review capture changes before accepting them.", "harness/harness capture --url http://127.0.0.1:18000 --golden fixtures/contract"},
	"bench":             {"Measure endpoint latency and process resources.", "db url output requests concurrency repeats pid workload full", "RESETS fixtures and performs writes. With --full, seed first; benchmark-written rows are reset between runs. --pid identifies the server process on Linux.", "harness/harness bench --url http://127.0.0.1:18001 --pid 1234 --output reports/new-run.json"},
	"compare":           {"Compare two saved benchmark reports.", "baseline candidate output workload", "Reads report files and overwrites --output. Does not run new requests. --baseline and --candidate are required inputs.", "harness/harness compare --baseline baseline.json --candidate candidate.json --output comparison.json"},
	"equivalence":       {"Compare full-data responses between two servers.", "db reference-db url reference-url output", "Requires both databases to be fully seeded. RESETS benchmark-written rows in both databases and issues requests that can modify counters. --reference-db is required.", "harness/harness equivalence --reference-db 'dbname=assignment_harness_django' --url http://127.0.0.1:18001 --output equivalence.json"},
	"operations":        {"Check production behavior and graceful shutdown.", "db input output", "RESETS the small fixture and starts temporary server processes. --input must name the contentd binary. Writes --output and a companion .log file.", "harness/harness operations --input go-service/contentd --output operations.json"},
	"plans":             {"Record SELECT-only EXPLAIN ANALYZE diagnostics.", "db output", "Runs queries against an owned, marked test database and overwrites --output. Does not reset data. Keep diagnostic runs separate from benchmark timing.", "harness/harness plans --output plans.json"},
	"waits":             {"Sample database waits during concurrent post reads.", "db url output requests concurrency", "RESETS the small fixture and issues requests that update post counters. Overwrites --output; this is diagnostic, not a benchmark.", "harness/harness waits --url http://127.0.0.1:18001 --output waits.json"},
	"export-errors":     {"Export compatibility error assets from captures.", "golden output", "OVERWRITES error assets in the --output directory. Here --output is a directory, not a JSON file.", "harness/harness export-errors --golden fixtures/contract --output go-service/compat_errors"},
	"export-transcript": {"Export visible conversation messages from JSONL.", "input output", "Reads --input and OVERWRITES --output with Markdown. Excludes tool payloads and internal messages.", "harness/harness export-transcript --input session.jsonl --output transcript.md"},
}

func printHarnessHelp(w io.Writer) {
	fmt.Fprintln(w, "Usage: harness <command> [flags]\n\nTest data, API verification, benchmarks, and diagnostics.")
	fmt.Fprintln(w, "\nCommands:")
	for _, name := range commandOrder {
		fmt.Fprintf(w, "  %-19s %s\n", name, commands[name].description)
	}
	fmt.Fprintln(w, "\nUse harness <command> --help for flags, effects, and an example.\nDatabase connection: --db overrides DATABASE_URL, then defaults to dbname=assignment_harness_native.\nUse only dedicated assignment_harness_* databases.\nPaths are relative to the current directory. Examples assume the repository root.\n\nExample:\n  harness/harness seed")
}

func helpCommand(args []string) (string, []string, bool, error) {
	if len(args) == 0 {
		printHarnessHelp(os.Stderr)
		return "", nil, true, fmt.Errorf("a command is required")
	}
	if args[0] == "--help" || args[0] == "-h" || args[0] == "help" {
		if args[0] == "help" && len(args) == 2 {
			args = []string{args[1], "--help"}
		} else if len(args) == 1 {
			printHarnessHelp(os.Stdout)
			return "", nil, true, nil
		} else {
			return "", nil, true, fmt.Errorf("usage: harness help [command]")
		}
	}
	if _, ok := commands[args[0]]; !ok {
		return "", nil, true, fmt.Errorf("unknown command %q; use harness --help", args[0])
	}
	return args[0], args[1:], false, nil
}

func printCommandHelp(w io.Writer, name string, command commandHelp, f *flag.FlagSet) {
	fmt.Fprintf(w, "Usage: harness %s [flags]\n\n%s\n\n%s\n\nFlags (single or double dash):\n", name, command.description, command.effects)
	f.PrintDefaults()
	fmt.Fprintln(w, "  -h, --help\n        Show help and exit without performing work.")
	fmt.Fprintf(w, "\nExample (from repository root):\n  %s\n", command.example)
}