From a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5 Mon Sep 17 00:00:00 2001 From: Nippy Date: Sat, 9 May 2026 13:33:09 +0200 Subject: raveos update --- .../DankMaterialShell/core/cmd/dankinstall/main.go | 219 --------------------- 1 file changed, 219 deletions(-) delete mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/core/cmd/dankinstall/main.go (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/core/cmd/dankinstall/main.go') diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/cmd/dankinstall/main.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/cmd/dankinstall/main.go deleted file mode 100644 index 042506e..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/cmd/dankinstall/main.go +++ /dev/null @@ -1,219 +0,0 @@ -package main - -import ( - "fmt" - "os" - "strings" - - "github.com/AvengeMedia/DankMaterialShell/core/internal/headless" - "github.com/AvengeMedia/DankMaterialShell/core/internal/log" - "github.com/AvengeMedia/DankMaterialShell/core/internal/tui" - tea "github.com/charmbracelet/bubbletea" - "github.com/spf13/cobra" -) - -var Version = "dev" - -// Flag variables bound via pflag -var ( - compositor string - term string - includeDeps []string - excludeDeps []string - replaceConfigs []string - replaceConfigsAll bool - yes bool -) - -var rootCmd = &cobra.Command{ - Use: "dankinstall", - Short: "Install DankMaterialShell and its dependencies", - Long: `dankinstall sets up DankMaterialShell with your chosen compositor and terminal. - -Without flags, it launches an interactive TUI. Providing either --compositor -or --term activates headless (unattended) mode, which requires both flags. - -Headless mode requires cached sudo credentials. Run 'sudo -v' beforehand, or -configure passwordless sudo for your user.`, - Args: cobra.NoArgs, - RunE: runDankinstall, - SilenceErrors: true, - SilenceUsage: true, -} - -func init() { - rootCmd.Flags().StringVarP(&compositor, "compositor", "c", "", "Compositor/WM to install: niri or hyprland (enables headless mode)") - rootCmd.Flags().StringVarP(&term, "term", "t", "", "Terminal emulator to install: ghostty, kitty, or alacritty (enables headless mode)") - rootCmd.Flags().StringSliceVar(&includeDeps, "include-deps", []string{}, "Optional deps to enable (e.g. dms-greeter)") - rootCmd.Flags().StringSliceVar(&excludeDeps, "exclude-deps", []string{}, "Deps to skip during installation") - rootCmd.Flags().StringSliceVar(&replaceConfigs, "replace-configs", []string{}, "Deploy only named configs (e.g. niri,ghostty)") - rootCmd.Flags().BoolVar(&replaceConfigsAll, "replace-configs-all", false, "Deploy and replace all configurations") - rootCmd.Flags().BoolVarP(&yes, "yes", "y", false, "Auto-confirm all prompts") -} - -func main() { - if os.Getuid() == 0 { - fmt.Fprintln(os.Stderr, "Error: dankinstall must not be run as root") - os.Exit(1) - } - - if err := rootCmd.Execute(); err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) - } -} - -func runDankinstall(cmd *cobra.Command, args []string) error { - headlessMode := compositor != "" || term != "" - - if !headlessMode { - // Reject headless-only flags when running in TUI mode. - headlessOnly := []string{ - "include-deps", - "exclude-deps", - "replace-configs", - "replace-configs-all", - "yes", - } - var set []string - for _, name := range headlessOnly { - if cmd.Flags().Changed(name) { - set = append(set, "--"+name) - } - } - if len(set) > 0 { - return fmt.Errorf("flags %s are only valid in headless mode (requires both --compositor and --term)", strings.Join(set, ", ")) - } - } - - if headlessMode { - return runHeadless() - } - return runTUI() -} - -func runHeadless() error { - // Validate required flags - if compositor == "" { - return fmt.Errorf("--compositor is required for headless mode (niri or hyprland)") - } - if term == "" { - return fmt.Errorf("--term is required for headless mode (ghostty, kitty, or alacritty)") - } - - cfg := headless.Config{ - Compositor: compositor, - Terminal: term, - IncludeDeps: includeDeps, - ExcludeDeps: excludeDeps, - ReplaceConfigs: replaceConfigs, - ReplaceConfigsAll: replaceConfigsAll, - Yes: yes, - } - - runner := headless.NewRunner(cfg) - - // Set up file logging - fileLogger, err := log.NewFileLogger() - if err != nil { - fmt.Fprintf(os.Stderr, "Warning: Failed to create log file: %v\n", err) - } - - if fileLogger != nil { - fmt.Printf("Logging to: %s\n", fileLogger.GetLogPath()) - fileLogger.StartListening(runner.GetLogChan()) - defer func() { - if err := fileLogger.Close(); err != nil { - fmt.Fprintf(os.Stderr, "Warning: Failed to close log file: %v\n", err) - } - }() - } else { - // Drain the log channel to prevent blocking sends from deadlocking - // downstream components (distros, config deployer) that write to it. - // Use an explicit stop signal because this code does not own the - // runner log channel and cannot assume it will be closed. - defer drainLogChan(runner.GetLogChan())() - } - - if err := runner.Run(); err != nil { - if fileLogger != nil { - fmt.Fprintf(os.Stderr, "\nFull logs are available at: %s\n", fileLogger.GetLogPath()) - } - return err - } - - if fileLogger != nil { - fmt.Printf("\nFull logs are available at: %s\n", fileLogger.GetLogPath()) - } - return nil -} - -func runTUI() error { - fileLogger, err := log.NewFileLogger() - if err != nil { - fmt.Printf("Warning: Failed to create log file: %v\n", err) - fmt.Println("Continuing without file logging...") - } - - logFilePath := "" - if fileLogger != nil { - logFilePath = fileLogger.GetLogPath() - fmt.Printf("Logging to: %s\n", logFilePath) - defer func() { - if err := fileLogger.Close(); err != nil { - fmt.Printf("Warning: Failed to close log file: %v\n", err) - } - }() - } - - model := tui.NewModel(Version, logFilePath) - - if fileLogger != nil { - fileLogger.StartListening(model.GetLogChan()) - } else { - // Drain the log channel to prevent blocking sends from deadlocking - // downstream components (distros, config deployer) that write to it. - // Use an explicit stop signal because this code does not own the - // model log channel and cannot assume it will be closed. - defer drainLogChan(model.GetLogChan())() - } - - p := tea.NewProgram(model, tea.WithAltScreen()) - if _, err := p.Run(); err != nil { - if logFilePath != "" { - fmt.Fprintf(os.Stderr, "\nFull logs are available at: %s\n", logFilePath) - } - return fmt.Errorf("error running program: %w", err) - } - - if logFilePath != "" { - fmt.Printf("\nFull logs are available at: %s\n", logFilePath) - } - return nil -} - -// drainLogChan starts a goroutine that discards all messages from logCh, -// preventing blocking sends from deadlocking downstream components. It returns -// a cleanup function that signals the goroutine to stop and waits for it to -// exit. Callers should defer the returned function. -func drainLogChan(logCh <-chan string) func() { - drainStop := make(chan struct{}) - drainDone := make(chan struct{}) - go func() { - defer close(drainDone) - for { - select { - case <-drainStop: - return - case _, ok := <-logCh: - if !ok { - return - } - } - } - }() - return func() { - close(drainStop) - <-drainDone - } -} -- cgit v1.3