Repository: ResearchObject/ro-crate-py
Pull request #47 (2021-02-12 17:13:01)

Data entity fixes
Fixes a bug with `Dataset` creation and changes data entities to format IDs with forward slashes on all platforms.


Patch:
diff --git a/rocrate/model/dataset.py b/rocrate/model/dataset.py
index 9fd378e..57c4d24 100644
--- a/rocrate/model/dataset.py
+++ b/rocrate/model/dataset.py
@@ -18,7 +18,7 @@
 # limitations under the License.
 
 import os
-import pathlib
+from pathlib import Path
 import shutil
 
 from .data_entity import DataEntity
@@ -30,9 +30,9 @@ class Dataset(DataEntity):
         identifier = None
         self.source = source
         if not dest_path:
-            identifier = os.path.dirname(source)
+            identifier = Path(source).name
         else:
-            identifier = str(dest_path)
+            identifier = Path(dest_path).as_posix()
         super().__init__(crate, identifier, properties)
 
     def _empty(self):
@@ -64,7 +64,7 @@ class Dataset(DataEntity):
 
     def write(self, base_path):
         out_path = self.filepath(base_path)
-        pathlib.Path(out_path).mkdir(parents=True, exist_ok=True)
+        Path(out_path).mkdir(parents=True, exist_ok=True)
         for file_src, file_dest in self.directory_entries(out_path):
             file_dest_path = os.path.dirname(file_dest)
             if not os.path.exists(file_dest_path):
diff --git a/rocrate/model/file.py b/rocrate/model/file.py
index 8d88885..2876d80 100644
--- a/rocrate/model/file.py
+++ b/rocrate/model/file.py
@@ -18,7 +18,7 @@
 # limitations under the License.
 
 import os
-import pathlib
+from pathlib import Path
 import shutil
 import urllib
 
@@ -39,7 +39,7 @@ class File(DataEntity):
         self.fetch_remote = fetch_remote
         self.source = source
         is_local = is_remote = False
-        if isinstance(source, (str, pathlib.Path)):
+        if isinstance(source, (str, Path)):
             is_local = os.path.isfile(str(source))
             is_remote = is_url(str(source))
             if not is_local and not is_remote:
@@ -48,7 +48,7 @@ class File(DataEntity):
             raise ValueError("dest_path must be provided if source is not a path or URI")
         if dest_path:
             # the entity is refrencing a path relative to the ro-crate root
-            identifier = dest_path  # relative path?
+            identifier = Path(dest_path).as_posix()  # relative path?
         else:
             # if there is no dest_path there must be a URI/local path as source
             if is_local:
@@ -98,7 +98,7 @@ class File(DataEntity):
         return val
 
     def write(self, base_path):
-        base_path = pathlib.Path(base_path)
+        base_path = Path(base_path)
         out_file_path = base_path / self.id
         # check if its local or remote URI
         if isinstance(self.source, IOBase):


Test patch:
diff --git a/test/test_write.py b/test/test_write.py
index 5308814..ceef9a8 100644
--- a/test/test_write.py
+++ b/test/test_write.py
@@ -20,6 +20,7 @@ import pytest
 import sys
 import uuid
 import zipfile
+from pathlib import Path
 from urllib.error import URLError
 
 from rocrate.model.dataset import Dataset
@@ -185,3 +186,19 @@ def test_no_source_no_dest(test_data_dir, fetch_remote, validate_url):
     crate = ROCrate()
     with pytest.raises(ValueError):
         crate.add_file()
+
+
+def test_dataset(test_data_dir, tmpdir):
+    crate = ROCrate()
+    path = test_data_dir / "a" / "b"
+    d1 = crate.add_dataset(str(path))
+    assert crate.dereference("b") is d1
+    d2 = crate.add_dataset(str(path), "a/b")
+    assert crate.dereference("a/b") is d2
+
+    out_path = tmpdir / 'ro_crate_out'
+    out_path.mkdir()
+    crate.write_crate(out_path)
+
+    assert (out_path / "b").is_dir()
+    assert (out_path / "a" / "b").is_dir()