diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e494b7..07d6e45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - Process anyOf and allOf and well as oneOf https://github.com/OpenDataServices/compile-to-json-schema/issues/28 +- Can specify multiple codelist directories + - New param `codelist_base_directories` + - CLI flag can be specified multiple times ### Removed diff --git a/compiletojsonschema/cli/__main__.py b/compiletojsonschema/cli/__main__.py index 993fb33..9ef1bb9 100644 --- a/compiletojsonschema/cli/__main__.py +++ b/compiletojsonschema/cli/__main__.py @@ -16,6 +16,7 @@ def main(): parser.add_argument( "-c", "--codelist-base-directory", + action="append", help="Which directory we should look in for codelists", ) @@ -24,6 +25,6 @@ def main(): ctjs = CompileToJsonSchema( input_filename=args.input_file, set_additional_properties_false_everywhere=args.set_additional_properties_false_everywhere, - codelist_base_directory=args.codelist_base_directory, + codelist_base_directories=args.codelist_base_directory, ) print(ctjs.get_as_string()) diff --git a/compiletojsonschema/compiletojsonschema.py b/compiletojsonschema/compiletojsonschema.py index b03d6d1..b56a11c 100644 --- a/compiletojsonschema/compiletojsonschema.py +++ b/compiletojsonschema/compiletojsonschema.py @@ -14,6 +14,7 @@ def __init__( input_filename=None, set_additional_properties_false_everywhere=False, codelist_base_directory=None, + codelist_base_directories=[], input_schema=None, ): if not isinstance(input_schema, dict) and not input_filename: @@ -23,8 +24,14 @@ def __init__( self.set_additional_properties_false_everywhere = ( set_additional_properties_false_everywhere ) - if codelist_base_directory: - self.codelist_base_directory = os.path.expanduser(codelist_base_directory) + if codelist_base_directories or codelist_base_directory: + self.codelist_base_directories = [ + os.path.expanduser(i) for i in codelist_base_directories + ] + if codelist_base_directory: + self.codelist_base_directories.append( + os.path.expanduser(codelist_base_directory) + ) else: self.codelist_base_directory = os.getcwd() @@ -83,24 +90,25 @@ def __process(self, source): if "codelist" in source and ( "openCodelist" not in source or not source["openCodelist"] ): - filename = os.path.join(self.codelist_base_directory, source["codelist"]) - if os.path.isfile(filename): - values = [] - with open(filename) as fp: - csvreader = csv.reader(fp, delimiter=",", quotechar='"') - next(csvreader, None) - for row in csvreader: - if len(row) > 0 and row[0]: - values.append(row[0]) - if values: - out["enum"] = values - else: - raise CodeListNotFoundException( - "Can not find codelist: " + source["codelist"] - ) + values = [] + with open(self._get_full_filename_to_codelist(source["codelist"])) as fp: + csvreader = csv.reader(fp, delimiter=",", quotechar='"') + next(csvreader, None) + for row in csvreader: + if len(row) > 0 and row[0]: + values.append(row[0]) + if values: + out["enum"] = values return out + def _get_full_filename_to_codelist(self, reference): + for codelist_base_directory in self.codelist_base_directories: + filename = os.path.join(codelist_base_directory, reference) + if os.path.isfile(filename): + return filename + raise CodeListNotFoundException("Can not find codelist: " + reference) + class CodeListNotFoundException(Exception): pass diff --git a/docs/cli.rst b/docs/cli.rst index 6dc3e1f..05c6803 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -26,6 +26,11 @@ You can set the directory that is searched for codelists using the `--codelist-b compiletojsonschema -c data/codelists schema.json compiletojsonschema --codelist-base-directory data/codelists schema.json +You can pass this multiple times. + +.. code-block:: shell-session + + compiletojsonschema -c data/codelists/open -c data/codelists/closed schema.json Set additional properties false everywhere ------------------------------------------ diff --git a/tests/test_codelist.py b/tests/test_codelist.py index 2c2ae38..68d8c17 100644 --- a/tests/test_codelist.py +++ b/tests/test_codelist.py @@ -52,6 +52,30 @@ def test_basic(): assert out["properties"]["pet"]["enum"] == ["Dog", "Cat", "Parrot"] +def test_multiple_dirs(): + + # schema.json has no openCodelist value deliberately so we can test the default options. + input_filename = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "codelists", + "schema.json", + ) + + codelist_dir1 = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "fixtures", + "codelists", + ) + + ctjs = CompileToJsonSchema( + input_filename=input_filename, codelist_base_directories=[codelist_dir1] + ) + out = ctjs.get() + + assert out["properties"]["pet"]["enum"] == ["Dog", "Cat", "Parrot"] + + def test_open_codelist(): input_filename = os.path.join(