Skip to content

Commit

Permalink
Add full chmod support (#18)
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 authored Oct 18, 2023
1 parent e4c67a4 commit 4ce8303
Show file tree
Hide file tree
Showing 3 changed files with 73 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 Dry::Files::Error, "mode should be an integer (e.g. 0o755)" 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
35 changes: 35 additions & 0 deletions spec/integration/dry/files_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,41 @@
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 Dry::Files::Error, "mode should be an integer (e.g. 0o755)"
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 4ce8303

Please sign in to comment.