diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fb4a63d..154fa1c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,10 @@ - v0.11.1: The new keyword argument `returns` for `Base.write(fp::S3Path, ...)` determines the output returned from `write`, which can now be the raw `AWS.Response` (`returns=:response`) or the `S3Path` (`returns=:path`); this latter option returns an `S3Path` populated with the version ID of the written object (when versioning is enabled on the bucket) ([#293]). - v0.11.2: `s3_copy` supports the `parse_response` keyword allowing for access to the unparsed AWS API response ([#300]). - v0.11.2: Added `s3_nuke_object` function to delete all versions of an object ([#299]). +- v0.11.2: Added `S3Path` copy constructor for allowing updating `version`, `config`, and/or `isdirectory` ([#297]). [#289]: https://github.com/JuliaCloud/AWSS3.jl/pull/289 [#293]: https://github.com/JuliaCloud/AWSS3.jl/pull/293 +[#297]: https://github.com/JuliaCloud/AWSS3.jl/pull/297 [#299]: https://github.com/JuliaCloud/AWSS3.jl/pull/299 [#300]: https://github.com/JuliaCloud/AWSS3.jl/pull/300 diff --git a/src/s3path.jl b/src/s3path.jl index 6b4394ac..e9d08927 100644 --- a/src/s3path.jl +++ b/src/s3path.jl @@ -46,7 +46,8 @@ end """ S3Path() - S3Path(str; version::$(AbstractS3Version)=nothing, config::$(AbstractS3PathConfig)=nothing) + S3Path(str::AbstractString; version::$(AbstractS3Version)=nothing, config::$(AbstractS3PathConfig)=nothing) + S3Path(path::S3Path; isdirectory=path.isdirectory, version=path.version, config=path.config) Construct a new AWS S3 path type which should be of the form `"s3:///prefix/to/my/object"`. @@ -73,8 +74,6 @@ NOTES: """ S3Path() = S3Path((), "/", "", true, nothing, nothing) -S3Path(path::S3Path) = path - # below definition needed by FilePathsBase S3Path{A}() where {A<:AbstractS3PathConfig} = S3Path() @@ -107,6 +106,12 @@ function S3Path( ) end +function S3Path( + path::S3Path; isdirectory=path.isdirectory, version=path.version, config=path.config +) + return S3Path(path.bucket, path.key; isdirectory, config, version) +end + # To avoid a breaking change. function S3Path( str::AbstractString; diff --git a/test/s3path.jl b/test/s3path.jl index 36d0b872..5d0f7b9e 100644 --- a/test/s3path.jl +++ b/test/s3path.jl @@ -636,6 +636,39 @@ function s3path_tests(base_config) @test_throws ArgumentError S3Path("s3://my_bucket/"; version="") end + @testset "construct S3Path from S3Path" begin + # Use custom config to test that config is preserved in construction + config = AWSConfig(; region="bogus") + path = S3Path("s3://my_bucket/prefix"; config) + + # When no kwargs provided, return identity + @test S3Path(path) === path + + # version kwarg overrides path.version + version = String('A':'Z') * String('0':'5') + p = S3Path(path; version) + @test p != path + @test p.bucket == path.bucket + @test p.key == path.key + @test p.config == path.config + @test p.version == version != path.version + + # ...if version already exists, overwrite silently + path_versioned = S3Path(path; version) + alt_version = String('0':'5') * String('A':'Z') + p = S3Path(path_versioned; version=alt_version) + @test p.version == alt_version != path_versioned.version + + # config kwarg overrides path.config + alt_config = AWSConfig(; region="foo") + p = S3Path(path; config=alt_config) + @test p.config == alt_config != path.config + + # isdirectory kwarg overrides path.config + p = S3Path(path; isdirectory=!path.isdirectory) + @test p.isdirectory != path.isdirectory + end + # `s3_list_versions` gives `SignatureDoesNotMatch` exceptions on Minio if is_aws(base_config) @testset "S3Path versioning" begin