Skip to content

Conversation

@bitfehler
Copy link

The billy package contains a Change interface type, which seems to have gone unused for several years now, presumably due to the difficulty of implementing most of the required methods for all supported platforms.

This commit reduces the Change interface to a Chmod interface, which is supported on all platforms. The interface is added to the main Filesystem interface and implemented in all applicable abstractions.

Supporting chmod in billy would help with issues such as go-git/go-git#588 (which was closed as stale, but is unfortunately still a real issue for some folks).

fs.go Outdated
TempFile
Dir
Symlink
Chmod
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this to Filesystem would increase the violations of the Liskov substitution principle across the implementations.

@pjbgf
Copy link
Member

pjbgf commented Oct 22, 2025

Thanks for the PR and for linking the other issue - I have just reopened it.

On the implementation, to avoid overly ambitious interfaces (as the existing Change), or changing Filesystem, I'd probably go about this with its own interface:

type Chmod interface {
  Chmod(name string, mode fs.FileMode) error
}

Consumers would need to check support before using it:

if c, ok := fs.(billy.Chmod); ok {
  return c.Chmod(name, mode)
}

What do you think?

The billy package contains a `Change` interface type, which seems to
have gone unused for several years now, presumably due to the difficulty
of implementing most of the required methods for all supported
platforms.

This commit reduces the `Change` interface to a `Chmod` interface, which
is supported on all platforms. The interface is implemented in all
applicable abstractions.

Supporting `chmod` in billy would help with issues such as
go-git/go-git#588 (which was closed as stale,
but is unfortunately still a real issue for some folks).

Signed-off-by: Conrad Hoffmann <ch@bitfehler.net>
@bitfehler
Copy link
Author

Thanks for the PR and for linking the other issue - I have just reopened it.

Great, thanks!

On the implementation, to avoid overly ambitious interfaces (as the existing Change), or changing Filesystem, I'd probably go about this with its own interface:

type Chmod interface {
  Chmod(name string, mode fs.FileMode) error
}

Consumers would need to check support before using it:

if c, ok := fs.(billy.Chmod); ok {
  return c.Chmod(name, mode)
}

What do you think?

Yes, that totally makes sense, especially given that there are still things like embedfs that don't support chmod at all. I updated the PR accordingly.

I am honestly not entirely sure how the capabilities interface is being used in the wild. Should I add a capability for chown, or is it good enough to have folks attempt a cast like in your example?

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

Successfully merging this pull request may close these issues.

2 participants