go-kt

module
v0.6.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2026 License: GPL-3.0

README

go-kt

GitHub release Go Version License build test lint coverage

The small packages every katbyte command-line tool needs, kept in one place instead of copy-pasted into each repo.

package what it is for
clog the shared logrus logger: stderr, timestamps, level from the tool's own env var
cout verbosity-levelled, coloured console output (--quiet, --verbose, --silent)
chttp an http.Client with per-attempt timeouts, retries that never re-send a mutation whose fate is unknown, and a trace of every exchange for the logger it is handed; and what an API client needs around one: an answer read whole, credentials kept out of errors, traces and other hosts, and one error for an unexpected status. Standard library only, so an SDK can be built on it
version the tool's version, stamped at build time or taken from module build info
pointer From and To for optional API fields: dereference-or-zero, and pointer-to-value in expression position
spelling one name spelled two ways: a key that folds case, accents, separators and punctuation, and the tests for a slip of the keyboard, a name cut short or a first name reduced to its initial
whitespace the spaces out of place in a name - doubled, at an end, odd, before a colon or a file extension - named, made visible and put right
outside text that came from outside - a release's name, a file's, a description anyone can write - with what does not show taken out and cut to a length, before a model reads it; and a server's own words for what went wrong, with what an address in them may carry a credential in blanked
parallel a batch of jobs run a few at a time, stopped at the first error
lock a lock on a record, a named piece of one or a plain string, any mix in one call, so two edits of one thing in one process take turns; one set for the process, or a set of your own
mcp/server an MCP server served over stdio, or over HTTP behind a bearer token with a health probe
mcp/registry which tools an MCP session gets: read, write and delete kinds, toolsets, an allow list that adds tools by name and a deny list that takes them out; and what stands around every tool: a line written for each write with its credentials blanked, a failure's words without an address's secrets, and every piece of text in an answer cleaned once
mcp/acctest a test suite that drives an MCP server as a client does, and fails when a tool was never seen to work
test/replayproxy what a server under test fetches from the internet, recorded once and replayed in CI
test/env a live suite's surroundings: its environment variables, its replay proxy, and files laid out where the server's container reads them
test/services/arrserver the servers a Sonarr, Radarr or Prowlarr calls home to, for a live suite to answer itself: the update server, the clock and the notices, none of which can be recorded once and replayed
test/services/newznab Newznab and Torznab indexers for a live suite to run beside the server under test: the test decides which releases exist, sees every request, and makes an indexer fail, flake, slow down or refuse its key
test/services/sabnzbd a SABnzbd for a live suite: a download client that downloads nothing, whose jobs the test progresses, pauses, completes with the files it names, or fails

Usage

import (
    "github.com/katbyte/go-kt/clog"
    "github.com/katbyte/go-kt/cout"
    "github.com/katbyte/go-kt/chttp"
    "github.com/katbyte/go-kt/version"
)

func init() {
    clog.SetLevelFromEnv("MYTOOL_LOG") // "debug", "trace", ... default WARN
}

func run(silent, quiet, verbose bool) {
    cout.SetLevelFromFlags(silent, quiet, verbose) // or embed cout.Flags in your flag struct and call Apply()

    cout.Printf("<green>mytool</> %s\n", version.Version)
    cout.Verbosef("only with -v\n")
    cout.Quietf("%s\n", "the one line a script parses; printed in quiet mode and above")
    cout.Errorf("<red>error:</> %v\n", err) // stderr, every mode except silent

    client := chttp.New(chttp.Options{Name: "MyAPI", Log: clog.Log}) // traces every exchange at TRACE, retries a 429, a 502-504 and a dropped connection
    req = chttp.MarkRetrySafe(req)                                    // a POST that is really a read may be sent again too
    resp, body, err := client.Fetch(req, 16<<20)                      // the whole answer, asked for again if it stops part way
}
Stamping the version

Point the linker at this module's variables instead of a local lib/version:

# .goreleaser.yaml
ldflags:
  - -X github.com/katbyte/go-kt/version.Version={{ .Tag }}
  - -X github.com/katbyte/go-kt/version.GitCommit={{ .ShortCommit }}

Tools installed with go install ...@version report the module version from build info; plain local builds report dev.

Development

make tools      # build the pinned dev tools into .tools/bin
make check-all  # build + test + lint + actionlint + yamllint + shellcheck + typos + depscheck
make cover      # tests with coverage; the coverage workflow publishes the total as the README badge

Nothing is vendored (consumers resolve dependencies through go.sum); tool versions are pinned in .tools/go.mod and dependabot keeps both current.

Directories

