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

Feature request: Being able to #61

Open
zveinn opened this issue Mar 29, 2021 · 2 comments
Open

Feature request: Being able to #61

zveinn opened this issue Mar 29, 2021 · 2 comments

Comments

@zveinn
Copy link

zveinn commented Mar 29, 2021

Hello again!

Yet again I find myself using godirwalk, just love this module <3

I was wondering if you could implement a way to detect if the current runtime does not have permissions to enter a folder.

Right now the Walk method just throws an error if I don't have permissions:

$ goto [DIRECTORY]
2021/03/29 08:37:55 trying: .
2021/03/29 08:37:55 trying: $Recycle.Bin
2021/03/29 08:37:55 trying: $Recycle.Bin/S-1-5-18
2021/03/29 08:37:55 open $Recycle.Bin/S-1-5-18: permission denied

Here is my suggestion:

Add a function called "CanAccess" or something similar, that let's you check for persmissions inside the Walk method itself. This way you can combine HasAccess with SkipThis to quickly bypass closed off directories and/or files.

Example:

func main() {
	err := godirwalk.Walk("./", &godirwalk.Options{
		Callback: func(osPathname string, info *godirwalk.Dirent) error {
			log.Println("trying:", osPathname)

			if info.CanAccess() {
				return godirwalk.SkipThis
			}

			if info.IsDir() {
				if strings.Contains(osPathname, os.Args[1]) {
					fmt.Println(osPathname)
					os.Exit(0)
				}
			}
			return nil
		},
		Unsorted: true,
	})

	if err != nil {
		// Permissions error happens here, outside the walk
		log.Println(err)
	}

	fmt.Print("no directory found")
}

I figured since you're all up in this code, you might be able to do it in a few minutes but it might take me hours :S

@zveinn
Copy link
Author

zveinn commented Mar 29, 2021

Actually, this functionality already exists in the configurable error callback.

func main() {
	err := godirwalk.Walk(os.Args[1], &godirwalk.Options{
		Callback: func(osPathname string, info *godirwalk.Dirent) error {
			log.Println("trying:", osPathname)
			if info.IsDir() {
				if strings.Contains(osPathname, os.Args[2]) {
					fmt.Println(osPathname)
					os.Exit(0)
				}
			}

			return nil
		},
		ErrorCallback: func(osPathname string, err error) godirwalk.ErrorAction {
			// 1 means continue, not sure about the other options but we can probably assume 0 means stop ?
			return 1
		},
		// Unsorted: true,
	})

	if err != nil {
		// Permissions error happens here, outside the walk
		log.Println(err)
	}

	fmt.Print("no directory found")

}

My only recommendation at this point is to maybe move the documentation about the callback higher up in the readme and maybe define what the godirwalk.ErrorAction options are ? maybe even add a code sample ?

@GwynethLlewelyn
Copy link

GwynethLlewelyn commented Aug 26, 2023

For the sake of completeness and consistency, instead of the "return 1" on the error callback, use either:

godirwalk.Halt       // set to iota, i.e. 0
godirwalk.SkipNode   // set to value next to iota, i.e. 1

At the time of writing this comment, no further options are being defined.

See https://github.com/karrick/godirwalk/blob/master/walk.go#L90 (note: line number may change depending on the version)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants