Skip to main content

cmd/apigw/main.go

Source

Overview

What:

CLI entrypoint for operating the gateway.

This command is the primary user-facing interface for:

  • running the gateway (run)
  • validating config (validate)
  • generating a sample config (init)
  • managing a background daemon (daemon)
  • calling the control-plane admin endpoints (admin)
  • snapshotting env-based config into YAML (convert-env)

Why:

The gateway is designed to be both embeddable and operable. A thin CLI makes it easy to run locally, integrate with deployment scripts, and manage long-running processes without forcing a specific process manager.

How:

main() dispatches based on the first CLI argument. Each subcommand parses its own flags and then calls into shared packages:

  • pkg/gateway/config for config loading/validation
  • pkg/gateway/runtime for runtime lifecycle (including reload callback)
  • pkg/gateway/daemon for PID-file based daemon management

Notes: The CLI does not attempt to hide secrets beyond what the admin endpoints do. Avoid printing full configs with secrets to logs/terminals in production.

Contents

Imports

import block 1

cmd/apigw/main.go#L3
import (
"context"
"errors"
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"os/exec"
"os/signal"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"

"github.com/fsnotify/fsnotify"
"gopkg.in/yaml.v3"

gatewayconfig "github.com/theroutercompany/api_router/pkg/gateway/config"
gatewaydaemon "github.com/theroutercompany/api_router/pkg/gateway/daemon"
gatewayruntime "github.com/theroutercompany/api_router/pkg/gateway/runtime"
)

Constants

const block 1

cmd/apigw/main.go#L223
const daemonChildEnv = "APIGW_DAEMON_CHILD"

daemonChildEnv

What: Environment variable used to mark a background daemon child process.

Why: Prevents recursive respawning when apigw daemon start --background launches a child that should run in the foreground.

How: The parent sets APIGW_DAEMON_CHILD=1 on the child process environment; the child checks it to decide whether to spawn again.

const block 2

cmd/apigw/main.go#L599
const sampleConfigYAML = `# Gateway configuration for the API router.
version: ""

http:
port: 8080
shutdownTimeout: 15s

readiness:
timeout: 2s
userAgent: api-router-gateway/readyz
upstreams:
- name: trade
baseURL: https://trade.example.com
healthPath: /health
tls:
enabled: false
insecureSkipVerify: false
caFile: ""
clientCertFile: ""
clientKeyFile: ""
- name: task
baseURL: https://task.example.com
healthPath: /health
tls:
enabled: false
insecureSkipVerify: false
caFile: ""
clientCertFile: ""
clientKeyFile: ""

auth:
secret: replace-me
issuer: router
audiences:
- api

cors:
allowedOrigins:
- https://app.example.com

rateLimit:
window: 60s
max: 120

metrics:
enabled: true
`

sampleConfigYAML

What: Embedded sample YAML used by the init command.

Why: Provides a quick starting point without requiring users to copy files from the repo.

How: Writes this string to disk in initCommand (optionally overwriting via --force).

Functions and Methods

main

What: Program entrypoint that dispatches to subcommands.

Why: Keeps the CLI simple and avoids a large framework for a small command surface.

How: Switches on os.Args[1], calls the matching command function, and exits non-zero on error.

