config

package
v4.7.2 Latest Latest
Warning

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

Go to latest
Published: Apr 25, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const RemoteNoPush = "_nopush"

RemoteNoPush is a sentinel value indicating that push is not allowed for this branch (e.g., a fork PR where maintainerCanModify is false).

Variables

This section is empty.

Functions

func ConfigDir

func ConfigDir() (string, error)

ConfigDir returns the path to the ezstack config directory. Checks EZSTACK_HOME first, then defaults to $HOME/.ezstack.

func GenerateStackHash

func GenerateStackHash(name string) string

GenerateStackHash generates a 7-char hex hash from a stack name using FNV-32a

func PRNumberFromURL

func PRNumberFromURL(url string) int

PRNumberFromURL extracts the PR number from a GitHub PR URL. e.g. "https://github.com/owner/repo/pull/123" → 123 Returns 0 if the URL is empty or unparseable.

Types

type Branch

type Branch struct {
	Name         string `json:"name"`
	Parent       string `json:"parent"`
	WorktreePath string `json:"worktree_path"`
	PRNumber     int    `json:"-"` // Runtime-only: derived from PRUrl via PRNumberFromURL
	PRUrl        string `json:"pr_url,omitempty"`
	PRState      string `json:"pr_state,omitempty"`  // Cached: "OPEN", "DRAFT", "MERGED", "CLOSED"
	BaseBranch   string `json:"base_branch"`         // original tree parent, used for display ordering
	IsRemote     bool   `json:"is_remote,omitempty"` // branch belongs to another contributor
	IsMerged     bool   `json:"is_merged,omitempty"`
	Remote       string `json:"remote,omitempty"` // Git remote to push to (empty means "origin")
}

Branch represents a single branch in a stack, constructed from the tree and cache at runtime.

func SortBranchesTopologically

func SortBranchesTopologically(branches []*Branch) []*Branch

SortBranchesTopologically sorts branches so parents come before children This ensures the display shows the correct parent -> child order IMPORTANT: When a parent branch is merged and its children are reparented to main, the merged branch should still appear in its original position (before its former children). We use BaseBranch to detect the original parent-child relationships.

func (*Branch) CanPush

func (b *Branch) CanPush() bool

CanPush returns true if push operations are allowed for this branch.

func (*Branch) EffectiveRemote

func (b *Branch) EffectiveRemote() string

EffectiveRemote returns the remote for this branch, defaulting to "origin".

type BranchCache

type BranchCache struct {
	WorktreePath string `json:"worktree_path,omitempty"`
	PRNumber     int    `json:"-"` // Runtime-only: derived from PRUrl via PRNumberFromURL
	PRUrl        string `json:"pr_url,omitempty"`
	PRState      string `json:"pr_state,omitempty"` // Cached: "OPEN", "DRAFT", "MERGED", "CLOSED"
	IsMerged     bool   `json:"is_merged,omitempty"`
	IsRemote     bool   `json:"is_remote,omitempty"`
	Remote       string `json:"remote,omitempty"` // git remote to push to (e.g. fork remote); defaults to "origin"
}

BranchCache holds cached metadata for a branch

type BranchTree

type BranchTree map[string]BranchTree

BranchTree is a recursive map representing the stack hierarchy Each key is a branch name, and its value is another BranchTree of its children

type CacheConfig

type CacheConfig struct {
	Branches map[string]*BranchCache `json:"branches"`
	// contains filtered or unexported fields
}

CacheConfig holds cached branch metadata for a repo

func LoadCacheConfig

func LoadCacheConfig(repoDir string) (*CacheConfig, error)

LoadCacheConfig loads cached branch metadata. This now delegates to the combined stacks file. Kept for backward compatibility with callers that load cache separately.

func (*CacheConfig) GetBranchCache

func (cc *CacheConfig) GetBranchCache(branchName string) *BranchCache

GetBranchCache returns cached metadata for a branch

func (*CacheConfig) Save

func (cc *CacheConfig) Save(repoDir string) error

Save writes the cache data back to the combined stacks.json file. This loads the current stacks.json, updates the branches for this repo, and writes it back atomically.

