mirror of
https://github.com/opentffoundation/opentf.git
synced 2026-03-20 22:01:25 -04:00
86 lines
2.0 KiB
Go
86 lines
2.0 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package command
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/opentofu/opentofu/internal/command/views"
|
|
"github.com/opentofu/opentofu/internal/repl"
|
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
|
|
|
"github.com/chzyer/readline"
|
|
)
|
|
|
|
func (c *ConsoleCommand) modeInteractive(session *repl.Session, view views.Console) int {
|
|
// Configure input
|
|
l, err := readline.NewEx(&readline.Config{
|
|
Prompt: "> ",
|
|
InterruptPrompt: "^C",
|
|
EOFPrompt: "exit",
|
|
HistorySearchFold: true,
|
|
Stdin: os.Stdin,
|
|
Stdout: os.Stdout,
|
|
Stderr: os.Stderr,
|
|
})
|
|
if err != nil {
|
|
view.Diagnostics(tfdiags.Diagnostics{}.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"Plugins loading error",
|
|
fmt.Sprintf("Error initializing console: %s", err),
|
|
)))
|
|
return 1
|
|
}
|
|
defer l.Close()
|
|
|
|
var consoleState consoleBracketState
|
|
|
|
for {
|
|
// Read a line
|
|
line, err := l.Readline()
|
|
if errors.Is(err, readline.ErrInterrupt) {
|
|
if len(line) == 0 {
|
|
break
|
|
} else {
|
|
continue
|
|
}
|
|
} else if errors.Is(err, io.EOF) {
|
|
break
|
|
}
|
|
line = strings.TrimSpace(line)
|
|
|
|
// we update the state with the new line, so if we have open
|
|
// brackets we know not to execute the command just yet
|
|
fullCommand, openState := consoleState.UpdateState(line)
|
|
|
|
if openState > 0 {
|
|
// here there are open brackets somewhere, so we don't execute it
|
|
// as we are in a bracket we update the prompt. we use one . per layer pf brackets
|
|
l.SetPrompt(fmt.Sprintf("%s ", strings.Repeat(".", openState)))
|
|
} else {
|
|
out, exit, diags := session.Handle(fullCommand)
|
|
if diags.HasErrors() {
|
|
view.Diagnostics(diags)
|
|
}
|
|
if exit {
|
|
break
|
|
}
|
|
|
|
// clear the state and buffer as we have executed a command
|
|
// we also reset the prompt
|
|
l.SetPrompt("> ")
|
|
|
|
view.Output(out)
|
|
}
|
|
}
|
|
|
|
return 0
|
|
}
|