You've already forked panic-cli
mirror of
https://github.com/Print-and-Panic/panic-cli.git
synced 2026-01-21 10:17:41 -08:00
Initial commit: Basic CLI structure with Persona management
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
GEMINI.md
|
||||
15
cmd/persona/root.go
Normal file
15
cmd/persona/root.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package persona
|
||||
|
||||
import (
|
||||
"github.com/Print-and-Panic/panic-cli/cmd"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var PersonaCmd = &cobra.Command{
|
||||
Use: "persona",
|
||||
Short: "Persona management",
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmd.RootCmd.AddCommand(PersonaCmd)
|
||||
}
|
||||
73
cmd/persona/set.go
Normal file
73
cmd/persona/set.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package persona
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/Print-and-Panic/panic-cli/internal/config"
|
||||
"github.com/Print-and-Panic/panic-cli/internal/git"
|
||||
"github.com/Print-and-Panic/panic-cli/internal/system"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var setCmd = &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "Set the persona to use",
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
var personas []string
|
||||
for k := range config.AppConfig.PersonaManagement.Personas {
|
||||
personas = append(personas, k)
|
||||
}
|
||||
return personas, cobra.ShellCompDirectiveNoFileComp
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
targetName := args[0]
|
||||
|
||||
// Update Config
|
||||
config.AppConfig.PersonaManagement.CurrentPersona = targetName
|
||||
viper.Set("persona_management.current_persona", targetName)
|
||||
|
||||
if err := viper.WriteConfig(); err != nil {
|
||||
fmt.Printf("โ Failed to save config: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("โ
Configuration saved.")
|
||||
}
|
||||
|
||||
// Access the global config from the internal package
|
||||
persona, exists := config.AppConfig.PersonaManagement.Personas[targetName]
|
||||
if !exists {
|
||||
fmt.Printf("โ Persona '%s' not found.\n", targetName)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("๐ญ Switching to: %s\n", targetName)
|
||||
|
||||
// Execute Logic
|
||||
err := system.CurrentSystem.SetGitIdentity(git.GitIdentity{
|
||||
Name: persona.GitName,
|
||||
Email: persona.GitEmail,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("โ Failed to set Git Identity: %v\n", err)
|
||||
}
|
||||
|
||||
// Verify the active identity (checks for local overrides, env vars, etc.)
|
||||
err = validatePersona()
|
||||
if err != nil {
|
||||
fmt.Printf("โ %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = system.CurrentSystem.SetTheme(persona.KdeTheme)
|
||||
if err != nil {
|
||||
fmt.Printf("โ Failed to set KDE Theme: %v\n", err)
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
PersonaCmd.AddCommand(setCmd)
|
||||
}
|
||||
45
cmd/persona/status.go
Normal file
45
cmd/persona/status.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package persona
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/Print-and-Panic/panic-cli/internal/config"
|
||||
"github.com/Print-and-Panic/panic-cli/internal/system"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var statusCmd = &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Show the current persona",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := validatePersona()
|
||||
if err != nil {
|
||||
fmt.Printf("โ %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("โ
Current persona: %s\n", config.AppConfig.PersonaManagement.CurrentPersona)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
PersonaCmd.AddCommand(statusCmd)
|
||||
}
|
||||
|
||||
func validatePersona() error {
|
||||
|
||||
targetName := config.AppConfig.PersonaManagement.CurrentPersona
|
||||
persona, exists := config.AppConfig.PersonaManagement.Personas[targetName]
|
||||
if !exists {
|
||||
return fmt.Errorf("persona '%s' not found", targetName)
|
||||
}
|
||||
|
||||
currentId, err := system.CurrentSystem.GetCurrentGitIdentity()
|
||||
if err == nil {
|
||||
if currentId.Name != persona.GitName || currentId.Email != persona.GitEmail {
|
||||
return fmt.Errorf("identity mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
65
cmd/root.go
Normal file
65
cmd/root.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// cmd/root.go
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/Print-and-Panic/panic-cli/internal/config"
|
||||
"github.com/Print-and-Panic/panic-cli/internal/platform"
|
||||
"github.com/Print-and-Panic/panic-cli/internal/system"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var cfgFile string
|
||||
var dryRun bool
|
||||
|
||||
var RootCmd = &cobra.Command{
|
||||
Use: "panic-cli",
|
||||
Short: "A set of tools to run the Print and Panic YouTube channel",
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
if dryRun {
|
||||
system.CurrentSystem = &platform.MockSystem{}
|
||||
fmt.Println("โ ๏ธ Running in DRY-RUN mode. No changes will be applied.")
|
||||
} else {
|
||||
system.CurrentSystem = &platform.LinuxKDE{}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
if err := RootCmd.Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
// Allow passing a specific config file
|
||||
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.config/panic-cli/config.yaml)")
|
||||
RootCmd.PersistentFlags().BoolVarP(&dryRun, "dry-run", "d", false, "Enable dry-run mode (no side effects)")
|
||||
}
|
||||
|
||||
func initConfig() {
|
||||
if cfgFile != "" {
|
||||
viper.SetConfigFile(cfgFile)
|
||||
} else {
|
||||
home, err := os.UserHomeDir()
|
||||
cobra.CheckErr(err)
|
||||
|
||||
viper.AddConfigPath(home)
|
||||
viper.SetConfigType("yaml")
|
||||
viper.SetConfigName(".panic-cli")
|
||||
}
|
||||
|
||||
viper.AutomaticEnv()
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
fmt.Println("DEBUG: No config file found or read error:", err)
|
||||
}
|
||||
err := viper.Unmarshal(&config.AppConfig)
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to decode into struct, %v", err)
|
||||
}
|
||||
}
|
||||
24
go.mod
Normal file
24
go.mod
Normal file
@@ -0,0 +1,24 @@
|
||||
module github.com/Print-and-Panic/panic-cli
|
||||
|
||||
go 1.25.3
|
||||
|
||||
require (
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/spf13/viper v1.21.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
)
|
||||
54
go.sum
Normal file
54
go.sum
Normal file
@@ -0,0 +1,54 @@
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
||||
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
19
internal/config/types.go
Normal file
19
internal/config/types.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package config
|
||||
|
||||
var AppConfig Config
|
||||
|
||||
type PersonaConfig struct {
|
||||
GitName string `mapstructure:"git_name"`
|
||||
GitEmail string `mapstructure:"git_email"`
|
||||
KdeTheme string `mapstructure:"kde_theme"`
|
||||
Wallpaper string `mapstructure:"wallpaper"`
|
||||
}
|
||||
|
||||
type PersonaManagement struct {
|
||||
CurrentPersona string `mapstructure:"current_persona"`
|
||||
Personas map[string]PersonaConfig `mapstructure:"personas"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
PersonaManagement PersonaManagement `mapstructure:"persona_management"`
|
||||
}
|
||||
54
internal/git/identity.go
Normal file
54
internal/git/identity.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type GitIdentity struct {
|
||||
Name string
|
||||
Email string
|
||||
}
|
||||
|
||||
type DefaultGitProvider struct{}
|
||||
|
||||
func (d *DefaultGitProvider) SetGitIdentity(gitIdentity GitIdentity) error {
|
||||
cmd := exec.Command("git", "config", "--global", "user.name", gitIdentity.Name)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return exec.Command("git", "config", "--global", "user.email", gitIdentity.Email).Run()
|
||||
}
|
||||
|
||||
func (d *DefaultGitProvider) GetCurrentGitIdentity() (GitIdentity, error) {
|
||||
nameOut, err := exec.Command("git", "config", "user.name").Output()
|
||||
if err != nil {
|
||||
return GitIdentity{}, err
|
||||
}
|
||||
|
||||
emailOut, err := exec.Command("git", "config", "user.email").Output()
|
||||
if err != nil {
|
||||
return GitIdentity{}, err
|
||||
}
|
||||
|
||||
return GitIdentity{
|
||||
Name: strings.TrimSpace(string(nameOut)),
|
||||
Email: strings.TrimSpace(string(emailOut)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DefaultGitProvider) GetLocalGitIdentity() (GitIdentity, error) {
|
||||
// Check if inside a git repo first to avoid noisy errors
|
||||
if err := exec.Command("git", "rev-parse", "--is-inside-work-tree").Run(); err != nil {
|
||||
return GitIdentity{}, nil // Not a git repo, so no local config
|
||||
}
|
||||
|
||||
// We ignore errors here because if the key isn't set, git exits with 1
|
||||
nameOut, _ := exec.Command("git", "config", "--local", "user.name").Output()
|
||||
emailOut, _ := exec.Command("git", "config", "--local", "user.email").Output()
|
||||
|
||||
return GitIdentity{
|
||||
Name: strings.TrimSpace(string(nameOut)),
|
||||
Email: strings.TrimSpace(string(emailOut)),
|
||||
}, nil
|
||||
}
|
||||
20
internal/kde/look_and_feel.go
Normal file
20
internal/kde/look_and_feel.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package kde
|
||||
|
||||
import "os/exec"
|
||||
|
||||
type DefaultLookAndFeel struct{}
|
||||
|
||||
func (d *DefaultLookAndFeel) SetTheme(themeName string) error {
|
||||
if themeName == "" {
|
||||
return nil
|
||||
}
|
||||
return exec.Command("plasma-apply-lookandfeel", "-a", themeName).Run()
|
||||
}
|
||||
|
||||
func (d *DefaultLookAndFeel) SetWallpaper(path string) error {
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
// Add plasma script logic here
|
||||
return nil
|
||||
}
|
||||
19
internal/platform/interface.go
Normal file
19
internal/platform/interface.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package platform
|
||||
|
||||
import "github.com/Print-and-Panic/panic-cli/internal/git"
|
||||
|
||||
type GitIdentityProvider interface {
|
||||
SetGitIdentity(git.GitIdentity) error
|
||||
GetCurrentGitIdentity() (git.GitIdentity, error)
|
||||
GetLocalGitIdentity() (git.GitIdentity, error)
|
||||
}
|
||||
|
||||
type ThemeHandler interface {
|
||||
SetTheme(theme string) error
|
||||
SetWallpaper(path string) error
|
||||
}
|
||||
|
||||
type System interface {
|
||||
GitIdentityProvider
|
||||
ThemeHandler
|
||||
}
|
||||
13
internal/platform/linux.go
Normal file
13
internal/platform/linux.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"github.com/Print-and-Panic/panic-cli/internal/git"
|
||||
"github.com/Print-and-Panic/panic-cli/internal/kde"
|
||||
)
|
||||
|
||||
type LinuxKDE struct {
|
||||
git.DefaultGitProvider
|
||||
kde.DefaultLookAndFeel
|
||||
}
|
||||
|
||||
var _ System = &LinuxKDE{}
|
||||
42
internal/platform/mock.go
Normal file
42
internal/platform/mock.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Print-and-Panic/panic-cli/internal/git"
|
||||
)
|
||||
|
||||
// MockSystem implements the System interface for dry-runs and testing.
|
||||
// It logs actions to stdout instead of performing system changes.
|
||||
type MockSystem struct{}
|
||||
|
||||
// Ensure MockSystem implements System
|
||||
var _ System = (*MockSystem)(nil)
|
||||
|
||||
func (m *MockSystem) SetGitIdentity(id git.GitIdentity) error {
|
||||
fmt.Printf("๐ [DRY-RUN] Setting Git Identity to: Name='%s', Email='%s'\n", id.Name, id.Email)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MockSystem) GetCurrentGitIdentity() (git.GitIdentity, error) {
|
||||
fmt.Println("๐ [DRY-RUN] Retrieving current Git Identity (Mocked)")
|
||||
return git.GitIdentity{
|
||||
Name: "Mock User",
|
||||
Email: "mock@example.com",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *MockSystem) GetLocalGitIdentity() (git.GitIdentity, error) {
|
||||
fmt.Println("๐ [DRY-RUN] Checking for local Git Identity (Mocked: None found)")
|
||||
return git.GitIdentity{}, nil
|
||||
}
|
||||
|
||||
func (m *MockSystem) SetTheme(theme string) error {
|
||||
fmt.Printf("๐ [DRY-RUN] Setting KDE Theme to: '%s'\n", theme)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MockSystem) SetWallpaper(path string) error {
|
||||
fmt.Printf("๐ [DRY-RUN] Setting Wallpaper to: '%s'\n", path)
|
||||
return nil
|
||||
}
|
||||
7
internal/system/system.go
Normal file
7
internal/system/system.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package system
|
||||
|
||||
import "github.com/Print-and-Panic/panic-cli/internal/platform"
|
||||
|
||||
// CurrentSystem is the global entry point for system side-effects.
|
||||
// It is initialized in cmd/root.go based on flags (e.g. --dry-run).
|
||||
var CurrentSystem platform.System
|
||||
Reference in New Issue
Block a user