Skip to content

Commit

Permalink
First Zenity wrapper for unix implemented ⚓
Browse files Browse the repository at this point in the history
- dlgs has to many wrong code pieces.
- ncruces is a good reference but is not complete.

- Windows will be implemented with walk.
  • Loading branch information
gabyx committed Feb 23, 2021
1 parent 818fc94 commit 9575885
Show file tree
Hide file tree
Showing 19 changed files with 801 additions and 84 deletions.
59 changes: 59 additions & 0 deletions githooks/apps/dialog/cmd/common/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package common

import (
"gabyx/githooks/apps/dialog/gui"

"github.com/spf13/cobra"
)

func AddFlagsGeneralSettings(cmd *cobra.Command, s *gui.GeneralSettings) {
cmd.Flags().StringVar(&s.Title, "title", "", "Dialog title.")
cmd.Flags().UintVar(&s.Width, "width", 0, "Dialog width.")
cmd.Flags().UintVar(&s.Height, "height", 0, "Dialog height.")
cmd.Flags().UintVar((*uint)(&s.WindowIcon), "window-icon", 0, "Window icon.")
}

func AddFlagsDefaultButtonSettings(cmd *cobra.Command, s *gui.DefaultButtonSettings) {
cmd.Flags().StringVar(&s.OkLabel, "ok-label", "", "Ok button label.")
cmd.Flags().StringVar(&s.CancelLabel, "cancel-label", "", "Cancel button label.")
cmd.Flags().BoolVar(&s.DefaultCancel, "default-cancel", false, "Set 'Cancel' as the default button.")

cmd.Flags().StringArrayVar(&s.ExtraButtons, "extra-button", nil, "Extra buttons labels.")

}

func AddFlagsGeneralTextSettings(cmd *cobra.Command, s *gui.GeneralTextSettings) {
cmd.Flags().StringVar(&s.Text, "text", "", "The general text of the dialog.")
cmd.Flags().BoolVar(&s.NoWrap, "no-wrap", false, "Don't wrap the text.")
cmd.Flags().BoolVar(&s.Ellipsize, "ellipsize", false, "Ellipsize the text if it doesn't fit.")
}

func AddFlagsMessageSettings(cmd *cobra.Command, s *gui.MessageSettings) {
AddFlagsGeneralSettings(cmd, &s.GeneralSettings)
AddFlagsGeneralTextSettings(cmd, &s.GeneralTextSettings)
AddFlagsDefaultButtonSettings(cmd, &s.DefaultButtonSettings)

cmd.Flags().UintVar((*uint)(&s.Style), "style", 0, "Message style.")
cmd.Flags().UintVar((*uint)(&s.Icon), "icon", 0, "Message icon.")
}

func AddFlagsOptionsSettings(cmd *cobra.Command, s *gui.OptionsSettings) {
AddFlagsGeneralSettings(cmd, &s.GeneralSettings)
AddFlagsGeneralTextSettings(cmd, &s.GeneralTextSettings)
AddFlagsDefaultButtonSettings(cmd, &s.DefaultButtonSettings)

cmd.Flags().StringArrayVar(&s.Options, "option", nil, "Option choices.")
cmd.Flags().UintVar(&s.DefaultOption, "default-option", 0, "Option choices.")

cmd.Flags().UintVar((*uint)(&s.Style), "style", 0, "Options style.")
cmd.Flags().BoolVar(&s.MultipleSelection, "multiple-selections", false, "Multiple selections allowed.")
}

func AddFlagsEntrySettings(cmd *cobra.Command, s *gui.EntrySettings) {
AddFlagsGeneralSettings(cmd, &s.GeneralSettings)
AddFlagsGeneralTextSettings(cmd, &s.GeneralTextSettings)
AddFlagsDefaultButtonSettings(cmd, &s.DefaultButtonSettings)

cmd.Flags().StringVar(&s.EntryText, "--entry-text", "", "Entry text.")
cmd.Flags().BoolVar(&s.HideEntry, "ellipsize", true, "Ellipsize the text if it doesn't fit.")
}
58 changes: 58 additions & 0 deletions githooks/apps/dialog/cmd/common/handle-result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package common

import (
"errors"
dcm "gabyx/githooks/apps/dialog/common"
strs "gabyx/githooks/strings"
"os"
"strings"
)

func indicesToList(l []uint) (s []string) {
for i := range l {
s = append(s, strs.Fmt("%d", l[i]))
}

return
}

func HandleOtherErrors(ctx *CmdContext, err error) error {

if e, ok := err.(*dcm.ErrExtraButton); ok { //nolint: gocritic

os.Stdout.WriteString(strs.Fmt("%d", e.ButtonIndex))
os.Stdout.WriteString("\n")
ctx.ExitCode = 1

return nil

} else if errors.Is(err, dcm.ErrCancled) {
ctx.ExitCode = 1

return nil

} else if os.IsTimeout(err) {
ctx.ExitCode = 5

return nil

}

// All other errors are not handled.
return err
}

func HandleOutputIndices(ctx *CmdContext, l []uint, err error) error {

if err == nil {

if len(l) > 0 {
os.Stdout.WriteString(strings.Join(indicesToList(l), ","))
os.Stdout.WriteString("\n")
}

return nil
}

return HandleOtherErrors(ctx, err)
}
21 changes: 21 additions & 0 deletions githooks/apps/dialog/cmd/common/settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package common

import (
cm "gabyx/githooks/common"
)

type CmdContext struct {

// Exit code of the dialog app.
ExitCode ExitCode

// Log context.
Log cm.ILogContext
}

type ExitCode = uint

const (
// ExitCodeCanceled is the exit code if the user cancled or closed the dialog.
ExitCodeCanceled = 1
)
46 changes: 46 additions & 0 deletions githooks/apps/dialog/cmd/message/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package message

