Skip to content

Commit

Permalink
fix: autocomplete panics expanding args when ~/... path is used (#4178)
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Couture-Beil <[email protected]>
  • Loading branch information
alexcb authored Jun 10, 2024
1 parent 49b6f03 commit 584c42c
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 12 deletions.
31 changes: 31 additions & 0 deletions autocomplete/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package autocomplete

import (
"fmt"
"os"
)

var logPath string

// SetupLog enables debug-level logging in the autocomplete package when path is set to a logfile.
// this is particuarly useful since autocompletion is called via a shell which can mangle stderr output
// and interprets stdout as autocompletion values.
func SetupLog(path string) {
logPath = path
}

func Logf(format string, args ...interface{}) {
Log(fmt.Sprintf(format, args...))
}

func Log(s string) {
if logPath == "" {
return
}
f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
return
}
defer f.Close()
_, _ = f.WriteString(s + "\n")
}
27 changes: 17 additions & 10 deletions cmd/earthly/helper/autocomplete.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,38 @@ import (

// to enable autocomplete, enter
// complete -o nospace -C "/path/to/earthly" earthly
//
// alternatively, you can run earthly with COMP_LINE and COMP_POINT set; for example:
// COMP_LINE="earthly ./buildkitd+buildkitd --" COMP_POINT="32" ./build/linux/amd64/earthly
// COMP_LINE="earthly ~/test/simple+test -" COMP_POINT="28" ./build/linux/amd64/earthly
func AutoComplete(ctx context.Context, cli *base.CLI) {
_, found := os.LookupEnv("COMP_LINE")
if !found {
return
}

cli.SetConsole(cli.Console().WithLogLevel(conslogging.Silent))

err := autoCompleteImp(ctx, cli)
if err != nil {
errToLog := err
_, debugEnabled := os.LookupEnv("EARTHLY_AUTOCOMPLETE_DEBUG")
if debugEnabled {
logDir, err := cliutil.GetOrCreateEarthlyDir(cli.Flags().InstallationName)
if err != nil {
fmt.Fprintf(os.Stderr, "GetOrCreateEarthlyDir failed: %v\n", err)
os.Exit(1)
}
logFile := filepath.Join(logDir, "autocomplete.log")
err = os.MkdirAll(logDir, 0755)
if err != nil {
fmt.Fprintf(os.Stderr, "MkdirAll %s failed: %v\n", logDir, err)
os.Exit(1)
}
f, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
os.Exit(1)
}
fmt.Fprintf(f, "error during autocomplete: %s\n", errToLog)
autocomplete.SetupLog(logFile)
autocomplete.Logf("COMP_LINE=%q COMP_POINT=%q", os.Getenv("COMP_LINE"), os.Getenv("COMP_POINT"))
}

cli.SetConsole(cli.Console().WithLogLevel(conslogging.Silent))

err := autoCompleteImp(ctx, cli)
if err != nil {
autocomplete.Logf("error during autocomplete: %s", err)
os.Exit(1)
}
os.Exit(0)
Expand Down
8 changes: 6 additions & 2 deletions domain/reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package domain

import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
Expand Down Expand Up @@ -181,10 +182,13 @@ func parseCommon(fullName string) (gitURL string, tag string, localPath string,
if partsPlus[0] == "" {
// Local target.
return "", "", ".", "", partsPlus[1], nil
} else if strings.HasPrefix(partsPlus[0], ".") || filepath.IsAbs(partsPlus[0]) {
} else if strings.HasPrefix(partsPlus[0], ".") || strings.HasPrefix(partsPlus[0], "~/") || filepath.IsAbs(partsPlus[0]) {
// Local external target.
localPath := partsPlus[0]
if filepath.IsAbs(localPath) {
if strings.HasPrefix(localPath, "~/") {
homeDir := os.Getenv("HOME")
localPath = homeDir + "/" + localPath[2:]
} else if filepath.IsAbs(localPath) {
localPath = path.Clean(localPath)
} else {
localPath = path.Clean(localPath)
Expand Down
13 changes: 13 additions & 0 deletions tests/autocompletion/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ test-target-with-build-args-from-other-dir:
RUN echo "--city=" > expected
DO +COMPLETION_TEST --COMP_LINE="earthly ./child/dir+othertargetwithargs --ci"

test-target-with-build-args-via-tilde:
RUN cd ~ && acbtest "$(pwd)" = "/root" # make sure $HOME=/root
COPY fake.earth /root/testdir/Earthfile

RUN echo "--city=
--country=" > expected
DO +COMPLETION_TEST --COMP_LINE="earthly ~/testdir+othertargetwithargs -"
DO +COMPLETION_TEST --COMP_LINE="earthly ~/testdir+othertargetwithargs --c"

RUN echo "--city=" > expected
DO +COMPLETION_TEST --COMP_LINE="earthly ~/testdir+othertargetwithargs --ci"

test-target-with-required-arg:
COPY fake.earth Earthfile

Expand Down Expand Up @@ -253,3 +265,4 @@ test-all:
BUILD +test-targets-in-dir-and-subdir
BUILD +test-targets-in-two-subdirs-that-are-similar
BUILD +test-no-errors-are-displayed
BUILD +test-target-with-build-args-via-tilde

0 comments on commit 584c42c

Please sign in to comment.