forked from MODFLOW-ORG/modflow-devtools
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdfn2toml.py
More file actions
125 lines (108 loc) · 3.71 KB
/
Copy pathdfn2toml.py
File metadata and controls
125 lines (108 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""Convert DFNs to TOML."""
import argparse
import sys
import textwrap
from dataclasses import asdict
from os import PathLike
from pathlib import Path
import tomli_w as tomli
from boltons.iterutils import remap
from modflow_devtools.dfns import Dfn, is_valid, load, load_flat, map, to_flat, to_tree
from modflow_devtools.dfns.parse import parse_dfn
from modflow_devtools.dfns.schema.block import block_sort_key
from modflow_devtools.misc import drop_none_or_empty
# mypy: ignore-errors
def convert(inpath: PathLike, outdir: PathLike, schema_version: str = "2") -> None:
"""
Convert DFN files in `inpath` to TOML files in `outdir`.
By default, convert the definitions to schema version 2.
"""
inpath = Path(inpath).expanduser().absolute()
outdir = Path(outdir).expanduser().absolute()
outdir.mkdir(exist_ok=True, parents=True)
if inpath.is_file():
if inpath.name == "common.dfn":
raise ValueError("Cannot convert common.dfn as a standalone file")
common_path = inpath.parent / "common.dfn"
if common_path.exists():
with common_path.open() as f:
common, _ = parse_dfn(f)
else:
common = {}
with inpath.open() as f:
dfn = load(f, name=inpath.stem, common=common, format="dfn")
dfn = map(dfn, schema_version=schema_version)
_convert(dfn, outdir / f"{inpath.stem}.toml")
else:
dfns = {
name: map(dfn, schema_version=schema_version) for name, dfn in load_flat(inpath).items()
}
tree = to_tree(dfns)
flat = to_flat(tree)
for dfn_name, dfn in flat.items():
_convert(dfn, outdir / f"{dfn_name}.toml")
def _convert(dfn: Dfn, outpath: Path) -> None:
with Path.open(outpath, "wb") as f:
# TODO if we start using c/attrs, swap out
# all this for a custom unstructuring hook
dfn_dict = asdict(dfn)
dfn_dict["schema_version"] = str(dfn_dict["schema_version"])
if blocks := dfn_dict.pop("blocks", None):
for block_name, block_fields in blocks.items():
if block_name not in dfn_dict:
dfn_dict[block_name] = {}
for field_name, field_data in block_fields.items():
dfn_dict[block_name][field_name] = field_data
tomli.dump(
dict(
sorted(
remap(dfn_dict, visit=drop_none_or_empty).items(),
key=block_sort_key,
)
),
f,
)
if __name__ == "__main__":
"""
Convert DFN files in the original format and schema version 1
to TOML files, by default also converting to schema version 2.
"""
parser = argparse.ArgumentParser(
description="Convert DFN files to TOML.",
epilog=textwrap.dedent(
"""\
Convert DFN files in the original format and schema version 1
to TOML files, by default also converting to schema version 2.
"""
),
)
parser.add_argument(
"--indir",
"-i",
type=str,
help="Directory containing DFN files, or a single DFN file.",
)
parser.add_argument(
"--outdir",
"-o",
help="Output directory.",
)
parser.add_argument(
"--schema-version",
"-s",
type=str,
default="2",
help="Schema version to convert to.",
)
parser.add_argument(
"--validate",
"-v",
action="store_true",
help="Validate DFN files without converting them.",
)
args = parser.parse_args()
if args.validate:
if not is_valid(args.indir):
sys.exit(1)
else:
convert(args.indir, args.outdir, args.schema_version)