Skip to content

Commit

Permalink
Merge pull request #63 from bcdev/forman-55-lock_file_issue
Browse files Browse the repository at this point in the history
Report that target parent must exist
  • Loading branch information
thomasstorm authored Feb 12, 2024
2 parents 9e6ec28 + a7e02b1 commit 906f8ad
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 3 deletions.
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## Version 0.4.1 (in development)

### Fixes

* If the target _parent_ directory did not exist, an exception was raised
reporting that the lock file to be written does not exist. Changed this to
report that the target parent directory does not exist. [#55]

### Enhancements

* Added missing documentation of the `append_step` setting in the
Expand Down
2 changes: 1 addition & 1 deletion docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ Variable metadata.
## `target_dir`

Type _string_.
The URI or local path of the target Zarr dataset. Must be a directory.
The URI or local path of the target Zarr dataset. Must specify a directory whose parent directory must exist.

## `target_storage_options`

Expand Down
4 changes: 3 additions & 1 deletion docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ zappend(os.listdir("inputs"), target_dir="output/mycube.zarr")

Both invocations will create the Zarr dataset `output/mycube.zarr` by concatenating
the "slice" datasets provided in the `inputs` directory along their `time` dimension.
Both the CLI command and the Python function can be run without any further
`target_dir` must specify a directory for the Zarr dataset. (Its parent directory must
exist.) Both the CLI command and the Python function can be run without any further
configuration provided the paths of the target dataset and the source slice datasets
are given. The target dataset path must point to a directory that will contain a Zarr
group to be created and updated. The slice dataset paths may be provided as Zarr as
Expand Down Expand Up @@ -433,6 +434,7 @@ You can disable transaction management by specifying
The `target_dir` setting is mandatory. If it is not specified in the configuration,
it must be passed either as `--target` or `-t` option to the `zappend` command or as
`target_dir` keyword argument when using the `zappend` Python function.
Note, the parent directory of `target_dir` must already exist.

If the target path is given for another filesystem, additional storage options may be
passed using the optional `target_storage_options` setting.
Expand Down
15 changes: 15 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ def test_some_slices_local(self):
for slice_dir in slices:
shutil.rmtree(slice_dir, ignore_errors=True)

def test_some_slices_local_output_to_non_existing_dir(self):
target_dir = "non_existent_dir/target.zarr"
slices = [
"slice-1.zarr",
"slice-2.zarr",
"slice-3.zarr",
]
for uri in slices:
make_test_dataset(uri=uri)
with pytest.raises(
FileNotFoundError,
match="\\ATarget parent directory does not exist: .*/non_existent_dir\\Z",
):
zappend(slices, target_dir=target_dir)

def test_some_slices_with_class_slice_source(self):
target_dir = "memory://target.zarr"
slices = [make_test_dataset(), make_test_dataset(), make_test_dataset()]
Expand Down
2 changes: 1 addition & 1 deletion zappend/config/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@
target_dir={
"description": (
"The URI or local path of the target Zarr dataset."
" Must be a directory."
" Must specify a directory whose parent directory must exist."
),
"type": "string",
"minLength": 1,
Expand Down
6 changes: 6 additions & 0 deletions zappend/fsutil/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ def __enter__(self):
)
self._entered_ctx = True

if not self.target_dir.parent.exists():
raise FileNotFoundError(
f"Target parent directory does not exist:"
f" {self.target_dir.parent.path}"
)

lock_file = self._lock_file
if lock_file.exists():
raise OSError(f"Target is locked: {lock_file.uri}")
Expand Down

0 comments on commit 906f8ad

Please sign in to comment.