115 lines
2.8 KiB
Go
115 lines
2.8 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
const DefaultWebhookPort = 17421
|
|
|
|
type Settings struct {
|
|
WebhookPort int `toml:"webhook_port"`
|
|
BrainstormPrompt string `toml:"brainstorm_prompt"`
|
|
BrainstormContinuePrompt string `toml:"brainstorm_continue_prompt"`
|
|
ImplementPlanPrompt string `toml:"implement_plan_prompt"`
|
|
ReviewPrompt string `toml:"review_prompt"`
|
|
AutoReview bool `toml:"auto_review"`
|
|
DevBranch string `toml:"dev_branch"`
|
|
AutoBuildBranch string `toml:"auto_build_branch"`
|
|
WorktreePostCreateScript string `toml:"worktree_post_create_script"`
|
|
WorktreePreRemoveScript string `toml:"worktree_pre_remove_script"`
|
|
ImplTabPreCreateScript string `toml:"impl_tab_pre_create_script"`
|
|
ImplTabPostCloseScript string `toml:"impl_tab_post_close_script"`
|
|
ProfilesDir string `toml:"profiles_dir"`
|
|
SystemPromptCommand string `toml:"system_prompt_command"`
|
|
}
|
|
|
|
func DefaultSettings() *Settings {
|
|
return &Settings{
|
|
WebhookPort: DefaultWebhookPort,
|
|
AutoReview: true,
|
|
DevBranch: "main",
|
|
}
|
|
}
|
|
|
|
// configFilePath returns the path to the config file. It's a variable so tests can override it.
|
|
var configFilePath = func() (string, error) {
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
return "", fmt.Errorf("resolve home dir: %w", err)
|
|
}
|
|
return filepath.Join(home, ".config", "superwork", "config.toml"), nil
|
|
}
|
|
|
|
func Load() (*Settings, error) {
|
|
return LoadFrom("")
|
|
}
|
|
|
|
func LoadFrom(path string) (*Settings, error) {
|
|
if path == "" {
|
|
var err error
|
|
path, err = configFilePath()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
s := DefaultSettings()
|
|
_, err := toml.DecodeFile(path, s)
|
|
if errors.Is(err, fs.ErrNotExist) {
|
|
return s, nil
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("decode config %s: %w", path, err)
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
func Save(s *Settings) error {
|
|
return SaveTo("", s)
|
|
}
|
|
|
|
func SaveTo(path string, s *Settings) error {
|
|
if path == "" {
|
|
var err error
|
|
path, err = configFilePath()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
return fmt.Errorf("create config dir: %w", err)
|
|
}
|
|
f, err := os.Create(path)
|
|
if err != nil {
|
|
return fmt.Errorf("create config file: %w", err)
|
|
}
|
|
defer f.Close()
|
|
if err := toml.NewEncoder(f).Encode(s); err != nil {
|
|
return fmt.Errorf("encode config: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func WorkspaceRoot() (string, error) {
|
|
out, err := exec.Command("git", "rev-parse", "--show-toplevel").Output()
|
|
if err != nil {
|
|
cwd, cerr := os.Getwd()
|
|
if cerr != nil {
|
|
return "", fmt.Errorf("get cwd: %w", cerr)
|
|
}
|
|
return cwd, nil
|
|
}
|
|
return strings.TrimSpace(string(out)), nil
|
|
}
|
|
|
|
func SpxDir(workspaceRoot string) string {
|
|
return filepath.Join(workspaceRoot, ".spx")
|
|
}
|