func (*CacheConfig) SetBranchCache

func (cc *CacheConfig) SetBranchCache(branchName string, cache *BranchCache)

SetBranchCache sets cached metadata for a branch

type Config

type Config struct {
	DefaultBaseBranch string                 `json:"default_base_branch"`
	GitHubToken       string                 `json:"github_token,omitempty"`
	Repos             map[string]*RepoConfig `json:"repos"`
}

Config holds the global configuration for ezstack

func Load

func Load() (*Config, error)

Load loads the configuration from ~/.ezstack/config.json. Top-level scalar values are resolved through Viper so that EZSTACK_-prefixed environment variables (e.g. EZSTACK_GITHUB_TOKEN) take precedence over the file. The repos map is read directly from JSON because Viper lowercases all keys, which would corrupt filesystem-path map keys like /Users/….

func (*Config) GetBaseBranch

func (c *Config) GetBaseBranch(repoPath string) string

GetBaseBranch returns the base branch for a repo (repo-specific or global default)

func (*Config) GetCdAfterNew

func (c *Config) GetCdAfterNew(repoPath string) bool

GetCdAfterNew returns whether to cd after creating a new worktree (default: true)

func (*Config) GetInitSubmodules added in v4.6.0

func (c *Config) GetInitSubmodules(repoPath string) bool

GetInitSubmodules returns whether to mirror the main worktree's initialized submodules into newly created worktrees (default: true).

func (*Config) GetRepoConfig

func (c *Config) GetRepoConfig(repoPath string) *RepoConfig

GetRepoConfig returns the configuration for a specific repo path

func (*Config) GetSyncStrategy

func (c *Config) GetSyncStrategy(repoPath string) string

GetSyncStrategy returns the sync strategy for a repo ("rebase" or "merge", default "rebase")

func (*Config) GetUseWorktrees

func (c *Config) GetUseWorktrees(repoPath string) bool

GetUseWorktrees returns whether to use worktrees for new branches (default: true)

func (*Config) GetWorktreeBaseDir

func (c *Config) GetWorktreeBaseDir(repoPath string) string

GetWorktreeBaseDir returns the worktree base dir for a repo, or empty if not configured

func (*Config) Save

func (c *Config) Save() error

Save saves the configuration to ~/.ezstack/config.json

func (*Config) SetRepoConfig

func (c *Config) SetRepoConfig(repoPath string, repoCfg *RepoConfig)

SetRepoConfig sets the configuration for a specific repo

type RepoConfig

type RepoConfig struct {
	RepoPath            string `json:"repo_path"`
	WorktreeBaseDir     string `json:"worktree_base_dir"`
	DefaultBaseBranch   string `json:"default_base_branch,omitempty"`
	CdAfterNew          *bool  `json:"cd_after_new,omitempty"`
	UseWorktrees        *bool  `json:"use_worktrees,omitempty"`
	AutoDraftWipCommits *bool  `json:"auto_draft_wip_commits,omitempty"`
	InitSubmodules      *bool  `json:"init_submodules,omitempty"` // Mirror main worktree's initialized submodules into new worktrees (default: true)
	SyncStrategy        string `json:"sync_strategy,omitempty"`   // "rebase" (default) or "merge"
	AgentCommand        string `json:"agent_command,omitempty"`   // AI agent CLI command (default: "claude")
}

RepoConfig holds configuration for a specific repository

func (*RepoConfig) GetAgentCommand

func (rc *RepoConfig) GetAgentCommand() string

GetAgentCommand returns the configured agent command, defaulting to "claude".

type Stack

