From 54dd62a2a43d36e10d075b2b3fe9b0f637f2e2b9 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Mon, 28 Aug 2023 09:05:12 -0300 Subject: [PATCH] fix: handle running inside a snap (#527) * fix: handle running inside a snap Signed-off-by: Carlos Alexandro Becker * test: fixes * docs: improve error message --------- Signed-off-by: Carlos Alexandro Becker Co-authored-by: bashbunni --- config_cmd.go | 20 ++++++++++++-------- editor/editor.go | 8 ++++++-- editor/editor_test.go | 13 ++++++++++++- ui/editor.go | 9 ++++++++- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/config_cmd.go b/config_cmd.go index a4cb5849..caeaac74 100644 --- a/config_cmd.go +++ b/config_cmd.go @@ -23,13 +23,14 @@ pager: false width: 80` var configCmd = &cobra.Command{ - Use: "config", - Hidden: false, - Short: "Edit the glow config file", - Long: paragraph(fmt.Sprintf("\n%s the glow config file. We’ll use EDITOR to determine which editor to use. If the config file doesn't exist, it will be created.", keyword("Edit"))), - Example: paragraph("glow config\nglow config --config path/to/config.yml"), - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { + Use: "config", + Hidden: false, + Short: "Edit the glow config file", + Long: paragraph(fmt.Sprintf("\n%s the glow config file. We’ll use EDITOR to determine which editor to use. If the config file doesn't exist, it will be created.", keyword("Edit"))), + Example: paragraph("glow config\nglow config --config path/to/config.yml"), + Args: cobra.NoArgs, + SilenceUsage: true, + RunE: func(_ *cobra.Command, _ []string) error { if configFile == "" { scope := gap.NewScope(gap.User, "glow") @@ -64,7 +65,10 @@ var configCmd = &cobra.Command{ return err } - c := editor.Cmd(configFile) + c, err := editor.Cmd(configFile) + if err != nil { + return fmt.Errorf("could not edit %s: %w", configFile, err) + } c.Stdin = os.Stdin c.Stdout = os.Stdout c.Stderr = os.Stderr diff --git a/editor/editor.go b/editor/editor.go index bbfe6ffa..304c9ac5 100644 --- a/editor/editor.go +++ b/editor/editor.go @@ -1,6 +1,7 @@ package editor import ( + "fmt" "os" "os/exec" "strings" @@ -10,9 +11,12 @@ const defaultEditor = "nano" // Cmd returns a *exec.Cmd editing the given path with $EDITOR or nano if no // $EDITOR is set. -func Cmd(path string) *exec.Cmd { +func Cmd(path string) (*exec.Cmd, error) { + if os.Getenv("SNAP_REVISION") != "" { + return nil, fmt.Errorf("Did you install with Snap? Glow is sandboxed and unable to open an editor. Please install Glow with Go or another package manager to enable editing.") + } editor, args := getEditor() - return exec.Command(editor, append(args, path)...) + return exec.Command(editor, append(args, path)...), nil } func getEditor() (string, []string) { diff --git a/editor/editor_test.go b/editor/editor_test.go index 2d1b5834..d8d5817b 100644 --- a/editor/editor_test.go +++ b/editor/editor_test.go @@ -16,11 +16,22 @@ func TestEditor(t *testing.T) { } { t.Run(k, func(t *testing.T) { t.Setenv("EDITOR", k) - cmd := Cmd("README.md") + cmd, _ := Cmd("README.md") got := cmd.Args if !reflect.DeepEqual(got, v) { t.Fatalf("expected %v; got %v", v, got) } }) } + + t.Run("inside snap", func(t *testing.T) { + t.Setenv("SNAP_REVISION", "10") + got, err := Cmd("foo") + if err == nil { + t.Fatalf("expected an error, got nil") + } + if got != nil { + t.Fatalf("should have returned nil, got %v", got) + } + }) } diff --git a/ui/editor.go b/ui/editor.go index c38ef017..4c65962c 100644 --- a/ui/editor.go +++ b/ui/editor.go @@ -11,5 +11,12 @@ func openEditor(path string) tea.Cmd { cb := func(err error) tea.Msg { return editorFinishedMsg{err} } - return tea.ExecProcess(editor.Cmd(path), cb) + + editor, err := editor.Cmd(path) + if err != nil { + return func() tea.Msg { + return errMsg{err} + } + } + return tea.ExecProcess(editor, cb) }