From 30c5f915d176da5c8987bd51fe658e3119fc0d7e Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Wed, 24 Jan 2024 09:54:53 -0500 Subject: [PATCH] Run `find` in a cross-platform manner Managed to finally get my hands on a relevant log entry and saw: ``` {"level":"error","github_event_type":"pull_request","github_delivery_id":"","error":"Failed to `find` latest docs version to generate cobradocs preview for https://github.com/vitessio/vitess/pull/14789: exit status 1\nstderr: find: unknown predicate `-sE'\n\nstdout: ","time":"2024-01-24T13:13:22Z","message":"Unexpected error handling webhook"} ``` So, we need to remove `-sE` on unix, but not on darwin. `-E` _before_ the path is replaced by `-regextype posix-extended` _after_ the path. There is no replacement for `-s` on non-darwin unix, so we now need to pipe to `sort` to sort in dictionary order. Signed-off-by: Andrew Mason --- go/pull_request.go | 21 ++++++++++++++------- go/shell/shell.go | 20 ++++++++++++++++++++ go/shell/shell_darwin.go | 7 +++++++ go/shell/shell_unix.go | 11 +++++++++++ 4 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 go/shell/shell_darwin.go create mode 100644 go/shell/shell_unix.go diff --git a/go/pull_request.go b/go/pull_request.go index 33801c4..6199c48 100644 --- a/go/pull_request.go +++ b/go/pull_request.go @@ -546,14 +546,21 @@ func (h *PullRequestHandler) createCobraDocsPreviewPR( if docsVersion == "main" { // We need to replace "main" with whatever the highest version under // content/en/docs is. - find, err := shell.NewContext(ctx, - "find", - "-sE", - "content/en/docs", + // + // MacOS does not support -regextype flag, but Unix (non-darwin) does + // not support the -E equivalent. Similarly, Unix does not support the + // lexicographic sort opt (-s), so we rely on sort's dictionary sort + // (-d) instead. + // + // Unix version: find content/en/docs -regextype posix-extended -maxdepth 1 -type d -regex ... | sort -d + // MacOS version: find -E content/en/docs -maxdepth 1 -type d -regex ... | sort -d + args := shell.FindRegexpExtended("content/en/docs", + "-maxdepth", "1", "-type", "d", - "-depth", "1", - "-regex", `.*/[0-9]+.[0-9]+`, - ).InDir(website.LocalDir).Output() + "-regex", `.*/[0-9]+.[0-9]+`, "|", + "sort", "-d", + ) + find, err := shell.NewContext(ctx, "bash", "-c", strings.Join(args, " ")).InDir(website.LocalDir).Output() if err != nil { return nil, errors.Wrapf(err, "Failed to `find` latest docs version to %s for %s", op, pr.GetHTMLURL()) } diff --git a/go/shell/shell.go b/go/shell/shell.go index 2a96d71..d304cb6 100644 --- a/go/shell/shell.go +++ b/go/shell/shell.go @@ -25,6 +25,11 @@ import ( type cmd exec.Cmd +var ( + globalRegexpOpt string + regexpTypeOpt []string +) + // New returns a new command can be run. func New(name string, arg ...string) *cmd { return NewContext(context.Background(), name, arg...) @@ -35,6 +40,21 @@ func NewContext(ctx context.Context, name string, arg ...string) *cmd { return (*cmd)(exec.CommandContext(ctx, name, arg...)) } +// FindRegexpExtended returns a slice of arguments for doing a `find` command +// using extended regular expressions in a cross-platform-friendly manner. +func FindRegexpExtended(path string, expressions ...string) (args []string) { + args = []string{path} + if globalRegexpOpt != "" { + args = []string{globalRegexpOpt, path} + } + + if len(regexpTypeOpt) > 0 { + args = append(args, regexpTypeOpt...) + } + + return append(args, expressions...) +} + // InDir updates the working directory of the command and returns it. // // Must be called before running the command. diff --git a/go/shell/shell_darwin.go b/go/shell/shell_darwin.go new file mode 100644 index 0000000..769a9b8 --- /dev/null +++ b/go/shell/shell_darwin.go @@ -0,0 +1,7 @@ +//go:build darwin + +package shell + +func init() { + globalRegexpOpt = "-E" +} diff --git a/go/shell/shell_unix.go b/go/shell/shell_unix.go new file mode 100644 index 0000000..924a719 --- /dev/null +++ b/go/shell/shell_unix.go @@ -0,0 +1,11 @@ +//go:build unix && !darwin + +package shell + +func init() { + regexpTypeOpt = []string{ + // This is not a typo. It is "regexp" in goland and "regex" in POSIX land. ¯\_(ツ)_/¯ + "-regextype", + "posix-extended", + } +}