config

package
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package config defines flow's configuration schema, its defaults, and the precedence rules that merge them: flags beat environment, environment beats the file, the file beats built-in defaults. flow works with no config at all.

Index

Constants

View Source
const EnvPrefix = "FLOW_"

EnvPrefix is the prefix for environment overrides; "__" separates nesting levels, so FLOW_ASSETS__ROOT sets assets.root.

View Source
const Template = `# ~/.config/flow/config.yaml
#
# Every key below is optional: flow runs with no config file at all. Values
# shown are the built-in defaults. Precedence, highest first:
#   command-line flags > FLOW_ environment variables > this file > defaults
# Environment variables use "__" for nesting, e.g. FLOW_ASSETS__ROOT.

defaults:
  base_branch: main            # branch to create new ticket branches from
  remote: origin
  fetch_before_branch: true    # fetch the remote before branching
  open_editor: true
  create_workspace: true
  create_assets: true

naming:
  # {id} is the normalized ticket ID (RD-19471), {slug} the normalized
  # description. Note the underscore in assets_dir and the hyphen elsewhere:
  # that difference is deliberate and load-bearing.
  branch: "{id}-{slug}"        # also used for the worktree directory name
  assets_dir: "{id}_{slug}"
  workspace_label: "{id}"
  worktrees_subdir: ".worktrees"

assets:
  root: "~/Developer/assets"

editor:
  command: "cursor"
  args: ["{path}"]             # {path} is substituted with the worktree path
  detach: true                 # spawn detached; flow must not block on it

workspace:
  provider: "herdr"            # only "herdr" and "none" are supported in v1
  command: "herdr"

jira:
  browse_url: "https://scaleopscom.atlassian.net/browse/{id}"

github:
  api_base: "https://api.github.com"
  # Token resolution order: $GITHUB_TOKEN, $GH_TOKEN, github.token below,
  # then the macOS keychain service named here.
  token_keychain_service: "flow-github-token"

# Per-repository overrides. Keys are "owner/name" or an absolute repo path.
# build_workflow is learned on first use — the cluster commands ask which
# workflow publishes the chart and record the answer here — so this block only
# needs filling in by hand to override something or to work non-interactively.
repos: {}
#  scaleops-sh/scaleops:
#    base_branch: main
#    helm_repo: scaleops                     # local ` + "`helm repo`" + ` name for this project's charts
#    chart_name: scaleops                    # chart within that repo
#    build_workflow: go.yaml                 # workflow file that produces the chart
#    chart_version_pattern: "alpha"          # "alpha" for feature branches, "rc-main" for main
#    # Jobs that must finish before the chart is installable. Matched by name
#    # prefix; a "skipped" job counts as satisfied.
#    wait_for_jobs:
#      - "Pre Release Helm"
#      - "Pre Release Images"

# Per-kube-context cluster settings, learned on first use and written back here.
# A context absent from this map is one flow will refuse to upgrade.
clusters: {}
#  ido-saban-dev:                            # the kube context name
#    release_name: scaleops
#    namespace: scaleops-system
#    values_file: "~/Developer/helm-values/ido-saban-dev.yaml"
#    helm_repo: scaleops
#    chart: scaleops/scaleops
#    extra_args: ["--reset-then-reuse-values"]
#    repo: scaleops-sh/scaleops              # which source repo this cluster tracks
`

Template is the fully-commented default config file written by `flow config init`. It documents every key, and every value in it matches Default(), so writing it changes nothing about flow's behaviour.

Variables

This section is empty.

Functions

func DefaultPath

func DefaultPath(override string) string

DefaultPath returns the config path, honoring --config and FLOW_CONFIG.

func ExpandPath

func ExpandPath(p string) string

ExpandPath expands a leading ~ and returns an absolute path where possible. Every path-valued config field passes through here.

func Marshal

func Marshal(c Config) (string, error)

Marshal renders the effective configuration as YAML, for `flow config show`.

func SetCluster

func SetCluster(path, context string, cc ClusterConfig) error

SetCluster writes a clusters.{context} block into the config file, creating the file if necessary. The edit is surgical — it walks the YAML node tree and replaces (or appends) one mapping entry — so the comments that `flow config init` wrote survive. The write itself is atomic: temp file, fsync, rename.

func SetRepo added in v0.4.0

func SetRepo(path, repoKey string, rc RepoConfig) error

SetRepo merges the settings flow learned into the repos.{repoKey} block, creating it when absent.

Field by field, and deliberately not a whole-node replacement the way SetCluster does it: learnCluster gathers every cluster field, whereas a repo block is built up one answer at a time and usually shares the key with settings the user wrote by hand. Replacing the node would delete them. A zero-valued field means "leave whatever is there alone".

func WriteFileAtomic

func WriteFileAtomic(path string, data []byte, perm os.FileMode) error

WriteFileAtomic writes data to path via a temp file in the same directory, fsyncs it, and renames it into place, so a crash mid-write cannot truncate the existing file.

The parent directory is deliberately not fsynced after the rename. That would be needed to guarantee the rename itself survives a power loss; for a CLI writing its own config and registry, the atomic-replace guarantee is what matters and the extra syscall on every write is not worth it.

Types

type Assets

type Assets struct {
	Root string `koanf:"root" yaml:"root"`
}

Assets locates the per-ticket asset folders.

type ClusterConfig

