diff --git a/main.go b/main.go index cf7a46c..15243b6 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,4 @@ +// package main is the package for the gendesk utility package main import ( @@ -13,6 +14,20 @@ import ( "github.com/xyproto/textoutput" ) +// WMStarter contains the information needed to generate +// a .desktop file for a Window Manager +type WMStarter struct { + Name, Exec string +} + +// AppStarter contains the information needed to generate +// a .desktop file for an application +type AppStarter struct { + Name, GenericName, Comment, Exec, Icon, Path string + CategoryList, MimeTypesList string + UseTerminal, StartupNotify bool +} + const ( versionString = "Desktop File Generator 1.0.10" @@ -39,20 +54,6 @@ const ( defaultPKGBUILD = "../PKGBUILD" ) -// WMStarter contains the information needed to generate -// a .desktop file for a Window Manager -type WMStarter struct { - Name, Exec string -} - -// AppStarter contains the information needed to generate -// a .desktop file for an application -type AppStarter struct { - Name, GenericName, Comment, Exec, Icon, Path string - UseTerminal, StartupNotify bool - CategoryList, MimeTypesList string -} - var ( // Template for a .desktop file for starting a Window Manager wmTemplate, _ = template.New("WMStarter").Parse("[Desktop Entry]\nType=XSession\nExec={{.Exec}}\nTryExec={{.Exec}}\nName={{.Name}}\n") @@ -62,34 +63,47 @@ var ( ) // Generate the contents for the .desktop file (for executing a window manager) -func createWindowManagerDesktopContents(name, execCommand string) *bytes.Buffer { - var ( - buf bytes.Buffer - wm = WMStarter{name, execCommand} - ) - // Inserting strings into the template should always work, panic if not - if err := wmTemplate.Execute(&buf, wm); err != nil { - panic(err) +func createWindowManagerDesktopContents(name, execCommand string) (*bytes.Buffer, error) { + var buf bytes.Buffer + // Insert strings into the template by using the WMStarter struct + if err := wmTemplate.Execute(&buf, WMStarter{name, execCommand}); err != nil { + return nil, err } - return &buf + return &buf, nil } // Generate the contents for the .desktop file (for executing a desktop application) -func createDesktopContents(name, genericName, comment, execCommand, icon, path string, useTerminal, startupNotify bool, categories, mimeTypes []string) *bytes.Buffer { +func createDesktopContents(name, genericName, comment, execCommand, icon, path string, useTerminal, startupNotify bool, categories, mimeTypes []string) (*bytes.Buffer, error) { var ( + appStarter = AppStarter{ + Name: name, + GenericName: genericName, + Comment: comment, + Exec: execCommand, + Icon: icon, + Path: path, + CategoryList: strings.Join(categories, ";"), + MimeTypesList: strings.Join(mimeTypes, ";"), + UseTerminal: useTerminal, + StartupNotify: startupNotify, + } buf bytes.Buffer - app = AppStarter{name, genericName, comment, execCommand, icon, path, useTerminal, startupNotify, strings.Join(categories, ";"), strings.Join(mimeTypes, ";")} ) - // Inserting strings into the template should always work, panic if not - if err := appTemplate.Execute(&buf, app); err != nil { - panic(err) + // Insert strings into the template by using an AppStarter variable + if err := appTemplate.Execute(&buf, appStarter); err != nil { + return nil, err } - return &buf + return &buf, nil } // Write the .desktop file as generated by createWindowManagerDesktopContents func writeWindowManagerDesktopFile(pkgname, name, execCommand, custom string, force bool, o *textoutput.TextOutput) { - buf := createWindowManagerDesktopContents(name, execCommand) + buf, err := createWindowManagerDesktopContents(name, execCommand) + if err != nil { + o.Err("no") + o.Fprintf(os.Stderr, "internal error when executing template: %v\n", err) + os.Exit(1) + } if custom != "" { // Write the custom string to the end of the .desktop file (may contain \n) buf.WriteString(custom + "\n") @@ -97,7 +111,7 @@ func writeWindowManagerDesktopFile(pkgname, name, execCommand, custom string, fo // Check if the file exists (and that force is not enabled) if exists(pkgname+".desktop") && !force { o.Err("no") - o.Fprintln(os.Stderr, pkgname+".desktop already exists. Use -f as the first argument to overwrite it.") + o.Fprintf(os.Stderr, "%s.desktop already exists. Use -f as the first argument to overwrite it.\n", pkgname) os.Exit(1) } os.WriteFile(pkgname+".desktop", buf.Bytes(), 0644) @@ -129,23 +143,30 @@ func writeDesktopFile(pkgname, name, comment, execCommand, icon, path, categorie // mimeTypes may be empty. Disabled terminal // and startupnotify for now. - buf := createDesktopContents(name, genericName, comment, execCommand, icon, path, useTerminal, startupNotify, categoryList, mimeTypeList) + buf, err := createDesktopContents(name, genericName, comment, execCommand, icon, path, useTerminal, startupNotify, categoryList, mimeTypeList) + if err != nil { + o.Err("no") + o.Fprintf(os.Stderr, "internal error when executing template: %v\n", err) + os.Exit(1) + } if custom != "" { // Write the custom string to the end of the .desktop file (may contain \n) buf.WriteString(custom + "\n") } + filename := pkgname + ".desktop" + // Check if the file exists (and that force is not enabled) - if exists(pkgname+".desktop") && !force { + if exists(filename) && !force { o.Err("no") - o.Fprintln(os.Stderr, pkgname+".desktop already exists. Use -f as the first argument to overwrite it.") + o.Fprintf(os.Stderr, "%s already exists. Use -f as the first argument to overwrite it.\n", filename) os.Exit(1) } - os.WriteFile(pkgname+".desktop", buf.Bytes(), 0644) + os.WriteFile(filename, buf.Bytes(), 0644) } -// Check if a keyword appears in a package description +// keywordsInDescription checks if the given package description contains one of the given keywords func keywordsInDescription(pkgdesc string, keywords []string) bool { for _, keyword := range keywords { if has(pkgdesc, keyword) { @@ -157,15 +178,16 @@ func keywordsInDescription(pkgdesc string, keywords []string) bool { // WriteDefaultIconFile copies /usr/share/pixmaps/gendesk.png to pkgname + ".png" func WriteDefaultIconFile(pkgname string, o *textoutput.TextOutput) error { - defaultIconFilename := "/usr/share/pixmaps/gendesk.png" + const defaultIconFilename = "/usr/share/pixmaps/gendesk.png" b, err := os.ReadFile(defaultIconFilename) if err != nil { o.Err("could not read " + defaultIconFilename + "!") + return err } filename := pkgname + ".png" - err = os.WriteFile(filename, b, 0644) - if err != nil { + if err := os.WriteFile(filename, b, 0644); err != nil { o.Err("could not write icon to " + filename + "!") + return err } return nil } @@ -250,6 +272,16 @@ func main() { filename string pkgnames []string iconurl string + + // Several fields are stored per pkgname + pkgdescMap = make(map[string]string) + execMap = make(map[string]string) + nameMap = make(map[string]string) + genericNameMap = make(map[string]string) + mimeTypesMap = make(map[string]string) + commentMap = make(map[string]string) + categoriesMap = make(map[string]string) + customMap = make(map[string]string) ) flag.Parse() @@ -293,16 +325,6 @@ func main() { // Environment variables dataFromEnvironment(&pkgdesc, execCommand, name, genericname, mimetypes, comment, categories, custom) - // Several fields are stored per pkgname - pkgdescMap := make(map[string]string) - execMap := make(map[string]string) - nameMap := make(map[string]string) - genericNameMap := make(map[string]string) - mimeTypesMap := make(map[string]string) - commentMap := make(map[string]string) - categoriesMap := make(map[string]string) - customMap := make(map[string]string) - // Strip the "-bin", "-git", "-hg" or "-svn" suffix from the name, if present for _, suf := range []string{"bin", "git", "hg", "svn"} { pkgname = strings.TrimSuffix(pkgname, "-"+suf)