From 91eeb0074635726930a76dcafe712a9d6f8962d5 Mon Sep 17 00:00:00 2001 From: kchason Date: Mon, 21 Mar 2022 14:33:31 -0400 Subject: [PATCH 01/23] CI job for black formatting --- .github/workflows/ci.yml | 4 ++++ .pre-commit-config.yaml | 5 +++++ CONTRIBUTE.md | 11 +++++++++++ 3 files changed, 20 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4d0c35..f92256a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,10 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + - name: Pre-commit Checks + run: | + pip -q install pre-commit + pre-commit run --all-files - name: Start from clean state run: make clean - name: Run tests diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..47b80d1 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,5 @@ +repos: +- repo: https://github.com/psf/black + rev: 22.1.0 + hooks: + - id: black diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md index 6d1e781..9619b97 100644 --- a/CONTRIBUTE.md +++ b/CONTRIBUTE.md @@ -32,3 +32,14 @@ make check git commit -m "Update CASE ontology pointer to version 0.6.0" dependencies/CASE case_utils/ontology/version_info.py git commit -m "Build CASE 0.6.0.ttl" case_utils/ontology/case-0.6.0.ttl ``` + +This project uses [the `pre-commit` tool](https://pre-commit.com/) for linting The easiest way to install it is with `pip`: +```bash +pip install pre-commit +pre-commit --version +``` + +The `pre-commit` tool hooks into Git's commit machinery to run a set of linters and static analyzers over each change. To install `pre-commit` into Git's hooks, run: +```bash +pre-commit install +``` \ No newline at end of file From 5c75d6053dd0e26a46efb195ea542b4b8948753d Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Thu, 24 Mar 2022 10:00:51 -0400 Subject: [PATCH 02/23] Centralize namespace constants in namespace.py References: * https://github.com/casework/CASE-Utilities-Python/issues/38 * [UCO OC-217] (CP-107) Revise ontology IRI to be slash-based and drop IRI base * [ONT-64] (CP-17) Define scheme for CASE and UCO importable versioned IRIs Signed-off-by: Alex Nelson --- case_utils/case_file/__init__.py | 12 +------ case_utils/namespace.py | 38 ++++++++++++++++++++ tests/case_utils/case_file/Makefile | 4 +++ tests/case_utils/case_file/test_case_file.py | 16 +++------ 4 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 case_utils/namespace.py diff --git a/case_utils/case_file/__init__.py b/case_utils/case_file/__init__.py index c776c22..75c6c42 100644 --- a/case_utils/case_file/__init__.py +++ b/case_utils/case_file/__init__.py @@ -26,20 +26,10 @@ import rdflib # type: ignore import case_utils +from case_utils.namespace import * DEFAULT_PREFIX = "http://example.org/kb/" -NS_RDF = rdflib.RDF -NS_UCO_CORE = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/core#") -NS_UCO_OBSERVABLE = rdflib.Namespace( - "https://unifiedcyberontology.org/ontology/uco/observable#" -) -NS_UCO_TYPES = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/types#") -NS_UCO_VOCABULARY = rdflib.Namespace( - "https://unifiedcyberontology.org/ontology/uco/vocabulary#" -) -NS_XSD = rdflib.XSD - # Shortcut syntax for defining an immutable named tuple is noted here: # https://docs.python.org/3/library/typing.html#typing.NamedTuple # via the "See also" box here: https://docs.python.org/3/library/collections.html#collections.namedtuple diff --git a/case_utils/namespace.py b/case_utils/namespace.py new file mode 100644 index 0000000..e6a0dd0 --- /dev/null +++ b/case_utils/namespace.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 + +# This software was developed at the National Institute of Standards +# and Technology by employees of the Federal Government in the course +# of their official duties. Pursuant to title 17 Section 105 of the +# United States Code this software is not subject to copyright +# protection and is in the public domain. NIST assumes no +# responsibility whatsoever for its use by other parties, and makes +# no guarantees, expressed or implied, about its quality, +# reliability, or any other characteristic. +# +# We would appreciate acknowledgement if the software is used. + +""" +This module provides importable constants for namespaces. + +To use, add "from case_utils.namespace import *". Namespace variables starting with "NS_" are imported. As needs are demonstrated in CASE tooling (both in case_utils and from downstream requests), namespaces will also be imported from rdflib for a consistent "NS_*" spelling. +""" + +import rdflib # type: ignore + +NS_SH = rdflib.SH +NS_RDF = rdflib.RDF +NS_XSD = rdflib.XSD + +NS_CASE_INVESTIGATION = rdflib.Namespace( + "https://ontology.caseontology.org/case/investigation/" +) +NS_UCO_ACTION = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/action#") +NS_UCO_CORE = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/core#") +NS_UCO_LOCATION = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/location#") +NS_UCO_OBSERVABLE = rdflib.Namespace( + "https://unifiedcyberontology.org/ontology/uco/observable#" +) +NS_UCO_TYPES = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/types#") +NS_UCO_VOCABULARY = rdflib.Namespace( + "https://unifiedcyberontology.org/ontology/uco/vocabulary#" +) diff --git a/tests/case_utils/case_file/Makefile b/tests/case_utils/case_file/Makefile index a771381..5306db9 100644 --- a/tests/case_utils/case_file/Makefile +++ b/tests/case_utils/case_file/Makefile @@ -127,6 +127,7 @@ sample.txt.json: \ $(tests_srcdir)/src/isomorphic_diff.py \ $(top_srcdir)/case_utils/case_file/__init__.py \ $(top_srcdir)/case_utils/local_uuid.py \ + $(top_srcdir)/case_utils/namespace.py \ sample.txt-nocompact.json rm -f $@ _$@ __$@ export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ @@ -158,6 +159,7 @@ sample.txt.ttl: \ $(tests_srcdir)/.venv.done.log \ $(top_srcdir)/case_utils/case_file/__init__.py \ $(top_srcdir)/case_utils/local_uuid.py \ + $(top_srcdir)/case_utils/namespace.py \ sample.txt.done.log rm -f _$@ __$@ export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ @@ -180,6 +182,7 @@ sample.txt-disable_hashes.ttl: \ $(tests_srcdir)/.venv.done.log \ $(top_srcdir)/case_utils/case_file/__init__.py \ $(top_srcdir)/case_utils/local_uuid.py \ + $(top_srcdir)/case_utils/namespace.py \ sample.txt.done.log rm -f _$@ __$@ export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ @@ -204,6 +207,7 @@ sample.txt-nocompact.json: \ $(tests_srcdir)/src/isomorphic_diff.py \ $(top_srcdir)/case_utils/case_file/__init__.py \ $(top_srcdir)/case_utils/local_uuid.py \ + $(top_srcdir)/case_utils/namespace.py \ sample.txt.done.log rm -f _$@ export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ diff --git a/tests/case_utils/case_file/test_case_file.py b/tests/case_utils/case_file/test_case_file.py index 4eda521..78b4a5c 100644 --- a/tests/case_utils/case_file/test_case_file.py +++ b/tests/case_utils/case_file/test_case_file.py @@ -19,22 +19,14 @@ import rdflib.plugins.sparql # type: ignore import case_utils.ontology +from case_utils.namespace import * _logger = logging.getLogger(os.path.basename(__file__)) -IRI_UCO_CORE = "https://unifiedcyberontology.org/ontology/uco/core#" -IRI_UCO_OBSERVABLE = "https://unifiedcyberontology.org/ontology/uco/observable#" -IRI_UCO_TYPES = "https://unifiedcyberontology.org/ontology/uco/types#" - -NS_RDF = rdflib.RDF -NS_UCO_CORE = rdflib.Namespace(IRI_UCO_CORE) -NS_UCO_OBSERVABLE = rdflib.Namespace(IRI_UCO_OBSERVABLE) -NS_UCO_TYPES = rdflib.Namespace(IRI_UCO_TYPES) - NSDICT = { - "uco-core": IRI_UCO_CORE, - "uco-observable": IRI_UCO_OBSERVABLE, - "uco-types": IRI_UCO_TYPES, + "uco-core": NS_UCO_CORE, + "uco-observable": NS_UCO_OBSERVABLE, + "uco-types": NS_UCO_TYPES, } SRCDIR = os.path.dirname(__file__) From cd2e528a29c8966675010523b22a33126c22dc15 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Mon, 18 Apr 2022 17:25:59 -0400 Subject: [PATCH 03/23] Fix unused variable reference A recent update in rdflib no longer infers the xsd prefix with the usage of the unprepared string query accidentally used before this commit. The `.prepareQuery` results should have been used here. Signed-off-by: Alex Nelson --- tests/case_utils/case_file/test_case_file.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/case_utils/case_file/test_case_file.py b/tests/case_utils/case_file/test_case_file.py index 727325b..6aff03a 100644 --- a/tests/case_utils/case_file/test_case_file.py +++ b/tests/case_utils/case_file/test_case_file.py @@ -122,14 +122,14 @@ def test_confirm_mtime( ) n_observable_object = None - for result in graph_case_file_disable_hashes.query(query_confirm_mtime): + for result in graph_case_file_disable_hashes.query(query_object): (n_observable_object,) = result assert ( not n_observable_object is None ), "File object with expected mtime not found in hashless graph." n_observable_object = None - for result in graph_case_file.query(query_confirm_mtime): + for result in graph_case_file.query(query_object): (n_observable_object,) = result assert ( not n_observable_object is None From 285c61ccfc7ccca6a1f9ac44c6664d51c1772c69 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Mon, 18 Apr 2022 19:50:23 -0400 Subject: [PATCH 04/23] Add other CASE and UCO namespaces Signed-off-by: Alex Nelson --- case_utils/namespace.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/case_utils/namespace.py b/case_utils/namespace.py index dfb6d55..f64b7a4 100644 --- a/case_utils/namespace.py +++ b/case_utils/namespace.py @@ -26,13 +26,35 @@ NS_CASE_INVESTIGATION = rdflib.Namespace( "https://ontology.caseontology.org/case/investigation/" ) -NS_UCO_ACTION = rdflib.Namespace("https://ontology.unifiedcyberontology.org/uco/action/") +NS_CASE_VOCABULARY = rdflib.Namespace( + "https://ontology.caseontology.org/case/vocabulary/" +) +NS_UCO_ACTION = rdflib.Namespace( + "https://ontology.unifiedcyberontology.org/uco/action/" +) NS_UCO_CORE = rdflib.Namespace("https://ontology.unifiedcyberontology.org/uco/core/") -NS_UCO_LOCATION = rdflib.Namespace("https://ontology.unifiedcyberontology.org/uco/location/") +NS_UCO_IDENTITY = rdflib.Namespace( + "https://ontology.unifiedcyberontology.org/uco/identity/" +) +NS_UCO_LOCATION = rdflib.Namespace( + "https://ontology.unifiedcyberontology.org/uco/location/" +) +NS_UCO_MARKING = rdflib.Namespace( + "https://ontology.unifiedcyberontology.org/uco/marking/" +) NS_UCO_OBSERVABLE = rdflib.Namespace( "https://ontology.unifiedcyberontology.org/uco/observable/" ) +NS_UCO_PATTERN = rdflib.Namespace( + "https://ontology.unifiedcyberontology.org/uco/pattern/" +) +NS_UCO_ROLE = rdflib.Namespace("https://ontology.unifiedcyberontology.org/uco/role/") +NS_UCO_TIME = rdflib.Namespace("https://ontology.unifiedcyberontology.org/uco/time/") +NS_UCO_TOOL = rdflib.Namespace("https://ontology.unifiedcyberontology.org/uco/tool/") NS_UCO_TYPES = rdflib.Namespace("https://ontology.unifiedcyberontology.org/uco/types/") +NS_UCO_VICTIM = rdflib.Namespace( + "https://ontology.unifiedcyberontology.org/uco/victim/" +) NS_UCO_VOCABULARY = rdflib.Namespace( "https://ontology.unifiedcyberontology.org/uco/vocabulary/" ) From a170bb1df7a97fbacc1fa06f4dd06af631e0c0ea Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 3 May 2022 13:51:37 -0400 Subject: [PATCH 05/23] Add pre-commit and configure hook to review with Black Disclaimer: Participation by NIST in the creation of the documentation of mentioned software is not intended to imply a recommendation or endorsement by the National Institute of Standards and Technology, nor is it intended to imply that any specific software is necessarily the best available for the purpose. References: * [AC-215] Evaluate pre-commit usage on casework repositories * [AC-216] Apply Black to all casework Python code bases * https://github.com/casework/CASE-Utilities-Python/pull/37 Signed-off-by: Alex Nelson --- .gitignore | 1 + Makefile | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index f45a3b3..2a4c981 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.swp .DS_Store .idea/ +.venv-pre-commit/ __pycache__ build/ case_utils.egg-info/ diff --git a/Makefile b/Makefile index aacc5ea..3997289 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,8 @@ $(error Unable to determine CASE version) endif all: \ - .ontology.done.log + .ontology.done.log \ + .venv-pre-commit/var/.pre-commit-built.log .PHONY: \ download @@ -64,8 +65,32 @@ all: \ test -r case_utils/ontology/case-$(case_version)-subclasses.ttl touch $@ +# This virtual environment is meant to be built once and then persist, even through 'make clean'. +# If a recipe is written to remove this flag file, it should first run `pre-commit uninstall`. +.venv-pre-commit/var/.pre-commit-built.log: + rm -rf .venv-pre-commit + test -r .pre-commit-config.yaml \ + || (echo "ERROR:Makefile:pre-commit is expected to install for this repository, but .pre-commit-config.yaml does not seem to exist." >&2 ; exit 1) + $(PYTHON3) -m venv \ + .venv-pre-commit + source .venv-pre-commit/bin/activate \ + && pip install \ + --upgrade \ + pip \ + setuptools \ + wheel + source .venv-pre-commit/bin/activate \ + && pip install \ + pre-commit + source .venv-pre-commit/bin/activate \ + && pre-commit install + mkdir -p \ + .venv-pre-commit/var + touch $@ + check: \ - .ontology.done.log + .ontology.done.log \ + .venv-pre-commit/var/.pre-commit-built.log $(MAKE) \ PYTHON3=$(PYTHON3) \ --directory tests \ From 0ecd01ff17b1c6dd5c9667adde9b7af37def541f Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 3 May 2022 13:53:30 -0400 Subject: [PATCH 06/23] Move Black-based auto-formatting to pre-commit Disclaimer: Participation by NIST in the creation of the documentation of mentioned software is not intended to imply a recommendation or endorsement by the National Institute of Standards and Technology, nor is it intended to imply that any specific software is necessarily the best available for the purpose. References: * [AC-215] Evaluate pre-commit usage on casework repositories * [AC-216] Apply Black to all casework Python code bases * https://github.com/casework/CASE-Utilities-Python/pull/37 Signed-off-by: Alex Nelson --- tests/Makefile | 21 --------------------- tests/requirements.txt | 1 - 2 files changed, 22 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 3b0fe93..25fa731 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -67,17 +67,6 @@ check: \ --ignore case_utils \ --log-level=DEBUG -# TODO - Need to settle on policy for incorporating this and 'format' recipe into CI. -# https://case.atlassian.net/browse/AC-215 -# https://case.atlassian.net/browse/AC-216 -check-black: \ - .venv.done.log - source venv/bin/activate \ - && black \ - --check \ - $(top_srcdir)/case_utils \ - $$PWD - check-case_utils: \ .venv.done.log $(MAKE) \ @@ -112,13 +101,3 @@ clean: download: \ .venv.done.log - -# TODO - Need to settle on policy for incorporating this and 'check-black' recipe into CI. -# https://case.atlassian.net/browse/AC-215 -# https://case.atlassian.net/browse/AC-216 -format: \ - .venv.done.log - source venv/bin/activate \ - && black \ - $(top_srcdir)/case_utils \ - $$PWD diff --git a/tests/requirements.txt b/tests/requirements.txt index acd3ddc..f913d96 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,5 +1,4 @@ PyLD -black mypy pytest python-dateutil From 63f01d4cfe769e41f04a9cc4e0ab0ff6d024ee3e Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 3 May 2022 13:55:14 -0400 Subject: [PATCH 07/23] Run pre-commit autoupdate Disclaimer: Participation by NIST in the creation of the documentation of mentioned software is not intended to imply a recommendation or endorsement by the National Institute of Standards and Technology, nor is it intended to imply that any specific software is necessarily the best available for the purpose. References: * [AC-215] Evaluate pre-commit usage on casework repositories * https://github.com/casework/CASE-Utilities-Python/pull/37 Signed-off-by: Alex Nelson --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 47b80d1..8bf5f39 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ repos: - repo: https://github.com/psf/black - rev: 22.1.0 + rev: 22.3.0 hooks: - id: black From 29077b351b36c88abdb0d20e4e472d85af94169d Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 3 May 2022 14:44:01 -0400 Subject: [PATCH 08/23] Update NIST license text References: * https://github.com/usnistgov/opensource-repo/pull/17 Signed-off-by: Alex Nelson --- LICENSE | 23 ----------------------- LICENSE.md | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 23 deletions(-) delete mode 100644 LICENSE create mode 100644 LICENSE.md diff --git a/LICENSE b/LICENSE deleted file mode 100644 index af2e9a3..0000000 --- a/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -NIST Software - -This software was developed by employees of the National Institute of Standards -and Technology (NIST), an agency of the Federal Government and is being made -available as a public service. Pursuant to title 17 United States Code Section -105, works of NIST employees are not subject to copyright protection in the -United States. This software may be subject to foreign copyright. Permission -in the United States and in foreign countries, to the extent that NIST may hold -copyright, to use, copy, modify, create derivative works, and distribute this -software and its documentation without fee is hereby granted on a non-exclusive -basis, provided that this notice and disclaimer of warranty appears in all copies. - -THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED -, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE -WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE -DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE -ERROR FREE. IN NO EVENT SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT -LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, -RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON -WARRANTY, CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS -OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF -THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..b19169a --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,35 @@ +# NIST Software Licensing Statement + +NIST-developed software is provided by NIST as a public service. +You may use, copy, and distribute copies of the software in any +medium, provided that you keep intact this entire notice. You may +improve, modify, and create derivative works of the software or +any portion of the software, and you may copy and distribute such +modifications or works. Modified works should carry a notice +stating that you changed the software and should note the date +and nature of any such change. Please explicitly acknowledge the +National Institute of Standards and Technology as the source of +the software. + +NIST-developed software is expressly provided "AS IS." NIST MAKES +NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT, OR ARISING BY +OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +NON-INFRINGEMENT, AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR +WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED +OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES +NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE +SOFTWARE OR THE RESULTS THEREOF, INCLUDING BUT NOT LIMITED TO THE +CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE +SOFTWARE. + +You are solely responsible for determining the appropriateness of +using and distributing the software and you assume all risks +associated with its use, including but not limited to the risks +and costs of program errors, compliance with applicable laws, +damage to or loss of data, programs or equipment, and the +unavailability or interruption of operation. This software is not +intended to be used in any situation where a failure could cause +risk of injury or damage to property. The software developed by +NIST employees is not subject to copyright protection within the +United States. From 6fbd24026605fd0991600b34a493a3f7e1a4fdb6 Mon Sep 17 00:00:00 2001 From: kchason Date: Tue, 3 May 2022 20:12:56 -0400 Subject: [PATCH 09/23] Switch to Apache 2.0 license --- LICENSE | 201 ++++++++++++++++++++++++++ NOTICE | 13 ++ README.md | 7 + LICENSE.md => THIRD_PARTY_LICENSES.md | 4 + setup.cfg | 2 +- 5 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 LICENSE create mode 100644 NOTICE rename LICENSE.md => THIRD_PARTY_LICENSES.md (95%) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f6652d7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Cyber Domain Ontology Project a Series of LF Projects, LLC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..73cbb20 --- /dev/null +++ b/NOTICE @@ -0,0 +1,13 @@ +Copyright 2021 Cyber Domain Ontology Project a Series of LF Projects, LLC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index 551633b..6d6d826 100644 --- a/README.md +++ b/README.md @@ -136,3 +136,10 @@ Some `make` targets are defined for this repository: * `check` - Run unit tests. * `clean` - Remove test build files, but not downloaded files. * `download` - Download files sufficiently to run the unit tests offline. This will *not* include the ontology repositories tracked as submodules. Note if you do need to work offline, be aware touching the `setup.cfg` file in the project root directory, or `tests/requirements.txt`, will trigger a virtual environment rebuild. + + +## Licensing + +This repository is licensed under the Apache 2.0 License. See [LICENSE](LICENSE). + +Portions of this repository contributed by NIST are governed by the [NIST Software Licensing Statement](THIRD_PARTY_LICENSES.md#nist-software-licensing-statement). diff --git a/LICENSE.md b/THIRD_PARTY_LICENSES.md similarity index 95% rename from LICENSE.md rename to THIRD_PARTY_LICENSES.md index b19169a..ad89f2d 100644 --- a/LICENSE.md +++ b/THIRD_PARTY_LICENSES.md @@ -1,3 +1,7 @@ +Portions of this repository contributed by NIST are governed by +the following license. + + # NIST Software Licensing Statement NIST-developed software is provided by NIST as a public service. diff --git a/setup.cfg b/setup.cfg index 6b94050..f54403c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,7 +10,7 @@ long_description_content_type = text/markdown url = https://github.com/casework/CASE-Utilities-Python classifiers = Development Status :: 4 - Beta - License :: Public Domain + License :: OSI Approved :: Apache Software License Operating System :: OS Independent Programming Language :: Python :: 3 From fbd44ecc41a00f572d2fc2e2e30e3d900c85cde9 Mon Sep 17 00:00:00 2001 From: kchason Date: Tue, 3 May 2022 20:14:48 -0400 Subject: [PATCH 10/23] Remove notice file --- NOTICE | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 NOTICE diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 73cbb20..0000000 --- a/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2021 Cyber Domain Ontology Project a Series of LF Projects, LLC - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file From 89ab0aabd9069876cc22c0ca0f72239cc3ea1ad2 Mon Sep 17 00:00:00 2001 From: kchason Date: Tue, 3 May 2022 20:18:16 -0400 Subject: [PATCH 11/23] Remove file stub from license --- LICENSE | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/LICENSE b/LICENSE index f6652d7..d9a10c0 100644 --- a/LICENSE +++ b/LICENSE @@ -174,28 +174,3 @@ of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Cyber Domain Ontology Project a Series of LF Projects, LLC - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. From 1312128463b11f4e6eb16c08e81efc64eccfff96 Mon Sep 17 00:00:00 2001 From: kchason Date: Wed, 4 May 2022 10:49:09 -0400 Subject: [PATCH 12/23] Initial build pipeline --- .github/workflows/ci.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4d0c35..f5dec37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,3 +39,30 @@ jobs: run: make clean - name: Run tests run: make PYTHON3=python check + + # Build the binary wheel as well as the source tar + - name: Build Objects + # if: startsWith(github.ref, 'refs/tags') + run: python setup.py sdist bdist_wheel + + # Ensure the objects were packaged correctly and there wasn't an issue with + # the compilation or packaging process. + - name: Check Objects + # if: startsWith(github.ref, 'refs/tags') + run: | + pip install -q twine + twine check dist/* + + # Upload the packages on all develop and main pipleines for test consumption + - name: Upload HTML Docs + # if: startsWith(github.ref, 'refs/tags') + uses: actions/upload-artifact@v2 + with: + name: packages + path: ./dist/ + + # If this commit is the result of a Git tag, push the wheel and tar packages + # to the PyPi registry + - name: Publish to PyPI + if: startsWith(github.ref, 'refs/tags') + run: twine upload --repository-url https://upload.pypi.org/legacy/ -u __token__ -p ${{ secrets.PYPI_API_TOKEN }} --skip-existing --verbose dist/* From a9948ed83044b7a0de8de35ede92ea5c3eaa3a80 Mon Sep 17 00:00:00 2001 From: kchason Date: Wed, 4 May 2022 10:54:16 -0400 Subject: [PATCH 13/23] Add wheel install --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5dec37..e1ab128 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: - name: Check Objects # if: startsWith(github.ref, 'refs/tags') run: | - pip install -q twine + pip install -q twine wheel twine check dist/* # Upload the packages on all develop and main pipleines for test consumption From 01711870821d313d16c48f76ebebb5fb4fd8af92 Mon Sep 17 00:00:00 2001 From: kchason Date: Wed, 4 May 2022 10:58:19 -0400 Subject: [PATCH 14/23] Reorder install and remove tag constraints --- .github/workflows/ci.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1ab128..2ad1ebf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,20 +42,17 @@ jobs: # Build the binary wheel as well as the source tar - name: Build Objects - # if: startsWith(github.ref, 'refs/tags') - run: python setup.py sdist bdist_wheel + run: | + pip install -q twine wheel + python setup.py sdist bdist_wheel # Ensure the objects were packaged correctly and there wasn't an issue with # the compilation or packaging process. - name: Check Objects - # if: startsWith(github.ref, 'refs/tags') - run: | - pip install -q twine wheel - twine check dist/* + run: twine check dist/* # Upload the packages on all develop and main pipleines for test consumption - name: Upload HTML Docs - # if: startsWith(github.ref, 'refs/tags') uses: actions/upload-artifact@v2 with: name: packages From 0c8066a0f50aa1f7aac1ae49c091f9e08dfb6781 Mon Sep 17 00:00:00 2001 From: kchason Date: Tue, 10 May 2022 08:09:34 -0400 Subject: [PATCH 15/23] Rename CI file --- .github/workflows/{ci.yml => cicd.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{ci.yml => cicd.yml} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/cicd.yml similarity index 100% rename from .github/workflows/ci.yml rename to .github/workflows/cicd.yml From b929496ca0d6005157f4b1516daccdd0fb606d98 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 10 May 2022 21:23:44 -0400 Subject: [PATCH 16/23] Add debug-logging option to case_file This flag was a useful development aid, and its presence in the Make command lines impacts generated UUID5s. However, at the end of the patch series adding this output, all of the debug statements will be disabled. A follow-on patch (at the end of the series) will regenerate Make-managed files. Signed-off-by: Alex Nelson --- case_utils/case_file/__init__.py | 7 +++++-- tests/case_utils/case_file/Makefile | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/case_utils/case_file/__init__.py b/case_utils/case_file/__init__.py index 316ed3f..e494514 100644 --- a/case_utils/case_file/__init__.py +++ b/case_utils/case_file/__init__.py @@ -17,8 +17,10 @@ __version__ = "0.3.0" +import argparse import datetime import hashlib +import logging import os import typing import warnings @@ -207,10 +209,9 @@ def create_file_node( def main() -> None: - import argparse - parser = argparse.ArgumentParser() parser.add_argument("--base-prefix", default=DEFAULT_PREFIX) + parser.add_argument("--debug", action="store_true") parser.add_argument("--disable-hashes", action="store_true") parser.add_argument("--disable-mtime", action="store_true") parser.add_argument( @@ -220,6 +221,8 @@ def main() -> None: parser.add_argument("in_file") args = parser.parse_args() + logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) + case_utils.local_uuid.configure() NS_BASE = rdflib.Namespace(args.base_prefix) diff --git a/tests/case_utils/case_file/Makefile b/tests/case_utils/case_file/Makefile index 28d7e62..6ed3878 100644 --- a/tests/case_utils/case_file/Makefile +++ b/tests/case_utils/case_file/Makefile @@ -117,6 +117,7 @@ sample.txt.json: \ export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ && source $(tests_srcdir)/venv/bin/activate \ && case_file \ + --debug \ __$@ \ sample.txt source $(tests_srcdir)/venv/bin/activate \ @@ -149,6 +150,7 @@ sample.txt.ttl: \ export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ && source $(tests_srcdir)/venv/bin/activate \ && case_file \ + --debug \ __$@ \ sample.txt java -jar $(RDF_TOOLKIT_JAR) \ @@ -172,6 +174,7 @@ sample.txt-disable_hashes.ttl: \ export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ && source $(tests_srcdir)/venv/bin/activate \ && case_file \ + --debug \ --disable-hashes \ __$@ \ sample.txt @@ -197,6 +200,7 @@ sample.txt-nocompact.json: \ export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ && source $(tests_srcdir)/venv/bin/activate \ && case_file \ + --debug \ _$@ \ sample.txt # 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. From 68687c2487ef6c26db516f09267a71e191865f31 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 10 May 2022 21:37:16 -0400 Subject: [PATCH 17/23] Update local_uuid configuration, deprecating prior variable `case_utils.local_uuid` provides a deterministic UUIDv5 generator based on the execution environment. Unfortunately, its prior implementation was not behaving correctly when changing environments - a different operating system, or working in a different rooted directory, would cause UUID churn. The issue turned out to be paths embedding in two manners: 1. The prior implementation assumed work happening somewhere under a user-home directory. This is not always true. 2. The prior implementation did not catch that for a program `pip`-installed into a virtual environment in editable mode (or, possibly more generally than that), `sys.argv[0]` is the absolute path to the installed command in the virtual environment root. Hence, changing operating systems from macOS to Linux would change `/Users/me` to `/home/me` within the UUID seeding data. This patch revises the practice from functionally operating in a Boolean manner ("Was this special string passed?") to passing an anchoring directory, preferably the repository's Git-root directory. Usage of the prior variable `DEMO_UUID_REQUESTING_NONRANDOM` is now deprecated, raising a warning. A test is also added to confirm new warnings are raised. A follow-on patch will regenerate Make-managed files. Signed-off-by: Alex Nelson --- case_utils/local_uuid.py | 107 ++++++++++++++++++++++------ tests/case_utils/case_file/Makefile | 8 +-- tests/case_utils/test_local_uuid.py | 36 ++++++++++ 3 files changed, 127 insertions(+), 24 deletions(-) create mode 100644 tests/case_utils/test_local_uuid.py diff --git a/case_utils/local_uuid.py b/case_utils/local_uuid.py index 7e526c0..b3b77ff 100644 --- a/case_utils/local_uuid.py +++ b/case_utils/local_uuid.py @@ -17,20 +17,91 @@ __version__ = "0.2.0" +import logging import os +import pathlib import sys +import typing +import warnings import uuid -USE_DEMO_UUID: bool = False +DEMO_UUID_BASE: typing.Optional[str] = None DEMO_UUID_COUNTER: int = 0 +_logger = logging.getLogger(pathlib.Path(__file__).name) + def configure() -> None: - global USE_DEMO_UUID + global DEMO_UUID_BASE if os.getenv("DEMO_UUID_REQUESTING_NONRANDOM") == "NONRANDOM_REQUESTED": - USE_DEMO_UUID = True + warnings.warn( + "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.", + DeprecationWarning, + ) + return + + env_base_dir_name = os.getenv("CASE_DEMO_NONRANDOM_UUID_BASE") + if env_base_dir_name is None: + return + + base_dir_original_path = pathlib.Path(env_base_dir_name) + if not base_dir_original_path.exists(): + warnings.warn( + "Environment variable CASE_DEMO_NONRANDOM_UUID_BASE is expected to refer to an existing directory. Proceeding with random UUIDs." + ) + return + if not base_dir_original_path.is_dir(): + warnings.warn( + "Environment variable CASE_DEMO_NONRANDOM_UUID_BASE is expected to refer to a directory. Proceeding with random UUIDs." + ) + return + + # Component: An emphasis this is an example. + demo_uuid_base_parts = ["example.org"] + + # Component: Present working directory, relative to CASE_DEMO_NONRANDOM_UUID_BASE if that environment variable is an ancestor of pwd. + base_dir_resolved_path = base_dir_original_path.resolve() + srcdir_original_path = pathlib.Path(os.getcwd()) + srcdir_resolved_path = srcdir_original_path.resolve() + # _logger.debug("base_dir_resolved_path = %r.", base_dir_resolved_path) + # _logger.debug("srcdir_resolved_path = %r.", srcdir_resolved_path) + try: + srcdir_relative_path = srcdir_resolved_path.relative_to(base_dir_resolved_path) + # _logger.debug("srcdir_relative_path = %r.", srcdir_relative_path) + demo_uuid_base_parts.append(str(srcdir_relative_path)) + except ValueError: + # If base_dir is not an ancestor directory of srcdir, default to srcdir. + # _logger.debug("PWD is not relative to base path.") + demo_uuid_base_parts.append(str(srcdir_resolved_path)) + + # Component: Command of argument vector. + env_venv_name = os.getenv("VIRTUAL_ENV") + if env_venv_name is None: + demo_uuid_base_parts.append(sys.argv[0]) + else: + command_original_path = pathlib.Path(sys.argv[0]) + command_resolved_path = command_original_path.resolve() + venv_original_path = pathlib.Path(env_venv_name) + venv_resolved_path = venv_original_path.resolve() + try: + command_relative_path = command_resolved_path.relative_to( + venv_resolved_path + ) + # _logger.debug("command_relative_path = %r.", command_relative_path) + demo_uuid_base_parts.append(str(command_relative_path)) + except ValueError: + # _logger.debug("Command path is not relative to virtual environment path.") + demo_uuid_base_parts.append(str(command_resolved_path)) + + if len(sys.argv) > 1: + # Component: Arguments of argument vector. + demo_uuid_base_parts.extend(sys.argv[1:]) + + # _logger.debug("demo_uuid_base_parts = %r.", demo_uuid_base_parts) + + DEMO_UUID_BASE = "/".join(demo_uuid_base_parts) def demo_uuid() -> str: @@ -39,29 +110,25 @@ def demo_uuid() -> str: 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. - To prevent accidental non-random UUID usage, an environment variable must be set to an uncommon string, hard-coded in this function. + 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. """ + global DEMO_UUID_BASE global DEMO_UUID_COUNTER - if os.getenv("DEMO_UUID_REQUESTING_NONRANDOM") != "NONRANDOM_REQUESTED": - raise EnvironmentError( - "demo_uuid() called without DEMO_UUID_REQUESTING_NONRANDOM in environment." + if os.getenv("CASE_DEMO_NONRANDOM_UUID_BASE") is None: + raise ValueError( + "demo_uuid() called without CASE_DEMO_NONRANDOM_UUID_BASE in environment." ) - # Component: An emphasis this is an example. - parts = ["example.org"] + if DEMO_UUID_BASE is None: + raise ValueError("demo_uuid() called with DEMO_UUID_BASE unset.") + + parts = [DEMO_UUID_BASE] # Component: Incrementing counter. DEMO_UUID_COUNTER += 1 parts.append(str(DEMO_UUID_COUNTER)) - # Component: Present working directory, replacing $HOME with '~'. - env_HOME: str = os.getenv("HOME", "/nonexistent") - parts.append(os.getcwd().replace(env_HOME, "~")) - - # Component: Argument vector. - parts.extend(sys.argv) - return str(uuid.uuid5(uuid.NAMESPACE_URL, "/".join(parts))) @@ -69,8 +136,8 @@ def local_uuid() -> str: """ Generate either a UUID4, or if requested via environment configuration, a non-random demo UUID. """ - global USE_DEMO_UUID - if USE_DEMO_UUID: - return demo_uuid() - else: + global DEMO_UUID_BASE + if DEMO_UUID_BASE is None: return str(uuid.uuid4()) + else: + return demo_uuid() diff --git a/tests/case_utils/case_file/Makefile b/tests/case_utils/case_file/Makefile index 6ed3878..0ce744a 100644 --- a/tests/case_utils/case_file/Makefile +++ b/tests/case_utils/case_file/Makefile @@ -114,7 +114,7 @@ sample.txt.json: \ $(top_srcdir)/case_utils/namespace.py \ sample.txt-nocompact.json rm -f $@ _$@ __$@ - export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ + export CASE_DEMO_NONRANDOM_UUID_BASE="$(top_srcdir)" \ && source $(tests_srcdir)/venv/bin/activate \ && case_file \ --debug \ @@ -147,7 +147,7 @@ sample.txt.ttl: \ $(top_srcdir)/case_utils/namespace.py \ sample.txt.done.log rm -f _$@ __$@ - export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ + export CASE_DEMO_NONRANDOM_UUID_BASE="$(top_srcdir)" \ && source $(tests_srcdir)/venv/bin/activate \ && case_file \ --debug \ @@ -171,7 +171,7 @@ sample.txt-disable_hashes.ttl: \ $(top_srcdir)/case_utils/namespace.py \ sample.txt.done.log rm -f _$@ __$@ - export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ + export CASE_DEMO_NONRANDOM_UUID_BASE="$(top_srcdir)" \ && source $(tests_srcdir)/venv/bin/activate \ && case_file \ --debug \ @@ -197,7 +197,7 @@ sample.txt-nocompact.json: \ $(top_srcdir)/case_utils/namespace.py \ sample.txt.done.log rm -f _$@ - export DEMO_UUID_REQUESTING_NONRANDOM=NONRANDOM_REQUESTED \ + export CASE_DEMO_NONRANDOM_UUID_BASE="$(top_srcdir)" \ && source $(tests_srcdir)/venv/bin/activate \ && case_file \ --debug \ diff --git a/tests/case_utils/test_local_uuid.py b/tests/case_utils/test_local_uuid.py new file mode 100644 index 0000000..c60ed09 --- /dev/null +++ b/tests/case_utils/test_local_uuid.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +# This software was developed at the National Institute of Standards +# and Technology by employees of the Federal Government in the course +# of their official duties. Pursuant to title 17 Section 105 of the +# United States Code this software is not subject to copyright +# protection and is in the public domain. NIST assumes no +# responsibility whatsoever for its use by other parties, and makes +# no guarantees, expressed or implied, about its quality, +# reliability, or any other characteristic. +# +# We would appreciate acknowledgement if the software is used. + +import os + +import pytest + +import case_utils.local_uuid + + +def test_local_uuid_deprecation(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("DEMO_UUID_REQUESTING_NONRANDOM", "NONRANDOM_REQUESTED") + with pytest.warns(DeprecationWarning): + case_utils.local_uuid.configure() + + +def test_local_uuid_nondirectory(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("CASE_DEMO_NONRANDOM_UUID_BASE", "/dev/null") + with pytest.warns(UserWarning): + case_utils.local_uuid.configure() + + +def test_local_uuid_nonexistent(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("CASE_DEMO_NONRANDOM_UUID_BASE", "/dev/nonexistent") + with pytest.warns(UserWarning): + case_utils.local_uuid.configure() From 15ff5e95b8aaff1b877af3ee1cc302a4d96f0596 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 10 May 2022 21:38:36 -0400 Subject: [PATCH 18/23] Regenerate Make-managed files Signed-off-by: Alex Nelson --- tests/case_utils/case_file/kb.json | 34 +++++++++---------- tests/case_utils/case_file/kb.ttl | 22 ++++++------ .../case_file/sample.txt-disable_hashes.ttl | 2 +- .../case_file/sample.txt-nocompact.json | 26 +++++++------- tests/case_utils/case_file/sample.txt.json | 26 +++++++------- tests/case_utils/case_file/sample.txt.ttl | 2 +- 6 files changed, 56 insertions(+), 56 deletions(-) diff --git a/tests/case_utils/case_file/kb.json b/tests/case_utils/case_file/kb.json index 5b7100d..b968377 100644 --- a/tests/case_utils/case_file/kb.json +++ b/tests/case_utils/case_file/kb.json @@ -9,7 +9,23 @@ }, "@graph": [ { - "@id": "kb:file-1080c4cc-7886-5a52-bac1-f6a2b16c0ddb", + "@id": "kb:file-800784de-5c9e-5eb2-b843-0ac51a1bd4b9", + "@type": "uco-observable:File", + "uco-core:hasFacet": { + "@type": "uco-observable:FileFacet", + "uco-observable:fileName": "sample.txt", + "uco-observable:modifiedTime": { + "@type": "xsd:dateTime", + "@value": "2010-01-02T03:04:56+00:00" + }, + "uco-observable:sizeInBytes": { + "@type": "xsd:integer", + "@value": "4" + } + } + }, + { + "@id": "kb:file-ace6460a-92a9-58b9-83ea-a18ae87f6e04", "@type": "uco-observable:File", "uco-core:hasFacet": [ { @@ -78,22 +94,6 @@ } } ] - }, - { - "@id": "kb:file-b5e8a943-c556-5964-a618-8f0d000822af", - "@type": "uco-observable:File", - "uco-core:hasFacet": { - "@type": "uco-observable:FileFacet", - "uco-observable:fileName": "sample.txt", - "uco-observable:modifiedTime": { - "@type": "xsd:dateTime", - "@value": "2010-01-02T03:04:56+00:00" - }, - "uco-observable:sizeInBytes": { - "@type": "xsd:integer", - "@value": "4" - } - } } ] } \ No newline at end of file diff --git a/tests/case_utils/case_file/kb.ttl b/tests/case_utils/case_file/kb.ttl index 6241217..942249b 100644 --- a/tests/case_utils/case_file/kb.ttl +++ b/tests/case_utils/case_file/kb.ttl @@ -8,7 +8,17 @@ @prefix uco-vocabulary: . @prefix xsd: . -kb:file-1080c4cc-7886-5a52-bac1-f6a2b16c0ddb +kb:file-800784de-5c9e-5eb2-b843-0ac51a1bd4b9 + a uco-observable:File ; + uco-core:hasFacet [ + a uco-observable:FileFacet ; + uco-observable:fileName "sample.txt" ; + uco-observable:modifiedTime "2010-01-02T03:04:56+00:00"^^xsd:dateTime ; + uco-observable:sizeInBytes "4"^^xsd:integer ; + ] ; + . + +kb:file-ace6460a-92a9-58b9-83ea-a18ae87f6e04 a uco-observable:File ; uco-core:hasFacet [ @@ -46,13 +56,3 @@ kb:file-1080c4cc-7886-5a52-bac1-f6a2b16c0ddb ; . -kb:file-b5e8a943-c556-5964-a618-8f0d000822af - a uco-observable:File ; - uco-core:hasFacet [ - a uco-observable:FileFacet ; - uco-observable:fileName "sample.txt" ; - uco-observable:modifiedTime "2010-01-02T03:04:56+00:00"^^xsd:dateTime ; - uco-observable:sizeInBytes "4"^^xsd:integer ; - ] ; - . - diff --git a/tests/case_utils/case_file/sample.txt-disable_hashes.ttl b/tests/case_utils/case_file/sample.txt-disable_hashes.ttl index 669aa51..edea5af 100644 --- a/tests/case_utils/case_file/sample.txt-disable_hashes.ttl +++ b/tests/case_utils/case_file/sample.txt-disable_hashes.ttl @@ -6,7 +6,7 @@ @prefix uco-observable: . @prefix xsd: . -kb:file-b5e8a943-c556-5964-a618-8f0d000822af +kb:file-800784de-5c9e-5eb2-b843-0ac51a1bd4b9 a uco-observable:File ; uco-core:hasFacet [ a uco-observable:FileFacet ; diff --git a/tests/case_utils/case_file/sample.txt-nocompact.json b/tests/case_utils/case_file/sample.txt-nocompact.json index e71f43a..e848ebf 100644 --- a/tests/case_utils/case_file/sample.txt-nocompact.json +++ b/tests/case_utils/case_file/sample.txt-nocompact.json @@ -35,19 +35,19 @@ }, "@graph": [ { - "@id": "http://example.org/kb/file-2999db3b-5e66-53b2-8470-8bfd838c444e", + "@id": "http://example.org/kb/file-23f45d80-7b16-5e7f-ba34-40392fa4f8fc", "@type": "https://ontology.unifiedcyberontology.org/uco/observable/File", "https://ontology.unifiedcyberontology.org/uco/core/hasFacet": [ { - "@id": "_:Nf16b91a8337843bfa9e99cbcceca4fea" + "@id": "_:N7b4f54f0f233497a8981441323dfdd27" }, { - "@id": "_:Ne9cc5032d4804fa19a3fe75c4966febf" + "@id": "_:Nf3c8a77cca9e4807a8b016f8b94eae64" } ] }, { - "@id": "_:Nf16b91a8337843bfa9e99cbcceca4fea", + "@id": "_:N7b4f54f0f233497a8981441323dfdd27", "@type": "https://ontology.unifiedcyberontology.org/uco/observable/FileFacet", "https://ontology.unifiedcyberontology.org/uco/observable/fileName": "sample.txt", "https://ontology.unifiedcyberontology.org/uco/observable/modifiedTime": { @@ -57,26 +57,26 @@ "https://ontology.unifiedcyberontology.org/uco/observable/sizeInBytes": 4 }, { - "@id": "_:Ne9cc5032d4804fa19a3fe75c4966febf", + "@id": "_:Nf3c8a77cca9e4807a8b016f8b94eae64", "@type": "https://ontology.unifiedcyberontology.org/uco/observable/ContentDataFacet", "https://ontology.unifiedcyberontology.org/uco/observable/hash": [ { - "@id": "_:N4074d88aa360403285b8cda26cfc74f2" + "@id": "_:N32345c071afb41eb8e4ac36497356af8" }, { - "@id": "_:N801158ea2716484791001371f60d5b60" + "@id": "_:N8f2e8439e67c4ae4b5d6dcf7947cf57a" }, { - "@id": "_:N550b15454d234888abb56ef4a1eb62a6" + "@id": "_:N94114772034d4c7f9ea8a7ce77a3b848" }, { - "@id": "_:N4a33b783148c43bd9bda1c04c581ea7c" + "@id": "_:Ndc9c78f6e42e4c96a9015ba58f3e8b3b" } ], "https://ontology.unifiedcyberontology.org/uco/observable/sizeInBytes": 4 }, { - "@id": "_:N4074d88aa360403285b8cda26cfc74f2", + "@id": "_:N32345c071afb41eb8e4ac36497356af8", "@type": "https://ontology.unifiedcyberontology.org/uco/types/Hash", "https://ontology.unifiedcyberontology.org/uco/types/hashMethod": { "@type": "https://ontology.unifiedcyberontology.org/uco/vocabulary/HashNameVocab", @@ -88,7 +88,7 @@ } }, { - "@id": "_:N801158ea2716484791001371f60d5b60", + "@id": "_:N8f2e8439e67c4ae4b5d6dcf7947cf57a", "@type": "https://ontology.unifiedcyberontology.org/uco/types/Hash", "https://ontology.unifiedcyberontology.org/uco/types/hashMethod": { "@type": "https://ontology.unifiedcyberontology.org/uco/vocabulary/HashNameVocab", @@ -100,7 +100,7 @@ } }, { - "@id": "_:N550b15454d234888abb56ef4a1eb62a6", + "@id": "_:N94114772034d4c7f9ea8a7ce77a3b848", "@type": "https://ontology.unifiedcyberontology.org/uco/types/Hash", "https://ontology.unifiedcyberontology.org/uco/types/hashMethod": { "@type": "https://ontology.unifiedcyberontology.org/uco/vocabulary/HashNameVocab", @@ -112,7 +112,7 @@ } }, { - "@id": "_:N4a33b783148c43bd9bda1c04c581ea7c", + "@id": "_:Ndc9c78f6e42e4c96a9015ba58f3e8b3b", "@type": "https://ontology.unifiedcyberontology.org/uco/types/Hash", "https://ontology.unifiedcyberontology.org/uco/types/hashMethod": { "@type": "https://ontology.unifiedcyberontology.org/uco/vocabulary/HashNameVocab", diff --git a/tests/case_utils/case_file/sample.txt.json b/tests/case_utils/case_file/sample.txt.json index b656d00..2539324 100644 --- a/tests/case_utils/case_file/sample.txt.json +++ b/tests/case_utils/case_file/sample.txt.json @@ -35,19 +35,19 @@ }, "@graph": [ { - "@id": "kb:file-44aa82fe-a733-5892-8daa-7a28378d6afc", + "@id": "kb:file-789a91ef-6446-548c-9911-dcc5168f25ea", "@type": "uco-observable:File", "uco-core:hasFacet": [ { - "@id": "_:N86dc036c736c420684afd0e2cdea35e8" + "@id": "_:N9cb3cc2ab59546a3a8409b0a43beb4c3" }, { - "@id": "_:N30cc9a3cb8d741c3896d6ff81ae053f6" + "@id": "_:N34067c06b9364c50870f642861cac333" } ] }, { - "@id": "_:N86dc036c736c420684afd0e2cdea35e8", + "@id": "_:N9cb3cc2ab59546a3a8409b0a43beb4c3", "@type": "uco-observable:FileFacet", "uco-observable:fileName": "sample.txt", "uco-observable:modifiedTime": { @@ -57,26 +57,26 @@ "uco-observable:sizeInBytes": 4 }, { - "@id": "_:N30cc9a3cb8d741c3896d6ff81ae053f6", + "@id": "_:N34067c06b9364c50870f642861cac333", "@type": "uco-observable:ContentDataFacet", "uco-observable:hash": [ { - "@id": "_:Ncdaad817bed0440cb8df78ea13bca979" + "@id": "_:N8536d3196ade4a33898077091ffe7b37" }, { - "@id": "_:Nb29e43af29e74e30af823ba2ac7fc826" + "@id": "_:Nee102c2e670c450b9c7bfe532916631a" }, { - "@id": "_:Nad4c18c5ea3a45589ee33d98134f4f6e" + "@id": "_:N874bad97d6e94943a23d04234517307f" }, { - "@id": "_:N3a34ed3719864b4fbd9e6da88ae97d54" + "@id": "_:Nb1f22efd766f43768fc83a2183df2396" } ], "uco-observable:sizeInBytes": 4 }, { - "@id": "_:Ncdaad817bed0440cb8df78ea13bca979", + "@id": "_:N8536d3196ade4a33898077091ffe7b37", "@type": "uco-types:Hash", "uco-types:hashMethod": { "@type": "uco-vocabulary:HashNameVocab", @@ -88,7 +88,7 @@ } }, { - "@id": "_:Nb29e43af29e74e30af823ba2ac7fc826", + "@id": "_:Nee102c2e670c450b9c7bfe532916631a", "@type": "uco-types:Hash", "uco-types:hashMethod": { "@type": "uco-vocabulary:HashNameVocab", @@ -100,7 +100,7 @@ } }, { - "@id": "_:Nad4c18c5ea3a45589ee33d98134f4f6e", + "@id": "_:N874bad97d6e94943a23d04234517307f", "@type": "uco-types:Hash", "uco-types:hashMethod": { "@type": "uco-vocabulary:HashNameVocab", @@ -112,7 +112,7 @@ } }, { - "@id": "_:N3a34ed3719864b4fbd9e6da88ae97d54", + "@id": "_:Nb1f22efd766f43768fc83a2183df2396", "@type": "uco-types:Hash", "uco-types:hashMethod": { "@type": "uco-vocabulary:HashNameVocab", diff --git a/tests/case_utils/case_file/sample.txt.ttl b/tests/case_utils/case_file/sample.txt.ttl index 6327640..3bcac8f 100644 --- a/tests/case_utils/case_file/sample.txt.ttl +++ b/tests/case_utils/case_file/sample.txt.ttl @@ -8,7 +8,7 @@ @prefix uco-vocabulary: . @prefix xsd: . -kb:file-1080c4cc-7886-5a52-bac1-f6a2b16c0ddb +kb:file-ace6460a-92a9-58b9-83ea-a18ae87f6e04 a uco-observable:File ; uco-core:hasFacet [ From 56121349d77318985443c9466f0096e44889400e Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 10 May 2022 21:43:10 -0400 Subject: [PATCH 19/23] Change test Python versions to earliest and latest Signed-off-by: Alex Nelson --- .github/workflows/cicd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 226ed72..ccf5892 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ 3.7, 3.8 ] + python-version: [ 3.7, 3.10 ] steps: - uses: actions/checkout@v2 From 417f27cff6698afe02430c6c366f2e2779d7143c Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 10 May 2022 21:44:56 -0400 Subject: [PATCH 20/23] Change YAML syntax to quoted strings An unexpected behavior arose, and the 3.10 somehow parsed as 3.1. Signed-off-by: Alex Nelson --- .github/workflows/cicd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index ccf5892..97df165 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ 3.7, 3.10 ] + python-version: [ '3.7', '3.10' ] steps: - uses: actions/checkout@v2 From ca8f4c757701f951d2cfff481930cbd5180f3469 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Wed, 11 May 2022 10:41:44 -0400 Subject: [PATCH 21/23] Include all license files in distributions Without this patch, `THIRD_PARTY_LICENSES.md` was not being included in the distribution files built by `setup.py`. References: * https://packaging.python.org/en/latest/guides/using-manifest-in/ Signed-off-by: Alex Nelson --- setup.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.cfg b/setup.cfg index f54403c..160976a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,6 +13,9 @@ classifiers = License :: OSI Approved :: Apache Software License Operating System :: OS Independent Programming Language :: Python :: 3 +license_files = + LICENSE + THIRD_PARTY_LICENSES.md [options] include_package_data = true From 2fc740d112d8e77c8b16e2039252495ca8ca5944 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Wed, 11 May 2022 11:53:42 -0400 Subject: [PATCH 22/23] Update documentation for PyPI deployment Signed-off-by: Alex Nelson --- README.md | 22 +++++++++++++++++++--- README_PyPI.md | 5 +++++ setup.cfg | 3 +-- 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 README_PyPI.md diff --git a/README.md b/README.md index 6d6d826..6271ecc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # CASE Python Utilities -This project provides various specialized utilities for producing data in the [CASE](https://caseontology.org/) format. +This project provides various specialized utilities for producing and analyzing data in the [CASE](https://caseontology.org/) format. ## Disclaimer @@ -10,12 +10,28 @@ Participation by NIST in the creation of the documentation of mentioned software ## Installation +This repository can be installed from PyPI or from source. + + +### Installing from PyPI + +```bash +pip install case_utils +``` + +Users who wish to install from PyPI should be aware that while CASE's ontology is in its pre-1.0.0 release state, backwards-incompatible ontology changes may occur. This may manifest as [`case_validate`](#case_validate) reporting data review errors after installing an updated `case_utils` version. Users may wish to pin `case_utils` within any dependent code bases to be less than the next unreleased SEMVER-minor version. (E.g. if `case_utils` version `0.8.0` is currently available, a newly adopting project might wish to track `case_utils<0.9.0` among its dependencies.) + + +### Installing from source + +Users who wish to install pre-release versions and/or make improvements to the code base should install in this manner. + 1. Clone this repository. 2. (Optional) Create and activate a virtual environment. 3. (Optional) Upgrade `pip` with `pip install --upgrade pip`. (This can speed installation of some dependent packages.) -4. Run `pip install .`. +4. Run `pip install $x`, where `$x` is the path to the cloned repository. -Installation is demonstrated in the `.venv.done.log` target of the `tests/` directory's [`Makefile`](tests/Makefile). +Local installation is demonstrated in the `.venv.done.log` target of the `tests/` directory's [`Makefile`](tests/Makefile). ## Usage diff --git a/README_PyPI.md b/README_PyPI.md new file mode 100644 index 0000000..ad292dd --- /dev/null +++ b/README_PyPI.md @@ -0,0 +1,5 @@ +# CASE Python Utilities + +This project provides various specialized utilities for producing and analyzing data in the [CASE](https://caseontology.org/) format. + +Full documentation is available at the [project homepage](https://github.com/casework/CASE-Utilities-Python). diff --git a/setup.cfg b/setup.cfg index 160976a..d8a7051 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,8 +4,7 @@ version = attr: case_utils.__version__ author = Alex Nelson author_email = alexander.nelson@nist.gov description = Python utilities for working with the CASE ontology -# TODO - PyPI will need a differently-written README. -long_description = file: README.md +long_description = file: README_PyPI.md long_description_content_type = text/markdown url = https://github.com/casework/CASE-Utilities-Python classifiers = From f2f87f121ee91708e25c3d7eb7b2ad69146ea08b Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Wed, 11 May 2022 17:00:58 -0400 Subject: [PATCH 23/23] Bump versions Signed-off-by: Alex Nelson --- case_utils/__init__.py | 2 +- case_utils/case_file/__init__.py | 2 +- case_utils/local_uuid.py | 2 +- case_utils/namespace.py | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/case_utils/__init__.py b/case_utils/__init__.py index efa0766..e8bc7ac 100644 --- a/case_utils/__init__.py +++ b/case_utils/__init__.py @@ -11,6 +11,6 @@ # # We would appreciate acknowledgement if the software is used. -__version__ = "0.4.0" +__version__ = "0.5.0" from . import local_uuid diff --git a/case_utils/case_file/__init__.py b/case_utils/case_file/__init__.py index e494514..61e2bb7 100644 --- a/case_utils/case_file/__init__.py +++ b/case_utils/case_file/__init__.py @@ -15,7 +15,7 @@ This module creates a graph object that provides a basic UCO characterization of a single file. The gathered metadata is among the more "durable" file characteristics, i.e. characteristics that would remain consistent when transferring a file between locations. """ -__version__ = "0.3.0" +__version__ = "0.3.1" import argparse import datetime diff --git a/case_utils/local_uuid.py b/case_utils/local_uuid.py index b3b77ff..dd1e6cb 100644 --- a/case_utils/local_uuid.py +++ b/case_utils/local_uuid.py @@ -15,7 +15,7 @@ This library is a wrapper for uuid, provided to generate repeatable UUIDs if requested. """ -__version__ = "0.2.0" +__version__ = "0.3.0" import logging import os diff --git a/case_utils/namespace.py b/case_utils/namespace.py index f64b7a4..6e12322 100644 --- a/case_utils/namespace.py +++ b/case_utils/namespace.py @@ -17,6 +17,8 @@ To use, add "from case_utils.namespace import *". Namespace variables starting with "NS_" are imported. As needs are demonstrated in CASE tooling (both in case_utils and from downstream requests), namespaces will also be imported from rdflib for a consistent "NS_*" spelling. """ +__version__ = "0.1.0" + import rdflib # type: ignore NS_SH = rdflib.SH