From 7a8d45f88a1a245533f6764c1bc089e5b6140dac Mon Sep 17 00:00:00 2001 From: Ned Palacios Date: Mon, 5 Feb 2024 02:08:01 +0800 Subject: [PATCH] feat(executor): add support for logical operators in monitor --- server/executor/executor.go | 51 +++++++++++++++++++++++++++++++++++++ server/helpers/runner.go | 5 ++++ 2 files changed, 56 insertions(+) diff --git a/server/executor/executor.go b/server/executor/executor.go index bcd9164..8f3546c 100644 --- a/server/executor/executor.go +++ b/server/executor/executor.go @@ -50,7 +50,58 @@ func (wr *StderrMonitor) Write(p []byte) (n int, err error) { return } +type executionLogicalOp int + +const ( + ExecutionLogicalOpNone executionLogicalOp = 0 + ExecutionLogicalOpOr executionLogicalOp = iota + ExecutionLogicalOpAnd executionLogicalOp = iota +) + +var logicalOps = map[string]executionLogicalOp{ + "||": ExecutionLogicalOpOr, + "&&": ExecutionLogicalOpAnd, +} + +func hasLogicalOpInCommand(cmd string) string { + for op := range logicalOps { + if strings.Contains(cmd, op) { + return op + } + } + return "" +} + func Execute(workingDir string, c Collector, prog string, args ...string) (int, int, error) { + sep := hasLogicalOpInCommand(prog) + if sep != "" { + commands := strings.Split(prog, sep) + var err error + var numErrors int + var exitCode int + for i, cmd := range commands { + if i > 0 { + switch logicalOps[sep] { + case ExecutionLogicalOpOr: + if exitCode == 0 { + continue + } + case ExecutionLogicalOpAnd: + if exitCode != 0 { + continue + } + } + } + + argv := strings.Split(strings.TrimSpace(cmd), " ") + numErrors, exitCode, err = Execute(workingDir, c, argv[0], argv[1:]...) + if err != nil { + return numErrors, exitCode, err + } + } + return numErrors, exitCode, nil + } + errProcessor := &StderrMonitor{ workingDir: workingDir, collector: c, diff --git a/server/helpers/runner.go b/server/helpers/runner.go index 9b8c8a9..1c88290 100644 --- a/server/helpers/runner.go +++ b/server/helpers/runner.go @@ -131,5 +131,10 @@ func GetRunCommand(languageId string, filePath string) (string, error) { ) runCommand = r.Replace(runCommand) + if strings.Count(runCommand, "||") > 0 || strings.Count(runCommand, "&&") > 0 { + // wrap the command in double quotes if it contains logical operators + runCommand = fmt.Sprintf("\"%s\"", runCommand) + } + return fmt.Sprintf("%s -- %s", executablePath, runCommand), nil }