diff options
| -rw-r--r-- | dirs/dirs.go | 2 | ||||
| -rw-r--r-- | snappy/click.go | 60 | ||||
| -rw-r--r-- | snappy/click_test.go | 65 | ||||
| -rw-r--r-- | snappy/snap_yaml.go | 5 |
4 files changed, 132 insertions, 0 deletions
diff --git a/dirs/dirs.go b/dirs/dirs.go index 7c71e7d11d..7d92882c26 100644 --- a/dirs/dirs.go +++ b/dirs/dirs.go @@ -46,6 +46,7 @@ var ( SnapBinariesDir string SnapServicesDir string + SnapDesktopDir string SnapBusPolicyDir string CloudMetaDataFile string @@ -89,6 +90,7 @@ func SetRootDir(rootdir string) { SnapTrustedAccountKey = filepath.Join(rootdir, "/usr/share/snappy/trusted.acckey") SnapBinariesDir = filepath.Join(SnapSnapsDir, "bin") + SnapDesktopDir = filepath.Join(rootdir, snappyDir, "applications") SnapServicesDir = filepath.Join(rootdir, "/etc/systemd/system") SnapBusPolicyDir = filepath.Join(rootdir, "/etc/dbus-1/system.d") diff --git a/snappy/click.go b/snappy/click.go index 25d87a351f..1f1adf99d8 100644 --- a/snappy/click.go +++ b/snappy/click.go @@ -59,6 +59,12 @@ func generateBinaryName(m *snapYaml, app *AppYaml) string { return filepath.Join(dirs.SnapBinariesDir, binName) } +func generateDesktopFileName(m *snapYaml, app *AppYaml) string { + binName := fmt.Sprintf("%s_%s.desktop", m.Name, filepath.Base(app.Name)) + + return filepath.Join(dirs.SnapDesktopDir, binName) +} + func binPathForBinary(pkgPath string, app *AppYaml) string { return filepath.Join(pkgPath, app.Command) } @@ -176,6 +182,47 @@ ubuntu-core-launcher {{.UdevAppName}} {{.AaProfile}} {{.Target}} "$@" return templateOut.String(), nil } +func generateSnapDesktopFile(app *AppYaml, pkgPath string, m *snapYaml) (string, error) { + desktopTemplate := `[Desktop Entry] +Encoding=UTF-8 +Type=Application +Name={{.Name}} +Comment={{.Comment}} +Icon={{.Icon}} +Exec={{.Exec}}{{if .Categories}} +Categories={{range .Categories}}{{.}};{{end}}{{end}} +` + + // no desktop file needed + if app.Icon == "" && app.Comment == "" { + return "", nil + } + + run, err := filepath.Rel(dirs.GlobalRootDir, generateBinaryName(m, app)) + if err != nil { + return "", err + } + + var templateOut bytes.Buffer + t := template.Must(template.New("desktop").Parse(desktopTemplate)) + wrapperData := struct { + Name string + Comment string + Icon string + Exec string + Categories []string + }{ + Name: app.Name, + Comment: app.Comment, + Icon: filepath.Join(pkgPath, app.Icon), + Exec: fmt.Sprintf("/%s", run), + Categories: app.Categories, + } + + t.Execute(&templateOut, wrapperData) + return templateOut.String(), nil +} + // FIXME: too much magic, just do explicit validation of the few // fields we have // verifyStructStringsAgainstWhitelist takes a struct and ensures that @@ -468,6 +515,18 @@ func addPackageBinaries(m *snapYaml, baseDir string) error { if err := helpers.AtomicWriteFile(generateBinaryName(m, app), []byte(content), 0755, 0); err != nil { return err } + + // now generate a desktop file (if needed) + desktop, err := generateSnapDesktopFile(app, realBaseDir, m) + if err != nil { + return err + } + // only write if there is anything for us) + if desktop != "" { + if err := helpers.AtomicWriteFile(generateDesktopFileName(m, app), []byte(desktop), 0644, 0); err != nil { + return err + } + } } return nil @@ -476,6 +535,7 @@ func addPackageBinaries(m *snapYaml, baseDir string) error { func removePackageBinaries(m *snapYaml, baseDir string) error { for _, app := range m.Apps { os.Remove(generateBinaryName(m, app)) + os.Remove(generateDesktopFileName(m, app)) } return nil diff --git a/snappy/click_test.go b/snappy/click_test.go index 6f90f046c5..9358c9cc09 100644 --- a/snappy/click_test.go +++ b/snappy/click_test.go @@ -1202,3 +1202,68 @@ apps: c.Assert(helpers.FileExists(binaryWrapper), Equals, false) c.Assert(helpers.FileExists(snapDir), Equals, false) } + +func (s *SnapTestSuite) TestSnappyGenerateSnapDesktopFileNotNeeded(c *C) { + app := &AppYaml{Name: "pastebinit", Command: "bin/pastebinit"} + pkgPath := "/snaps/pastebinit.mvo/1.4.0.0.1/" + m := &snapYaml{ + Name: "pastebinit", + Version: "1.4.0.0.1", + } + + generatedDesktopFile, err := generateSnapDesktopFile(app, pkgPath, m) + c.Assert(err, IsNil) + c.Assert(generatedDesktopFile, Equals, "") +} + +func (s *SnapTestSuite) TestSnappyGenerateSnapDesktopFile(c *C) { + app := &AppYaml{ + Name: "pastebinit", + Command: "bin/pastebinit", + Comment: "Best evar", + Icon: "something.png", + Categories: []string{"Game", "LogicGame"}, + } + pkgPath := "/snaps/pastebinit.mvo/1.4.0.0.1/" + m := &snapYaml{ + Name: "pastebinit", + Version: "1.4.0.0.1", + } + + generatedDesktopFile, err := generateSnapDesktopFile(app, pkgPath, m) + c.Assert(err, IsNil) + c.Assert(generatedDesktopFile, Equals, `[Desktop Entry] +Encoding=UTF-8 +Type=Application +Name=pastebinit +Comment=Best evar +Icon=/snaps/pastebinit.mvo/1.4.0.0.1/something.png +Exec=/snaps/bin/pastebinit.pastebinit +Categories=Game;LogicGame; +`) +} + +func (s *SnapTestSuite) TestSnappyGenerateSnapDesktopFileNoCategories(c *C) { + app := &AppYaml{ + Name: "pastebinit", + Command: "bin/pastebinit", + Comment: "Best evar", + Icon: "something.png", + Categories: nil, + } + pkgPath := "/snaps/pastebinit.mvo/1.4.0.0.1/" + m := &snapYaml{ + Name: "pastebinit", + Version: "1.4.0.0.1", + } + generatedDesktopFile, err := generateSnapDesktopFile(app, pkgPath, m) + c.Assert(err, IsNil) + c.Assert(generatedDesktopFile, Equals, `[Desktop Entry] +Encoding=UTF-8 +Type=Application +Name=pastebinit +Comment=Best evar +Icon=/snaps/pastebinit.mvo/1.4.0.0.1/something.png +Exec=/snaps/bin/pastebinit.pastebinit +`) +} diff --git a/snappy/snap_yaml.go b/snappy/snap_yaml.go index 41c46bbde6..e2b71a5107 100644 --- a/snappy/snap_yaml.go +++ b/snappy/snap_yaml.go @@ -63,6 +63,11 @@ type AppYaml struct { Command string `yaml:"command"` Daemon string `yaml:"daemon"` + // desktop file stuff + Icon string `yaml:"icon,omitempty"` + Comment string `yaml:"comment,omitempty"` + Categories []string `yaml:"categories,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` Stop string `yaml:"stop,omitempty"` PostStop string `yaml:"poststop,omitempty"` |
