Skip to content

Commit 83ece60

Browse files
authored
Merge pull request #49 from casework/change_local_uuid_setup_parameter
2 parents 710f44e + 15ff5e9 commit 83ece60

File tree

10 files changed

+192
-82
lines changed

10 files changed

+192
-82
lines changed

case_utils/case_file/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717

1818
__version__ = "0.3.0"
1919

20+
import argparse
2021
import datetime
2122
import hashlib
23+
import logging
2224
import os
2325
import typing
2426
import warnings
@@ -207,10 +209,9 @@ def create_file_node(
207209

208210

209211
def main() -> None:
210-
import argparse
211-
212212
parser = argparse.ArgumentParser()
213213
parser.add_argument("--base-prefix", default=DEFAULT_PREFIX)
214+
parser.add_argument("--debug", action="store_true")
214215
parser.add_argument("--disable-hashes", action="store_true")
215216
parser.add_argument("--disable-mtime", action="store_true")
216217
parser.add_argument(
@@ -220,6 +221,8 @@ def main() -> None:
220221
parser.add_argument("in_file")
221222
args = parser.parse_args()
222223

224+
logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO)
225+
223226
case_utils.local_uuid.configure()
224227

225228
NS_BASE = rdflib.Namespace(args.base_prefix)

case_utils/local_uuid.py

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,91 @@
1717

1818
__version__ = "0.2.0"
1919

20+
import logging
2021
import os
22+
import pathlib
2123
import sys
24+
import typing
25+
import warnings
2226
import uuid
2327

24-
USE_DEMO_UUID: bool = False
28+
DEMO_UUID_BASE: typing.Optional[str] = None
2529

2630
DEMO_UUID_COUNTER: int = 0
2731

32+
_logger = logging.getLogger(pathlib.Path(__file__).name)
33+
2834

2935
def configure() -> None:
30-
global USE_DEMO_UUID
36+
global DEMO_UUID_BASE
3137

3238
if os.getenv("DEMO_UUID_REQUESTING_NONRANDOM") == "NONRANDOM_REQUESTED":
33-
USE_DEMO_UUID = True
39+
warnings.warn(
40+
"Environment variable DEMO_UUID_REQUESTING_NONRANDOM is deprecated. See case_utils.local_uuid.demo_uuid for usage notes on its replacement, CASE_DEMO_NONRANDOM_UUID_BASE. Proceeding with random UUIDs.",
41+
DeprecationWarning,
42+
)
43+
return
44+
45+
env_base_dir_name = os.getenv("CASE_DEMO_NONRANDOM_UUID_BASE")
46+
if env_base_dir_name is None:
47+
return
48+
49+
base_dir_original_path = pathlib.Path(env_base_dir_name)
50+
if not base_dir_original_path.exists():
51+
warnings.warn(
52+
"Environment variable CASE_DEMO_NONRANDOM_UUID_BASE is expected to refer to an existing directory. Proceeding with random UUIDs."
53+
)
54+
return
55+
if not base_dir_original_path.is_dir():
56+
warnings.warn(
57+
"Environment variable CASE_DEMO_NONRANDOM_UUID_BASE is expected to refer to a directory. Proceeding with random UUIDs."
58+
)
59+
return
60+
61+
# Component: An emphasis this is an example.
62+
demo_uuid_base_parts = ["example.org"]
63+
64+
# Component: Present working directory, relative to CASE_DEMO_NONRANDOM_UUID_BASE if that environment variable is an ancestor of pwd.
65+
base_dir_resolved_path = base_dir_original_path.resolve()
66+
srcdir_original_path = pathlib.Path(os.getcwd())
67+
srcdir_resolved_path = srcdir_original_path.resolve()
68+
# _logger.debug("base_dir_resolved_path = %r.", base_dir_resolved_path)
69+
# _logger.debug("srcdir_resolved_path = %r.", srcdir_resolved_path)
70+
try:
71+
srcdir_relative_path = srcdir_resolved_path.relative_to(base_dir_resolved_path)
72+
# _logger.debug("srcdir_relative_path = %r.", srcdir_relative_path)
73+
demo_uuid_base_parts.append(str(srcdir_relative_path))
74+
except ValueError:
75+
# If base_dir is not an ancestor directory of srcdir, default to srcdir.
76+
# _logger.debug("PWD is not relative to base path.")
77+
demo_uuid_base_parts.append(str(srcdir_resolved_path))
78+
79+
# Component: Command of argument vector.
80+
env_venv_name = os.getenv("VIRTUAL_ENV")
81+
if env_venv_name is None:
82+
demo_uuid_base_parts.append(sys.argv[0])
83+
else:
84+
command_original_path = pathlib.Path(sys.argv[0])
85+
command_resolved_path = command_original_path.resolve()
86+
venv_original_path = pathlib.Path(env_venv_name)
87+
venv_resolved_path = venv_original_path.resolve()
88+
try:
89+
command_relative_path = command_resolved_path.relative_to(
90+
venv_resolved_path
91+
)
92+
# _logger.debug("command_relative_path = %r.", command_relative_path)
93+
demo_uuid_base_parts.append(str(command_relative_path))
94+
except ValueError:
95+
# _logger.debug("Command path is not relative to virtual environment path.")
96+
demo_uuid_base_parts.append(str(command_resolved_path))
97+
98+
if len(sys.argv) > 1:
99+
# Component: Arguments of argument vector.
100+
demo_uuid_base_parts.extend(sys.argv[1:])
101+
102+
# _logger.debug("demo_uuid_base_parts = %r.", demo_uuid_base_parts)
103+
104+
DEMO_UUID_BASE = "/".join(demo_uuid_base_parts)
34105

35106

36107
def demo_uuid() -> str:
@@ -39,38 +110,34 @@ def demo_uuid() -> str:
39110
40111
WARNING: This function was developed for use ONLY for reducing (but not eliminating) version-control edits to identifiers in sample data. It creates UUIDs that are decidedly NOT random, and should remain consistent on repeated calls to the importing script.
41112
42-
To prevent accidental non-random UUID usage, an environment variable must be set to an uncommon string, hard-coded in this function.
113+
To prevent accidental non-random UUID usage, an environment variable must be set to a string provided by the caller. The variable's required value is the path to some directory. The variable's recommended value is the equivalent of the Make variable "top_srcdir" - that is, the root directory of the containing Git repository, some parent of the current process's current working directory.
43114
"""
115+
global DEMO_UUID_BASE
44116
global DEMO_UUID_COUNTER
45117

46-
if os.getenv("DEMO_UUID_REQUESTING_NONRANDOM") != "NONRANDOM_REQUESTED":
47-
raise EnvironmentError(
48-
"demo_uuid() called without DEMO_UUID_REQUESTING_NONRANDOM in environment."
118+
if os.getenv("CASE_DEMO_NONRANDOM_UUID_BASE") is None:
119+
raise ValueError(
120+
"demo_uuid() called without CASE_DEMO_NONRANDOM_UUID_BASE in environment."
49121
)
50122

51-
# Component: An emphasis this is an example.
52-
parts = ["example.org"]
123+
if DEMO_UUID_BASE is None:
124+
raise ValueError("demo_uuid() called with DEMO_UUID_BASE unset.")
125+
126+
parts = [DEMO_UUID_BASE]
53127

54128
# Component: Incrementing counter.
55129
DEMO_UUID_COUNTER += 1
56130
parts.append(str(DEMO_UUID_COUNTER))
57131

58-
# Component: Present working directory, replacing $HOME with '~'.
59-
env_HOME: str = os.getenv("HOME", "/nonexistent")
60-
parts.append(os.getcwd().replace(env_HOME, "~"))
61-
62-
# Component: Argument vector.
63-
parts.extend(sys.argv)
64-
65132
return str(uuid.uuid5(uuid.NAMESPACE_URL, "/".join(parts)))
66133

67134

68135
def local_uuid() -> str:
69136
"""
70137
Generate either a UUID4, or if requested via environment configuration, a non-random demo UUID.
71138
"""
72-
global USE_DEMO_UUID
73-
if USE_DEMO_UUID:
74-
return demo_uuid()
75-
else:
139+
global DEMO_UUID_BASE
140+
if DEMO_UUID_BASE is None:
76141
return str(uuid.uuid4())
142+
else:
143+
return demo_uuid()

tests/case_utils/case_file/Makefile

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,10 @@ sample.txt.json: \
114114
$(top_srcdir)/case_utils/namespace.py \
115115
sample.txt-nocompact.json
116116
rm -f $@ _$@ __$@
117-
export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \
117+
export CASE_DEMO_NONRANDOM_UUID_BASE="$(top_srcdir)" \
118118
&& source $(tests_srcdir)/venv/bin/activate \
119119
&& case_file \
120+
--debug \
120121
__$@ \
121122
sample.txt
122123
source $(tests_srcdir)/venv/bin/activate \
@@ -146,9 +147,10 @@ sample.txt.ttl: \
146147
$(top_srcdir)/case_utils/namespace.py \
147148
sample.txt.done.log
148149
rm -f _$@ __$@
149-
export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \
150+
export CASE_DEMO_NONRANDOM_UUID_BASE="$(top_srcdir)" \
150151
&& source $(tests_srcdir)/venv/bin/activate \
151152
&& case_file \
153+
--debug \
152154
__$@ \
153155
sample.txt
154156
java -jar $(RDF_TOOLKIT_JAR) \
@@ -169,9 +171,10 @@ sample.txt-disable_hashes.ttl: \
169171
$(top_srcdir)/case_utils/namespace.py \
170172
sample.txt.done.log
171173
rm -f _$@ __$@
172-
export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \
174+
export CASE_DEMO_NONRANDOM_UUID_BASE="$(top_srcdir)" \
173175
&& source $(tests_srcdir)/venv/bin/activate \
174176
&& case_file \
177+
--debug \
175178
--disable-hashes \
176179
__$@ \
177180
sample.txt
@@ -194,9 +197,10 @@ sample.txt-nocompact.json: \
194197
$(top_srcdir)/case_utils/namespace.py \
195198
sample.txt.done.log
196199
rm -f _$@
197-
export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \
200+
export CASE_DEMO_NONRANDOM_UUID_BASE="$(top_srcdir)" \
198201
&& source $(tests_srcdir)/venv/bin/activate \
199202
&& case_file \
203+
--debug \
200204
_$@ \
201205
sample.txt
202206
# To avoid making noisy, uninformative updates from blank node identifiers, only move the new file into place if it is not isomorphic with the Git-tracked version of the target.

tests/case_utils/case_file/kb.json

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,23 @@
99
},
1010
"@graph": [
1111
{
12-
"@id": "kb:file-1080c4cc-7886-5a52-bac1-f6a2b16c0ddb",
12+
"@id": "kb:file-800784de-5c9e-5eb2-b843-0ac51a1bd4b9",
13+
"@type": "uco-observable:File",
14+
"uco-core:hasFacet": {
15+
"@type": "uco-observable:FileFacet",
16+
"uco-observable:fileName": "sample.txt",
17+
"uco-observable:modifiedTime": {
18+
"@type": "xsd:dateTime",
19+
"@value": "2010-01-02T03:04:56+00:00"
20+
},
21+
"uco-observable:sizeInBytes": {
22+
"@type": "xsd:integer",
23+
"@value": "4"
24+
}
25+
}
26+
},
27+
{
28+
"@id": "kb:file-ace6460a-92a9-58b9-83ea-a18ae87f6e04",
1329
"@type": "uco-observable:File",
1430
"uco-core:hasFacet": [
1531
{
@@ -78,22 +94,6 @@
7894
}
7995
}
8096
]
81-
},
82-
{
83-
"@id": "kb:file-b5e8a943-c556-5964-a618-8f0d000822af",
84-
"@type": "uco-observable:File",
85-
"uco-core:hasFacet": {
86-
"@type": "uco-observable:FileFacet",
87-
"uco-observable:fileName": "sample.txt",
88-
"uco-observable:modifiedTime": {
89-
"@type": "xsd:dateTime",
90-
"@value": "2010-01-02T03:04:56+00:00"
91-
},
92-
"uco-observable:sizeInBytes": {
93-
"@type": "xsd:integer",
94-
"@value": "4"
95-
}
96-
}
9797
}
9898
]
9999
}

tests/case_utils/case_file/kb.ttl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,17 @@
88
@prefix uco-vocabulary: <https://ontology.unifiedcyberontology.org/uco/vocabulary/> .
99
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
1010

11-
kb:file-1080c4cc-7886-5a52-bac1-f6a2b16c0ddb
11+
kb:file-800784de-5c9e-5eb2-b843-0ac51a1bd4b9
12+
a uco-observable:File ;
13+
uco-core:hasFacet [
14+
a uco-observable:FileFacet ;
15+
uco-observable:fileName "sample.txt" ;
16+
uco-observable:modifiedTime "2010-01-02T03:04:56+00:00"^^xsd:dateTime ;
17+
uco-observable:sizeInBytes "4"^^xsd:integer ;
18+
] ;
19+
.
20+
21+
kb:file-ace6460a-92a9-58b9-83ea-a18ae87f6e04
1222
a uco-observable:File ;
1323
uco-core:hasFacet
1424
[
@@ -46,13 +56,3 @@ kb:file-1080c4cc-7886-5a52-bac1-f6a2b16c0ddb
4656
;
4757
.
4858

49-
kb:file-b5e8a943-c556-5964-a618-8f0d000822af
50-
a uco-observable:File ;
51-
uco-core:hasFacet [
52-
a uco-observable:FileFacet ;
53-
uco-observable:fileName "sample.txt" ;
54-
uco-observable:modifiedTime "2010-01-02T03:04:56+00:00"^^xsd:dateTime ;
55-
uco-observable:sizeInBytes "4"^^xsd:integer ;
56-
] ;
57-
.
58-

tests/case_utils/case_file/sample.txt-disable_hashes.ttl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
@prefix uco-observable: <https://ontology.unifiedcyberontology.org/uco/observable/> .
77
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
88

9-
kb:file-b5e8a943-c556-5964-a618-8f0d000822af
9+
kb:file-800784de-5c9e-5eb2-b843-0ac51a1bd4b9
1010
a uco-observable:File ;
1111
uco-core:hasFacet [
1212
a uco-observable:FileFacet ;

0 commit comments

Comments
 (0)