Skip to content

Commit bd1600d

Browse files
authored
Improve sudoers command output (#675)
`trellis vm sudoers` is meant to be piped into `sudo tee` but if its run without that, the output might be confusing. This uses `isatty` to detect if its being run in an interactive terminal or not to vary the output and be more helpful
1 parent 00162b9 commit bd1600d

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

cmd/vm_sudoers.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package cmd
22

33
import (
44
"fmt"
5+
"os"
56
"strings"
67

78
"github.com/hashicorp/cli"
9+
"github.com/mattn/go-isatty"
810
"github.com/roots/trellis-cli/pkg/vm"
911
"github.com/roots/trellis-cli/trellis"
1012
)
@@ -32,12 +34,29 @@ func (c *VmSudoersCommand) Run(args []string) int {
3234

3335
hostResolver := vm.NewHostsFileResolver([]string{})
3436
cmd := hostResolver.SudoersCommand()
37+
line := fmt.Sprintf("%%staff ALL=(root:wheel) NOPASSWD:NOSETENV: %s", strings.Join(cmd, " "))
38+
39+
if stdoutIsTerminal() {
40+
c.UI.Warn("The following sudoers rule lets trellis-cli update /etc/hosts without prompting for your password.")
41+
c.UI.Warn("")
42+
c.UI.Warn("To install it, re-run this command and pipe the output to tee:")
43+
c.UI.Warn("")
44+
c.UI.Warn(" trellis vm sudoers | sudo tee /etc/sudoers.d/trellis")
45+
c.UI.Warn("")
46+
c.UI.Warn("Generated rule:")
47+
c.UI.Warn("")
48+
}
3549

36-
c.UI.Info(fmt.Sprintf("%%staff ALL=(root:wheel) NOPASSWD:NOSETENV: %s", strings.Join(cmd, " ")))
50+
c.UI.Info(line)
3751

3852
return 0
3953
}
4054

55+
func stdoutIsTerminal() bool {
56+
fd := os.Stdout.Fd()
57+
return isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd)
58+
}
59+
4160
func (c *VmSudoersCommand) Synopsis() string {
4261
return "Generates sudoers content for passwordless updating of /etc/hosts"
4362
}

0 commit comments

Comments
 (0)