type Stack struct {
	Hash           string     `json:"-"`                         // Populated from map key at load time
	Name           string     `json:"name,omitempty"`            // Optional user-given name for the stack
	Root           string     `json:"root"`                      // The base branch (e.g. "main", or a remote branch name)
	RootBase       string     `json:"root_base,omitempty"`       // The branch the root's PR targets (for computing root diff)
	RootPRNumber   int        `json:"-"`                         // Runtime-only: derived from RootPRUrl
	RootPRUrl      string     `json:"root_pr_url,omitempty"`     // PR URL of the root branch (for remote base branches)
	DeleteDeclined bool       `json:"delete_declined,omitempty"` // User declined cleanup prompt; don't re-ask
	Tree           BranchTree `json:"tree"`                      // The tree of branches
	Branches       []*Branch  `json:"-"`                         // Runtime-only: populated from Tree for backward compatibility
	// contains filtered or unexported fields
}

Stack represents a chain of stacked branches as a tree Hash is the map key in StackConfig.Stacks and is populated at load time.

func (*Stack) AddBranch

func (s *Stack) AddBranch(branchName, parentName string)

AddBranch adds a branch to the stack tree under the specified parent

func (*Stack) AddSubtree

func (s *Stack) AddSubtree(branchName string, subtree BranchTree, parentName string) bool

AddSubtree adds a branch with its subtree under a parent. Returns false if parentName was not found in the tree (non-root case).

func (*Stack) DisplayName

func (s *Stack) DisplayName() string

DisplayName returns the display string for a stack: "name hash" or just hash

func (*Stack) ExtractSubtree

func (s *Stack) ExtractSubtree(branchName string) BranchTree

ExtractSubtree removes a branch and its entire subtree from the stack and returns the subtree

func (*Stack) FindBranch

func (s *Stack) FindBranch(branchName string) (parent string, found bool)

FindBranch finds a branch in the tree and returns its parent name

func (*Stack) GetBranches

func (s *Stack) GetBranches(cache *CacheConfig) []*Branch

GetBranches returns a flat list of branches from the tree structure Branches are returned in depth-first order with siblings sorted alphabetically The cache is used to populate metadata fields

func (*Stack) GetChildren

func (s *Stack) GetChildren(branchName string) []string

GetChildren returns the immediate children of a branch

func (*Stack) HasBranch

func (s *Stack) HasBranch(branchName string) bool

HasBranch returns true if the branch exists in the stack

func (*Stack) IsFullyMerged

func (s *Stack) IsFullyMerged(cache *CacheConfig) bool

IsFullyMerged returns true if every branch in the stack is marked as merged

func (*Stack) PopulateBranches

func (s *Stack) PopulateBranches()

PopulateBranches rebuilds the Branches slice from the Tree structure This should be called after loading or after modifying the Tree

func (*Stack) PopulateBranchesWithCache

func (s *Stack) PopulateBranchesWithCache(cache *CacheConfig)

PopulateBranchesWithCache rebuilds the Branches slice using the provided cache

func (*Stack) RemoveBranch

func (s *Stack) RemoveBranch(branchName string)

RemoveBranch removes a branch from the stack tree If the branch has children, they are moved up to the branch's parent

func (*Stack) RenameBranchInTree

func (s *Stack) RenameBranchInTree(oldName, newName string) bool

RenameBranchInTree renames a branch in the tree, preserving its children and position

func (*Stack) ReparentBranch

func (s *Stack) ReparentBranch(branchName, newParent string)

ReparentBranch moves a branch to be under a new parent If newParent is empty or matches the root, the branch becomes a root-level branch

func (*Stack) SetCache

func (s *Stack) SetCache(cache *CacheConfig)

SetCache sets the cache for this stack, allowing branch metadata to be loaded

type StackConfig

type StackConfig struct {
	Stacks map[string]*Stack `json:"stacks"`
	Cache  *CacheConfig      `json:"-"` // loaded alongside stacks, not serialized separately
	// contains filtered or unexported fields
}

StackConfig holds metadata about stacks for a single repo

func LoadStackConfig

func LoadStackConfig(repoDir string) (*StackConfig, error)

LoadStackConfig loads stack metadata and branch cache for a specific repo from $HOME/.ezstack/stacks.json It handles migration from older formats using a versioned migration chain.

func (*StackConfig) Save

func (sc *StackConfig) Save(repoDir string) error

Save saves the stack config and cache for this repo to $HOME/.ezstack/stacks.json

Jump to

Keyboard shortcuts

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