Skip to content

Commit

Permalink
Implement Base.mkpath() for SFTP
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesWrigley committed Dec 6, 2024
1 parent 305150e commit 4b3088f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 0 deletions.
3 changes: 3 additions & 0 deletions docs/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Changelog](https://keepachangelog.com).

## Unreleased

### Added
- Implemented [`Base.mkpath(::AbstractString, ::SftpSession)`](@ref) ([#30]).

### Fixed
- Fixed behaviour of the [`Session`](@ref)`.known_hosts` property ([#30]).

Expand Down
1 change: 1 addition & 0 deletions docs/src/sftp.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Base.unlock(::SftpSession)
Base.readdir(::AbstractString, ::SftpSession)
Base.rm(::AbstractString, ::SftpSession)
Base.mkdir(::AbstractString, ::SftpSession)
Base.mkpath(::AbstractString, ::SftpSession)
Base.mv(::AbstractString, ::AbstractString, ::SftpSession)
Base.stat(::String, ::SftpSession)
get_extensions(::SftpSession)
Expand Down
31 changes: 31 additions & 0 deletions src/sftp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,37 @@ end
"""
$(TYPEDSIGNATURES)
Create a remote path. This behaves in exactly the same way as `Base.mkpath()`.
# Throws
- `ArgumentError`: If `sftp` is closed.
- [`SftpException`](@ref): If making the path fails for some reason, such as
part of `path` being an existing file.
"""
function Base.mkpath(path::AbstractString, sftp::SftpSession; mode=0o777)
if !isopen(sftp)
throw(ArgumentError("$(sftp) is closed, cannot use it to mkpath()"))
end

parts = splitpath(path)
for i in eachindex(parts)
part= joinpath(parts[1:i])

try
mkdir(part, sftp; mode)
catch ex
if !(ex isa SftpException && ex.error_code == SftpError_FileAlreadyExists && isdir(part, sftp))
rethrow()
end
end
end

return path
end

"""
$(TYPEDSIGNATURES)
Move `src` to `dst` remotely. Has the same behaviour as `Base.mv()`.
# Throws
Expand Down
15 changes: 15 additions & 0 deletions test/LibSSHTests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,21 @@ end
@test_throws ssh.SftpException mkdir(path, sftp)
end

# Test mkpath()
mktempdir() do tmpdir
parent_dir = joinpath(tmpdir, "foo")
path = joinpath(parent_dir, "bar")

# Creating a path with no existing files in the name should work
@test mkpath(path, sftp) == path
@test isdir(path)

# But if there's a file already in there we should get an exception
rm(parent_dir; force=true, recursive=true)
touch(parent_dir)
@test_throws ssh.SftpException mkpath(path, sftp)
end

# Test mv()
mktempdir() do tmpdir
src = joinpath(tmpdir, "foo")
Expand Down

0 comments on commit 4b3088f

Please sign in to comment.