diff --git a/main_permissions_test.go b/main_permissions_test.go new file mode 100644 index 000000000..562840cba --- /dev/null +++ b/main_permissions_test.go @@ -0,0 +1,60 @@ +//go:build !windows + +package main + +import ( + "bufio" + "os" + "strings" + "testing" + + "github.com/rogpeppe/go-internal/testscript" +) + +func isDocker() bool { + if _, err := os.Stat("/.dockerenv"); err == nil { + return true + } + + paths := []string{"/proc/1/cgroup", "/proc/self/cgroup"} + for _, path := range paths { + file, err := os.Open(path) + if err != nil { + continue + } + + scanner := bufio.NewScanner(file) + isDocker := false + for scanner.Scan() { + if strings.Contains(scanner.Text(), "docker") || strings.Contains(scanner.Text(), "kubepods") { + isDocker = true + break + } + } + + if err := scanner.Err(); err != nil { + _ = file.Close() + return false + } + + _ = file.Close() + + if isDocker { + return true + } + } + + return false +} + +func TestRunmeFilePermissions(t *testing.T) { + if isDocker() { + t.Skip("Test skipped when running inside a Docker container") + return + } + + testscript.Run(t, testscript.Params{ + Dir: "testdata/permissions", + ContinueOnError: true, + }) +} diff --git a/pkg/project/project.go b/pkg/project/project.go index 5890e7b1d..95582327d 100644 --- a/pkg/project/project.go +++ b/pkg/project/project.go @@ -365,14 +365,22 @@ func (p *Project) loadFromDirectory( p.send(ctx, eventc, LoadEvent{Type: LoadEventStartedWalk}) err := util.Walk(p.fs, ".", func(path string, info fs.FileInfo, err error) error { - if err != nil { - return err - } - ignored := ignoreMatcher.Match( strings.Split(path, string(filepath.Separator)), info.IsDir(), ) + + switch err.(type) { + case nil: + case *os.PathError: + if !ignored { + p.logger.Warn("path error", zap.String("path", path), zap.Error(err)) + } + ignored = true + default: + return err + } + if !ignored { absPath := p.fs.Join(p.fs.Root(), path) @@ -454,7 +462,12 @@ func (p *Project) extractTasksFromFile( Data: LoadEventFinishedParsingDocumentData{Path: path}, }) - if err != nil { + switch err.(type) { + case nil: + case *os.PathError: + p.logger.Warn("path error", zap.String("path", path), zap.Error(err)) + return + default: p.send(ctx, eventc, LoadEvent{ Type: LoadEventError, Data: LoadEventErrorData{Err: err}, diff --git a/testdata/permissions/basic.txtar b/testdata/permissions/basic.txtar new file mode 100644 index 000000000..3a1024628 --- /dev/null +++ b/testdata/permissions/basic.txtar @@ -0,0 +1,32 @@ +exec chmod 000 secret +exec chmod 000 CONTRIBUTING.md +exec runme ls +cmp stdout output.txt +! stderr . + +-- secret/README.md -- + +```sh {"name":"secret-command"} +$ echo "This is a secret command" +``` + +-- CONTRIBUTING.md -- + +```sh {"name":"contributing-cell"} +$ echo "This is a secret command" +``` + +-- README.md -- + +```sh {"name":"command1"} +$ echo "Hello, runme 1!" +``` + +```sh {"name":"command2"} +$ echo "Hello, runme 2!" +``` + +-- output.txt -- +NAME FILE FIRST COMMAND DESCRIPTION NAMED +command1 README.md echo "Hello, runme 1!" Yes +command2 README.md echo "Hello, runme 2!" Yes