From 154f900d2a51411127212e8c0048e239780e38fe Mon Sep 17 00:00:00 2001 From: James Shubin Date: Mon, 29 Sep 2025 21:24:40 -0400 Subject: [PATCH] engine: resources: Add an ifequals option to block cmd If the ifcmd returns true and this option is set, it will match that output against this field, and if they match, then we skip cmd. Much cleaner than needing to invoke bash to compare two strings. --- engine/resources/exec.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/engine/resources/exec.go b/engine/resources/exec.go index 4ed507ae..cd1c67b9 100644 --- a/engine/resources/exec.go +++ b/engine/resources/exec.go @@ -138,6 +138,13 @@ type ExecRes struct { // IfShell is the Shell for the IfCmd. See the docs for Shell. IfShell string `lang:"ifshell" yaml:"ifshell"` + // IfEquals specifies that if the ifcmd returns zero, and that the + // output matches this string, then it will guard against the Cmd + // running. This can be the empty string. Remember to take into account + // if the output includes a trailing newline or not. (Hint: it usually + // does!) + IfEquals *string `lang:"ifequals" yaml:"ifequals"` + // Creates is the absolute file path to check for before running the // main cmd. If this path exists, then the cmd will not run. More // precisely we attempt to `stat` the file, so it must succeed for a @@ -515,12 +522,17 @@ func (obj *ExecRes) CheckApply(ctx context.Context, apply bool) (bool, error) { } return true, nil // don't run } - if s := out.String(); s == "" { + s := out.String() + if s == "" { obj.init.Logf("ifcmd out empty!") } else { obj.init.Logf("ifcmd out:") obj.init.Logf("%s", s) } + if obj.IfEquals != nil && *obj.IfEquals == s { + obj.init.Logf("ifequals matched") + return true, nil // don't run + } } if obj.Creates != "" { // gate the extra syscall @@ -895,6 +907,9 @@ func (obj *ExecRes) Cmp(r engine.Res) error { if obj.IfShell != res.IfShell { return fmt.Errorf("the IfShell differs") } + if err := engineUtil.StrPtrCmp(obj.IfEquals, res.IfEquals); err != nil { + return errwrap.Wrapf(err, "the IfEquals differs") + } if obj.Creates != res.Creates { return fmt.Errorf("the Creates differs")