cmd/apigw/main.go#L28
func main() {
if len(os.Args) < 2 {
usage()
os.Exit(1)
}

var err error
switch os.Args[1] {
case "run":
err = runCommand(os.Args[2:])
case "validate":
err = validateCommand(os.Args[2:])
case "init":
err = initCommand(os.Args[2:])
case "daemon":
err = daemonCommand(os.Args[2:])
case "admin":
err = adminCommand(os.Args[2:])
case "convert-env":
err = convertEnvCommand(os.Args[2:])
default:
usage()
os.Exit(1)
}

if err != nil {
log.Fatalf("apigw %s: %v", os.Args[1], err)
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L29: if len(os.Args) < 2 { usage() os.Exit(1) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L30: usage()
        • What: Calls usage.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L31: os.Exit(1)
        • What: Calls os.Exit.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
  • L34: var err error
    • What: Declares local names.
    • Why: Introduces variables or types used later in the function.
    • How: Executes a Go declaration statement inside the function body.
  • L35: switch os.Args[1] { case "run": err = runCommand(os.Args[2:]) case "validate": err = validateCommand(os.Args[2:]) case "init": err = initCo…
    • What: Selects a branch from multiple cases.
    • Why: Keeps multi-case branching readable and explicit.
    • How: Evaluates the switch expression and executes the first matching case.
    • Nested steps:
      • L36: case "run":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L37: err = runCommand(os.Args[2:])
            • What: Assigns err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L38: case "validate":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L39: err = validateCommand(os.Args[2:])
            • What: Assigns err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L40: case "init":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L41: err = initCommand(os.Args[2:])
            • What: Assigns err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L42: case "daemon":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L43: err = daemonCommand(os.Args[2:])
            • What: Assigns err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L44: case "admin":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L45: err = adminCommand(os.Args[2:])
            • What: Assigns err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L46: case "convert-env":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L47: err = convertEnvCommand(os.Args[2:])
            • What: Assigns err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L48: default:
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L49: usage()
            • What: Calls usage.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L50: os.Exit(1)
            • What: Calls os.Exit.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
  • L53: if err != nil { log.Fatalf("apigw %s: %v", os.Args[1], err) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L54: log.Fatalf("apigw %s: %v", os.Args[1], err)
        • What: Calls log.Fatalf.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.

runCommand

What: Implements apigw run to start the gateway runtime and optionally hot-reload on config changes.

Why: Provides the primary "run the gateway locally/in containers" workflow with an optional file watcher.

How: Loads config, builds a runtime with a reload callback, optionally starts a config watcher, and loops handling OS signals, runtime exit, watcher errors, and reload requests by stopping and restarting the runtime with rt.Reload.

cmd/apigw/main.go#L58
func runCommand(args []string) error {
fs := flag.NewFlagSet("run", flag.ExitOnError)
configPath := fs.String("config", "", "Path to gateway configuration file")
watch := fs.Bool("watch", false, "Watch the config file for changes and hot-reload")
if err := fs.Parse(args); err != nil {
return err
}

opts := []gatewayconfig.Option{}
if *configPath != "" {
opts = append(opts, gatewayconfig.WithPath(*configPath))
}

cfg, err := gatewayconfig.Load(opts...)
if err != nil {
return fmt.Errorf("load config: %w", err)
}

reloadRequests := make(chan gatewayconfig.Config, 1)
enqueueReload := func(cfg gatewayconfig.Config) {
select {
case reloadRequests <- cfg:
default:
go func() { reloadRequests <- cfg }()
}
}

reloadFunc := func() (gatewayconfig.Config, error) {
cfg, err := gatewayconfig.Load(opts...)
if err != nil {
return gatewayconfig.Config{}, err
}
enqueueReload(cfg)
return cfg, nil
}

rt, err := gatewayruntime.New(cfg, gatewayruntime.WithReloadFunc(reloadFunc))
if err != nil {
return fmt.Errorf("build runtime: %w", err)
}

ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()

var (
watchErrCh <-chan error
watchCancel context.CancelFunc
)
if *watch {
if *configPath == "" {
return errors.New("--config is required when --watch is enabled")
}
watchReloadCh, errCh, cancelWatch, err := watchConfig(ctx, *configPath, opts)
if err != nil {
return fmt.Errorf("watch config: %w", err)
}
watchErrCh = errCh
watchCancel = cancelWatch
go func() {
for cfg := range watchReloadCh {
enqueueReload(cfg)
}
}()
}
defer func() {
if watchCancel != nil {
watchCancel()
}
}()

runCtx, runCancel := context.WithCancel(ctx)
runDone := make(chan error, 1)
go func() {
runDone <- rt.Run(runCtx)
}()

for {
select {
case err := <-runDone:
runCancel()
if err != nil && !errors.Is(err, context.Canceled) {
return err
}
return nil
case cfg := <-reloadRequests:
runCancel()
if err := <-runDone; err != nil && !errors.Is(err, context.Canceled) {
return err
}
if err := rt.Reload(cfg); err != nil {
return fmt.Errorf("reload config: %w", err)
}
runCtx, runCancel = context.WithCancel(ctx)
runDone = make(chan error, 1)
go func() {
runDone <- rt.Run(runCtx)
}()
log.Printf("configuration reloaded")
case err, ok := <-watchErrCh:
if !ok {
watchErrCh = nil
continue
}
if err != nil {
log.Printf("config watch error: %v", err)
}
case <-ctx.Done():
runCancel()
}
}
}

Walkthrough

Expand walkthrough (84 steps)

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L59: fs := flag.NewFlagSet("run", flag.ExitOnError)
    • What: Defines fs.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L60: configPath := fs.String("config", "", "Path to gateway configuration file")
    • What: Defines configPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L61: watch := fs.Bool("watch", false, "Watch the config file for changes and hot-reload")
    • What: Defines watch.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L62: if err := fs.Parse(args); err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L62: err := fs.Parse(args)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L63: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L66: opts := []gatewayconfig.Option{}
    • What: Defines opts.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L67: if *configPath != "" { opts = append(opts, gatewayconfig.WithPath(*configPath)) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L68: opts = append(opts, gatewayconfig.WithPath(*configPath))
        • What: Assigns opts.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L71: cfg, err := gatewayconfig.Load(opts...)
    • What: Defines cfg, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L72: if err != nil { return fmt.Errorf("load config: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L73: return fmt.Errorf("load config: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L76: reloadRequests := make(chan gatewayconfig.Config, 1)
    • What: Defines reloadRequests.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L77: enqueueReload := func(cfg gatewayconfig.Config) { select { case reloadRequests <- cfg: default: go func() { reloadRequests <- cfg }() } }
    • What: Defines enqueueReload.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
    • Nested steps:
      • L77: func(cfg gatewayconfig.Config) { select { case reloadRequests <- cfg: default: go func() { reloadRequests <- cfg }() } }
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L78: select { case reloadRequests <- cfg: default: go func() { reloadRequests <- cfg }() }
            • What: Selects among concurrent operations.
            • Why: Coordinates channel operations without blocking incorrectly.
            • How: Executes a select statement and runs one ready case.
            • Nested steps:
              • L79: case reloadRequests <- cfg:
                • What: Selects a select-case branch.
                • Why: Coordinates concurrent operations without blocking incorrectly.
                • How: Runs this case body when its channel operation is ready (or runs default immediately).
              • L80: default:
                • What: Selects a select-case branch.
                • Why: Coordinates concurrent operations without blocking incorrectly.
                • How: Runs this case body when its channel operation is ready (or runs default immediately).
                • Nested steps:
                  • L81: go func() { reloadRequests <- cfg }()
                    • What: Starts a goroutine.
                    • Why: Runs work concurrently.
                    • How: Invokes the function call asynchronously using go.
                    • Nested steps:
                      • L81: func() { reloadRequests <- cfg }
                        • What: Defines an inline function (closure).
                        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
                        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
                        • Nested steps:
                          • L81: reloadRequests <- cfg
                            • What: Sends a value on a channel.
                            • Why: Communicates with another goroutine.
                            • How: Executes a channel send operation.
  • L85: reloadFunc := func() (gatewayconfig.Config, error) { cfg, err := gatewayconfig.Load(opts...) if err != nil { return gatewayconfig.Config{},…
    • What: Defines reloadFunc.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
    • Nested steps:
      • L85: func() (gatewayconfig.Config, error) { cfg, err := gatewayconfig.Load(opts...) if err != nil { return gatewayconfig.Config{}, err } enqueue…
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L86: cfg, err := gatewayconfig.Load(opts...)
            • What: Defines cfg, err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L87: if err != nil { return gatewayconfig.Config{}, err }
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L88: return gatewayconfig.Config{}, err
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L90: enqueueReload(cfg)
            • What: Calls enqueueReload.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L91: return cfg, nil
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
  • L94: rt, err := gatewayruntime.New(cfg, gatewayruntime.WithReloadFunc(reloadFunc))
    • What: Defines rt, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L95: if err != nil { return fmt.Errorf("build runtime: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L96: return fmt.Errorf("build runtime: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L99: ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
    • What: Defines ctx, cancel.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L100: defer cancel()
    • What: Defers a call for cleanup.
    • Why: Ensures the deferred action runs even on early returns.
    • How: Schedules the call to run when the surrounding function returns.
  • L102: var ( watchErrCh <-chan error watchCancel context.CancelFunc )
    • What: Declares local names.
    • Why: Introduces variables or types used later in the function.
    • How: Executes a Go declaration statement inside the function body.
  • L106: if *watch { if *configPath == "" { return errors.New("--config is required when --watch is enabled") } watchReloadCh, errCh, cancelWatch, e…
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L107: if *configPath == "" { return errors.New("--config is required when --watch is enabled") }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L108: return errors.New("--config is required when --watch is enabled")
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L110: watchReloadCh, errCh, cancelWatch, err := watchConfig(ctx, *configPath, opts)
        • What: Defines watchReloadCh, errCh, cancelWatch, err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L111: if err != nil { return fmt.Errorf("watch config: %w", err) }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L112: return fmt.Errorf("watch config: %w", err)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L114: watchErrCh = errCh
        • What: Assigns watchErrCh.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L115: watchCancel = cancelWatch
        • What: Assigns watchCancel.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L116: go func() { for cfg := range watchReloadCh { enqueueReload(cfg) } }()
        • What: Starts a goroutine.
        • Why: Runs work concurrently.
        • How: Invokes the function call asynchronously using go.
        • Nested steps:
          • L116: func() { for cfg := range watchReloadCh { enqueueReload(cfg) } }
            • What: Defines an inline function (closure).
            • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
            • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
            • Nested steps:
              • L117: for cfg := range watchReloadCh { enqueueReload(cfg) }
                • What: Iterates over a collection.
                • Why: Processes multiple elements with the same logic.
                • How: Executes a for ... range loop.
                • Nested steps:
                  • L118: enqueueReload(cfg)
                    • What: Calls enqueueReload.
                    • Why: Performs side effects or delegates work to a helper.
                    • How: Executes the expression statement.
  • L122: defer func() { if watchCancel != nil { watchCancel() } }()
    • What: Defers a call for cleanup.
    • Why: Ensures the deferred action runs even on early returns.
    • How: Schedules the call to run when the surrounding function returns.
    • Nested steps:
      • L122: func() { if watchCancel != nil { watchCancel() } }
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L123: if watchCancel != nil { watchCancel() }
            • What: Branches conditionally.
            • Why: Handles different execution paths based on runtime state.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L124: watchCancel()
                • What: Calls watchCancel.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
  • L128: runCtx, runCancel := context.WithCancel(ctx)
    • What: Defines runCtx, runCancel.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L129: runDone := make(chan error, 1)
    • What: Defines runDone.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L130: go func() { runDone <- rt.Run(runCtx) }()
    • What: Starts a goroutine.
    • Why: Runs work concurrently.
    • How: Invokes the function call asynchronously using go.
    • Nested steps:
      • L130: func() { runDone <- rt.Run(runCtx) }
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L131: runDone <- rt.Run(runCtx)
            • What: Sends a value on a channel.
            • Why: Communicates with another goroutine.
            • How: Executes a channel send operation.
  • L134: for { select { case err := <-runDone: runCancel() if err != nil && !errors.Is(err, context.Canceled) { return err } return nil case cfg := …
    • What: Runs a loop.
    • Why: Repeats logic until a condition is met or the loop terminates.
    • How: Executes a for loop statement.
    • Nested steps:
      • L135: select { case err := <-runDone: runCancel() if err != nil && !errors.Is(err, context.Canceled) { return err } return nil case cfg := <-relo…
        • What: Selects among concurrent operations.
        • Why: Coordinates channel operations without blocking incorrectly.
        • How: Executes a select statement and runs one ready case.
        • Nested steps:
          • L136: case err := <-runDone:
            • What: Selects a select-case branch.
            • Why: Coordinates concurrent operations without blocking incorrectly.
            • How: Runs this case body when its channel operation is ready (or runs default immediately).
            • Nested steps:
              • L137: runCancel()
                • What: Calls runCancel.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
              • L138: if err != nil && !errors.Is(err, context.Canceled) { return err }
                • What: Branches conditionally.
                • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
                • How: Evaluates the condition and executes the matching branch.
                • Nested steps:
                  • L139: return err
                    • What: Returns from the current function.
                    • Why: Ends the current execution path and hands control back to the caller.
                    • How: Executes a return statement (possibly returning values).
              • L141: return nil
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L142: case cfg := <-reloadRequests:
            • What: Selects a select-case branch.
            • Why: Coordinates concurrent operations without blocking incorrectly.
            • How: Runs this case body when its channel operation is ready (or runs default immediately).
            • Nested steps:
              • L143: runCancel()
                • What: Calls runCancel.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
              • L144: if err := <-runDone; err != nil && !errors.Is(err, context.Canceled) { return err }
                • What: Branches conditionally.
                • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
                • How: Evaluates the condition and executes the matching branch.
                • Nested steps:
                  • L144: err := <-runDone
                    • What: Defines err.
                    • Why: Keeps intermediate state available for later steps in the function.
                    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                  • L145: return err
                    • What: Returns from the current function.
                    • Why: Ends the current execution path and hands control back to the caller.
                    • How: Executes a return statement (possibly returning values).
              • L147: if err := rt.Reload(cfg); err != nil { return fmt.Errorf("reload config: %w", err) }
                • What: Branches conditionally.
                • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
                • How: Evaluates the condition and executes the matching branch.
                • Nested steps:
                  • L147: err := rt.Reload(cfg)
                    • What: Defines err.
                    • Why: Keeps intermediate state available for later steps in the function.
                    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                  • L148: return fmt.Errorf("reload config: %w", err)
                    • What: Returns from the current function.
                    • Why: Ends the current execution path and hands control back to the caller.
                    • How: Executes a return statement (possibly returning values).
              • L150: runCtx, runCancel = context.WithCancel(ctx)
                • What: Assigns runCtx, runCancel.
                • Why: Keeps intermediate state available for later steps in the function.
                • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
              • L151: runDone = make(chan error, 1)
                • What: Assigns runDone.
                • Why: Keeps intermediate state available for later steps in the function.
                • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
              • L152: go func() { runDone <- rt.Run(runCtx) }()
                • What: Starts a goroutine.
                • Why: Runs work concurrently.
                • How: Invokes the function call asynchronously using go.
                • Nested steps:
                  • L152: func() { runDone <- rt.Run(runCtx) }
                    • What: Defines an inline function (closure).
                    • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
                    • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
                    • Nested steps:
                      • L153: runDone <- rt.Run(runCtx)
                        • What: Sends a value on a channel.
                        • Why: Communicates with another goroutine.
                        • How: Executes a channel send operation.
              • L155: log.Printf("configuration reloaded")
                • What: Calls log.Printf.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
          • L156: case err, ok := <-watchErrCh:
            • What: Selects a select-case branch.
            • Why: Coordinates concurrent operations without blocking incorrectly.
            • How: Runs this case body when its channel operation is ready (or runs default immediately).
            • Nested steps:
              • L157: if !ok { watchErrCh = nil continue }
                • What: Branches conditionally.
                • Why: Handles different execution paths based on runtime state.
                • How: Evaluates the condition and executes the matching branch.
                • Nested steps:
                  • L158: watchErrCh = nil
                    • What: Assigns watchErrCh.
                    • Why: Keeps intermediate state available for later steps in the function.
                    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                  • L159: continue
                    • What: Executes a statement.
                    • Why: Advances the function logic.
                    • How: Runs this statement as part of the function body.
              • L161: if err != nil { log.Printf("config watch error: %v", err) }
                • What: Branches conditionally.
                • Why: Handles different execution paths based on runtime state.
                • How: Evaluates the condition and executes the matching branch.
                • Nested steps:
                  • L162: log.Printf("config watch error: %v", err)
                    • What: Calls log.Printf.
                    • Why: Performs side effects or delegates work to a helper.
                    • How: Executes the expression statement.
          • L164: case <-ctx.Done():
            • What: Selects a select-case branch.
            • Why: Coordinates concurrent operations without blocking incorrectly.
            • How: Runs this case body when its channel operation is ready (or runs default immediately).
            • Nested steps:
              • L165: runCancel()
                • What: Calls runCancel.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.

validateCommand

What: Implements apigw validate to check config validity without starting the server.

Why: Useful in CI and in deployment pipelines to fail fast before rollout.

How: Loads config via gatewayconfig.Load (optionally with --config) and prints a success message on completion.

cmd/apigw/main.go#L170
func validateCommand(args []string) error {
fs := flag.NewFlagSet("validate", flag.ExitOnError)
configPath := fs.String("config", "", "Path to gateway configuration file")
if err := fs.Parse(args); err != nil {
return err
}

opts := []gatewayconfig.Option{}
if *configPath != "" {
opts = append(opts, gatewayconfig.WithPath(*configPath))
}

if _, err := gatewayconfig.Load(opts...); err != nil {
return fmt.Errorf("validate config: %w", err)
}

fmt.Println("configuration valid")
return nil
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L171: fs := flag.NewFlagSet("validate", flag.ExitOnError)
    • What: Defines fs.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L172: configPath := fs.String("config", "", "Path to gateway configuration file")
    • What: Defines configPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L173: if err := fs.Parse(args); err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L173: err := fs.Parse(args)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L174: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L177: opts := []gatewayconfig.Option{}
    • What: Defines opts.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L178: if *configPath != "" { opts = append(opts, gatewayconfig.WithPath(*configPath)) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L179: opts = append(opts, gatewayconfig.WithPath(*configPath))
        • What: Assigns opts.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L182: if _, err := gatewayconfig.Load(opts...); err != nil { return fmt.Errorf("validate config: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L182: _, err := gatewayconfig.Load(opts...)
        • What: Defines _, err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L183: return fmt.Errorf("validate config: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L186: fmt.Println("configuration valid")
    • What: Calls fmt.Println.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L187: return nil
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

initCommand

What: Implements apigw init to write a sample configuration file.

Why: Reduces friction for first-time setup and local development.

How: Writes sampleConfigYAML to --path (default apigw.yaml) and refuses to overwrite unless --force is set.

cmd/apigw/main.go#L190
func initCommand(args []string) error {
fs := flag.NewFlagSet("init", flag.ExitOnError)
outputPath := fs.String("path", "apigw.yaml", "Destination path for generated config")
force := fs.Bool("force", false, "Overwrite existing file")
if err := fs.Parse(args); err != nil {
return err
}

if !*force {
if _, err := os.Stat(*outputPath); err == nil {
return fmt.Errorf("config file %s already exists (use --force to overwrite)", *outputPath)
}
}

if err := os.WriteFile(*outputPath, []byte(sampleConfigYAML), 0o644); err != nil {
return fmt.Errorf("write config: %w", err)
}

fmt.Printf("configuration written to %s\n", *outputPath)
return nil
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L191: fs := flag.NewFlagSet("init", flag.ExitOnError)
    • What: Defines fs.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L192: outputPath := fs.String("path", "apigw.yaml", "Destination path for generated config")
    • What: Defines outputPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L193: force := fs.Bool("force", false, "Overwrite existing file")
    • What: Defines force.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L194: if err := fs.Parse(args); err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L194: err := fs.Parse(args)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L195: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L198: if !*force { if _, err := os.Stat(*outputPath); err == nil { return fmt.Errorf("config file %s already exists (use --force to overwrite)", …
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L199: if _, err := os.Stat(*outputPath); err == nil { return fmt.Errorf("config file %s already exists (use --force to overwrite)", *outputPath) }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L199: _, err := os.Stat(*outputPath)
            • What: Defines _, err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L200: return fmt.Errorf("config file %s already exists (use --force to overwrite)", *outputPath)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
  • L204: if err := os.WriteFile(*outputPath, []byte(sampleConfigYAML), 0o644); err != nil { return fmt.Errorf("write config: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L204: err := os.WriteFile(*outputPath, []byte(sampleConfigYAML), 0o644)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L205: return fmt.Errorf("write config: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L208: fmt.Printf("configuration written to %s\n", *outputPath)
    • What: Calls fmt.Printf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L209: return nil
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

usage

What: Prints CLI usage text.

Why: Provides a quick help message when the CLI is invoked incorrectly.

How: Writes a static usage block to stderr.

cmd/apigw/main.go#L212
func usage() {
fmt.Fprintf(os.Stderr, "Usage: apigw <command> [options]\n")
fmt.Fprintf(os.Stderr, "Commands:\n")
fmt.Fprintf(os.Stderr, " run Start the gateway using the provided config\n")
fmt.Fprintf(os.Stderr, " validate Validate configuration without starting the gateway\n")
fmt.Fprintf(os.Stderr, " init Generate a config skeleton\n")
fmt.Fprintf(os.Stderr, " daemon Manage the gateway as a background process\n")
fmt.Fprintf(os.Stderr, " admin Invoke admin control-plane endpoints (status/reload)\n")
fmt.Fprintf(os.Stderr, " convert-env Snapshot environment variables into a YAML config\n")
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L213: fmt.Fprintf(os.Stderr, "Usage: apigw <command> [options]\n")
    • What: Calls fmt.Fprintf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L214: fmt.Fprintf(os.Stderr, "Commands:\n")
    • What: Calls fmt.Fprintf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L215: fmt.Fprintf(os.Stderr, " run Start the gateway using the provided config\n")
    • What: Calls fmt.Fprintf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L216: fmt.Fprintf(os.Stderr, " validate Validate configuration without starting the gateway\n")
    • What: Calls fmt.Fprintf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L217: fmt.Fprintf(os.Stderr, " init Generate a config skeleton\n")
    • What: Calls fmt.Fprintf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L218: fmt.Fprintf(os.Stderr, " daemon Manage the gateway as a background process\n")
    • What: Calls fmt.Fprintf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L219: fmt.Fprintf(os.Stderr, " admin Invoke admin control-plane endpoints (status/reload)\n")
    • What: Calls fmt.Fprintf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L220: fmt.Fprintf(os.Stderr, " convert-env Snapshot environment variables into a YAML config\n")
    • What: Calls fmt.Fprintf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.

daemonCommand

What: Implements apigw daemon subcommand dispatch (start/stop/status).

Why: Groups daemon lifecycle operations under a single top-level command.

How: Selects a subcommand (default start) and delegates to daemonStart, daemonStop, or daemonStatus.

cmd/apigw/main.go#L225
func daemonCommand(args []string) error {
subcommand := "start"
if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
subcommand = args[0]
args = args[1:]
}

switch subcommand {
case "start":
return daemonStart(args)
case "stop":
return daemonStop(args)
case "status":
return daemonStatus(args)
default:
return fmt.Errorf("unknown daemon subcommand %q", subcommand)
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L226: subcommand := "start"
    • What: Defines subcommand.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L227: if len(args) > 0 && !strings.HasPrefix(args[0], "-") { subcommand = args[0] args = args[1:] }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L228: subcommand = args[0]
        • What: Assigns subcommand.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L229: args = args[1:]
        • What: Assigns args.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L232: switch subcommand { case "start": return daemonStart(args) case "stop": return daemonStop(args) case "status": return daemonStatus(args) de…
    • What: Selects a branch from multiple cases.
    • Why: Keeps multi-case branching readable and explicit.
    • How: Evaluates the switch expression and executes the first matching case.
    • Nested steps:
      • L233: case "start":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L234: return daemonStart(args)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L235: case "stop":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L236: return daemonStop(args)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L237: case "status":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L238: return daemonStatus(args)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L239: default:
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L240: return fmt.Errorf("unknown daemon subcommand %q", subcommand)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).

daemonStart

What: Starts the gateway daemon, optionally in background mode.

Why: Supports running the gateway as a managed process with PID/log files without requiring external tooling.

How: If --background and not already a child, spawns a child apigw daemon start process; otherwise calls gatewaydaemon.Run with config/pid/log options and a signal-cancelled context.

cmd/apigw/main.go#L244
func daemonStart(args []string) error {
rawArgs := append([]string(nil), args...)
fs := flag.NewFlagSet("daemon start", flag.ExitOnError)
configPath := fs.String("config", "", "Path to gateway configuration file")
pidPath := fs.String("pid", "apigw.pid", "Path to write the PID file")
logPath := fs.String("log", "", "Path to write daemon logs")
background := fs.Bool("background", false, "Run the daemon in the background")
if err := fs.Parse(args); err != nil {
return err
}

isChild := os.Getenv(daemonChildEnv) == "1"
if *background && !isChild {
childArgs := []string{"daemon", "start"}
for _, arg := range rawArgs {
if strings.HasPrefix(arg, "--background") {
continue
}
childArgs = append(childArgs, arg)
}
cmd := exec.Command(os.Args[0], childArgs...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = append(os.Environ(), daemonChildEnv+"=1")
if err := cmd.Start(); err != nil {
return fmt.Errorf("start background daemon: %w", err)
}
fmt.Fprintf(os.Stdout, "daemon started (pid %d)\n", cmd.Process.Pid)
return nil
}

os.Unsetenv(daemonChildEnv)
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()

options := gatewaydaemon.Options{
ConfigPath: *configPath,
PIDFile: *pidPath,
LogFile: *logPath,
}

return gatewaydaemon.Run(ctx, options)
}

Walkthrough

Expand walkthrough (30 steps)

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L245: rawArgs := append([]string(nil), args...)
    • What: Defines rawArgs.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L246: fs := flag.NewFlagSet("daemon start", flag.ExitOnError)
    • What: Defines fs.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L247: configPath := fs.String("config", "", "Path to gateway configuration file")
    • What: Defines configPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L248: pidPath := fs.String("pid", "apigw.pid", "Path to write the PID file")
    • What: Defines pidPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L249: logPath := fs.String("log", "", "Path to write daemon logs")
    • What: Defines logPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L250: background := fs.Bool("background", false, "Run the daemon in the background")
    • What: Defines background.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L251: if err := fs.Parse(args); err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L251: err := fs.Parse(args)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L252: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L255: isChild := os.Getenv(daemonChildEnv) == "1"
    • What: Defines isChild.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L256: if *background && !isChild { childArgs := []string{"daemon", "start"} for _, arg := range rawArgs { if strings.HasPrefix(arg, "--background…
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L257: childArgs := []string{"daemon", "start"}
        • What: Defines childArgs.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L258: for _, arg := range rawArgs { if strings.HasPrefix(arg, "--background") { continue } childArgs = append(childArgs, arg) }
        • What: Iterates over a collection.
        • Why: Processes multiple elements with the same logic.
        • How: Executes a for ... range loop.
        • Nested steps:
          • L259: if strings.HasPrefix(arg, "--background") { continue }
            • What: Branches conditionally.
            • Why: Handles different execution paths based on runtime state.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L260: continue
                • What: Executes a statement.
                • Why: Advances the function logic.
                • How: Runs this statement as part of the function body.
          • L262: childArgs = append(childArgs, arg)
            • What: Assigns childArgs.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L264: cmd := exec.Command(os.Args[0], childArgs...)
        • What: Defines cmd.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L265: cmd.Stdout = os.Stdout
        • What: Assigns cmd.Stdout.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L266: cmd.Stderr = os.Stderr
        • What: Assigns cmd.Stderr.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L267: cmd.Env = append(os.Environ(), daemonChildEnv+"=1")
        • What: Assigns cmd.Env.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L268: if err := cmd.Start(); err != nil { return fmt.Errorf("start background daemon: %w", err) }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L268: err := cmd.Start()
            • What: Defines err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L269: return fmt.Errorf("start background daemon: %w", err)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L271: fmt.Fprintf(os.Stdout, "daemon started (pid %d)\n", cmd.Process.Pid)
        • What: Calls fmt.Fprintf.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L272: return nil
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L275: os.Unsetenv(daemonChildEnv)
    • What: Calls os.Unsetenv.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L276: ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
    • What: Defines ctx, cancel.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L277: defer cancel()
    • What: Defers a call for cleanup.
    • Why: Ensures the deferred action runs even on early returns.
    • How: Schedules the call to run when the surrounding function returns.
  • L279: options := gatewaydaemon.Options{ ConfigPath: *configPath, PIDFile: *pidPath, LogFile: *logPath, }
    • What: Defines options.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L285: return gatewaydaemon.Run(ctx, options)
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

daemonStop

What: Stops the daemon process by sending a signal and waiting for exit.

Why: Provides a controlled shutdown path and cleans up stale PID files.

How: Parses a signal, calls gatewaydaemon.Stop, then polls gatewaydaemon.Status until the process exits or the wait timeout expires.

cmd/apigw/main.go#L288
func daemonStop(args []string) error {
fs := flag.NewFlagSet("daemon stop", flag.ExitOnError)
pidPath := fs.String("pid", "apigw.pid", "Path to PID file")
signalName := fs.String("signal", "SIGTERM", "Signal to send (name or number)")
wait := fs.Duration("wait", 5*time.Second, "Time to wait for shutdown")
if err := fs.Parse(args); err != nil {
return err
}

sig, err := parseSignal(*signalName)
if err != nil {
return err
}

status, err := gatewaydaemon.Stop(*pidPath, sig)
if errors.Is(err, os.ErrNotExist) {
fmt.Fprintln(os.Stdout, "daemon not running (no pid file)")
return nil
}
if err != nil {
return fmt.Errorf("stop daemon: %w", err)
}

if !status.Running {
fmt.Fprintln(os.Stdout, "daemon already stopped")
_ = os.Remove(*pidPath)
return nil
}

deadline := time.Now().Add(*wait)
waitDur := *wait
for {
time.Sleep(200 * time.Millisecond)
st, err := gatewaydaemon.Status(*pidPath)
if errors.Is(err, os.ErrNotExist) {
fmt.Fprintln(os.Stdout, "daemon stopped")
_ = os.Remove(*pidPath)
return nil
}
if err != nil {
return fmt.Errorf("check status: %w", err)
}
if !st.Running {
fmt.Fprintln(os.Stdout, "daemon stopped")
_ = os.Remove(*pidPath)
return nil
}
if time.Now().After(deadline) {
return fmt.Errorf("daemon pid %d did not stop within %s", st.PID, waitDur)
}
}
}

Walkthrough

Expand walkthrough (37 steps)

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L289: fs := flag.NewFlagSet("daemon stop", flag.ExitOnError)
    • What: Defines fs.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L290: pidPath := fs.String("pid", "apigw.pid", "Path to PID file")
    • What: Defines pidPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L291: signalName := fs.String("signal", "SIGTERM", "Signal to send (name or number)")
    • What: Defines signalName.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L292: wait := fs.Duration("wait", 5*time.Second, "Time to wait for shutdown")
    • What: Defines wait.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L293: if err := fs.Parse(args); err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L293: err := fs.Parse(args)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L294: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L297: sig, err := parseSignal(*signalName)
    • What: Defines sig, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L298: if err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L299: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L302: status, err := gatewaydaemon.Stop(*pidPath, sig)
    • What: Defines status, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L303: if errors.Is(err, os.ErrNotExist) { fmt.Fprintln(os.Stdout, "daemon not running (no pid file)") return nil }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L304: fmt.Fprintln(os.Stdout, "daemon not running (no pid file)")
        • What: Calls fmt.Fprintln.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L305: return nil
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L307: if err != nil { return fmt.Errorf("stop daemon: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L308: return fmt.Errorf("stop daemon: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L311: if !status.Running { fmt.Fprintln(os.Stdout, "daemon already stopped") _ = os.Remove(*pidPath) return nil }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L312: fmt.Fprintln(os.Stdout, "daemon already stopped")
        • What: Calls fmt.Fprintln.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L313: _ = os.Remove(*pidPath)
        • What: Assigns _.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L314: return nil
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L317: deadline := time.Now().Add(*wait)
    • What: Defines deadline.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L318: waitDur := *wait
    • What: Defines waitDur.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L319: for { time.Sleep(200 * time.Millisecond) st, err := gatewaydaemon.Status(*pidPath) if errors.Is(err, os.ErrNotExist) { fmt.Fprintln(os.Stdo…
    • What: Runs a loop.
    • Why: Repeats logic until a condition is met or the loop terminates.
    • How: Executes a for loop statement.
    • Nested steps:
      • L320: time.Sleep(200 * time.Millisecond)
        • What: Calls time.Sleep.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L321: st, err := gatewaydaemon.Status(*pidPath)
        • What: Defines st, err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L322: if errors.Is(err, os.ErrNotExist) { fmt.Fprintln(os.Stdout, "daemon stopped") _ = os.Remove(*pidPath) return nil }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L323: fmt.Fprintln(os.Stdout, "daemon stopped")
            • What: Calls fmt.Fprintln.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L324: _ = os.Remove(*pidPath)
            • What: Assigns _.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L325: return nil
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L327: if err != nil { return fmt.Errorf("check status: %w", err) }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L328: return fmt.Errorf("check status: %w", err)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L330: if !st.Running { fmt.Fprintln(os.Stdout, "daemon stopped") _ = os.Remove(*pidPath) return nil }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L331: fmt.Fprintln(os.Stdout, "daemon stopped")
            • What: Calls fmt.Fprintln.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L332: _ = os.Remove(*pidPath)
            • What: Assigns _.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L333: return nil
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L335: if time.Now().After(deadline) { return fmt.Errorf("daemon pid %d did not stop within %s", st.PID, waitDur) }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L336: return fmt.Errorf("daemon pid %d did not stop within %s", st.PID, waitDur)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).

daemonStatus

What: Reports daemon status based on the PID file.

Why: Allows scripts and operators to check whether the managed process is running.

How: Calls gatewaydaemon.Status and prints daemon running, daemon stopped, or daemon not running depending on the PID/state.

cmd/apigw/main.go#L341
func daemonStatus(args []string) error {
fs := flag.NewFlagSet("daemon status", flag.ExitOnError)
pidPath := fs.String("pid", "apigw.pid", "Path to PID file")
if err := fs.Parse(args); err != nil {
return err
}

status, err := gatewaydaemon.Status(*pidPath)
if err != nil {
return fmt.Errorf("status: %w", err)
}
if status.PID == 0 {
fmt.Fprintln(os.Stdout, "daemon not running")
return nil
}
if status.Running {
fmt.Fprintf(os.Stdout, "daemon running (pid %d)\n", status.PID)
} else {
fmt.Fprintf(os.Stdout, "daemon stopped (stale pid %d)\n", status.PID)
}
return nil
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L342: fs := flag.NewFlagSet("daemon status", flag.ExitOnError)
    • What: Defines fs.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L343: pidPath := fs.String("pid", "apigw.pid", "Path to PID file")
    • What: Defines pidPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L344: if err := fs.Parse(args); err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L344: err := fs.Parse(args)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L345: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L348: status, err := gatewaydaemon.Status(*pidPath)
    • What: Defines status, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L349: if err != nil { return fmt.Errorf("status: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L350: return fmt.Errorf("status: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L352: if status.PID == 0 { fmt.Fprintln(os.Stdout, "daemon not running") return nil }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L353: fmt.Fprintln(os.Stdout, "daemon not running")
        • What: Calls fmt.Fprintln.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L354: return nil
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L356: if status.Running { fmt.Fprintf(os.Stdout, "daemon running (pid %d)\n", status.PID) } else { fmt.Fprintf(os.Stdout, "daemon stopped (stale …
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L357: fmt.Fprintf(os.Stdout, "daemon running (pid %d)\n", status.PID)
        • What: Calls fmt.Fprintf.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L359: fmt.Fprintf(os.Stdout, "daemon stopped (stale pid %d)\n", status.PID)
        • What: Calls fmt.Fprintf.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
  • L361: return nil
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

parseSignal

What: Parses a signal name or number into a syscall.Signal.

Why: Allows daemon stop to accept both human-friendly names and numeric values.

How: Accepts integers and a small set of common names (TERM, KILL, INT, QUIT), returning an error for unsupported values.

cmd/apigw/main.go#L364
func parseSignal(value string) (syscall.Signal, error) {
if value == "" {
return syscall.SIGTERM, nil
}
if n, err := strconv.Atoi(value); err == nil {
return syscall.Signal(n), nil
}

switch strings.ToUpper(value) {
case "TERM", "SIGTERM":
return syscall.SIGTERM, nil
case "KILL", "SIGKILL":
return syscall.SIGKILL, nil
case "INT", "SIGINT":
return syscall.SIGINT, nil
case "QUIT", "SIGQUIT":
return syscall.SIGQUIT, nil
default:
return 0, fmt.Errorf("unsupported signal %q", value)
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L365: if value == "" { return syscall.SIGTERM, nil }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L366: return syscall.SIGTERM, nil
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L368: if n, err := strconv.Atoi(value); err == nil { return syscall.Signal(n), nil }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L368: n, err := strconv.Atoi(value)
        • What: Defines n, err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L369: return syscall.Signal(n), nil
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L372: switch strings.ToUpper(value) { case "TERM", "SIGTERM": return syscall.SIGTERM, nil case "KILL", "SIGKILL": return syscall.SIGKILL, nil cas…
    • What: Selects a branch from multiple cases.
    • Why: Keeps multi-case branching readable and explicit.
    • How: Evaluates the switch expression and executes the first matching case.
    • Nested steps:
      • L373: case "TERM", "SIGTERM":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L374: return syscall.SIGTERM, nil
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L375: case "KILL", "SIGKILL":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L376: return syscall.SIGKILL, nil
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L377: case "INT", "SIGINT":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L378: return syscall.SIGINT, nil
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L379: case "QUIT", "SIGQUIT":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L380: return syscall.SIGQUIT, nil
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L381: default:
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L382: return 0, fmt.Errorf("unsupported signal %q", value)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).

adminCommand

What: Implements the apigw admin subcommand (status/config/reload).

Why: Provides a simple way to query or trigger control-plane behavior from scripts and terminals.

How: Parses flags (base URL, token, timeout) and dispatches to adminGET or adminPOST based on subcommand.

cmd/apigw/main.go#L386
func adminCommand(args []string) error {
subcommand := "status"
if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
subcommand = args[0]
args = args[1:]
}

fs := flag.NewFlagSet("admin "+subcommand, flag.ExitOnError)
baseURL := fs.String("url", "http://127.0.0.1:9090", "Base URL for the admin server")
token := fs.String("token", "", "Bearer token for admin requests")
timeout := fs.Duration("timeout", 5*time.Second, "HTTP request timeout")
if err := fs.Parse(args); err != nil {
return err
}

client := &http.Client{Timeout: *timeout}
base := strings.TrimRight(*baseURL, "/")

switch subcommand {
case "status":
return adminGET(client, base+"/__admin/status", *token)
case "config":
return adminGET(client, base+"/__admin/config", *token)
case "reload":
return adminPOST(client, base+"/__admin/reload", *token)
default:
return fmt.Errorf("unknown admin subcommand %q", subcommand)
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L387: subcommand := "status"
    • What: Defines subcommand.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L388: if len(args) > 0 && !strings.HasPrefix(args[0], "-") { subcommand = args[0] args = args[1:] }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L389: subcommand = args[0]
        • What: Assigns subcommand.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L390: args = args[1:]
        • What: Assigns args.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L393: fs := flag.NewFlagSet("admin "+subcommand, flag.ExitOnError)
    • What: Defines fs.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L394: baseURL := fs.String("url", "http://127.0.0.1:9090", "Base URL for the admin server")
    • What: Defines baseURL.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L395: token := fs.String("token", "", "Bearer token for admin requests")
    • What: Defines token.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L396: timeout := fs.Duration("timeout", 5*time.Second, "HTTP request timeout")
    • What: Defines timeout.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L397: if err := fs.Parse(args); err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L397: err := fs.Parse(args)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L398: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L401: client := &http.Client{Timeout: *timeout}
    • What: Defines client.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L402: base := strings.TrimRight(*baseURL, "/")
    • What: Defines base.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L404: switch subcommand { case "status": return adminGET(client, base+"/__admin/status", *token) case "config": return adminGET(client, base+"/__…
    • What: Selects a branch from multiple cases.
    • Why: Keeps multi-case branching readable and explicit.
    • How: Evaluates the switch expression and executes the first matching case.
    • Nested steps:
      • L405: case "status":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L406: return adminGET(client, base+"/__admin/status", *token)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L407: case "config":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L408: return adminGET(client, base+"/__admin/config", *token)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L409: case "reload":
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L410: return adminPOST(client, base+"/__admin/reload", *token)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L411: default:
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L412: return fmt.Errorf("unknown admin subcommand %q", subcommand)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).

adminGET

What: Performs an admin GET request and prints the JSON response body.

Why: Shared helper for admin status and admin config.

How: Builds an HTTP request, optionally sets bearer token header, checks for 200 OK, and prints the response body.

cmd/apigw/main.go#L416
func adminGET(client *http.Client, url, token string) error {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return err
}
if token != "" {
req.Header.Set("Authorization", "Bearer "+token)
}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("admin request failed: %s", strings.TrimSpace(string(body)))
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
fmt.Println(string(body))
return nil
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L417: req, err := http.NewRequest(http.MethodGet, url, nil)
    • What: Defines req, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L418: if err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L419: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L421: if token != "" { req.Header.Set("Authorization", "Bearer "+token) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L422: req.Header.Set("Authorization", "Bearer "+token)
        • What: Calls req.Header.Set.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
  • L424: resp, err := client.Do(req)
    • What: Defines resp, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L425: if err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L426: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L428: defer resp.Body.Close()
    • What: Defers a call for cleanup.
    • Why: Ensures the deferred action runs even on early returns.
    • How: Schedules the call to run when the surrounding function returns.
  • L429: if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("admin request failed: %s", strings.TrimSpace(stri…
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L430: body, _ := io.ReadAll(resp.Body)
        • What: Defines body, _.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L431: return fmt.Errorf("admin request failed: %s", strings.TrimSpace(string(body)))
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L433: body, err := io.ReadAll(resp.Body)
    • What: Defines body, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L434: if err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L435: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L437: fmt.Println(string(body))
    • What: Calls fmt.Println.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L438: return nil
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

adminPOST

What: Performs an admin POST request and prints the response body (or a fallback message).

Why: Shared helper for admin reload.

How: Builds an HTTP POST request, optionally sets bearer token header, checks for 202 Accepted, and prints the response body or "reload requested".

cmd/apigw/main.go#L441
func adminPOST(client *http.Client, url, token string) error {
req, err := http.NewRequest(http.MethodPost, url, nil)
if err != nil {
return err
}
if token != "" {
req.Header.Set("Authorization", "Bearer "+token)
}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusAccepted {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("admin reload failed: %s", strings.TrimSpace(string(body)))
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
if len(strings.TrimSpace(string(body))) > 0 {
fmt.Println(string(body))
} else {
fmt.Println("reload requested")
}
return nil
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L442: req, err := http.NewRequest(http.MethodPost, url, nil)
    • What: Defines req, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L443: if err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L444: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L446: if token != "" { req.Header.Set("Authorization", "Bearer "+token) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L447: req.Header.Set("Authorization", "Bearer "+token)
        • What: Calls req.Header.Set.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
  • L449: resp, err := client.Do(req)
    • What: Defines resp, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L450: if err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L451: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L453: defer resp.Body.Close()
    • What: Defers a call for cleanup.
    • Why: Ensures the deferred action runs even on early returns.
    • How: Schedules the call to run when the surrounding function returns.
  • L454: if resp.StatusCode != http.StatusAccepted { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("admin reload failed: %s", strings.TrimSpace…
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L455: body, _ := io.ReadAll(resp.Body)
        • What: Defines body, _.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L456: return fmt.Errorf("admin reload failed: %s", strings.TrimSpace(string(body)))
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L458: body, err := io.ReadAll(resp.Body)
    • What: Defines body, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L459: if err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L460: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L462: if len(strings.TrimSpace(string(body))) > 0 { fmt.Println(string(body)) } else { fmt.Println("reload requested") }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L463: fmt.Println(string(body))
        • What: Calls fmt.Println.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L465: fmt.Println("reload requested")
        • What: Calls fmt.Println.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
  • L467: return nil
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

watchConfig

What: Watches a config file for changes and emits reloaded gatewayconfig.Config values.

Why: Enables apigw run --watch hot reloads without external tooling.

How: Creates an fsnotify watcher on the config directory, debounces write/create/rename events, reloads config via gatewayconfig.Load, and returns channels for configs and errors plus a cancel function.

cmd/apigw/main.go#L470
func watchConfig(parent context.Context, path string, opts []gatewayconfig.Option) (<-chan gatewayconfig.Config, <-chan error, context.CancelFunc, error) {
absPath, err := filepath.Abs(path)
if err != nil {
return nil, nil, nil, fmt.Errorf("resolve config path: %w", err)
}

watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, nil, nil, err
}
dir := filepath.Dir(absPath)
if err := watcher.Add(dir); err != nil {
watcher.Close()
return nil, nil, nil, fmt.Errorf("watch directory: %w", err)
}

ctx, cancel := context.WithCancel(parent)
reloadCh := make(chan gatewayconfig.Config)
errCh := make(chan error, 1)

go func() {
defer close(reloadCh)
defer close(errCh)
defer watcher.Close()

var debounce <-chan time.Time
for {
select {
case <-ctx.Done():
return
case evt, ok := <-watcher.Events:
if !ok {
return
}
if !targetsFile(evt.Name, absPath) {
continue
}
if evt.Op&(fsnotify.Write|fsnotify.Create|fsnotify.Rename) == 0 {
continue
}
debounce = time.After(200 * time.Millisecond)
case <-debounce:
cfg, err := gatewayconfig.Load(opts...)
if err != nil {
errCh <- err
debounce = nil
continue
}
select {
case reloadCh <- cfg:
case <-ctx.Done():
}
debounce = nil
case err, ok := <-watcher.Errors:
if !ok {
return
}
errCh <- err
}
}
}()

return reloadCh, errCh, cancel, nil
}

Walkthrough

Expand walkthrough (47 steps)

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L471: absPath, err := filepath.Abs(path)
    • What: Defines absPath, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L472: if err != nil { return nil, nil, nil, fmt.Errorf("resolve config path: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L473: return nil, nil, nil, fmt.Errorf("resolve config path: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L476: watcher, err := fsnotify.NewWatcher()
    • What: Defines watcher, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L477: if err != nil { return nil, nil, nil, err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L478: return nil, nil, nil, err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L480: dir := filepath.Dir(absPath)
    • What: Defines dir.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L481: if err := watcher.Add(dir); err != nil { watcher.Close() return nil, nil, nil, fmt.Errorf("watch directory: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L481: err := watcher.Add(dir)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L482: watcher.Close()
        • What: Calls watcher.Close.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L483: return nil, nil, nil, fmt.Errorf("watch directory: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L486: ctx, cancel := context.WithCancel(parent)
    • What: Defines ctx, cancel.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L487: reloadCh := make(chan gatewayconfig.Config)
    • What: Defines reloadCh.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L488: errCh := make(chan error, 1)
    • What: Defines errCh.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L490: go func() { defer close(reloadCh) defer close(errCh) defer watcher.Close() var debounce <-chan time.Time for { select { case <-ctx.Done(): …
    • What: Starts a goroutine.
    • Why: Runs work concurrently.
    • How: Invokes the function call asynchronously using go.
    • Nested steps:
      • L490: func() { defer close(reloadCh) defer close(errCh) defer watcher.Close() var debounce <-chan time.Time for { select { case <-ctx.Done(): ret…
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L491: defer close(reloadCh)
            • What: Defers a call for cleanup.
            • Why: Ensures the deferred action runs even on early returns.
            • How: Schedules the call to run when the surrounding function returns.
          • L492: defer close(errCh)
            • What: Defers a call for cleanup.
            • Why: Ensures the deferred action runs even on early returns.
            • How: Schedules the call to run when the surrounding function returns.
          • L493: defer watcher.Close()
            • What: Defers a call for cleanup.
            • Why: Ensures the deferred action runs even on early returns.
            • How: Schedules the call to run when the surrounding function returns.
          • L495: var debounce <-chan time.Time
            • What: Declares local names.
            • Why: Introduces variables or types used later in the function.
            • How: Executes a Go declaration statement inside the function body.
          • L496: for { select { case <-ctx.Done(): return case evt, ok := <-watcher.Events: if !ok { return } if !targetsFile(evt.Name, absPath) { continue …
            • What: Runs a loop.
            • Why: Repeats logic until a condition is met or the loop terminates.
            • How: Executes a for loop statement.
            • Nested steps:
              • L497: select { case <-ctx.Done(): return case evt, ok := <-watcher.Events: if !ok { return } if !targetsFile(evt.Name, absPath) { continue } if e…
                • What: Selects among concurrent operations.
                • Why: Coordinates channel operations without blocking incorrectly.
                • How: Executes a select statement and runs one ready case.
                • Nested steps:
                  • L498: case <-ctx.Done():
                    • What: Selects a select-case branch.
                    • Why: Coordinates concurrent operations without blocking incorrectly.
                    • How: Runs this case body when its channel operation is ready (or runs default immediately).
                    • Nested steps:
                      • L499: return
                        • What: Returns from the current function.
                        • Why: Ends the current execution path and hands control back to the caller.
                        • How: Executes a return statement (possibly returning values).
                  • L500: case evt, ok := <-watcher.Events:
                    • What: Selects a select-case branch.
                    • Why: Coordinates concurrent operations without blocking incorrectly.
                    • How: Runs this case body when its channel operation is ready (or runs default immediately).
                    • Nested steps:
                      • L501: if !ok { return }
                        • What: Branches conditionally.
                        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
                        • How: Evaluates the condition and executes the matching branch.
                        • Nested steps:
                          • L502: return
                            • What: Returns from the current function.
                            • Why: Ends the current execution path and hands control back to the caller.
                            • How: Executes a return statement (possibly returning values).
                      • L504: if !targetsFile(evt.Name, absPath) { continue }
                        • What: Branches conditionally.
                        • Why: Handles different execution paths based on runtime state.
                        • How: Evaluates the condition and executes the matching branch.
                        • Nested steps:
                          • L505: continue
                            • What: Executes a statement.
                            • Why: Advances the function logic.
                            • How: Runs this statement as part of the function body.
                      • L507: if evt.Op&(fsnotify.Write|fsnotify.Create|fsnotify.Rename) == 0 { continue }
                        • What: Branches conditionally.
                        • Why: Handles different execution paths based on runtime state.
                        • How: Evaluates the condition and executes the matching branch.
                        • Nested steps:
                          • L508: continue
                            • What: Executes a statement.
                            • Why: Advances the function logic.
                            • How: Runs this statement as part of the function body.
                      • L510: debounce = time.After(200 * time.Millisecond)
                        • What: Assigns debounce.
                        • Why: Keeps intermediate state available for later steps in the function.
                        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                  • L511: case <-debounce:
                    • What: Selects a select-case branch.
                    • Why: Coordinates concurrent operations without blocking incorrectly.
                    • How: Runs this case body when its channel operation is ready (or runs default immediately).
                    • Nested steps:
                      • L512: cfg, err := gatewayconfig.Load(opts...)
                        • What: Defines cfg, err.
                        • Why: Keeps intermediate state available for later steps in the function.
                        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                      • L513: if err != nil { errCh <- err debounce = nil continue }
                        • What: Branches conditionally.
                        • Why: Handles different execution paths based on runtime state.
                        • How: Evaluates the condition and executes the matching branch.
                        • Nested steps:
                          • L514: errCh <- err
                            • What: Sends a value on a channel.
                            • Why: Communicates with another goroutine.
                            • How: Executes a channel send operation.
                          • L515: debounce = nil
                            • What: Assigns debounce.
                            • Why: Keeps intermediate state available for later steps in the function.
                            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                          • L516: continue
                            • What: Executes a statement.
                            • Why: Advances the function logic.
                            • How: Runs this statement as part of the function body.
                      • L518: select { case reloadCh <- cfg: case <-ctx.Done(): }
                        • What: Selects among concurrent operations.
                        • Why: Coordinates channel operations without blocking incorrectly.
                        • How: Executes a select statement and runs one ready case.
                        • Nested steps:
                          • L519: case reloadCh <- cfg:
                            • What: Selects a select-case branch.
                            • Why: Coordinates concurrent operations without blocking incorrectly.
                            • How: Runs this case body when its channel operation is ready (or runs default immediately).
                          • L520: case <-ctx.Done():
                            • What: Selects a select-case branch.
                            • Why: Coordinates concurrent operations without blocking incorrectly.
                            • How: Runs this case body when its channel operation is ready (or runs default immediately).
                      • L522: debounce = nil
                        • What: Assigns debounce.
                        • Why: Keeps intermediate state available for later steps in the function.
                        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                  • L523: case err, ok := <-watcher.Errors:
                    • What: Selects a select-case branch.
                    • Why: Coordinates concurrent operations without blocking incorrectly.
                    • How: Runs this case body when its channel operation is ready (or runs default immediately).
                    • Nested steps:
                      • L524: if !ok { return }
                        • What: Branches conditionally.
                        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
                        • How: Evaluates the condition and executes the matching branch.
                        • Nested steps:
                          • L525: return
                            • What: Returns from the current function.
                            • Why: Ends the current execution path and hands control back to the caller.
                            • How: Executes a return statement (possibly returning values).
                      • L527: errCh <- err
                        • What: Sends a value on a channel.
                        • Why: Communicates with another goroutine.
                        • How: Executes a channel send operation.
  • L532: return reloadCh, errCh, cancel, nil
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

convertEnvCommand

What: Implements apigw convert-env to snapshot the effective configuration into YAML.

Why: Helps migrate legacy env-driven deployments to YAML by producing a reproducible config file.

How: Loads config (optionally merging an input YAML first), marshals to YAML, and writes to stdout or an output path (with optional --force).

cmd/apigw/main.go#L535
func convertEnvCommand(args []string) error {
fs := flag.NewFlagSet("convert-env", flag.ExitOnError)
configPath := fs.String("config", "", "Optional config file to merge before env overrides")
outputPath := fs.String("output", "", "Destination path for generated YAML (stdout when empty)")
force := fs.Bool("force", false, "Overwrite existing output file")
if err := fs.Parse(args); err != nil {
return err
}

opts := []gatewayconfig.Option{}
if strings.TrimSpace(*configPath) != "" {
opts = append(opts, gatewayconfig.WithPath(*configPath))
}

cfg, err := gatewayconfig.Load(opts...)
if err != nil {
return fmt.Errorf("load config from environment: %w", err)
}

data, err := yaml.Marshal(cfg)
if err != nil {
return fmt.Errorf("encode config: %w", err)
}

path := strings.TrimSpace(*outputPath)
if path == "" {
fmt.Print(string(data))
return nil
}

if !*force {
if _, err := os.Stat(path); err == nil {
return fmt.Errorf("output file %s already exists (use --force to overwrite)", path)
} else if err != nil && !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("stat output file: %w", err)
}
}

dir := filepath.Dir(path)
if dir != "." && dir != "" {
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("ensure output directory: %w", err)
}
}

if err := os.WriteFile(path, data, 0o644); err != nil {
return fmt.Errorf("write output file: %w", err)
}

fmt.Printf("configuration written to %s\n", path)
return nil
}

Walkthrough

Expand walkthrough (36 steps)

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L536: fs := flag.NewFlagSet("convert-env", flag.ExitOnError)
    • What: Defines fs.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L537: configPath := fs.String("config", "", "Optional config file to merge before env overrides")
    • What: Defines configPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L538: outputPath := fs.String("output", "", "Destination path for generated YAML (stdout when empty)")
    • What: Defines outputPath.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L539: force := fs.Bool("force", false, "Overwrite existing output file")
    • What: Defines force.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L540: if err := fs.Parse(args); err != nil { return err }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L540: err := fs.Parse(args)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L541: return err
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L544: opts := []gatewayconfig.Option{}
    • What: Defines opts.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L545: if strings.TrimSpace(*configPath) != "" { opts = append(opts, gatewayconfig.WithPath(*configPath)) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L546: opts = append(opts, gatewayconfig.WithPath(*configPath))
        • What: Assigns opts.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L549: cfg, err := gatewayconfig.Load(opts...)
    • What: Defines cfg, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L550: if err != nil { return fmt.Errorf("load config from environment: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L551: return fmt.Errorf("load config from environment: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L554: data, err := yaml.Marshal(cfg)
    • What: Defines data, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L555: if err != nil { return fmt.Errorf("encode config: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L556: return fmt.Errorf("encode config: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L559: path := strings.TrimSpace(*outputPath)
    • What: Defines path.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L560: if path == "" { fmt.Print(string(data)) return nil }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L561: fmt.Print(string(data))
        • What: Calls fmt.Print.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L562: return nil
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L565: if !*force { if _, err := os.Stat(path); err == nil { return fmt.Errorf("output file %s already exists (use --force to overwrite)", path) }…
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L566: if _, err := os.Stat(path); err == nil { return fmt.Errorf("output file %s already exists (use --force to overwrite)", path) } else if err …
        • What: Branches conditionally.
        • Why: Handles different execution paths based on runtime state.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L566: _, err := os.Stat(path)
            • What: Defines _, err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L567: return fmt.Errorf("output file %s already exists (use --force to overwrite)", path)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
          • L568: if err != nil && !errors.Is(err, os.ErrNotExist) { return fmt.Errorf("stat output file: %w", err) }
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L569: return fmt.Errorf("stat output file: %w", err)
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
  • L573: dir := filepath.Dir(path)
    • What: Defines dir.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L574: if dir != "." && dir != "" { if err := os.MkdirAll(dir, 0o755); err != nil { return fmt.Errorf("ensure output directory: %w", err) } }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L575: if err := os.MkdirAll(dir, 0o755); err != nil { return fmt.Errorf("ensure output directory: %w", err) }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L575: err := os.MkdirAll(dir, 0o755)
            • What: Defines err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L576: return fmt.Errorf("ensure output directory: %w", err)
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
  • L580: if err := os.WriteFile(path, data, 0o644); err != nil { return fmt.Errorf("write output file: %w", err) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L580: err := os.WriteFile(path, data, 0o644)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L581: return fmt.Errorf("write output file: %w", err)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L584: fmt.Printf("configuration written to %s\n", path)
    • What: Calls fmt.Printf.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L585: return nil
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

targetsFile

What: Checks whether a filesystem watcher event refers to the target config file.

Why: fsnotify emits directory-level events; this filters down to the single config file we care about.

How: Resolves the event path to an absolute path and compares it to the expected absolute config path.

cmd/apigw/main.go#L588
func targetsFile(eventPath, target string) bool {
if eventPath == "" {
return false
}
abs, err := filepath.Abs(eventPath)
if err != nil {
return false
}
return abs == target
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L589: if eventPath == "" { return false }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L590: return false
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L592: abs, err := filepath.Abs(eventPath)
    • What: Defines abs, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L593: if err != nil { return false }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L594: return false
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L596: return abs == target
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

Start Here

Guides

Reference

Neighboring source