feat: add stop command to terminate the clipboard watcher daemon
This commit is contained in:
parent
2e77ee2333
commit
72705afc16
@ -1,6 +1,8 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -14,14 +16,26 @@ func NewStatusCmd() *cobra.Command {
|
|||||||
Use: "status",
|
Use: "status",
|
||||||
Short: "Check if the clipboard watcher daemon is running",
|
Short: "Check if the clipboard watcher daemon is running",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
// Check for the process by name (simple approach)
|
out, err := exec.Command("ps", "-C", "kcm", "-o", "pid=").Output()
|
||||||
out, err := exec.Command("ps", "-C", "kcm").Output()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg("Failed to check kcm daemon status")
|
log.Fatal().Err(err).Msg("Failed to check kcm daemon status")
|
||||||
}
|
}
|
||||||
lines := strings.Split(string(out), "\n")
|
pids := strings.Fields(string(out))
|
||||||
if len(lines) > 1 {
|
currentPID := os.Getpid()
|
||||||
log.Info().Msg("kcm daemon is running.")
|
filteredPIDs := make([]string, 0, len(pids))
|
||||||
|
for _, pidStr := range pids {
|
||||||
|
if pidStr == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if pidStr == fmt.Sprintf("%d", currentPID) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filteredPIDs = append(filteredPIDs, pidStr)
|
||||||
|
}
|
||||||
|
if len(filteredPIDs) > 0 {
|
||||||
|
log.Info().
|
||||||
|
Strs("pids", filteredPIDs).
|
||||||
|
Msg("kcm daemon is running.")
|
||||||
} else {
|
} else {
|
||||||
log.Warn().Msg("kcm daemon is not running, start a new one using `kcm watch`.")
|
log.Warn().Msg("kcm daemon is not running, start a new one using `kcm watch`.")
|
||||||
}
|
}
|
||||||
|
54
src/commands/cmd_stop.go
Normal file
54
src/commands/cmd_stop.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewStopCmd creates a new stop command to kill the kcm daemon.
|
||||||
|
func NewStopCmd() *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "stop",
|
||||||
|
Short: "Stop the clipboard watcher daemon",
|
||||||
|
Aliases: []string{"--stop", "kill"},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
out, err := exec.Command("ps", "-C", "kcm", "-o", "pid=").Output()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("Failed to check for running kcm processes")
|
||||||
|
}
|
||||||
|
pids := strings.Fields(string(out))
|
||||||
|
if len(pids) == 0 {
|
||||||
|
log.Info().Msg("No running kcm daemon found.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
killed := 0
|
||||||
|
for _, pidStr := range pids {
|
||||||
|
pid, err := strconv.Atoi(pidStr)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if pid == os.Getpid() {
|
||||||
|
continue // Don't kill self
|
||||||
|
}
|
||||||
|
proc, err := os.FindProcess(pid)
|
||||||
|
if err == nil {
|
||||||
|
err = proc.Kill()
|
||||||
|
if err == nil {
|
||||||
|
log.Info().Msgf("Killed kcm daemon with PID %d", pid)
|
||||||
|
killed++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if killed == 0 {
|
||||||
|
log.Warn().Msg("No kcm daemons were killed.")
|
||||||
|
} else {
|
||||||
|
log.Info().Msgf("Stopped %d kcm daemon(s).", killed)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,9 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
@ -20,9 +23,22 @@ func NewWatchCmd(history *models.History) *cobra.Command {
|
|||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
noDaemon, _ := cmd.Flags().GetBool("no-daemon")
|
noDaemon, _ := cmd.Flags().GetBool("no-daemon")
|
||||||
if !noDaemon {
|
if !noDaemon {
|
||||||
cfg, _ := config.LoadConfig()
|
// Safety net: check if kcm daemon is already running (ignore self)
|
||||||
|
out, err := exec.Command("ps", "-C", "kcm", "-o", "pid=").Output()
|
||||||
|
if err == nil {
|
||||||
|
pids := strings.Fields(string(out))
|
||||||
|
myPid := os.Getpid()
|
||||||
|
for _, pidStr := range pids {
|
||||||
|
pid, err := strconv.Atoi(pidStr)
|
||||||
|
if err == nil && pid != myPid {
|
||||||
|
log.Warn().Msg("kcm daemon is already running. Exiting to avoid duplicate daemons.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set log file path since we are daemonizing
|
// Set log file path since we are daemonizing
|
||||||
|
cfg, _ := config.LoadConfig()
|
||||||
if cfg.Logging.Path != "" {
|
if cfg.Logging.Path != "" {
|
||||||
file, err := os.OpenFile(cfg.Logging.Path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
file, err := os.OpenFile(cfg.Logging.Path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -46,13 +62,13 @@ func NewWatchCmd(history *models.History) *cobra.Command {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg("Failed to daemonize")
|
log.Fatal().Err(err).Msg("Failed to daemonize")
|
||||||
}
|
}
|
||||||
log.Info().Msgf("Daemon started with PID %d", proc.Pid)
|
log.Info().
|
||||||
|
Str("logging_path", cfg.Logging.Path).
|
||||||
|
Msgf("Daemon started with PID %d", proc.Pid)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info().Msg("Starting clipboard watcher (golang.design/x/clipboard)...")
|
|
||||||
|
|
||||||
if err := clipboard.Init(); err != nil {
|
if err := clipboard.Init(); err != nil {
|
||||||
log.Fatal().Err(err).Msg("Failed to initialize clipboard")
|
log.Fatal().Err(err).Msg("Failed to initialize clipboard")
|
||||||
}
|
}
|
||||||
@ -63,7 +79,7 @@ func NewWatchCmd(history *models.History) *cobra.Command {
|
|||||||
)
|
)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(250 * time.Millisecond)
|
||||||
|
|
||||||
textOut := clipboard.Read(clipboard.FmtText)
|
textOut := clipboard.Read(clipboard.FmtText)
|
||||||
imgOut := clipboard.Read(clipboard.FmtImage)
|
imgOut := clipboard.Read(clipboard.FmtImage)
|
||||||
@ -79,7 +95,7 @@ func NewWatchCmd(history *models.History) *cobra.Command {
|
|||||||
}
|
}
|
||||||
history.Add(item)
|
history.Add(item)
|
||||||
lastText = text
|
lastText = text
|
||||||
log.Info().Str("content", text).Msg("Text clipboard item added to history")
|
log.Info().Str("content", text).Msg("Text item added ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +108,7 @@ func NewWatchCmd(history *models.History) *cobra.Command {
|
|||||||
}
|
}
|
||||||
history.Add(item)
|
history.Add(item)
|
||||||
lastImage = imgOut
|
lastImage = imgOut
|
||||||
log.Info().Msg("Image clipboard item added to history")
|
log.Info().Msg("Image item added")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -37,11 +37,15 @@ func LoadConfig() (Config, string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
defer file.Close()
|
|
||||||
d := yaml.NewDecoder(file)
|
d := yaml.NewDecoder(file)
|
||||||
if err := d.Decode(&cfg); err == nil {
|
if err := d.Decode(&cfg); err == nil {
|
||||||
|
file.Close()
|
||||||
|
if cfg.Logging.Path == "" {
|
||||||
|
cfg.Logging.Path = logFilePath()
|
||||||
|
}
|
||||||
return cfg, path
|
return cfg, path
|
||||||
}
|
}
|
||||||
|
file.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.Logging.Format = "console"
|
cfg.Logging.Format = "console"
|
||||||
|
@ -56,6 +56,7 @@ func main() {
|
|||||||
commands.NewSearchCmd(history),
|
commands.NewSearchCmd(history),
|
||||||
commands.NewStatusCmd(),
|
commands.NewStatusCmd(),
|
||||||
commands.NewVersionCmd(),
|
commands.NewVersionCmd(),
|
||||||
|
commands.NewStopCmd(), // Add the stop command
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := rootCmd.Execute(); err != nil {
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user