1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-08 06:28:27 -04:00

dankinstall: add danksearch and dankcalendar as optional deps

This commit is contained in:
bbedward
2026-07-08 10:01:56 -04:00
parent bb9e69e0c1
commit e94af2a7aa
15 changed files with 268 additions and 42 deletions
+38 -10
View File
@@ -41,6 +41,8 @@ type Config struct {
ReplaceConfigs []string // specific configs to deploy (e.g. "niri", "ghostty")
ReplaceConfigsAll bool // deploy/replace all configurations
Yes bool
DankSearch bool // install danksearch and enable its user service
DankCalendar bool // install dankcalendar
}
// Runner orchestrates unattended (headless) installation.
@@ -214,6 +216,11 @@ func (r *Runner) Run() error {
return fmt.Errorf("package installation failed: %w", err)
}
useSystemd := true
if distroConfig, exists := distros.Registry[osInfo.Distribution.ID]; exists && distroConfig.Family == distros.FamilyVoid {
useSystemd = false
}
// 9. Greeter setup (if dms-greeter was included)
if !disabledItems["dms-greeter"] && r.depExists(dependencies, "dms-greeter") {
compositorName := "niri"
@@ -231,15 +238,24 @@ func (r *Runner) Run() error {
}
}
// 9b. danksearch service setup (if danksearch was included)
if useSystemd && !disabledItems["danksearch"] && r.depExists(dependencies, "danksearch") {
fmt.Fprintln(os.Stdout, "Enabling danksearch service...")
logFunc := func(line string) {
r.log(line)
fmt.Fprintf(os.Stdout, " danksearch: %s\n", line)
}
if err := distros.SetupDsearchService(context.Background(), logFunc); err != nil {
// Non-fatal, matching greeter behavior
fmt.Fprintf(os.Stderr, "Warning: danksearch service setup issue (non-fatal): %v\n", err)
}
}
// 10. Deploy configurations
fmt.Fprintln(os.Stdout, "Deploying configurations...")
r.log("Starting configuration deployment")
deployer := config.NewConfigDeployer(r.logChan)
useSystemd := true
if distroConfig, exists := distros.Registry[osInfo.Distribution.ID]; exists && distroConfig.Family == distros.FamilyVoid {
useSystemd = false
}
results, err := deployer.DeployConfigurationsSelectiveWithReinstallsAndSystemd(
context.Background(),
wm,
@@ -272,19 +288,31 @@ func (r *Runner) Run() error {
}
// buildDisabledItems computes the set of dependencies that should be skipped
// during installation, applying the --include-deps and --exclude-deps filters.
// dms-greeter is disabled by default (opt-in), matching TUI behavior.
// during installation. Optional components are opt-in (disabled by default),
// then re-enabled by the dedicated flags and --include-deps.
func (r *Runner) buildDisabledItems(dependencies []deps.Dependency) (map[string]bool, error) {
disabledItems := make(map[string]bool)
// dms-greeter is opt-in (disabled by default), matching TUI behavior
for i := range dependencies {
if dependencies[i].Name == "dms-greeter" {
disabledItems["dms-greeter"] = true
break
if !dependencies[i].Required {
disabledItems[dependencies[i].Name] = true
}
}
// Dedicated flags resolve before include/exclude
if r.cfg.DankSearch {
if !r.depExists(dependencies, "danksearch") {
return nil, fmt.Errorf("--danksearch: not available on this distribution")
}
delete(disabledItems, "danksearch")
}
if r.cfg.DankCalendar {
if !r.depExists(dependencies, "dankcalendar") {
return nil, fmt.Errorf("--dankcalendar: not available on this distribution")
}
delete(disabledItems, "dankcalendar")
}
// Process --include-deps (enable items that are disabled by default)
for _, name := range r.cfg.IncludeDeps {
name = strings.TrimSpace(name)
+51 -17
View File
@@ -342,17 +342,21 @@ func TestConfigReplaceConfigsStoredCorrectly(t *testing.T) {
func TestBuildDisabledItems(t *testing.T) {
dependencies := []deps.Dependency{
{Name: "niri", Status: deps.StatusInstalled},
{Name: "ghostty", Status: deps.StatusMissing},
{Name: "dms (DankMaterialShell)", Status: deps.StatusInstalled},
{Name: "niri", Status: deps.StatusInstalled, Required: true},
{Name: "ghostty", Status: deps.StatusMissing, Required: true},
{Name: "dms (DankMaterialShell)", Status: deps.StatusInstalled, Required: true},
{Name: "dms-greeter", Status: deps.StatusMissing},
{Name: "waybar", Status: deps.StatusMissing},
{Name: "danksearch", Status: deps.StatusMissing},
{Name: "dankcalendar", Status: deps.StatusMissing},
{Name: "waybar", Status: deps.StatusMissing, Required: true},
}
tests := []struct {
name string
includeDeps []string
excludeDeps []string
dankSearch bool
dankCalendar bool
deps []deps.Dependency // nil means use the shared fixture
wantErr bool
errContains string // substring expected in error message
@@ -360,19 +364,20 @@ func TestBuildDisabledItems(t *testing.T) {
wantEnabled []string // dep names that should NOT be in disabledItems (extra check)
}{
{
name: "no flags set, dms-greeter disabled by default",
wantDisabled: []string{"dms-greeter"},
name: "no flags set, optional deps disabled by default",
wantDisabled: []string{"dms-greeter", "danksearch", "dankcalendar"},
wantEnabled: []string{"niri", "ghostty", "waybar"},
},
{
name: "include dms-greeter enables it",
includeDeps: []string{"dms-greeter"},
wantEnabled: []string{"dms-greeter"},
name: "include dms-greeter enables it",
includeDeps: []string{"dms-greeter"},
wantEnabled: []string{"dms-greeter"},
wantDisabled: []string{"danksearch", "dankcalendar"},
},
{
name: "exclude a regular dep",
excludeDeps: []string{"waybar"},
wantDisabled: []string{"dms-greeter", "waybar"},
wantDisabled: []string{"dms-greeter", "danksearch", "dankcalendar", "waybar"},
},
{
name: "include unknown dep returns error",
@@ -399,24 +404,53 @@ func TestBuildDisabledItems(t *testing.T) {
wantDisabled: []string{"dms-greeter"},
},
{
name: "whitespace entries are skipped",
includeDeps: []string{" ", "dms-greeter"},
wantEnabled: []string{"dms-greeter"},
name: "whitespace entries are skipped",
includeDeps: []string{" ", "dms-greeter"},
wantEnabled: []string{"dms-greeter"},
wantDisabled: []string{"danksearch", "dankcalendar"},
},
{
name: "no dms-greeter in deps, nothing disabled by default",
name: "no optional deps present, nothing disabled by default",
deps: []deps.Dependency{
{Name: "niri", Status: deps.StatusInstalled},
{Name: "niri", Status: deps.StatusInstalled, Required: true},
},
wantEnabled: []string{"niri"},
},
{
name: "danksearch flag enables it",
dankSearch: true,
wantEnabled: []string{"danksearch"},
wantDisabled: []string{"dms-greeter", "dankcalendar"},
},
{
name: "dankcalendar flag enables it",
dankCalendar: true,
wantEnabled: []string{"dankcalendar"},
wantDisabled: []string{"dms-greeter", "danksearch"},
},
{
name: "danksearch flag when unavailable errors",
dankSearch: true,
deps: []deps.Dependency{{Name: "niri", Status: deps.StatusInstalled, Required: true}},
wantErr: true,
errContains: "--danksearch",
},
{
name: "dankcalendar flag when unavailable errors",
dankCalendar: true,
deps: []deps.Dependency{{Name: "niri", Status: deps.StatusInstalled, Required: true}},
wantErr: true,
errContains: "--dankcalendar",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := NewRunner(Config{
IncludeDeps: tt.includeDeps,
ExcludeDeps: tt.excludeDeps,
IncludeDeps: tt.includeDeps,
ExcludeDeps: tt.excludeDeps,
DankSearch: tt.dankSearch,
DankCalendar: tt.dankCalendar,
})
d := tt.deps
if d == nil {