ctxweaver

module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2025 License: MIT

README

ctxweaver

Go Reference Go Report Card Codecov

[!NOTE] This project was written by AI (Claude Code).

A Go code generator that weaves statements into functions receiving context-like parameters.

Overview

ctxweaver automatically inserts or updates statements at the beginning of functions that receive context.Context or other context-carrying types. This is useful for:

  • APM instrumentation: Automatically add tracing segments to all context-aware functions
  • Logging setup: Insert structured logging initialization
  • Metrics collection: Add timing or counting instrumentation
  • Custom middleware: Any pattern that needs to run at function entry with context

How It Works

// Before: A function receiving context
func (s *Service) ProcessOrder(ctx context.Context, orderID string) error {
    // business logic...
}

// After: ctxweaver inserts your template at the top
func (s *Service) ProcessOrder(ctx context.Context, orderID string) error {
    defer newrelic.FromContext(ctx).StartSegment("myapp.(*Service).ProcessOrder").End()

    // business logic...
}

The inserted statement is fully customizable via Go templates.

Installation & Usage

Using go install
go install github.com/mpyw/ctxweaver/cmd/ctxweaver@latest
ctxweaver ./...
Using go tool (Go 1.24+)
# Add to go.mod as a tool dependency
go get -tool github.com/mpyw/ctxweaver/cmd/ctxweaver@latest

# Run via go tool
go tool ctxweaver ./...
Using go run
go run github.com/mpyw/ctxweaver/cmd/ctxweaver@latest ./...

[!CAUTION] To prevent supply chain attacks, pin to a specific version tag instead of @latest in CI/CD pipelines (e.g., @v0.1.0).

Configuration

ctxweaver uses a YAML configuration file. Create ctxweaver.yaml in your project root:

# ctxweaver.yaml
template: |
  defer newrelic.FromContext({{.Ctx}}).StartSegment({{.FuncName | quote}}).End()

imports:
  - github.com/newrelic/go-agent/v3/newrelic

patterns:
  - ./...

test: false

See ctxweaver.example.yaml for a complete example with all options.

Flags

Flag Default Description
-config ctxweaver.yaml Path to configuration file
-dry-run false Print changes without writing files
-verbose false Print processed files
-test false Process test files (*_test.go)
Examples
# Use default config file (ctxweaver.yaml)
ctxweaver ./...

# Use custom config file
ctxweaver -config=.ctxweaver.yaml ./...

# Dry run - preview changes
ctxweaver -dry-run -verbose ./...

# Include test files
ctxweaver -test ./...

Template System

[!TIP] For Go text/template syntax guide, see: https://docs.gomplate.ca/syntax/

Available Variables
Variable Type Description
{{.Ctx}} string Expression to access context.Context
{{.CtxVar}} string Name of the context parameter variable
{{.FuncName}} string Fully qualified function name
{{.PackageName}} string Package name
{{.PackagePath}} string Full import path of the package
{{.FuncBaseName}} string Function name without package/receiver
{{.ReceiverType}} string Receiver type name (empty if not a method)
{{.ReceiverVar}} string Receiver variable name (empty if not a method)
{{.IsMethod}} bool Whether this is a method
{{.IsPointerReceiver}} bool Whether the receiver is a pointer
FuncName Format

{{.FuncName}} provides a fully qualified function name in the following format:

Type Format Example
Function pkg.Func service.CreateUser
Method (pointer receiver) pkg.(*Type).Method service.(*UserService).GetByID
Method (value receiver) pkg.Type.Method service.UserService.String
Built-in Functions
Function Description
quote Wraps string in double quotes
backtick Wraps string in backticks
Basic Example

New Relic

template: |
  defer newrelic.FromContext({{.Ctx}}).StartSegment({{.FuncName | quote}}).End()
imports:
  - github.com/newrelic/go-agent/v3/newrelic

OpenTelemetry

template: |
  {{.CtxVar}}, span := otel.Tracer({{.PackageName | quote}}).Start({{.Ctx}}, {{.FuncName | quote}}); defer span.End()
imports:
  - go.opentelemetry.io/otel
Custom Function Name Format