type ClusterConfig struct {
	ReleaseName string   `koanf:"release_name" yaml:"release_name"`
	Namespace   string   `koanf:"namespace" yaml:"namespace"`
	ValuesFile  string   `koanf:"values_file" yaml:"values_file,omitempty"`
	HelmRepo    string   `koanf:"helm_repo" yaml:"helm_repo,omitempty"`
	Chart       string   `koanf:"chart" yaml:"chart,omitempty"`
	ExtraArgs   []string `koanf:"extra_args" yaml:"extra_args,omitempty"`
	Repo        string   `koanf:"repo" yaml:"repo,omitempty"`
}

ClusterConfig holds per-kube-context settings. An unknown context is never acted on silently: interactively flow asks for these and records them, and non-interactively it refuses rather than guessing.

type Config

type Config struct {
	Defaults  Defaults                 `koanf:"defaults" yaml:"defaults"`
	Naming    Naming                   `koanf:"naming" yaml:"naming"`
	Assets    Assets                   `koanf:"assets" yaml:"assets"`
	Editor    Editor                   `koanf:"editor" yaml:"editor"`
	Workspace Workspace                `koanf:"workspace" yaml:"workspace"`
	Jira      Jira                     `koanf:"jira" yaml:"jira"`
	GitHub    GitHub                   `koanf:"github" yaml:"github"`
	Repos     map[string]RepoConfig    `koanf:"repos" yaml:"repos,omitempty"`
	Clusters  map[string]ClusterConfig `koanf:"clusters" yaml:"clusters,omitempty"`
}

Config is the whole configuration tree.

func Default

func Default() Config

Default returns the built-in configuration, which is a complete, usable configuration on its own.

func (Config) AssetsRoot

func (c Config) AssetsRoot() string

AssetsRoot returns the assets root with ~ expanded.

func (Config) BaseBranchFor

func (c Config) BaseBranchFor(repoKey string) string

BaseBranchFor resolves the base branch for a repo, falling back to the global default.

func (Config) Cluster

func (c Config) Cluster(ctx string) (ClusterConfig, bool)

Cluster returns the settings for a kube context and whether they exist. The boolean matters: absence is the signal to run first-use setup, or to refuse.

func (Config) Repo

func (c Config) Repo(key string) RepoConfig

Repo returns the overrides for a repo key, or the zero value if there are none. It never returns nil, so callers can read fields unconditionally.

func (Config) Validate

func (c Config) Validate() error

Validate reports configuration that flow cannot act on.

type Defaults

type Defaults struct {
	BaseBranch        string `koanf:"base_branch" yaml:"base_branch"`
	Remote            string `koanf:"remote" yaml:"remote"`
	FetchBeforeBranch bool   `koanf:"fetch_before_branch" yaml:"fetch_before_branch"`
	OpenEditor        bool   `koanf:"open_editor" yaml:"open_editor"`
	CreateWorkspace   bool   `koanf:"create_workspace" yaml:"create_workspace"`
	CreateAssets      bool   `koanf:"create_assets" yaml:"create_assets"`
}

Defaults control branch creation and which side effects flow init performs.

type Editor

type Editor struct {
	Command string   `koanf:"command" yaml:"command"`
	Args    []string `koanf:"args" yaml:"args"`
	Detach  bool     `koanf:"detach" yaml:"detach"`
}

Editor describes how to launch the editor for a worktree.

type GitHub

type GitHub struct {
	APIBase              string `koanf:"api_base" yaml:"api_base"`
	Token                string `koanf:"token" yaml:"token,omitempty"`
	TokenKeychainService string `koanf:"token_keychain_service" yaml:"token_keychain_service"`
}

GitHub holds API and token-resolution settings.

type Jira

type Jira struct {
	BrowseURL string `koanf:"browse_url" yaml:"browse_url"`
}

Jira holds the browse URL template. flow never calls the Jira API.

type Loaded

type Loaded struct {
	Config Config
	// Path is the config file flow resolved, whether or not it exists.
	Path string
	// Exists reports whether that file was actually read.
	Exists bool
}

Loaded is a Config plus the provenance a user needs to debug it.

func Load

func Load(override string) (Loaded, error)

Load merges defaults, the config file, and FLOW_-prefixed environment variables, in that order of increasing precedence. Flags are applied by the caller, on top. A missing file is not an error.

type Naming

type Naming struct {
	Branch          string `koanf:"branch" yaml:"branch"`
	AssetsDir       string `koanf:"assets_dir" yaml:"assets_dir"`
	WorkspaceLabel  string `koanf:"workspace_label" yaml:"workspace_label"`
	WorktreesSubdir string `koanf:"worktrees_subdir" yaml:"worktrees_subdir"`
}

Naming holds the templates that derive every path and label from a ticket.

type RepoConfig

type RepoConfig struct {
	BaseBranch          string   `koanf:"base_branch" yaml:"base_branch,omitempty"`
	HelmRepo            string   `koanf:"helm_repo" yaml:"helm_repo,omitempty"`
	ChartName           string   `koanf:"chart_name" yaml:"chart_name,omitempty"`
	BuildWorkflow       string   `koanf:"build_workflow" yaml:"build_workflow,omitempty"`
	ChartVersionPattern string   `koanf:"chart_version_pattern" yaml:"chart_version_pattern,omitempty"`
	WaitForJobs         []string `koanf:"wait_for_jobs" yaml:"wait_for_jobs,omitempty"`
}

RepoConfig holds per-repository overrides, keyed by "owner/name" or by absolute repo path when the origin remote cannot be parsed.

type Workspace

type Workspace struct {
	Provider string `koanf:"provider" yaml:"provider"`
	Command  string `koanf:"command" yaml:"command"`
}

Workspace selects the terminal workspace provider.

Jump to

Keyboard shortcuts

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