Skip to content

Commit

Permalink
Add full chmod support
Browse files Browse the repository at this point in the history
This was already supported inside the memory file system adapter. Update the main file system adapter to support this, and expose a public method.
  • Loading branch information
timriley committed Oct 16, 2023
1 parent e4c67a4 commit e809a3c
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
19 changes: 19 additions & 0 deletions lib/dry/files.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,25 @@ def write(path, *content)
adapter.write(path, *content)
end

# Sets UNIX permissions of the file at the given path.
#
# Accepts permissions in numeric mode only, best provided as octal numbers matching the
# standard UNIX octal permission modes, such as `0o544` for a file writeable by its owner and
# readable by others, or `0o755` for a file writeable by its owner and executable by everyone.
#
# @param path [String,Pathname] the path to the file
# @param mode [Integer] the UNIX permissions mode
#
# @raise [Dry::Files::IOError] in case of I/O error
#
# @since @1.1.0
# @api public
def chmod(path, mode)
raise ArgumentError, "file mode should be an integer" unless mode.is_a?(Integer)

adapter.chmod(path, mode)
end

# Returns a new string formed by joining the strings using Operating
# System path separator
#
Expand Down
19 changes: 19 additions & 0 deletions lib/dry/files/file_system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,25 @@ def write(path, *content)
end
end

# Sets UNIX permissions of the file at the given path.
#
# Accepts permissions in numeric mode only, best provided as octal numbers matching the
# standard UNIX octal permission modes, such as `0o544` for a file writeable by its owner and
# readable by others, or `0o755` for a file writeable by its owner and executable by everyone.
#
# @param path [String,Pathname] the path to the file
# @param mode [Integer] the UNIX permissions mode
#
# @raise [Dry::Files::IOError] in case of I/O error
#
# @since @1.1.0
# @api private
def chmod(path, mode)
with_error_handling do
file_utils.chmod(mode, path)
end
end

# Returns a new string formed by joining the strings using Operating
# System path separator
#
Expand Down
34 changes: 34 additions & 0 deletions spec/integration/dry/files_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,40 @@
end
end

describe "#chmod" do
it "sets the given permissions" do
path = root.join("permissions")
subject.touch(path)
mode = path.stat.mode

begin
expect { subject.chmod(path, 0o755) }
.to change { path.executable? }.to true

expect { subject.chmod(path, 0o644) }
.to change { path.executable? }.to false
ensure
path.chmod(mode)
end
end

it "raises an argument error when the permissions are given in non-numeric format" do
path = root.join("permissions")

expect { subject.chmod(path, "+x") }.to raise_error ArgumentError, "file mode should be an integer"
end

it "raises an error when the path doesn't exist" do
path = root.join("permissions-does-not-exist")

expect { subject.chmod(path, 0o755) }.to raise_error do |exception|
expect(exception).to be_kind_of(Dry::Files::IOError)
expect(exception.cause).to be_kind_of(Errno::ENOENT)
expect(exception.message).to include(path.to_s)
end
end
end

describe "#cp" do
let(:source) { root.join("..", "source") }

Expand Down

0 comments on commit e809a3c

Please sign in to comment.