Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes runme when it attempts to access unreadable files or directories #646

Merged
Merged
60 changes: 60 additions & 0 deletions main_permissions_test.go
Original file line number Diff line number Diff line change
@@ -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,
})
}
23 changes: 18 additions & 5 deletions pkg/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
pastuxso marked this conversation as resolved.
Show resolved Hide resolved
}

if !ignored {
absPath := p.fs.Join(p.fs.Root(), path)

Expand Down Expand Up @@ -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},
Expand Down
32 changes: 32 additions & 0 deletions testdata/permissions/basic.txtar
Original file line number Diff line number Diff line change
@@ -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