Documentation
¶
Overview ¶
Package dev runs a web service's local development dependencies without Docker, and is the base for an app's own development command.
Index ¶
- Constants
- func Env(ctx context.Context, cfg Config) (map[string]string, error)
- func FindConfig(dir string) (string, error)
- func HandOff(configPath string, args []string) error
- func LogPath(logs, service string) string
- func NewRootCmd(cfg Config, opts ...Option) *cobra.Command
- func RequireConfig(root *cobra.Command, err error)
- func ResetStack(ctx context.Context, cfg Config, logger *slog.Logger) error
- func Up(ctx context.Context, cfg Config, logger *slog.Logger, out io.Writer, ...) error
- func Version() string
- func WaitStack(ctx context.Context, cfg Config, timeout time.Duration) error
- type Config
- type ExitError
- type Instance
- type Key
- type Option
- type Postgres
- type Profile
- type Row
- type S3
- type Service
- type Stack
Constants ¶
const ConfigFile = "dev.json"
ConfigFile is the name the dev command looks for, from the working directory up, so that `go -C tools tool dev` still finds the repository's.
Variables ¶
This section is empty.
Functions ¶
func Env ¶ added in v0.11.0
Env is what the checkout's running dev sets for every command, without the real environment: dev.json's env with its allocated ports, {postgres} and the rest filled in, and the env files. An app's own tools, such as one that queries the database its services use, read it to find what they use.
func FindConfig ¶
FindConfig returns the path of the nearest dev.json in dir or its parents.
func HandOff ¶ added in v0.8.0
HandOff runs a repository's own dev in place of this one, when this is a dev installed globally (`go install …/cmd/dev`). The repository whose dev.json is at configPath says which: its `command`, for an app whose dev adds commands of its own, or else the version its tools module pins, when that is newer than this one. A newer dev reads an older dev.json as it was meant, so an install runs its own commands everywhere until a repository needs a later one; CI and agents still run the pin. On success it does not return; it returns nil when this dev should run.
func LogPath ¶ added in v0.4.0
LogPath is where a service's output from the latest run is kept, given the directory of a stack's logs.
func NewRootCmd ¶
NewRootCmd returns the dev command with the standard subcommands. An app with its own development tasks adds them with AddCommand, and extends the view and the MCP server with options.
func RequireConfig ¶ added in v0.6.1
RequireConfig makes every command but those that need no dev.json fail with err, for a dev run where no dev.json was found.
func ResetStack ¶
ResetStack deletes the stack's data. A server still running from the same directory is stopped first, since it would recreate files as they go.
Types ¶
type Config ¶
type Config struct {
// Name is the Postgres user, password and database, and required with
// Postgres. Tests get Name_test.
Name string `json:"name"`
// Command is the repository's own dev, for an app whose dev adds commands
// of its own, such as ["go", "tool", "dev"]. A dev installed globally runs
// it instead of itself; {root} stands for the directory of dev.json.
Command []string `json:"command,omitempty"`
// Root is the directory commands run in and relative paths resolve
// against. LoadConfig sets it to the config file's directory; otherwise
// it defaults to the working directory.
Root string `json:"-"`
// Dir keeps Postgres data, S3 objects and service logs between runs;
// defaults to .devstack.
Dir string `json:"dir,omitempty"`
// Env is set for every command. Values may name the stack:
// {postgres} and {postgres_test} are database URLs, {s3} the S3 endpoint.
Env map[string]string `json:"env,omitempty"`
// EnvFile is a dotenv file for personal settings and secrets, over Env
// and under the real environment. Defaults to .env; a missing file is
// skipped.
EnvFile string `json:"envFile,omitempty"`
// Ports names the ports the app's services listen on, with the one each
// prefers, such as {"server": 8080, "web": 5173}. dev gives each its
// preferred port when free and the next free one otherwise, and
// {port.<name>} stands for it in env, commands, url and health.
Ports map[string]int `json:"ports,omitempty"`
// Postgres runs when set.
Postgres *Postgres `json:"postgres,omitempty"`
// S3 runs when set.
S3 *S3 `json:"s3,omitempty"`
// Before lists commands run once, in order, before anything starts, such
// as generating files a server embeds. A failure stops dev.
Before [][]string `json:"before,omitempty"`
// Profiles are alternative setups to choose between per checkout, such as
// a local database or a shared remote one. Each can set env, include other
// profiles, and enable the services that name it.
Profiles map[string]Profile `json:"profiles,omitempty"`
// DefaultProfiles are active until a checkout chooses others with
// --profile.
DefaultProfiles []string `json:"defaultProfiles,omitempty"`
// Active names the profiles to use, overriding the checkout's choice;
// --profile sets it.
Active []string `json:"-"`
// Services run until dev stops: servers rebuilt when their sources
// change, and processes such as a Vite dev server.
Services []Service `json:"services,omitempty"`
// contains filtered or unexported fields
}
Config describes an app's local stack.
func LoadConfig ¶
LoadConfig reads a dev.json, rooted at its directory.
func (Config) DatabaseURL ¶
DatabaseURL is the URL of the app's database, or "" without Postgres.
func (Config) TestDatabaseURL ¶
TestDatabaseURL is the URL of the database for tests, or "" without Postgres.
type ExitError ¶ added in v0.6.0
type ExitError struct{ Code int }
ExitError carries a command's exit status out of `dev exec`, so that dev exits with it.
type Instance ¶ added in v0.10.0
type Instance struct {
Root string `json:"root"`
Dir string `json:"dir"`
PID int `json:"pid"`
Version string `json:"version"`
Started time.Time `json:"started"`
Ports map[string]int `json:"ports,omitempty"`
Profiles []string `json:"profiles,omitempty"`
}
Instance describes a running dev, for `dev ps` and tools.
type Key ¶ added in v0.9.0
type Key struct {
// Key is as the view reads it, such as "e" or "ctrl+e"; it must not be one
// of the view's own.
Key string
// Help is the few words the help line shows for it.
Help string
// Do runs off the view's goroutine; its error is shown on the status line.
Do func(context.Context) error
}
Key is a key the view's main screen answers, beside its own.
type Option ¶ added in v0.9.0
type Option func(*extension)
Option extends the dev command NewRootCmd builds.
type Postgres ¶
type Postgres struct {
// Port defaults to 5432.
Port int `json:"port,omitempty"`
// Parameters are server settings, e.g. max_connections for test suites
// that open pools in parallel.
Parameters map[string]string `json:"parameters,omitempty"`
}
Postgres configures the local PostgreSQL server.
type Profile ¶ added in v0.9.0
type Profile struct {
// Description says what choosing it means, for `dev profiles`.
Description string `json:"description,omitempty"`
// Include activates other profiles first, which makes presets.
Include []string `json:"include,omitempty"`
// Env is set over the config's env, in the order profiles are chosen.
Env map[string]string `json:"env,omitempty"`
}
Profile is one of the setups a checkout can choose.
type Row ¶ added in v0.9.0
type Row struct {
Name string
// State colors the row: "ok", "busy", "error" or "off".
State string
// Detail is a short note, such as a port or an error.
Detail string
// URL, if any, is shown as a link.
URL string
}
Row is a line the view shows above the services, for something the app runs beside them, such as a tunnel to a shared database.
type S3 ¶
type S3 struct {
// Addr defaults to 127.0.0.1:8333.
Addr string `json:"addr,omitempty"`
}
S3 configures the local S3-compatible server.
type Service ¶ added in v0.4.0
type Service struct {
// Name prefixes its output, names its log, and selects it on the
// command line.
Name string `json:"name"`
// Dir is where its commands run, relative to the root.
Dir string `json:"dir,omitempty"`
// Build compiles a server, e.g. ["go", "build", "-o", "tmp/shop", "./cmd/shop"].
Build []string `json:"build,omitempty"`
// Run starts it, e.g. ["tmp/shop", "serve"] or ["pnpm", "--filter", "web", "dev"].
Run []string `json:"run"`
// Watch lists the directories, relative to Dir, whose changes rebuild a
// server; defaults to Dir. Hidden directories and node_modules are skipped.
Watch []string `json:"watch,omitempty"`
// Exclude names further directories to skip wherever they appear, such
// as the frontend or the build output.
Exclude []string `json:"exclude,omitempty"`
// Extensions are the file types that rebuild a server; defaults to .go.
Extensions []string `json:"extensions,omitempty"`
// Env is set for this service over the config's Env, with the same
// references to the stack.
Env map[string]string `json:"env,omitempty"`
// EnvFile is a dotenv file for this service, relative to Dir, over the
// config's EnvFile.
EnvFile string `json:"envFile,omitempty"`
// URL is where to open the service, such as http://localhost:8080. The
// interactive view links to it, and dev logs it once the service is up.
URL string `json:"url,omitempty"`
// Health is a URL that answers 2xx once the service can do its job, such
// as http://localhost:8080/readyz. With it, the service reads starting,
// then ready, or unhealthy if it stops answering.
Health string `json:"health,omitempty"`
// Manual services start only when named: `dev web worker`.
Manual bool `json:"manual,omitempty"`
// DependsOn names services that must be up (ready, running without a
// health URL, or finished when they run once) before this one starts, such
// as a database. Starting this one starts them too.
DependsOn []string `json:"dependsOn,omitempty"`
// Restart is "on-failure" to start the service again, with backoff, when
// it exits with an error; by default it is left stopped.
Restart string `json:"restart,omitempty"`
// RebuildOnCheckout rebuilds a server when the checkout's branch changes,
// as a branch-stamped build needs.
RebuildOnCheckout bool `json:"rebuildOnCheckout,omitempty"`
// Profiles limits the service to checkouts that choose one of them, such
// as a local database that the remote setup does without.
Profiles []string `json:"profiles,omitempty"`
// Once is for a command that readies something and exits, such as one
// that loads a database: it reads starting while it runs and finished once
// it exits cleanly, and services that depend on it wait for it to finish.
Once bool `json:"once,omitempty"`
}
Service is a long-running command. With Build it is a server: built, run, and rebuilt and restarted when its sources change; a failed build stops it until the next change. Without, it runs once and is left stopped if it exits, so a startup error is not buried under restarts.
type Stack ¶
type Stack struct {
// contains filtered or unexported fields
}
Stack is a running set of local dependencies.
func StartStack ¶
StartStack starts the configured dependencies and returns once they accept connections. The first run downloads the Postgres binaries.