If you need a different naming format, you can build it yourself using template variables:

template: |
  {{- $name := "" -}}
  {{- if .IsMethod -}}
    {{- if .IsPointerReceiver -}}
      {{- $name = printf "%s.(*%s).%s" .PackageName .ReceiverType .FuncBaseName -}}
    {{- else -}}
      {{- $name = printf "%s.%s.%s" .PackageName .ReceiverType .FuncBaseName -}}
    {{- end -}}
  {{- else -}}
    {{- $name = printf "%s.%s" .PackageName .FuncBaseName -}}
  {{- end -}}
  defer newrelic.FromContext({{.Ctx}}).StartSegment({{$name | quote}}).End()
imports:
  - github.com/newrelic/go-agent/v3/newrelic

This gives you full control over the naming format. Available variables for building custom names:

  • {{.PackageName}} - Package name (e.g., service)
  • {{.PackagePath}} - Full import path (e.g., github.com/example/myapp/pkg/service)
  • {{.ReceiverType}} - Receiver type (e.g., UserService)
  • {{.FuncBaseName}} - Function/method name (e.g., GetByID)
  • {{.IsMethod}} - true if method, false if function
  • {{.IsPointerReceiver}} - true if pointer receiver

Built-in Context Carriers

ctxweaver recognizes the following types as context carriers (checks the first parameter only):

Type Accessor Notes
context.Context (none) Standard library
echo.Context .Request().Context() Echo framework
*cli.Context .Context urfave/cli
*cobra.Command .Context() Cobra
*gin.Context .Request.Context() Gin
*fiber.Ctx .Context() Fiber
Custom Carriers

Add custom carriers in your config file:

carriers:
  - package: github.com/example/myapp/pkg/web
    type: Context
    accessor: .Ctx()

Directives

//ctxweaver:skip

Skip processing for a specific function or entire file:

//ctxweaver:skip
func legacyHandler(ctx context.Context) {
    // This function will not be modified
}

File-level skip (place at the top of the file):

//ctxweaver:skip

package legacy

// All functions in this file will be skipped

Existing Statement Detection

ctxweaver detects if a matching statement already exists and:

  1. Skips if the statement is up-to-date
  2. Updates if the function name in the statement doesn't match (e.g., after rename)
  3. Inserts if no matching statement exists

Currently, detection is specific to the defer XXX.StartSegment(ctx, "name").End() pattern.

Performance

ctxweaver uses golang.org/x/tools/go/packages to load type information efficiently:

  • Single load: All target packages are loaded in one pass
  • Accurate type resolution: Import paths are resolved correctly via type information
  • Comment preservation: Uses DST (Decorated Syntax Tree) to preserve comments

Import Management

ctxweaver automatically adds imports specified in the config file when statements are inserted.

[!NOTE] ctxweaver does not reorder or reformat existing imports. Use goimports or gci after ctxweaver if you need consistent import formatting.

Development

# Run tests
go test ./...

# Build CLI
go build -o bin/ctxweaver ./cmd/ctxweaver

# Run on a project
./bin/ctxweaver -config=ctxweaver.yaml ./...

License

MIT License

Directories

Path Synopsis
cmd
ctxweaver command
Command ctxweaver weaves statements into context-aware functions.
Command ctxweaver weaves statements into context-aware functions.
Package internal provides shared internal utilities.
Package internal provides shared internal utilities.
directive
Package directive provides utilities for processing ctxweaver directives in comments.
Package directive provides utilities for processing ctxweaver directives in comments.
dstutil
Package dstutil provides utilities for DST (Decorated Syntax Tree) manipulation.
Package dstutil provides utilities for DST (Decorated Syntax Tree) manipulation.
pkg
carrier
Package carrier provides carrier type matching for context propagation.
Package carrier provides carrier type matching for context propagation.
config
Package config provides configuration loading for ctxweaver.
Package config provides configuration loading for ctxweaver.
processor
Package processor provides DST-based code transformation.
Package processor provides DST-based code transformation.
template
Package template provides template rendering for ctxweaver.
Package template provides template rendering for ctxweaver.

Jump to

Keyboard shortcuts

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