dev

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: Apache-2.0 Imports: 28 Imported by: 0

README

dev

go tool dev runs an app's whole development setup in one terminal: Postgres 18 and an S3-compatible server natively, with data kept between runs; the Go server, rebuilt and restarted when its sources change; and processes beside it, such as Vite. Add it to the tools module (not the service's module: the S3 emulator's MD5 ETags fail under fips140=only), and describe the stack in dev.json at the repository root:

go -C tools get -tool github.com/parallelworks/foundation/dev/cmd/dev
{
  "name": "shop",
  "postgres": { "parameters": { "max_connections": "300" } },
  "s3": {},
  "before": [["sh", "-c", "find web/dist -mindepth 1 ! -name .gitkeep -delete"]],
  "server": {
    "build": ["go", "build", "-o", "tmp/shop", "./cmd/shop"],
    "run": ["tmp/shop", "serve"],
    "exclude": ["tmp", "web", "tools"],
    "extensions": [".go", ".sql"]
  },
  "processes": [
    { "name": "web", "run": ["pnpm", "--filter", "web", "dev"] }
  ]
}
Command
dev Run all of it until interrupted, each line prefixed with its source
dev stack Run Postgres on :5432 and S3 on 127.0.0.1:8333 until interrupted. User, password and database are name (required with Postgres); tests get name_test
dev wait Block until a stack started elsewhere accepts connections
dev reset Delete the stack's data

Data lives in .devstack/ beside dev.json, or --dir. The command finds dev.json from the working directory up, so go -C tools tool dev works too. A Postgres left running by a stack that was killed is stopped on the next start.

before commands run once, in order, before anything starts: generating files the server embeds, or clearing a stale build. If one fails, dev stops with its error.

The server, processes and before commands get .env beside dev.json (or env), under the real environment, so SHOP_LOG_LEVEL=info go tool dev overrides it. A build that fails stops the server until the next change, so nothing runs stale code. Each command runs in its own process group, and stopping one ends everything it started, such as the Vite under pnpm. Unix only.

An app with its own development tasks builds its command on the same base:

func main() {
	root := dev.NewRootCmd(dev.Config{Name: "shop", Postgres: &dev.Postgres{}, S3: &dev.S3{}})
	root.AddCommand(seedCmd)
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()
	if err := root.ExecuteContext(ctx); err != nil {
		os.Exit(1)
	}
}

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

View Source
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 FindConfig

func FindConfig(dir string) (string, error)

FindConfig returns the path of the nearest dev.json in dir or its parents.

func NewRootCmd

func NewRootCmd(cfg Config) *cobra.Command

NewRootCmd returns the dev command with the standard subcommands. An app with its own development tasks adds them with AddCommand.

func ResetStack

func ResetStack(ctx context.Context, cfg Config, logger *slog.Logger) error

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.

func Up added in v0.2.0

func Up(ctx context.Context, cfg Config, logger *slog.Logger, out io.Writer) error

Up runs the stack, the server and the processes until ctx ends. The server is rebuilt and restarted when its sources change; a failed build stops it, so that nothing is tested against stale code.

func WaitStack

func WaitStack(ctx context.Context, cfg Config, timeout time.Duration) error

WaitStack blocks until a stack started elsewhere accepts connections, so that a server started alongside it does not race it.

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"`
	// 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 and S3 objects between runs; defaults to
	// .devstack.
	Dir string `json:"dir,omitempty"`
	// Env is a dotenv file loaded into the server and processes, where the
	// real environment wins. Defaults to .env; a missing file is skipped.
	Env string `json:"env,omitempty"`
	// Postgres runs when set.
	Postgres *Postgres `json:"postgres,omitempty"`
	// S3 runs when set.
	S3 *S3 `json:"s3,omitempty"`
	// Server is built, run, and rebuilt when its sources change.
	Server *Server `json:"server,omitempty"`
	// Before lists commands run once, in order, before anything starts, such
	// as generating files the server embeds. A failure stops dev.
	Before [][]string `json:"before,omitempty"`
	// Processes run alongside the server, such as a Vite dev server.
	Processes []Process `json:"processes,omitempty"`
}

Config describes an app's local stack.

func LoadConfig

func LoadConfig(path string) (Config, error)

LoadConfig reads a dev.json, rooted at its directory.

func (Config) DatabaseURL

func (c Config) DatabaseURL() string

DatabaseURL is the URL of the app's database, or "" without Postgres.

func (Config) TestDatabaseURL

func (c Config) TestDatabaseURL() string

TestDatabaseURL is the URL of the database for tests, or "" without Postgres.

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 Process added in v0.2.0

type Process struct {
	// Name prefixes its output.
	Name string `json:"name"`
	// Run is the command, e.g. ["pnpm", "--filter", "web", "dev"].
	Run []string `json:"run"`
	// Dir is where it runs, relative to the root.
	Dir string `json:"dir,omitempty"`
}

Process is a long-running command beside the server.

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 Server added in v0.2.0

type Server struct {
	// Build compiles the server, e.g. ["go", "build", "-o", "tmp/shop", "./cmd/shop"].
	Build []string `json:"build"`
	// Run starts what Build produced, e.g. ["tmp/shop", "serve"].
	Run []string `json:"run"`
	// Watch lists the directories whose changes rebuild the server;
	// defaults to the root. 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 trigger a rebuild; defaults to .go.
	Extensions []string `json:"extensions,omitempty"`
}

Server is the app's Go server.

type Stack

type Stack struct {
	// contains filtered or unexported fields
}

Stack is a running set of local dependencies.

func StartStack

func StartStack(ctx context.Context, cfg Config, logger *slog.Logger) (*Stack, error)

StartStack starts the configured dependencies and returns once they accept connections. The first run downloads the Postgres binaries.

func (*Stack) Stop

func (s *Stack) Stop(ctx context.Context) error

Stop shuts the dependencies down; Postgres flushes its data first.

Directories

Path Synopsis
cmd
dev command
Command dev runs an app's local development stack as described by the nearest dev.json.
Command dev runs an app's local development stack as described by the nearest dev.json.

Jump to

Keyboard shortcuts

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