···66 "os"
77 "path/filepath"
88 "strings"
99+1010+ "github.com/alyraffauf/goxdgdesktop/desktopfile"
911)
10121113func (a App) Install(appimage string) (appName string, err error) {
···3840 // No desktop file inside the AppImage: synthesize a terminal launcher so
3941 // CLI apps still get a menu entry and are tracked by managedApps.
4042 if desktop == nil {
4141- desktop = parseDesktopFile([]byte(fmt.Sprintf(
4343+ desktop = desktopfile.Parse([]byte(fmt.Sprintf(
4244 "[Desktop Entry]\nType=Application\nName=%s\nTerminal=true\n",
4345 appNameFromPath(appimage),
4446 )))
···9799// deriveAppName picks the canonical install name, matching GearLever so the
98100// two tools land at the same path: the desktop entry's Name field (e.g.
99101// "ES-DE" -> "esde"), then the desktop-file id, then the source filename.
100100-func deriveAppName(desktop *desktopFile, desktopName string, appimagePath string) string {
102102+func deriveAppName(desktop *desktopfile.File, desktopName string, appimagePath string) string {
101103 if desktop != nil {
102102- if name, ok := desktop.get("Name", desktopEntrySection); ok && name != "" {
104104+ if name, ok := desktop.Get(desktopEntrySection, "Name"); ok && name != "" {
103105 return sanitizeAppName(name)
104106 }
105107 }
+5-3
internal/appherder/list.go
···44 "os"
55 "path/filepath"
66 "sort"
77+88+ "github.com/alyraffauf/goxdgdesktop/desktopfile"
79)
810911// AppInfo is one managed app's display metadata, as returned by List.
···3739func gatherAppInfo(appsDir, appimagesDir, appid string) AppInfo {
3840 info := AppInfo{AppID: appid, Source: "none"}
39414040- if desktop, err := readDesktopFile(filepath.Join(appsDir, appid+".desktop")); err == nil {
4141- if name, ok := desktop.get("Name", desktopEntrySection); ok && name != "" {
4242+ if desktop, err := desktopfile.Read(filepath.Join(appsDir, appid+".desktop")); err == nil {
4343+ if name, ok := desktop.Get(desktopEntrySection, "Name"); ok && name != "" {
4244 info.Name = name
4345 }
4444- if version, ok := desktop.get("X-AppImage-Version", desktopEntrySection); ok {
4646+ if version, ok := desktop.Get(desktopEntrySection, "X-AppImage-Version"); ok {
4547 info.Version = version
4648 }
4749 }
+7-5
internal/appherder/sync.go
···77 "path/filepath"
88 "sort"
99 "strings"
1010+1111+ "github.com/alyraffauf/goxdgdesktop/desktopfile"
1012)
11131214// installConcurrency caps parallel installs: enough to overlap metadata I/O
···159161 prefix := appimagesDir + string(filepath.Separator)
160162 var orphans []string
161163 for _, path := range matches {
162162- desktop, err := readDesktopFile(path)
164164+ desktop, err := desktopfile.Read(path)
163165 if err != nil {
164166 return nil, fmt.Errorf("read desktop file %s: %w", path, err)
165167 }
166166- if value, ok := desktop.get(desktopOwnerKey, desktopEntrySection); ok && value == "true" {
168168+ if value, ok := desktop.Get(desktopEntrySection, desktopOwnerKey); ok && value == "true" {
167169 continue
168170 }
169171 target := desktopTarget(desktop)
···182184183185// desktopTarget returns the executable path a launcher points at, preferring
184186// TryExec.
185185-func desktopTarget(desktop *desktopFile) string {
186186- if tryExec, ok := desktop.get("TryExec", desktopEntrySection); ok && tryExec != "" {
187187+func desktopTarget(desktop *desktopfile.File) string {
188188+ if tryExec, ok := desktop.Get(desktopEntrySection, "TryExec"); ok && tryExec != "" {
187189 return tryExec
188190 }
189189- if exec, ok := desktop.get("Exec", desktopEntrySection); ok {
191191+ if exec, ok := desktop.Get(desktopEntrySection, "Exec"); ok {
190192 return execPath(exec)
191193 }
192194 return ""