Skip to content

Commit

Permalink
add support for cancelling the current statement in the console / a r…
Browse files Browse the repository at this point in the history
…unning program with Ctrl-C (closes #8)
  • Loading branch information
xrstf committed Dec 21, 2023
1 parent 226486b commit f247c71
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 13 deletions.
22 changes: 17 additions & 5 deletions cmd/rudi/cmd/console/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ var replCommands = map[string]replCommandFunc{
"help": helpCommand,
}

func Run(ctx context.Context, opts *cmdtypes.Options, args []string, rudiVersion string) error {
func Run(handler *util.SignalHandler, opts *cmdtypes.Options, args []string, rudiVersion string) error {
rl, err := readline.New("⮞ ")
if err != nil {
return fmt.Errorf("failed to setup readline prompt: %w", err)
Expand All @@ -69,15 +69,23 @@ func Run(ctx context.Context, opts *cmdtypes.Options, args []string, rudiVersion

for {
line, err := rl.Readline()
if err != nil { // io.EOF

// treat interrupts as "clear input"
if errors.Is(err, readline.ErrInterrupt) {
continue
}

// io.EOF (Ctrl-D)
if err != nil {
break
}

line = strings.TrimSpace(line)
if line == "" {
continue
}

newCtx, stop, err := processInput(ctx, rudiCtx, opts, line)
newCtx, stop, err := processInput(handler, rudiCtx, opts, line)
if err != nil {
parseErr := &rudi.ParseError{}
if errors.As(err, parseErr) {
Expand All @@ -99,7 +107,7 @@ func Run(ctx context.Context, opts *cmdtypes.Options, args []string, rudiVersion
return nil
}

func processInput(ctx context.Context, rudiCtx types.Context, opts *cmdtypes.Options, input string) (newCtx types.Context, stop bool, err error) {
func processInput(handler *util.SignalHandler, rudiCtx types.Context, opts *cmdtypes.Options, input string) (newCtx types.Context, stop bool, err error) {
if command, exists := replCommands[input]; exists {
return rudiCtx, false, command(rudiCtx, opts)
}
Expand All @@ -119,7 +127,11 @@ func processInput(ctx context.Context, rudiCtx types.Context, opts *cmdtypes.Opt
return rudiCtx, false, err
}

// TODO: Setup a new context that can be cancelled with Ctrl-C to interrupt long running statements.
// allow to interrupt the statement
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

handler.SetCancelFn(cancel)

newCtx, evaluated, err := program.RunContext(rudiCtx.WithGoContext(ctx))
if err != nil {
Expand Down
12 changes: 9 additions & 3 deletions cmd/rudi/cmd/script/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ import (
"os"
"strings"

"github.com/BurntSushi/toml"
"go.xrstf.de/rudi"
"go.xrstf.de/rudi/cmd/rudi/types"
"go.xrstf.de/rudi/cmd/rudi/util"
"go.xrstf.de/rudi/pkg/debug"

"github.com/BurntSushi/toml"
"gopkg.in/yaml.v3"
)

func Run(ctx context.Context, opts *types.Options, args []string) error {
func Run(handler *util.SignalHandler, opts *types.Options, args []string) error {
// determine input script to evaluate
var (
script string
Expand Down Expand Up @@ -73,8 +73,14 @@ func Run(ctx context.Context, opts *types.Options, args []string) error {
return fmt.Errorf("failed to setup context: %w", err)
}

// allow to interrupt the script
subCtx, cancel := context.WithCancel(context.Background())
defer cancel()

handler.SetCancelFn(cancel)

// evaluate the script
_, evaluated, err := program.RunContext(rudiCtx.WithGoContext(ctx))
_, evaluated, err := program.RunContext(rudiCtx.WithGoContext(subCtx))
if err != nil {
return fmt.Errorf("failed to evaluate script: %w", err)
}
Expand Down
8 changes: 4 additions & 4 deletions cmd/rudi/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package main

import (
"context"
"errors"
"fmt"
"os"
Expand All @@ -17,6 +16,7 @@ import (
"go.xrstf.de/rudi/cmd/rudi/cmd/help"
"go.xrstf.de/rudi/cmd/rudi/cmd/script"
"go.xrstf.de/rudi/cmd/rudi/types"
"go.xrstf.de/rudi/cmd/rudi/util"

"github.com/spf13/pflag"
)
Expand Down Expand Up @@ -112,18 +112,18 @@ func main() {
return
}

ctx := context.Background()
handler := util.SetupSignalHandler()

if opts.Interactive || len(args) == 0 {
if err := console.Run(ctx, &opts, args, BuildTag); err != nil {
if err := console.Run(handler, &opts, args, BuildTag); err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}

return
}

if err := script.Run(ctx, &opts, args); err != nil {
if err := script.Run(handler, &opts, args); err != nil {
parseErr := &rudi.ParseError{}
if errors.As(err, parseErr) {
fmt.Println(parseErr.Snippet())
Expand Down
2 changes: 1 addition & 1 deletion cmd/rudi/util/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (
"path/filepath"
"strings"

"github.com/BurntSushi/toml"
"go.xrstf.de/rudi/cmd/rudi/types"

"github.com/BurntSushi/toml"
"gopkg.in/yaml.v3"
)

Expand Down

0 comments on commit f247c71

Please sign in to comment.