import (
"context"
dcm "gabyx/githooks/apps/dialog/cmd/common"
"gabyx/githooks/apps/dialog/gui"
ccm "gabyx/githooks/cmd/common"
"time"

"github.com/spf13/cobra"
)

func NewCmd(ctx *dcm.CmdContext) *cobra.Command {

settings := gui.MessageSettings{}
var timeout uint

cmd := &cobra.Command{
Use: "message",
Short: "Shows a message dialog.",
Long: `Shows a message dialog similar to 'zenity'.
See 'https://help.gnome.org/users/zenity/3.32/list.html.de' for details.`,
Run: func(cmd *cobra.Command, args []string) {

var cancel func()
var cont context.Context

if timeout > 0 {
cont, cancel = context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
}

_, err := gui.ShowMessage(cont, &settings)

err = dcm.HandleOutputIndices(ctx, nil, err)
ctx.Log.AssertNoErrorPanic(err, "Dialog failed")

}}

cmd.Flags().UintVar(&timeout, "timeout", 0, "Timeout for the dialog")

dcm.AddFlagsMessageSettings(cmd, &settings)
ccm.SetCommandDefaults(ctx.Log, cmd)

return cmd
}
46 changes: 46 additions & 0 deletions githooks/apps/dialog/cmd/options/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package options

import (
"context"
dcm "gabyx/githooks/apps/dialog/cmd/common"
"gabyx/githooks/apps/dialog/gui"
ccm "gabyx/githooks/cmd/common"
"time"

"github.com/spf13/cobra"
)

func NewCmd(ctx *dcm.CmdContext) *cobra.Command {

settings := gui.OptionsSettings{}
var timeout uint

cmd := &cobra.Command{
Use: "options",
Short: "Shows a options selection dialog.",
Long: `Shows a list selection dialog similar to 'zenity'.
See 'https://help.gnome.org/users/zenity/3.32/list.html.de' for details.`,
Run: func(cmd *cobra.Command, args []string) {

var cancel func()
var cont context.Context

if timeout > 0 {
cont, cancel = context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
}

res, err := gui.ShowOptions(cont, &settings)

err = dcm.HandleOutputIndices(ctx, res, err)
ctx.Log.AssertNoErrorPanic(err, "Dialog failed")

}}

cmd.Flags().UintVar(&timeout, "timeout", 0, "Timeout for the dialog")

dcm.AddFlagsOptionsSettings(cmd, &settings)
ccm.SetCommandDefaults(ctx.Log, cmd)

return cmd
}
16 changes: 16 additions & 0 deletions githooks/apps/dialog/common/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package common

import (
"errors"
strs "gabyx/githooks/strings"
)

var ErrCancled = errors.New("Cancled")

type ErrExtraButton struct {
ButtonIndex uint
}

func (e *ErrExtraButton) Error() string {
return strs.Fmt("Extra Button '%v'", e.ButtonIndex)
}
79 changes: 79 additions & 0 deletions githooks/apps/dialog/dialog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package main

import (
dcm "gabyx/githooks/apps/dialog/cmd/common"
"gabyx/githooks/apps/dialog/cmd/message"
"gabyx/githooks/apps/dialog/cmd/options"
"gabyx/githooks/build"
ccm "gabyx/githooks/cmd/common"
cm "gabyx/githooks/common"
"gabyx/githooks/hooks"
"os"
"path/filepath"

"github.com/spf13/cobra"
)

func addSubCommands(cmd *cobra.Command, ctx *dcm.CmdContext) {
cmd.AddCommand(options.NewCmd(ctx))
cmd.AddCommand(message.NewCmd(ctx))
}

// makeDialogCtl returns the root command of the Githooks dialog executable.
func makeDialogCtl(ctx *dcm.CmdContext) (rootCmd *cobra.Command) {

fmt := ctx.Log.GetInfoFormatter(false)
title := fmt("Githooks Dialog CLI [version: %s]", build.BuildVersion)
firstPrefix := " ▶ "
ccm.InitTemplates(title, firstPrefix, ctx.Log.GetIndent())

rootCmd = &cobra.Command{
Use: "dialog", // Contains a en-space (utf-8: U+2002) to make it work...
Short: "Githooks dialog application",
Long: "See further information at https://github.com/gabyx/githooks/blob/main/README.md"}

ccm.ModifyTemplate(rootCmd, ctx.Log.GetIndent())

rootCmd.SetOut(cm.ToInfoWriter(ctx.Log))
rootCmd.SetErr(cm.ToErrorWriter(ctx.Log))
rootCmd.Version = build.BuildVersion

addSubCommands(rootCmd, ctx)

ccm.SetCommandDefaults(ctx.Log, rootCmd)

return rootCmd
}

func mainRun() (exitCode int) {
cwd, err := os.Getwd()
cm.AssertNoErrorPanic(err, "Could not get current working dir.")
cwd = filepath.ToSlash(cwd)

// We only log to stderr, because we need stdout for the output.
log, err := cm.CreateLogContext(true)
cm.AssertOrPanic(err == nil, "Could not create log")

// Handle all panics and report the error
defer func() {
r := recover()
if cm.HandleCLIErrors(r, cwd, log, hooks.GetBugReportingInfo) {
exitCode = 111
}
}()

ctx := dcm.CmdContext{Log: log}
cmd := makeDialogCtl(&ctx)

err = cmd.Execute()
if err != nil {
_ = cmd.Help()
}
ctx.Log.AssertNoErrorPanic(err, "Command failed.")

return int(ctx.ExitCode)
}

func main() {
os.Exit(mainRun())
}
Loading

0 comments on commit 9575885

Please sign in to comment.