From 350d9e4593e5a1d69b720a59cf7cc20083158234 Mon Sep 17 00:00:00 2001 From: Simeon Warner Date: Fri, 11 Oct 2024 00:12:06 -0700 Subject: [PATCH] Tidy --- build_demo_docs.sh | 7 +- docs/README.md | 3 +- docs/demo_build_v1_0_spec_examples.md | 20 ++--- docs/demo_build_v1_1_spec_examples.md | 20 ++--- docs/demo_ocfl_object_script.md | 57 ++++++++------ docs/demo_ocfl_script.md | 48 ++++++++++-- docs/demo_ocfl_sidecar_script.md | 84 ++++++++++++++++++--- docs/demo_ocfl_validate_script.md | 10 +-- docs/demo_using_bagit_bags.md | 26 +++---- ocfl-sidecar.py | 7 +- tests/test_demo_build_spec_v1_0_examples.py | 2 +- tests/test_demo_build_spec_v1_1_examples.py | 2 +- tests/test_demo_ocfl_sidecar_script.py | 38 +++++++++- 13 files changed, 237 insertions(+), 87 deletions(-) diff --git a/build_demo_docs.sh b/build_demo_docs.sh index ac9b3b88..0c9a6d08 100755 --- a/build_demo_docs.sh +++ b/build_demo_docs.sh @@ -1,8 +1,9 @@ #!/bin/bash -python tests/test_demo_build_spec_v1_0_examples.py > docs/demo_build_v1_0_spec_examples.md -python tests/test_demo_build_spec_v1_1_examples.py > docs/demo_build_v1_1_spec_examples.md +python tests/test_demo_ocfl_script.py > docs/demo_ocfl_script.md python tests/test_demo_ocfl_object_script.py > docs/demo_ocfl_object_script.md -python tests/test_demo_ocfl_store_script.py > docs/demo_ocfl_store_script.md +python tests/test_demo_ocfl_validate_script.py > docs/demo_ocfl_validate_script.md python tests/test_demo_using_bagit_bags.py > docs/demo_using_bagit_bags.md python tests/test_demo_ocfl_sidecar_script.py > docs/demo_ocfl_sidecar_script.md +python tests/test_demo_build_spec_v1_0_examples.py > docs/demo_build_v1_0_spec_examples.md +python tests/test_demo_build_spec_v1_1_examples.py > docs/demo_build_v1_1_spec_examples.md diff --git a/docs/README.md b/docs/README.md index 168741b3..e0563673 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,8 @@ Documentation is limited to a set of example run outputs, mostly produced automa * [OCFL Object and Storage Root validation script](demo_ocfl_validate_script.md) * [OCFL Object manipulation using Bagit bags to import and export versions](demo_using_bagit_bags.md) * [OCFL Sidecar creation and update script](demo_ocfl_sidecar_script.md) - * [Examples using `ocfl-object.py` to build the inventory examples used in the specification](demo_build_spec_examples.md) + * [Examples using `ocfl-object.py` to build the inventory examples used in the v1.0 specification](demo_build_v1_0_spec_examples.md) + * [Examples using `ocfl-object.py` to build the inventory examples used in the v1.1 specification](demo_build_v1_1_spec_examples.md) * [Use of JSON Schema to do partial validation on `inventory.json`](demo_jsonschema_inventory_validation.md) There is also a list of error and warning codes generated by `ocfl-validate.py` diff --git a/docs/demo_build_v1_0_spec_examples.md b/docs/demo_build_v1_0_spec_examples.md index 5671112f..b8b9625c 100644 --- a/docs/demo_build_v1_0_spec_examples.md +++ b/docs/demo_build_v1_0_spec_examples.md @@ -2,14 +2,14 @@ _Output from `tests/test_demo_build_spec_v1_0_examples.py`._ -## 1. Test for minumal example. +## 1. Test for minimal example. ### 1.1 Minimal example The digest type sha512-spec-ex is sha512 with most of the content stripped out and replaced with an ellipsis. This is inventory should match the example in . ``` -> python ocfl-object.py --build --src fixtures/1.0/content/spec-ex-minimal --id http://example.org/minimal --spec-version 1.0 --digest sha512-spec-ex --created 2018-10-02T12:00:00Z --message One file --name Alice --address alice@example.org -v +> python ocfl-object.py build --src fixtures/1.0/content/spec-ex-minimal --id http://example.org/minimal --spec-version 1.0 --digest sha512-spec-ex --created 2018-10-02T12:00:00Z --message One file --name Alice --address alice@example.org -v WARNING:ocfl.object:### Inventory for v1{ "digestAlgorithm": "sha512-spec-ex", "head": "v1", @@ -47,7 +47,7 @@ WARNING:ocfl.object:### Inventory for v1{ This is inventory should match the example with 3 versions in . ``` -> python ocfl-object.py --build --src fixtures/1.0/content/spec-ex-full --spec-version 1.0 --id ark:/12345/bcd987 --fixity md5 --fixity sha1 --digest sha512-spec-ex -v +> python ocfl-object.py build --src fixtures/1.0/content/spec-ex-full --spec-version 1.0 --id ark:/12345/bcd987 --fixity md5 --fixity sha1 --digest sha512-spec-ex -v WARNING:ocfl.object:### Inventory for v1{ "digestAlgorithm": "sha512-spec-ex", "fixity": { @@ -90,7 +90,7 @@ WARNING:ocfl.object:### Inventory for v1{ "type": "https://ocfl.io/1.0/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:51.144164Z", + "created": "2024-10-11T07:04:27.308760Z", "state": { "7dcc352f96c56dc...c31": [ "foo/bar.xml" @@ -157,7 +157,7 @@ WARNING:ocfl.object:### Inventory for v2{ "type": "https://ocfl.io/1.0/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:51.144164Z", + "created": "2024-10-11T07:04:27.308760Z", "state": { "7dcc352f96c56dc...c31": [ "foo/bar.xml" @@ -171,7 +171,7 @@ WARNING:ocfl.object:### Inventory for v2{ } }, "v2": { - "created": "2024-10-01T12:11:51.145036Z", + "created": "2024-10-11T07:04:27.309573Z", "state": { "4d27c86b026ff70...b53": [ "foo/bar.xml" @@ -236,7 +236,7 @@ WARNING:ocfl.object:### Inventory for v3{ "type": "https://ocfl.io/1.0/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:51.144164Z", + "created": "2024-10-11T07:04:27.308760Z", "state": { "7dcc352f96c56dc...c31": [ "foo/bar.xml" @@ -250,7 +250,7 @@ WARNING:ocfl.object:### Inventory for v3{ } }, "v2": { - "created": "2024-10-01T12:11:51.145036Z", + "created": "2024-10-11T07:04:27.309573Z", "state": { "4d27c86b026ff70...b53": [ "foo/bar.xml" @@ -262,7 +262,7 @@ WARNING:ocfl.object:### Inventory for v3{ } }, "v3": { - "created": "2024-10-01T12:11:51.145505Z", + "created": "2024-10-11T07:04:27.310019Z", "state": { "4d27c86b026ff70...b53": [ "foo/bar.xml" @@ -288,7 +288,7 @@ WARNING:ocfl.object:### Inventory for v3{ This is inventory should match the example showing how content paths may differ from logical paths in . ``` -> python ocfl-object.py --build --src fixtures/1.0/content/spec-ex-diff-paths --id http://example.org/diff-paths --spec-version 1.0 --digest sha512-spec-ex --normalization md5 --created 2019-03-14T20:31:00Z -v +> python ocfl-object.py build --src fixtures/1.0/content/spec-ex-diff-paths --id http://example.org/diff-paths --spec-version 1.0 --digest sha512-spec-ex --normalization md5 --created 2019-03-14T20:31:00Z -v WARNING:ocfl.object:### Inventory for v1{ "digestAlgorithm": "sha512-spec-ex", "head": "v1", diff --git a/docs/demo_build_v1_1_spec_examples.md b/docs/demo_build_v1_1_spec_examples.md index 5f11c721..e4d1d29a 100644 --- a/docs/demo_build_v1_1_spec_examples.md +++ b/docs/demo_build_v1_1_spec_examples.md @@ -2,14 +2,14 @@ _Output from `tests/test_demo_build_spec_v1_1_examples.py`._ -## 1. Test for minumal example. +## 1. Test for minimal example. ### 1.1 Minimal example The digest type sha512-spec-ex is sha512 with most of the content stripped out and replaced with an ellipsis. This is inventory should match the example in . ``` -> python ocfl-object.py --build --src fixtures/1.1/content/spec-ex-minimal --id http://example.org/minimal --spec-version 1.1 --digest sha512-spec-ex --created 2018-10-02T12:00:00Z --message One file --name Alice --address alice@example.org -v +> python ocfl-object.py build --src fixtures/1.1/content/spec-ex-minimal --id http://example.org/minimal --spec-version 1.1 --digest sha512-spec-ex --created 2018-10-02T12:00:00Z --message One file --name Alice --address alice@example.org -v WARNING:ocfl.object:### Inventory for v1{ "digestAlgorithm": "sha512-spec-ex", "head": "v1", @@ -47,7 +47,7 @@ WARNING:ocfl.object:### Inventory for v1{ This is inventory should match the example with 3 versions in . ``` -> python ocfl-object.py --build --src fixtures/1.1/content/spec-ex-full --spec-version 1.1 --id ark:/12345/bcd987 --fixity md5 --fixity sha1 --digest sha512-spec-ex -v +> python ocfl-object.py build --src fixtures/1.1/content/spec-ex-full --spec-version 1.1 --id ark:/12345/bcd987 --fixity md5 --fixity sha1 --digest sha512-spec-ex -v WARNING:ocfl.object:### Inventory for v1{ "digestAlgorithm": "sha512-spec-ex", "fixity": { @@ -90,7 +90,7 @@ WARNING:ocfl.object:### Inventory for v1{ "type": "https://ocfl.io/1.1/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:51.675916Z", + "created": "2024-10-11T07:04:27.845344Z", "state": { "7dcc352f96c56dc...c31": [ "foo/bar.xml" @@ -157,7 +157,7 @@ WARNING:ocfl.object:### Inventory for v2{ "type": "https://ocfl.io/1.1/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:51.675916Z", + "created": "2024-10-11T07:04:27.845344Z", "state": { "7dcc352f96c56dc...c31": [ "foo/bar.xml" @@ -171,7 +171,7 @@ WARNING:ocfl.object:### Inventory for v2{ } }, "v2": { - "created": "2024-10-01T12:11:51.676579Z", + "created": "2024-10-11T07:04:27.846110Z", "state": { "4d27c86b026ff70...b53": [ "foo/bar.xml" @@ -236,7 +236,7 @@ WARNING:ocfl.object:### Inventory for v3{ "type": "https://ocfl.io/1.1/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:51.675916Z", + "created": "2024-10-11T07:04:27.845344Z", "state": { "7dcc352f96c56dc...c31": [ "foo/bar.xml" @@ -250,7 +250,7 @@ WARNING:ocfl.object:### Inventory for v3{ } }, "v2": { - "created": "2024-10-01T12:11:51.676579Z", + "created": "2024-10-11T07:04:27.846110Z", "state": { "4d27c86b026ff70...b53": [ "foo/bar.xml" @@ -262,7 +262,7 @@ WARNING:ocfl.object:### Inventory for v3{ } }, "v3": { - "created": "2024-10-01T12:11:51.677024Z", + "created": "2024-10-11T07:04:27.846566Z", "state": { "4d27c86b026ff70...b53": [ "foo/bar.xml" @@ -288,7 +288,7 @@ WARNING:ocfl.object:### Inventory for v3{ This is inventory should match the example showing how content paths may differ from logical paths in . ``` -> python ocfl-object.py --build --src fixtures/1.1/content/spec-ex-diff-paths --id http://example.org/diff-paths --spec-version 1.1 --digest sha512-spec-ex --normalization md5 --created 2019-03-14T20:31:00Z -v +> python ocfl-object.py build --src fixtures/1.1/content/spec-ex-diff-paths --id http://example.org/diff-paths --spec-version 1.1 --digest sha512-spec-ex --normalization md5 --created 2019-03-14T20:31:00Z -v WARNING:ocfl.object:### Inventory for v1{ "digestAlgorithm": "sha512-spec-ex", "head": "v1", diff --git a/docs/demo_ocfl_object_script.md b/docs/demo_ocfl_object_script.md index f442ea09..0c3fa6b0 100644 --- a/docs/demo_ocfl_object_script.md +++ b/docs/demo_ocfl_object_script.md @@ -21,7 +21,7 @@ ocfl-object.py is part of ocfl-py version 1.9.0 Without an `--objdir` argument the script just writes out the inventory for the object that would have been created. ``` -> python ocfl-object.py --create --id http://example.org/obj1 --src fixtures/1.0/content/cf1/v1 +> python ocfl-object.py create --id http://example.org/obj1 --src fixtures/1.0/content/cf1/v1 WARNING:ocfl.object:### Inventory for v1{ "digestAlgorithm": "sha512", "head": "v1", @@ -34,7 +34,7 @@ WARNING:ocfl.object:### Inventory for v1{ "type": "https://ocfl.io/1.1/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:52.198398Z", + "created": "2024-10-11T07:04:22.583276Z", "state": { "43a43fe8a8a082d3b5343dfaf2fd0c8b8e370675b1f376e92e9994612c33ea255b11298269d72f797399ebb94edeefe53df243643676548f584fb8603ca53a0f": [ "a_file.txt" @@ -52,7 +52,7 @@ WARNING:ocfl.object:### Inventory for v1{ Without an `--objdir` argument the script just writes out the inventory for each version in the object that would have been created. ``` -> python ocfl-object.py --build --id http://example.org/obj2 --src fixtures/1.0/content/cf3 +> python ocfl-object.py build --id http://example.org/obj2 --src fixtures/1.0/content/cf3 WARNING:ocfl.object:### Inventory for v1{ "digestAlgorithm": "sha512", "head": "v1", @@ -65,7 +65,7 @@ WARNING:ocfl.object:### Inventory for v1{ "type": "https://ocfl.io/1.1/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:52.343080Z", + "created": "2024-10-11T07:04:22.727134Z", "state": { "43a43fe8a8a082d3b5343dfaf2fd0c8b8e370675b1f376e92e9994612c33ea255b11298269d72f797399ebb94edeefe53df243643676548f584fb8603ca53a0f": [ "a_file.txt" @@ -90,7 +90,7 @@ WARNING:ocfl.object:### Inventory for v2{ "type": "https://ocfl.io/1.1/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:52.343080Z", + "created": "2024-10-11T07:04:22.727134Z", "state": { "43a43fe8a8a082d3b5343dfaf2fd0c8b8e370675b1f376e92e9994612c33ea255b11298269d72f797399ebb94edeefe53df243643676548f584fb8603ca53a0f": [ "a_file.txt" @@ -98,7 +98,7 @@ WARNING:ocfl.object:### Inventory for v2{ } }, "v2": { - "created": "2024-10-01T12:11:52.343591Z", + "created": "2024-10-11T07:04:22.727775Z", "state": { "296e72b8fd5f7f0ac1473993600ae34953d5dab646f17e7b182b8648aff830d7bf01b56490777cb3e72b33fcc1ae520506badea1032252d1a55fd7362e269975": [ "a_file.txt" @@ -123,7 +123,7 @@ WARNING:ocfl.object:### Inventory for v3{ "type": "https://ocfl.io/1.1/spec/#inventory", "versions": { "v1": { - "created": "2024-10-01T12:11:52.343080Z", + "created": "2024-10-11T07:04:22.727134Z", "state": { "43a43fe8a8a082d3b5343dfaf2fd0c8b8e370675b1f376e92e9994612c33ea255b11298269d72f797399ebb94edeefe53df243643676548f584fb8603ca53a0f": [ "a_file.txt" @@ -131,7 +131,7 @@ WARNING:ocfl.object:### Inventory for v3{ } }, "v2": { - "created": "2024-10-01T12:11:52.343591Z", + "created": "2024-10-11T07:04:22.727775Z", "state": { "296e72b8fd5f7f0ac1473993600ae34953d5dab646f17e7b182b8648aff830d7bf01b56490777cb3e72b33fcc1ae520506badea1032252d1a55fd7362e269975": [ "a_file.txt" @@ -139,7 +139,7 @@ WARNING:ocfl.object:### Inventory for v3{ } }, "v3": { - "created": "2024-10-01T12:11:52.343826Z", + "created": "2024-10-11T07:04:22.728036Z", "state": { "43a43fe8a8a082d3b5343dfaf2fd0c8b8e370675b1f376e92e9994612c33ea255b11298269d72f797399ebb94edeefe53df243643676548f584fb8603ca53a0f": [ "a_file.txt" @@ -157,7 +157,7 @@ WARNING:ocfl.object:### Inventory for v3{ ### 3.1 New object with just v1 ``` -> python ocfl-object.py --create --id http://example.org/obj1 --src fixtures/1.0/content/cf1/v1 --objdir tmp/obj1 -v +> python ocfl-object.py create --id http://example.org/obj1 --src fixtures/1.0/content/cf1/v1 --objdir tmp/obj1 -v INFO:ocfl.object:Created OCFL object http://example.org/obj1 in tmp/obj1 ``` @@ -167,7 +167,7 @@ INFO:ocfl.object:Created OCFL object http://example.org/obj1 in tmp/obj1 ### 4.1 New object with three versions ``` -> python ocfl-object.py --build --id http://example.org/obj2 --src fixtures/1.0/content/cf3 --objdir tmp/obj2 -v +> python ocfl-object.py build --id http://example.org/obj2 --src fixtures/1.0/content/cf3 --objdir tmp/obj2 -v INFO:ocfl.object:Built object http://example.org/obj2 with 3 versions ``` @@ -177,7 +177,7 @@ INFO:ocfl.object:Built object http://example.org/obj2 with 3 versions ### 5.1 Extract v1 of an OCFL v1.0 object ``` -> python ocfl-object.py --extract v1 --objdir fixtures/1.0/good-objects/spec-ex-full --dstdir tmp/v1 -v +> python ocfl-object.py extract --objver v1 --objdir fixtures/1.0/good-objects/spec-ex-full --dstdir tmp/v1 -v INFO:ocfl.object:Extracted v1 into tmp/v1 Extracted content for v1 in tmp/v1 ``` @@ -186,12 +186,22 @@ Extracted content for v1 in tmp/v1 ### 5.2 Extract v2 of content in the same OCFL v1.1 object ``` -> python ocfl-object.py --extract v2 --objdir fixtures/1.1/good-objects/spec-ex-full --dstdir tmp/v2 -v +> python ocfl-object.py extract --objver v2 --objdir fixtures/1.1/good-objects/spec-ex-full --dstdir tmp/v2 -v INFO:ocfl.object:Extracted v2 into tmp/v2 Extracted content for v2 in tmp/v2 ``` +### 5.3 Extract head version (v3) of content in the same OCFL v1.1 object + +``` +> python ocfl-object.py extract --objver head --objdir fixtures/1.1/good-objects/spec-ex-full --dstdir tmp/head -v +INFO:ocfl.object:Object at fixtures/1.1/good-objects/spec-ex-full has head v3 +INFO:ocfl.object:Extracted v3 into tmp/head +Extracted content for v3 in tmp/head +``` + + ## 6. Test error conditions. ### 6.1 No valid command argument @@ -200,7 +210,7 @@ With no argument and error and suggections are shown. ``` > python ocfl-object.py -Error - Exactly one command (create, build, update, show, validate, extract) must be specified +ERROR:root:No command, nothing to do (use -h to show help) ``` (last command exited with return code 1) @@ -208,11 +218,11 @@ Error - Exactly one command (create, build, update, show, validate, extract) mus ### 6.2 No source directory (--srcdir) -The `--create` action requires a source. +The `create` command requires a source. ``` -> python ocfl-object.py --create -Error - Must specify either --srcdir or --srcbag containing v1 files when creating an OCFL object! +> python ocfl-object.py create --objdir TMP/v1 +ERROR:root:Must specify either --srcdir or --srcbag containing v1 files when creating an OCFL object! ``` (last command exited with return code 1) @@ -220,12 +230,17 @@ Error - Must specify either --srcdir or --srcbag containing v1 files when creati ### 6.3 No identifier -The `--create` action requires an identifier. +The `show` command requires --objdir. ``` -> python ocfl-object.py --create --srcdir tmp -Error - Identifier is not set! +> python ocfl-object.py show --srcdir tmp +usage: ocfl-object.py show [-h] [--verbose] [--debug] [--quiet] --objdir + OBJDIR [--spec-version SPEC_VERSION] + [--digest DIGEST] [--fixity FIXITY] [--id ID] + [--skip SKIP] [--normalization NORMALIZATION] + [--no-forward-delta] [--no-dedupe] [--lax-digests] +ocfl-object.py show: error: the following arguments are required: --objdir/--obj ``` -(last command exited with return code 1) +(last command exited with return code 2) diff --git a/docs/demo_ocfl_script.md b/docs/demo_ocfl_script.md index 3ccaedd6..c0de4822 100644 --- a/docs/demo_ocfl_script.md +++ b/docs/demo_ocfl_script.md @@ -1,6 +1,6 @@ # OCFL Object Root Store manipulation script -_Output from `tests/test_demo_ocfl_store_script.py`._ +_Output from `tests/test_demo_ocfl_script.py`._ ## 1. Test showing version number. @@ -14,12 +14,12 @@ ocfl.py is part of ocfl-py version 1.9.0 ``` -## 2. Test store initialization and object addition. +## 2. Test store creation and object addition. ### 2.1 Create new store ``` -> python ocfl.py init --root=tmp/root --layout=nnnn-flat-quoted-storage-layout -v +> python ocfl.py create --root=tmp/root --layout=nnnn-flat-quoted-storage-layout -v Created OCFL storage root tmp/root ``` @@ -71,7 +71,7 @@ Found 3 OCFL Objects under root extra_fixtures/good-storage-roots/simple-root ### 4.1 Create new store ``` -> python ocfl.py init --root=tmp/root --layout=0002-flat-direct-storage-layout -v +> python ocfl.py create --root=tmp/root --layout=0002-flat-direct-storage-layout -v Created OCFL storage root tmp/root ``` @@ -91,7 +91,7 @@ ERROR:root:Must specify object path with --src ### 5.1 Create new store ``` -> python ocfl.py init --root=tmp/ex2 --spec-version=1.0 --layout=0003-hash-and-id-n-tuple-storage-layout --layout-params={"digestAlgorithm":"md5", "tupleSize":2, "numberOfTuples":15} -v +> python ocfl.py create --root=tmp/ex2 --spec-version=1.0 --layout=0003-hash-and-id-n-tuple-storage-layout --layout-params={"digestAlgorithm":"md5", "tupleSize":2, "numberOfTuples":15} -v Created OCFL storage root tmp/ex2 ``` @@ -113,3 +113,41 @@ INFO:root:Storage root layout is 0003-hash-and-id-n-tuple-storage-layout Added object ..hor/rib:le-$id at path 08/31/97/66/fb/6c/29/35/dd/17/5b/94/26/77/17/%2e%2ehor%2frib%3ale-%24id ``` + +## 6. Test error conditions. + +### 6.1 No valid command argument + +With no argument and error and suggections are shown. + +``` +> python ocfl.py +ERROR:root:No command, nothing to do (use -h to show help) +``` + +(last command exited with return code 1) + + +### 6.2 No source directory (--srcdir) + +The `create` command requires a root to be specifed. + +``` +> python ocfl.py create +ERROR:root:The storage root must be set either via --root or $OCFL_ROOT +``` + +(last command exited with return code 1) + + +### 6.3 No identifier + +The `show` command requires an identifier. + +``` +> python ocfl.py show --root tmp +ERROR:root:Must specify id to act on an object in the store +``` + +(last command exited with return code 1) + diff --git a/docs/demo_ocfl_sidecar_script.md b/docs/demo_ocfl_sidecar_script.md index 5bc1694b..38e1a893 100644 --- a/docs/demo_ocfl_sidecar_script.md +++ b/docs/demo_ocfl_sidecar_script.md @@ -14,7 +14,7 @@ ocfl-sidecar.py is part of ocfl-py version 1.9.0 ``` -## 2. Test creation of sidecar file. +## 2. Test creation of a sidecar file. ### 2.1 Set up directory as object root @@ -32,26 +32,92 @@ fixtures/1.0/good-objects/minimal_one_version_one_file/inventory.json -> tmp/obj ``` -### 2.3 Create sidecar +### 2.3 Create sidecar for inventory in specified object The digest type will be set by reading the inventory (in this case, sha512) ``` > python ocfl-sidecar.py tmp/obj -INFO:root:Looking at path tmp/obj -INFO:root:Written sidecar file inventory.json.sha512 -Done. +Written sidecar file tmp/obj/inventory.json.sha512 ``` -### 2.4 Create a new sidecar with a different digest +### 2.4 Create sidecar for specified inventory + +The digest type will be set by reading the inventory (in this case, sha512) + +``` +> python ocfl-sidecar.py tmp/obj/inventory.json +Written sidecar file tmp/obj/inventory.json.sha512 +``` + + +### 2.5 Create a new sidecar with a different digest The digest type is set with the --digest parameter ``` > python ocfl-sidecar.py --digest sha256 tmp/obj -INFO:root:Looking at path tmp/obj -INFO:root:Written sidecar file inventory.json.sha256 -Done. +Written sidecar file tmp/obj/inventory.json.sha256 +``` + + +## 3. Test creation of multiple sidecar files. + +### 3.1 Set up directory as object 1 root + +``` +> mkdir -v tmp/obj1 +tmp/obj1 +``` + + +### 3.2 Set up directory as object 2 root + +``` +> mkdir -v tmp/obj2 +tmp/obj2 +``` + + +### 3.3 Set up directory as object 3 root + +``` +> mkdir -v tmp/obj3 +tmp/obj3 +``` + + +### 3.4 Copy in an inventory from an example for object 1 + +``` +> cp -v fixtures/1.1/good-objects/minimal_uppercase_digests/inventory.json tmp/obj1 +fixtures/1.1/good-objects/minimal_uppercase_digests/inventory.json -> tmp/obj1/inventory.json +``` + + +### 3.5 Copy in an inventory from an example for object 2 + +``` +> cp -v fixtures/1.1/good-objects/minimal_mixed_digests/inventory.json tmp/obj2 +fixtures/1.1/good-objects/minimal_mixed_digests/inventory.json -> tmp/obj2/inventory.json +``` + + +### 3.6 Copy in an inventory from an example for object 3 + +``` +> cp -v fixtures/1.1/good-objects/minimal_no_content/inventory.json tmp/obj3 +fixtures/1.1/good-objects/minimal_no_content/inventory.json -> tmp/obj3/inventory.json +``` + + +### 3.7 Create sidecars for all 3 inventory files + +``` +> python ocfl-sidecar.py tmp/obj1 tmp/obj2 tmp/obj3 +Written sidecar file tmp/obj1/inventory.json.sha512 +Written sidecar file tmp/obj2/inventory.json.sha512 +Written sidecar file tmp/obj3/inventory.json.sha512 ``` diff --git a/docs/demo_ocfl_validate_script.md b/docs/demo_ocfl_validate_script.md index e03e0e39..07c9df78 100644 --- a/docs/demo_ocfl_validate_script.md +++ b/docs/demo_ocfl_validate_script.md @@ -10,7 +10,7 @@ The `--version` argument will show version number and exit ``` > python ocfl-validate.py --version -ocfl-validate.py is part of ocfl-py version 0.0.7 +ocfl-validate.py is part of ocfl-py version 1.9.0 ``` @@ -20,7 +20,7 @@ ocfl-validate.py is part of ocfl-py version 0.0.7 ``` > python ocfl-validate.py fixtures/1.0/good-objects/minimal_uppercase_digests -INFO:ocfl.object:OCFL object at fixtures/1.0/good-objects/minimal_uppercase_digests is VALID +OCFL v1.0 Object at fixtures/1.0/good-objects/minimal_uppercase_digests is VALID ``` @@ -30,7 +30,7 @@ INFO:ocfl.object:OCFL object at fixtures/1.0/good-objects/minimal_uppercase_dige ``` > python ocfl-validate.py -q fixtures/1.0/warn-objects/W004_uses_sha256 -INFO:ocfl.object:OCFL object at fixtures/1.0/warn-objects/W004_uses_sha256 is VALID +OCFL v1.0 Object at fixtures/1.0/warn-objects/W004_uses_sha256 is VALID ``` @@ -38,7 +38,7 @@ INFO:ocfl.object:OCFL object at fixtures/1.0/warn-objects/W004_uses_sha256 is VA ``` > python ocfl-validate.py fixtures/1.0/warn-objects/W004_uses_sha256 -INFO:ocfl.object:OCFL object at fixtures/1.0/warn-objects/W004_uses_sha256 is VALID -[W004] OCFL Object root inventory SHOULD use sha512 but uses sha256 as the DigestAlgorithm (see https://ocfl.io/draft/spec/#W004) +[W004] OCFL Object root inventory SHOULD use sha512 but uses sha256 as the DigestAlgorithm (see https://ocfl.io/1.0/spec/#W004) +OCFL v1.0 Object at fixtures/1.0/warn-objects/W004_uses_sha256 is VALID ``` diff --git a/docs/demo_using_bagit_bags.md b/docs/demo_using_bagit_bags.md index 676ffa89..4809ef1b 100644 --- a/docs/demo_using_bagit_bags.md +++ b/docs/demo_using_bagit_bags.md @@ -9,7 +9,7 @@ _Output from `tests/test_demo_using_bagit_bags.py`._ Imagine that we have a Bagit bag [`tests/testdata/bags/uaa_v1`](https://github.com/zimeon/ocfl-py/tree/main/tests/testdata/bags/uaa_v1) that represents the initial state of an object. We can use `--create` to make a new OCFL object `/tmp/obj` with that content as the `v1` state: ``` -> python ocfl-object.py --create --objdir tmp/obj --srcbag tests/testdata/bags/uaa_v1 -v +> python ocfl-object.py create --objdir tmp/obj --srcbag tests/testdata/bags/uaa_v1 -v INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v1/data/my_content/dracula.txt INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v1/data/my_content/poe.txt INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v1/bagit.txt @@ -25,7 +25,7 @@ Now that we have the object it is of course valid. ``` > python ocfl-validate.py tmp/obj -INFO:ocfl.object:OCFL v1.1 Object at tmp/obj is VALID +OCFL v1.1 Object at tmp/obj is VALID ``` @@ -34,7 +34,7 @@ INFO:ocfl.object:OCFL v1.1 Object at tmp/obj is VALID Looking inside the object we see `v1` with the expected 2 content files. ``` -> python ocfl-object.py --show --objdir tmp/obj +> python ocfl-object.py show --objdir tmp/obj WARNING:ocfl.object:OCFL v1.1 Object at tmp/obj has VALID STRUCTURE (DIGESTS NOT CHECKED) WARNING:root:Object tree [tmp/obj] @@ -54,7 +54,7 @@ WARNING:root:Object tree If we have a bag [`tests/testdata/bags/uaa_v2`](https://github.com/zimeon/ocfl-py/tree/main/tests/testdata/bags/uaa_v2) with updated content we can `--update` the object to create `v2`. ``` -> python ocfl-object.py --update --objdir tmp/obj --srcbag tests/testdata/bags/uaa_v2 -v +> python ocfl-object.py update --objdir tmp/obj --srcbag tests/testdata/bags/uaa_v2 -v INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v2/data/my_content/a_second_copy_of_dracula.txt INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v2/data/my_content/dracula.txt INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v2/data/my_content/poe-nevermore.txt @@ -72,7 +72,7 @@ INFO:ocfl.object:Updated OCFL object info:bb123cd4567 in tmp/obj by adding v2 Looking inside the object we now see `v1` and `v2`. There are no content files inside `v2` because although this update added two files they have identical content (and hence digest) as one of the files in `v1` ``` -> python ocfl-object.py --show --objdir tmp/obj +> python ocfl-object.py show --objdir tmp/obj WARNING:ocfl.object:OCFL v1.1 Object at tmp/obj has VALID STRUCTURE (DIGESTS NOT CHECKED) WARNING:root:Object tree [tmp/obj] @@ -95,7 +95,7 @@ WARNING:root:Object tree Similarly we can `--update` with [`tests/testdata/bags/uaa_v3`](https://github.com/zimeon/ocfl-py/tree/main/tests/testdata/bags/uaa_v3) to create `v3`. ``` -> python ocfl-object.py --update --objdir tmp/obj --srcbag tests/testdata/bags/uaa_v3 -v +> python ocfl-object.py update --objdir tmp/obj --srcbag tests/testdata/bags/uaa_v3 -v INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v3/data/my_content/dracula.txt INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v3/data/my_content/poe-nevermore.txt INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v3/data/my_content/another_directory/a_third_copy_of_dracula.txt @@ -112,7 +112,7 @@ INFO:ocfl.object:Updated OCFL object info:bb123cd4567 in tmp/obj by adding v3 Looking inside again we see that `v3` does add another content file. ``` -> python ocfl-object.py --show --objdir tmp/obj +> python ocfl-object.py show --objdir tmp/obj WARNING:ocfl.object:OCFL v1.1 Object at tmp/obj has VALID STRUCTURE (DIGESTS NOT CHECKED) WARNING:root:Object tree [tmp/obj] @@ -139,7 +139,7 @@ WARNING:root:Object tree Finally, we can `--update` again with [`tests/testdata/bags/uaa_v4`](https://github.com/zimeon/ocfl-py/tree/main/tests/testdata/bags/uaa_v4) to create `v4`. ``` -> python ocfl-object.py --update --objdir tmp/obj --srcbag tests/testdata/bags/uaa_v4 -v +> python ocfl-object.py update --objdir tmp/obj --srcbag tests/testdata/bags/uaa_v4 -v INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v4/data/my_content/dracula.txt INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v4/data/my_content/dunwich.txt INFO:bagit:Verifying checksum for file /Users/sw272/src/ocfl-py/tests/testdata/bags/uaa_v4/data/my_content/poe-nevermore.txt @@ -157,12 +157,12 @@ INFO:ocfl.object:Updated OCFL object info:bb123cd4567 in tmp/obj by adding v4 Taking the newly created OCFL object `/tmp/obj` we can `--extract` the `v4` content as a Bagit bag. ``` -> python ocfl-object.py --extract v4 --objdir tmp/obj --dstbag tmp/extracted_v4 -v +> python ocfl-object.py extract --objver v4 --objdir tmp/obj --dstbag tmp/extracted_v4 -v INFO:ocfl.object:Extracted v4 into tmp/extracted_v4 INFO:bagit:Creating bag for directory tmp/extracted_v4 INFO:bagit:Creating data directory -INFO:bagit:Moving my_content to /privatetmp/extracted_v4/tmpjxsrp64j/my_content -INFO:bagit:Moving /privatetmp/extracted_v4/tmpjxsrp64j to data +INFO:bagit:Moving my_content to /privatetmp/extracted_v4/tmpkvg4v621/my_content +INFO:bagit:Moving /privatetmp/extracted_v4/tmpkvg4v621 to data INFO:bagit:Using 1 processes to generate manifests: sha512 INFO:bagit:Generating manifest lines for file data/my_content/dracula.txt INFO:bagit:Generating manifest lines for file data/my_content/dunwich.txt @@ -184,12 +184,12 @@ We note that the OCFL object had only one `content` file in `v4` but the extract diff -r tmp/extracted_v4/bag-info.txt tests/testdata/bags/uaa_v4/bag-info.txt 1,2c1 < Bag-Software-Agent: bagit.py v1.8.1 -< Bagging-Date: 2024-10-01 +< Bagging-Date: 2024-10-11 --- > Bagging-Date: 2020-01-04 diff -r tmp/extracted_v4/tagmanifest-sha512.txt tests/testdata/bags/uaa_v4/tagmanifest-sha512.txt 2c2 -< b6c3b7a9d2f840cc177626d596b1a3fe425c4607ad93c01cd113bf9c2241bf9b9242546f1c0512a17c1213f605e0df4e1911a43a49eee5a7507878329872ffd7 bag-info.txt +< d20b7a443b7721ed884e48c83c6487b7f7c59ed01868339f448700ffc3ed9926f552a5892cb3be3966e92940486de749859445ccbe10db9be23c255c6017b500 bag-info.txt --- > 10624e6d45462def7af66d1a0d977606c7b073b01809c1d42258cfab5c34a275480943cbe78044416aee1f23822cc3762f92247b8f39b5c6ddc5ae32a8f94ce5 bag-info.txt ``` diff --git a/ocfl-sidecar.py b/ocfl-sidecar.py index 19700910..b911cfbb 100755 --- a/ocfl-sidecar.py +++ b/ocfl-sidecar.py @@ -17,7 +17,7 @@ def parse_arguments(): supplied. Returns Namespace object from argparse parsing of command line arguments. - """ + """ parser = argparse.ArgumentParser( description="Update OCFL inventory sidecar file for each inventory " "path specified. Usually used without the --digest argument and the " @@ -52,7 +52,7 @@ def create_sidecar(args, directory): except ocfl.ObjectException as e: logging.warning("Failed to read inventory in directory %s (%s)", directory, e) sidecar = obj.write_inventory_sidecar() - logging.info("Written sidecar file %s", sidecar) + print("Written sidecar file %s" % (os.path.join(directory, sidecar))) def main(): @@ -60,7 +60,7 @@ def main(): args = parse_arguments() paths = ["."] if len(args.path) == 0 else args.path for path in paths: - logging.info("Looking at path %s", path) + logging.debug("Looking at path %s", path) if os.path.isdir(path): create_sidecar(args, path) else: @@ -73,4 +73,3 @@ def main(): if __name__ == "__main__": main() - print("Done.") diff --git a/tests/test_demo_build_spec_v1_0_examples.py b/tests/test_demo_build_spec_v1_0_examples.py index 8a2dfdc4..f7651077 100644 --- a/tests/test_demo_build_spec_v1_0_examples.py +++ b/tests/test_demo_build_spec_v1_0_examples.py @@ -7,7 +7,7 @@ class TestAll(DemoTestCase): """TestAll class to run tests.""" def test00_minimal_example(self): - """Test for minumal example.""" + """Test for minimal example.""" text = "The digest type sha512-spec-ex is sha512 with most of the content " \ "stripped out and replaced with an ellipsis. This is inventory should " \ "match the example in ." diff --git a/tests/test_demo_build_spec_v1_1_examples.py b/tests/test_demo_build_spec_v1_1_examples.py index 84feba6b..9aa77f0c 100644 --- a/tests/test_demo_build_spec_v1_1_examples.py +++ b/tests/test_demo_build_spec_v1_1_examples.py @@ -7,7 +7,7 @@ class TestAll(DemoTestCase): """TestAll class to run tests.""" def test00_minimal_example(self): - """Test for minumal example.""" + """Test for minimal example.""" text = "The digest type sha512-spec-ex is sha512 with most of the content " \ "stripped out and replaced with an ellipsis. This is inventory should " \ "match the example in ." diff --git a/tests/test_demo_ocfl_sidecar_script.py b/tests/test_demo_ocfl_sidecar_script.py index 60c336ee..1a105453 100644 --- a/tests/test_demo_ocfl_sidecar_script.py +++ b/tests/test_demo_ocfl_sidecar_script.py @@ -14,20 +14,50 @@ def test00_version(self): self.assertIn("ocfl-sidecar.py is part of ocfl-py version", out) def test01_create(self): - """Test creation of sidecar file.""" + """Test creation of a sidecar file.""" out = self.run_script("Set up directory as object root", ["mkdir", "-v", "TMPDIR/obj"]) out = self.run_script("Copy in an inventory from an example", ["cp", "-v", "fixtures/1.0/good-objects/minimal_one_version_one_file/inventory.json", "TMPDIR/obj"]) self.assertIn("obj/inventory.json", out) - out = self.run_script("Create sidecar", + out = self.run_script("Create sidecar for inventory in specified object", ["python", "ocfl-sidecar.py", "TMPDIR/obj"], text="The digest type will be set by reading the inventory (in this case, sha512)") - self.assertIn("INFO:root:Written sidecar file inventory.json.sha512", out) + self.assertIn("Written sidecar file", out) + self.assertIn("obj/inventory.json.sha512", out) + out = self.run_script("Create sidecar for specified inventory", + ["python", "ocfl-sidecar.py", "TMPDIR/obj/inventory.json"], + text="The digest type will be set by reading the inventory (in this case, sha512)") + self.assertIn("obj/inventory.json.sha512", out) out = self.run_script("Create a new sidecar with a different digest", ["python", "ocfl-sidecar.py", "--digest", "sha256", "TMPDIR/obj"], text="The digest type is set with the --digest parameter") - self.assertIn("INFO:root:Written sidecar file inventory.json.sha256", out) + self.assertIn("obj/inventory.json.sha256", out) + + def test02_create_multiple(self): + """Test creation of multiple sidecar files.""" + out = self.run_script("Set up directory as object 1 root", + ["mkdir", "-v", "TMPDIR/obj1"]) + out = self.run_script("Set up directory as object 2 root", + ["mkdir", "-v", "TMPDIR/obj2"]) + out = self.run_script("Set up directory as object 3 root", + ["mkdir", "-v", "TMPDIR/obj3"]) + out = self.run_script("Copy in an inventory from an example for object 1", + ["cp", "-v", "fixtures/1.1/good-objects/minimal_uppercase_digests/inventory.json", "TMPDIR/obj1"]) + self.assertIn("obj1/inventory.json", out) + out = self.run_script("Copy in an inventory from an example for object 2", + ["cp", "-v", "fixtures/1.1/good-objects/minimal_mixed_digests/inventory.json", "TMPDIR/obj2"]) + self.assertIn("obj2/inventory.json", out) + out = self.run_script("Copy in an inventory from an example for object 3", + ["cp", "-v", "fixtures/1.1/good-objects/minimal_no_content/inventory.json", "TMPDIR/obj3"]) + self.assertIn("obj3/inventory.json", out) + out = self.run_script("Create sidecars for all 3 inventory files", + ["python", "ocfl-sidecar.py", + "TMPDIR/obj1", "TMPDIR/obj2", "TMPDIR/obj3"]) + self.assertIn("Written sidecar file ", out) + self.assertIn("obj1/inventory.json.sha512", out) + self.assertIn("obj2/inventory.json.sha512", out) + self.assertIn("obj3/inventory.json.sha512", out) if __name__ == "__main__":