Path Synopsis
Package chttp is the HTTP client every katbyte tool talks to APIs with: a stalled server fails fast, a passing failure is tried again without ever re-sending a write whose fate is unknown, and every exchange is traced to whatever logger it is handed, with credentials blanked.
Package chttp is the HTTP client every katbyte tool talks to APIs with: a stalled server fails fast, a passing failure is tried again without ever re-sending a write whose fate is unknown, and every exchange is traced to whatever logger it is handed, with credentials blanked.
Package clog is the one logger every katbyte tool logs through: stderr, since stdout is the tool's real output, with timestamps, at WARN unless the tool's own variable (TCTEST_LOG, KOI_LOG) raises it.
Package clog is the one logger every katbyte tool logs through: stderr, since stdout is the tool's real output, with timestamps, at WARN unless the tool's own variable (TCTEST_LOG, KOI_LOG) raises it.
Package cout prints for the person running a tool, as clog logs for whoever diagnoses it.
Package cout prints for the person running a tool, as clog logs for whoever diagnoses it.
internal
addresses
Package addresses blanks what an address in text may carry a credential in: the one rule behind outside.BlankAddresses and the registry's write line, kept here so the registry can also be told what was blanked.
Package addresses blanks what an address in text may carry a credential in: the one rule behind outside.BlankAddresses and the registry's write line, kept here so the registry can also be told what was blanked.
Package lock makes callers in one process take turns at a record, so one does not undo another's change.
Package lock makes callers in one process take turns at a record, so one does not undo another's change.
mcp
acctest
Package acctest drives an MCP server the way a client does, for a suite against a live one: calls counted for coverage, readers for the answers, waits on background work, put-backs for what a test changed, and a watch on everything the tools say for a key the suite gave the server.
Package acctest drives an MCP server the way a client does, for a suite against a live one: calls counted for coverage, readers for the answers, waits on background work, put-backs for what a test changed, and a watch on everything the tools say for a key the suite gave the server.
registry
Package registry decides which of an MCP server's tools a session gets, what each tells a client about itself, and what stands around every call.
Package registry decides which of an MCP server's tools a session gets, what each tells a client about itself, and what stands around every call.
server
Package server runs an MCP server over stdio for a client that starts it, or over HTTP for an always-on one, behind a bearer token and with a health probe.
Package server runs an MCP server over stdio for a client that starts it, or over HTTP for an always-on one, behind a bearer token and with a health probe.
Package outside makes text from outside safe to hand to a model: a release's name, a file's, anything fetched from a service anyone can write to.
Package outside makes text from outside safe to hand to a model: a release's name, a file's, anything fetched from a service anyone can write to.
Package parallel runs a batch of jobs a few at a time, as many as a server answers at once.
Package parallel runs a batch of jobs a few at a time, as many as a server answers at once.
Package pointer reads and makes the optional fields API models type as *T, where a statement is awkward: inside a literal, an argument or a return.
Package pointer reads and makes the optional fields API models type as *T, where a statement is awkward: inside a literal, an argument or a return.
Package spelling finds one name spelled two ways, as genres, tags and studios arrive typed by hand: "Sci-Fi" and "sci fi", "Amélie" and "Amelie", "Noir" and "Nior".
Package spelling finds one name spelled two ways, as genres, tags and studios arrive typed by hand: "Sci-Fi" and "sci fi", "Amélie" and "Amelie", "Noir" and "Nior".
test
env
Package env is what a suite against a live server in a container is handed: the variables its test script exports, the replay proxy the server's internet calls go through, a check the container can reach it, the report on what the proxy saw, and files laid out where the container reads them.
Package env is what a suite against a live server in a container is handed: the variables its test script exports, the replay proxy the server's internet calls go through, a check the container can reach it, the report on what the proxy saw, and files laid out where the container reads them.
replayproxy
Package replayproxy records and replays what a server under test fetches from the internet: metadata providers, a podcast feed, an artwork CDN.
Package replayproxy records and replays what a server under test fetches from the internet: metadata providers, a podcast feed, an artwork CDN.
services/arrserver
Package arrserver is the servers a Prowlarr, Sonarr or Radarr calls home to, for a live suite to answer itself: the update server, the clock, and the notices.
Package arrserver is the servers a Prowlarr, Sonarr or Radarr calls home to, for a live suite to answer itself: the update server, the clock, and the notices.
services/newznab
Package newznab is a Newznab and Torznab indexer for a live suite to run beside the server under test: one listener, any number of indexers at /<name>/api, each usenet or torrent, each healthy or broken as the test says.
Package newznab is a Newznab and Torznab indexer for a live suite to run beside the server under test: one listener, any number of indexers at /<name>/api, each usenet or torrent, each healthy or broken as the test says.
services/sabnzbd
Package sabnzbd is a SABnzbd for a live suite to run beside the server under test: a download client that downloads nothing, whose jobs the test moves along itself, written for Sonarr, whose reading of each answer the comments name.
Package sabnzbd is a SABnzbd for a live suite to run beside the server under test: a download client that downloads nothing, whose jobs the test moves along itself, written for Sonarr, whose reading of each answer the comments name.
Package version is the version of the tool that imports it: stamped at release, else the module version from a go install, else "dev".
Package version is the version of the tool that imports it: stamped at release, else the module version from a go install, else "dev".
Package whitespace finds the spaces out of place in a name: doubled, at an end, odd, or before a colon or a file extension.
Package whitespace finds the spaces out of place in a name: doubled, at an end, odd, or before a colon or a file extension.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL