Pulse/pkg/pulsecli/deps.go
2026-03-18 16:06:30 +00:00

188 lines
3.6 KiB
Go

package pulsecli
import (
"os"
"golang.org/x/term"
)
type ConfigDeps struct {
ExportFile *string
ImportFile *string
Passphrase *string
ForceImport *bool
ReadPassword func(int) ([]byte, error)
}
type BootstrapDeps struct {
Exit func(int)
}
type MockDeps struct {
Exit func(int)
DefaultEnvDir func() string
Stat func(string) (os.FileInfo, error)
}
type Env struct {
ExportFile string
ImportFile string
Passphrase string
ForceImport bool
}
type ProcessIO struct {
Exit func(int)
ReadPassword func(int) ([]byte, error)
}
type MockFS struct {
DefaultEnvDir string
Stat func(string) (os.FileInfo, error)
}
func NewEnv() *Env {
return &Env{}
}
func NewProcessIO() ProcessIO {
return ProcessIO{
Exit: os.Exit,
ReadPassword: term.ReadPassword,
}
}
func NewMockFS() MockFS {
return MockFS{
DefaultEnvDir: "/opt/pulse",
Stat: os.Stat,
}
}
func (process ProcessIO) readPassword() func(int) ([]byte, error) {
if process.ReadPassword != nil {
return process.ReadPassword
}
return term.ReadPassword
}
func (process ProcessIO) exit() func(int) {
if process.Exit != nil {
return process.Exit
}
return os.Exit
}
func (mockFS MockFS) defaultEnvDir() func() string {
if mockFS.DefaultEnvDir != "" {
return func() string {
return mockFS.DefaultEnvDir
}
}
return func() string {
return "/opt/pulse"
}
}
func (mockFS MockFS) stat() func(string) (os.FileInfo, error) {
if mockFS.Stat != nil {
return mockFS.Stat
}
return os.Stat
}
func (env *Env) ConfigDeps(process ProcessIO) *ConfigDeps {
if env == nil {
env = NewEnv()
}
return NewConfigDeps(
&env.ExportFile,
&env.ImportFile,
&env.Passphrase,
&env.ForceImport,
process.readPassword(),
)
}
func BuildBootstrapDeps(process ProcessIO) *BootstrapDeps {
return NewBootstrapDeps(process.exit())
}
func BuildMockDeps(process ProcessIO, mockFS MockFS) *MockDeps {
return NewMockDeps(
process.exit(),
mockFS.defaultEnvDir(),
mockFS.stat(),
)
}
func (env *Env) CommandDeps(process ProcessIO, mockFS MockFS) CommandDeps {
return CommandDeps{
Config: env.ConfigDeps(process),
Bootstrap: BuildBootstrapDeps(process),
Mock: BuildMockDeps(process, mockFS),
}
}
func (env *Env) ResetFlags() {
ResetFlags(env.ConfigDeps(ProcessIO{}))
}
func NewConfigDeps(exportFile, importFile, passphrase *string, forceImport *bool, readPassword func(int) ([]byte, error)) *ConfigDeps {
return &ConfigDeps{
ExportFile: exportFile,
ImportFile: importFile,
Passphrase: passphrase,
ForceImport: forceImport,
ReadPassword: readPassword,
}
}
func NewBootstrapDeps(exit func(int)) *BootstrapDeps {
return &BootstrapDeps{Exit: exit}
}
func NewMockDeps(exit func(int), defaultEnvDir func() string, stat func(string) (os.FileInfo, error)) *MockDeps {
return &MockDeps{
Exit: exit,
DefaultEnvDir: defaultEnvDir,
Stat: stat,
}
}
func configReadPassword(config *ConfigDeps, fd int) ([]byte, error) {
if config != nil && config.ReadPassword != nil {
return config.ReadPassword(fd)
}
return term.ReadPassword(fd)
}
func bootstrapExit(bootstrap *BootstrapDeps, code int) {
if bootstrap != nil && bootstrap.Exit != nil {
bootstrap.Exit(code)
return
}
os.Exit(code)
}
func mockExit(mock *MockDeps, code int) {
if mock != nil && mock.Exit != nil {
mock.Exit(code)
return
}
os.Exit(code)
}
func mockDefaultEnvDir(mock *MockDeps) string {
if mock != nil && mock.DefaultEnvDir != nil {
return mock.DefaultEnvDir()
}
return "/opt/pulse"
}
func mockStat(mock *MockDeps, path string) (os.FileInfo, error) {
if mock != nil && mock.Stat != nil {
return mock.Stat(path)
}
return os.Stat(path)
}