Skip to content

Commit 39aeaf9

Browse files
committed
Submitting review dfdd159
Consolidate the editor logic into a single place, and make it more reliable. With this change we will try to run the editor in a shell if launching it directly does not work.
2 parents ca1ae88 + aee6f75 commit 39aeaf9

File tree

3 files changed

+86
-58
lines changed

3 files changed

+86
-58
lines changed

commands/comment.go

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@ import (
2020
"errors"
2121
"flag"
2222
"fmt"
23+
"github.com/google/git-appraise/commands/input"
2324
"github.com/google/git-appraise/repository"
2425
"github.com/google/git-appraise/review"
2526
"github.com/google/git-appraise/review/comment"
26-
"io/ioutil"
27-
"os"
28-
"os/exec"
2927
)
3028

3129
var commentFlagSet = flag.NewFlagSet("comment", flag.ExitOnError)
@@ -87,34 +85,10 @@ func commentOnReview(repo repository.Repo, args []string) error {
8785
}
8886

8987
if *commentMessage == "" {
90-
editor, err := repo.GetCoreEditor()
88+
*commentMessage, err = input.LaunchEditor(repo, commentFilename)
9189
if err != nil {
92-
return fmt.Errorf("Unable to detect default git editor: %v\n", err)
90+
return err
9391
}
94-
95-
path := fmt.Sprintf("%s/.git/%s", repo.GetPath(), commentFilename)
96-
97-
cmd := exec.Command(editor, path)
98-
cmd.Stdin = os.Stdin
99-
cmd.Stdout = os.Stdout
100-
cmd.Stderr = os.Stderr
101-
err = cmd.Start()
102-
if err != nil {
103-
return fmt.Errorf("Unable to start editor: %v\n", err)
104-
}
105-
106-
err = cmd.Wait()
107-
if err != nil {
108-
return fmt.Errorf("Editing finished with error: %v\n", err)
109-
}
110-
111-
comment, err := ioutil.ReadFile(path)
112-
if err != nil {
113-
os.Remove(path)
114-
return fmt.Errorf("Error reading comment file: %v\n", err)
115-
}
116-
*commentMessage = string(comment)
117-
os.Remove(path)
11892
}
11993

12094
commentedUponCommit, err := r.GetHeadCommit()

commands/input/input.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
Copyright 2015 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package input
18+
19+
import (
20+
"fmt"
21+
"github.com/google/git-appraise/repository"
22+
"io/ioutil"
23+
"os"
24+
"os/exec"
25+
)
26+
27+
// LaunchEditor launches the default editor configured for the given repo. This
28+
// method blocks until the editor command has returned.
29+
//
30+
// The specified filename should be a temporary file and provided as a relative path
31+
// from the repo (e.g. "FILENAME" will be converted to ".git/FILENAME"). This file
32+
// will be deleted after the editor is closed and its contents have been read.
33+
//
34+
// This method returns the text that was read from the temporary file, or
35+
// an error if any step in the process failed.
36+
func LaunchEditor(repo repository.Repo, fileName string) (string, error) {
37+
editor, err := repo.GetCoreEditor()
38+
if err != nil {
39+
return "", fmt.Errorf("Unable to detect default git editor: %v\n", err)
40+
}
41+
42+
path := fmt.Sprintf("%s/.git/%s", repo.GetPath(), fileName)
43+
44+
cmd, err := startInlineCommand(editor, path)
45+
if err != nil {
46+
// Running the editor directly did not work. This might mean that
47+
// the editor string is not a path to an executable, but rather
48+
// a shell command (e.g. "emacsclient --tty"). As such, we'll try
49+
// to run the command through bash, and if that fails, try with sh
50+
args := []string{"-c", fmt.Sprintf("%s %q", editor, path)}
51+
cmd, err = startInlineCommand("bash", args...)
52+
if err != nil {
53+
cmd, err = startInlineCommand("sh", args...)
54+
}
55+
}
56+
if err != nil {
57+
return "", fmt.Errorf("Unable to start editor: %v\n", err)
58+
}
59+
60+
if err := cmd.Wait(); err != nil {
61+
return "", fmt.Errorf("Editing finished with error: %v\n", err)
62+
}
63+
64+
output, err := ioutil.ReadFile(path)
65+
if err != nil {
66+
os.Remove(path)
67+
return "", fmt.Errorf("Error reading edited file: %v\n", err)
68+
}
69+
os.Remove(path)
70+
return string(output), err
71+
}
72+
73+
func startInlineCommand(command string, args ...string) (*exec.Cmd, error) {
74+
cmd := exec.Command(command, args...)
75+
cmd.Stdin = os.Stdin
76+
cmd.Stdout = os.Stdout
77+
cmd.Stderr = os.Stderr
78+
err := cmd.Start()
79+
return cmd, err
80+
}

commands/reject.go

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@ import (
2020
"errors"
2121
"flag"
2222
"fmt"
23+
"github.com/google/git-appraise/commands/input"
2324
"github.com/google/git-appraise/repository"
2425
"github.com/google/git-appraise/review"
2526
"github.com/google/git-appraise/review/comment"
26-
"io/ioutil"
27-
"os"
28-
"os/exec"
2927
)
3028

3129
var rejectFlagSet = flag.NewFlagSet("reject", flag.ExitOnError)
@@ -60,34 +58,10 @@ func rejectReview(repo repository.Repo, args []string) error {
6058
}
6159

6260
if *rejectMessage == "" {
63-
editor, err := repo.GetCoreEditor()
61+
*rejectMessage, err = input.LaunchEditor(repo, rejectFilename)
6462
if err != nil {
65-
return fmt.Errorf("Unable to detect default git editor: %v\n", err)
63+
return err
6664
}
67-
68-
path := fmt.Sprintf("%s/.git/%s", repo.GetPath(), rejectFilename)
69-
70-
cmd := exec.Command(editor, path)
71-
cmd.Stdin = os.Stdin
72-
cmd.Stdout = os.Stdout
73-
cmd.Stderr = os.Stderr
74-
err = cmd.Start()
75-
if err != nil {
76-
return fmt.Errorf("Unable to start editor: %v\n", err)
77-
}
78-
79-
err = cmd.Wait()
80-
if err != nil {
81-
return fmt.Errorf("Editing finished with error: %v\n", err)
82-
}
83-
84-
comment, err := ioutil.ReadFile(path)
85-
if err != nil {
86-
os.Remove(path)
87-
return fmt.Errorf("Error reading comment file: %v\n", err)
88-
}
89-
*rejectMessage = string(comment)
90-
os.Remove(path)
9165
}
9266

9367
rejectedCommit, err := r.GetHeadCommit()

0 commit comments

Comments
 (0)