mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-05 05:12:05 -04:00
core: add slices, paths, exec utils
This commit is contained in:
@@ -211,45 +211,13 @@ func runBrightnessSet(cmd *cobra.Command, args []string) {
|
||||
exponential, _ := cmd.Flags().GetBool("exponential")
|
||||
exponent, _ := cmd.Flags().GetFloat64("exponent")
|
||||
|
||||
// For backlight/leds devices, try logind backend first (requires D-Bus connection)
|
||||
parts := strings.SplitN(deviceID, ":", 2)
|
||||
if len(parts) == 2 && (parts[0] == "backlight" || parts[0] == "leds") {
|
||||
subsystem := parts[0]
|
||||
name := parts[1]
|
||||
|
||||
// Initialize backends needed for logind approach
|
||||
sysfs, err := brightness.NewSysfsBackend()
|
||||
if err != nil {
|
||||
log.Debugf("NewSysfsBackend failed: %v", err)
|
||||
} else {
|
||||
logind, err := brightness.NewLogindBackend()
|
||||
if err != nil {
|
||||
log.Debugf("NewLogindBackend failed: %v", err)
|
||||
} else {
|
||||
defer logind.Close()
|
||||
|
||||
// Get device info to convert percent to value
|
||||
dev, err := sysfs.GetDevice(deviceID)
|
||||
if err == nil {
|
||||
// Calculate hardware value using the same logic as Manager.setViaSysfsWithLogind
|
||||
value := sysfs.PercentToValueWithExponent(percent, dev, exponential, exponent)
|
||||
|
||||
// Call logind with hardware value
|
||||
if err := logind.SetBrightness(subsystem, name, uint32(value)); err == nil {
|
||||
log.Debugf("set %s to %d%% (%d) via logind", deviceID, percent, value)
|
||||
fmt.Printf("Set %s to %d%%\n", deviceID, percent)
|
||||
return
|
||||
} else {
|
||||
log.Debugf("logind.SetBrightness failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
log.Debugf("sysfs.GetDeviceByID failed: %v", err)
|
||||
}
|
||||
}
|
||||
if ok := tryLogindBrightness(parts[0], parts[1], deviceID, percent, exponential, exponent); ok {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to direct sysfs (requires write permissions)
|
||||
sysfs, err := brightness.NewSysfsBackend()
|
||||
if err == nil {
|
||||
if err := sysfs.SetBrightnessWithExponent(deviceID, percent, exponential, exponent); err == nil {
|
||||
@@ -280,6 +248,37 @@ func runBrightnessSet(cmd *cobra.Command, args []string) {
|
||||
log.Fatalf("Failed to set brightness for device: %s", deviceID)
|
||||
}
|
||||
|
||||
func tryLogindBrightness(subsystem, name, deviceID string, percent int, exponential bool, exponent float64) bool {
|
||||
sysfs, err := brightness.NewSysfsBackend()
|
||||
if err != nil {
|
||||
log.Debugf("NewSysfsBackend failed: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
logind, err := brightness.NewLogindBackend()
|
||||
if err != nil {
|
||||
log.Debugf("NewLogindBackend failed: %v", err)
|
||||
return false
|
||||
}
|
||||
defer logind.Close()
|
||||
|
||||
dev, err := sysfs.GetDevice(deviceID)
|
||||
if err != nil {
|
||||
log.Debugf("sysfs.GetDeviceByID failed: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
value := sysfs.PercentToValueWithExponent(percent, dev, exponential, exponent)
|
||||
if err := logind.SetBrightness(subsystem, name, uint32(value)); err != nil {
|
||||
log.Debugf("logind.SetBrightness failed: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Debugf("set %s to %d%% (%d) via logind", deviceID, percent, value)
|
||||
fmt.Printf("Set %s to %d%%\n", deviceID, percent)
|
||||
return true
|
||||
}
|
||||
|
||||
func getBrightnessDevices(includeDDC bool) []string {
|
||||
allDevices := getAllBrightnessDevices(includeDDC)
|
||||
|
||||
|
||||
@@ -152,6 +152,24 @@ var pluginsUninstallCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var pluginsUpdateCmd = &cobra.Command{
|
||||
Use: "update <plugin-id>",
|
||||
Short: "Update a plugin by ID",
|
||||
Long: "Update an installed DMS plugin using its ID (e.g., 'myPlugin'). Plugin names are also supported.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(args) != 0 {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
return getInstalledPluginIDs(), cobra.ShellCompDirectiveNoFileComp
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := updatePluginCLI(args[0]); err != nil {
|
||||
log.Fatalf("Error updating plugin: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func runVersion(cmd *cobra.Command, args []string) {
|
||||
printASCII()
|
||||
fmt.Printf("%s\n", formatVersion(Version))
|
||||
@@ -408,49 +426,70 @@ func uninstallPluginCLI(idOrName string) error {
|
||||
return fmt.Errorf("failed to create registry: %w", err)
|
||||
}
|
||||
|
||||
pluginList, err := registry.List()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list plugins: %w", err)
|
||||
}
|
||||
pluginList, _ := registry.List()
|
||||
plugin := plugins.FindByIDOrName(idOrName, pluginList)
|
||||
|
||||
// First, try to find by ID (preferred method)
|
||||
var plugin *plugins.Plugin
|
||||
for _, p := range pluginList {
|
||||
if p.ID == idOrName {
|
||||
plugin = &p
|
||||
break
|
||||
if plugin != nil {
|
||||
installed, err := manager.IsInstalled(*plugin)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check install status: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to name for backward compatibility
|
||||
if plugin == nil {
|
||||
for _, p := range pluginList {
|
||||
if p.Name == idOrName {
|
||||
plugin = &p
|
||||
break
|
||||
}
|
||||
if !installed {
|
||||
return fmt.Errorf("plugin not installed: %s", plugin.Name)
|
||||
}
|
||||
|
||||
fmt.Printf("Uninstalling plugin: %s (ID: %s)\n", plugin.Name, plugin.ID)
|
||||
if err := manager.Uninstall(*plugin); err != nil {
|
||||
return fmt.Errorf("failed to uninstall plugin: %w", err)
|
||||
}
|
||||
fmt.Printf("Plugin uninstalled successfully: %s\n", plugin.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
if plugin == nil {
|
||||
return fmt.Errorf("plugin not found: %s", idOrName)
|
||||
fmt.Printf("Uninstalling plugin: %s\n", idOrName)
|
||||
if err := manager.UninstallByIDOrName(idOrName); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Plugin uninstalled successfully: %s\n", idOrName)
|
||||
return nil
|
||||
}
|
||||
|
||||
installed, err := manager.IsInstalled(*plugin)
|
||||
func updatePluginCLI(idOrName string) error {
|
||||
manager, err := plugins.NewManager()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check install status: %w", err)
|
||||
return fmt.Errorf("failed to create manager: %w", err)
|
||||
}
|
||||
|
||||
if !installed {
|
||||
return fmt.Errorf("plugin not installed: %s", plugin.Name)
|
||||
registry, err := plugins.NewRegistry()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create registry: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Uninstalling plugin: %s (ID: %s)\n", plugin.Name, plugin.ID)
|
||||
if err := manager.Uninstall(*plugin); err != nil {
|
||||
return fmt.Errorf("failed to uninstall plugin: %w", err)
|
||||
pluginList, _ := registry.List()
|
||||
plugin := plugins.FindByIDOrName(idOrName, pluginList)
|
||||
|
||||
if plugin != nil {
|
||||
installed, err := manager.IsInstalled(*plugin)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check install status: %w", err)
|
||||
}
|
||||
if !installed {
|
||||
return fmt.Errorf("plugin not installed: %s", plugin.Name)
|
||||
}
|
||||
|
||||
fmt.Printf("Updating plugin: %s (ID: %s)\n", plugin.Name, plugin.ID)
|
||||
if err := manager.Update(*plugin); err != nil {
|
||||
return fmt.Errorf("failed to update plugin: %w", err)
|
||||
}
|
||||
fmt.Printf("Plugin updated successfully: %s\n", plugin.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("Plugin uninstalled successfully: %s\n", plugin.Name)
|
||||
fmt.Printf("Updating plugin: %s\n", idOrName)
|
||||
if err := manager.UpdateByIDOrName(idOrName); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Plugin updated successfully: %s\n", idOrName)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/distros"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/errdefs"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/log"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/utils"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/version"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -121,10 +122,10 @@ func updateArchLinux() error {
|
||||
var helper string
|
||||
var updateCmd *exec.Cmd
|
||||
|
||||
if commandExists("yay") {
|
||||
if utils.CommandExists("yay") {
|
||||
helper = "yay"
|
||||
updateCmd = exec.Command("yay", "-S", packageName)
|
||||
} else if commandExists("paru") {
|
||||
} else if utils.CommandExists("paru") {
|
||||
helper = "paru"
|
||||
updateCmd = exec.Command("paru", "-S", packageName)
|
||||
} else {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/greeter"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/log"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
@@ -448,7 +449,7 @@ func enableGreeter() error {
|
||||
fmt.Println("Detecting installed compositors...")
|
||||
compositors := greeter.DetectCompositors()
|
||||
|
||||
if commandExists("sway") {
|
||||
if utils.CommandExists("sway") {
|
||||
compositors = append(compositors, "sway")
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ func init() {
|
||||
updateCmd.AddCommand(updateCheckCmd)
|
||||
|
||||
// Add subcommands to plugins
|
||||
pluginsCmd.AddCommand(pluginsBrowseCmd, pluginsListCmd, pluginsInstallCmd, pluginsUninstallCmd)
|
||||
pluginsCmd.AddCommand(pluginsBrowseCmd, pluginsListCmd, pluginsInstallCmd, pluginsUninstallCmd, pluginsUpdateCmd)
|
||||
|
||||
// Add common commands to root
|
||||
rootCmd.AddCommand(getCommonCommands()...)
|
||||
|
||||
@@ -21,7 +21,7 @@ func init() {
|
||||
greeterCmd.AddCommand(greeterSyncCmd, greeterEnableCmd, greeterStatusCmd)
|
||||
|
||||
// Add subcommands to plugins
|
||||
pluginsCmd.AddCommand(pluginsBrowseCmd, pluginsListCmd, pluginsInstallCmd, pluginsUninstallCmd)
|
||||
pluginsCmd.AddCommand(pluginsBrowseCmd, pluginsListCmd, pluginsInstallCmd, pluginsUninstallCmd, pluginsUpdateCmd)
|
||||
|
||||
// Add common commands to root
|
||||
rootCmd.AddCommand(getCommonCommands()...)
|
||||
|
||||
@@ -104,7 +104,6 @@ func getAllDMSPIDs() []int {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if the child process is still alive
|
||||
proc, err := os.FindProcess(childPID)
|
||||
if err != nil {
|
||||
os.Remove(pidFile)
|
||||
@@ -112,18 +111,15 @@ func getAllDMSPIDs() []int {
|
||||
}
|
||||
|
||||
if err := proc.Signal(syscall.Signal(0)); err != nil {
|
||||
// Process is dead, remove stale PID file
|
||||
os.Remove(pidFile)
|
||||
continue
|
||||
}
|
||||
|
||||
pids = append(pids, childPID)
|
||||
|
||||
// Also get the parent PID from the filename
|
||||
parentPIDStr := strings.TrimPrefix(entry.Name(), "danklinux-")
|
||||
parentPIDStr = strings.TrimSuffix(parentPIDStr, ".pid")
|
||||
if parentPID, err := strconv.Atoi(parentPIDStr); err == nil {
|
||||
// Check if parent is still alive
|
||||
if parentProc, err := os.FindProcess(parentPID); err == nil {
|
||||
if err := parentProc.Signal(syscall.Signal(0)); err == nil {
|
||||
pids = append(pids, parentPID)
|
||||
@@ -225,7 +221,6 @@ func runShellInteractive(session bool) {
|
||||
return
|
||||
}
|
||||
|
||||
// All other signals: clean shutdown
|
||||
log.Infof("\nReceived signal %v, shutting down...", sig)
|
||||
cancel()
|
||||
cmd.Process.Signal(syscall.SIGTERM)
|
||||
@@ -282,7 +277,6 @@ func restartShell() {
|
||||
}
|
||||
|
||||
func killShell() {
|
||||
// Get all tracked DMS PIDs from PID files
|
||||
pids := getAllDMSPIDs()
|
||||
|
||||
if len(pids) == 0 {
|
||||
@@ -293,14 +287,12 @@ func killShell() {
|
||||
currentPid := os.Getpid()
|
||||
uniquePids := make(map[int]bool)
|
||||
|
||||
// Deduplicate and filter out current process
|
||||
for _, pid := range pids {
|
||||
if pid != currentPid {
|
||||
uniquePids[pid] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Kill all tracked processes
|
||||
for pid := range uniquePids {
|
||||
proc, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
@@ -308,7 +300,6 @@ func killShell() {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if process is still alive before killing
|
||||
if err := proc.Signal(syscall.Signal(0)); err != nil {
|
||||
continue
|
||||
}
|
||||
@@ -320,7 +311,6 @@ func killShell() {
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up any remaining PID files
|
||||
dir := getRuntimeDir()
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
@@ -337,7 +327,6 @@ func killShell() {
|
||||
|
||||
func runShellDaemon(session bool) {
|
||||
isSessionManaged = session
|
||||
// Check if this is the daemon child process by looking for the hidden flag
|
||||
isDaemonChild := false
|
||||
for _, arg := range os.Args {
|
||||
if arg == "--daemon-child" {
|
||||
|
||||
@@ -6,12 +6,6 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func commandExists(cmd string) bool {
|
||||
_, err := exec.LookPath(cmd)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// findCommandPath returns the absolute path to a command in PATH
|
||||
func findCommandPath(cmd string) (string, error) {
|
||||
path, err := exec.LookPath(cmd)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user