Skip to content

Commit 5347fbd

Browse files
authored
feat(programs): add programs module and database (#243)
Rehome the programs database and related module from pymake. Also create MANIFEST.in referencing data files to include them in the published package. Metadata creation (code.json) and related capabilities coming separately
1 parent fe5f124 commit 5347fbd

File tree

5 files changed

+149
-0
lines changed

5 files changed

+149
-0
lines changed

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include modflow_devtools/programs/*.csv
2+
include modflow_devtools/registry/*.toml

autotest/test_programs.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import pytest
2+
3+
from modflow_devtools.programs import get_program, get_programs, load_programs
4+
5+
6+
def test_load_programs():
7+
programs = get_programs()
8+
assert isinstance(programs, dict)
9+
assert "mf6" in programs
10+
mf6 = get_program("mf6")
11+
assert mf6 == programs["mf6"]
12+
assert isinstance(mf6.version, str)
13+
assert isinstance(mf6.current, bool)
14+
assert isinstance(mf6.url, str)
15+
assert isinstance(mf6.dirname, str)
16+
assert isinstance(mf6.srcdir, str)
17+
assert isinstance(mf6.standard_switch, bool)
18+
assert isinstance(mf6.double_switch, bool)
19+
assert isinstance(mf6.shared_object, bool)
20+
21+
22+
def test_strict_unrecognized_keys(function_tmpdir):
23+
tmp_path = function_tmpdir / "programs.csv"
24+
with tmp_path.open("w") as f:
25+
f.write(
26+
"target,version,current,url,dirname,srcdir,standard_switch,double_switch,shared_object,garbage\n"
27+
)
28+
f.write(
29+
"mf6,6.6.3,True,https://github.com/MODFLOW-ORG/modflow6/releases/download/6.6.3/mf6.6.3_linux.zip,mf6.6.3_linux,src,True,False,False,garbage\n"
30+
)
31+
32+
with pytest.raises(ValueError) as e:
33+
load_programs(tmp_path, strict=True)
34+
assert "Unrecognized keys in program data: {'unrecognized_key'}" in e.message

docs/md/programs.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# MODFLOW and related programs
2+
3+
The `modflow_devtools.programs` module provides a database of programs in the MODFLOW ecosystem. This has previously been housed in [`pymake`](https://github.com/modflowpy/pymake).
4+
5+
The database is accessible as a dictionary of programs:
6+
7+
```python
8+
from modflow_devtools.programs import get_programs, get_program
9+
10+
programs = get_programs()
11+
mf6 = programs["mf6"]
12+
mf6 = get_program("mf6") # equivalent
13+
```
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""Utilities for accessing the program database"""
2+
3+
from csv import DictReader
4+
from dataclasses import dataclass
5+
from os import PathLike
6+
from pathlib import Path
7+
8+
from modflow_devtools.misc import try_literal_eval
9+
10+
DB_NAME = "programs.csv"
11+
DB_PATH = Path(__file__).parent / DB_NAME
12+
13+
14+
@dataclass
15+
class Program:
16+
target: str
17+
version: str
18+
current: bool
19+
url: str
20+
dirname: str
21+
srcdir: str
22+
standard_switch: bool
23+
double_switch: bool
24+
shared_object: bool
25+
26+
@classmethod
27+
def from_dict(cls, d: dict, strict: bool = False) -> "Program":
28+
"""
29+
Create a Program instance from a dictionary.
30+
31+
Parameters
32+
----------
33+
d : dict
34+
Dictionary containing program data
35+
strict : bool, optional
36+
If True, raise ValueError if dict contains unrecognized keys.
37+
If False (default), ignore unrecognized keys.
38+
"""
39+
keys = set(cls.__annotations__.keys())
40+
if strict:
41+
dkeys = {k.strip() for k in d.keys()}
42+
if extra_keys := dkeys - keys:
43+
raise ValueError(f"Unrecognized keys in program data: {extra_keys}")
44+
return cls(
45+
**{
46+
k.strip(): try_literal_eval(v.strip())
47+
for k, v in d.items()
48+
if k.strip() in keys
49+
}
50+
)
51+
52+
53+
def load_programs(path: str | PathLike, strict: bool = False) -> dict[str, Program]:
54+
"""Load the program database from the CSV file."""
55+
56+
path = Path(path).expanduser().resolve()
57+
with path.open() as csvfile:
58+
# assumes the first row is the header!
59+
reader = DictReader(csvfile, skipinitialspace=True)
60+
programs = [Program.from_dict(row, strict) for row in reader]
61+
return {program.target: program for program in programs}
62+
63+
64+
PROGRAMS = load_programs(DB_PATH, strict=True)
65+
66+
67+
def get_programs() -> dict[str, Program]:
68+
"""Get the program database."""
69+
return PROGRAMS
70+
71+
72+
def get_program(name: str) -> Program:
73+
"""Get a specific program by name."""
74+
return PROGRAMS[name]
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
target , version , current, url , dirname , srcdir , standard_switch, double_switch, shared_object
2+
mf6 , 6.6.3 , True , https://github.com/MODFLOW-ORG/modflow6/releases/download/6.6.3/mf6.6.3_linux.zip , mf6.6.3_linux , src , True , False , False
3+
zbud6 , 6.6.3 , True , https://github.com/MODFLOW-ORG/modflow6/releases/download/6.6.3/mf6.6.3_linux.zip , mf6.6.3_linux , utils/zonebudget/src, True , False , False
4+
libmf6 , 6.6.3 , True , https://github.com/MODFLOW-ORG/modflow6/releases/download/6.6.3/mf6.6.3_linux.zip , mf6.6.3_linux , srcbmi , True , False , True
5+
mp7 , 7.2.001 , True , https://water.usgs.gov/water-resources/software/MODPATH/modpath_7_2_001.zip , modpath_7_2_001 , source , True , False , False
6+
mt3dms , 5.3.0 , True , https://github.com/MODFLOW-ORG/mt3dms/releases/download/2.0/mt3dms-2.0.zip , mt3dms-2.0 , true-binary , True , False , False
7+
mt3dusgs , 1.1.0 , True , https://github.com/MODFLOW-ORG/mt3d-usgs/releases/download/1.1.0/mt3dusgs1.1.0.zip , mt3dusgs1.1.0 , src , True , False , False
8+
vs2dt , 3.3 , True , https://water.usgs.gov/water-resources/software/VS2DI/vs2dt3_3.zip , vs2dt3_3 , include , True , False , False
9+
triangle , 1.6 , True , https://github.com/MODFLOW-ORG/triangle/releases/download/1.0/triangle-1.0.zip , triangle-1.0 , src , True , False , False
10+
gridgen , 1.0.02 , True , https://github.com/MODFLOW-ORG/gridgen/releases/download/1.0.02/gridgen-1.0.02.zip , gridgen-1.0.02 , src , True , False , False
11+
crt , 1.3.1 , True , https://water.usgs.gov/ogw/CRT/CRT_1.3.1.zip , CRT_1.3.1 , SOURCE , True , False , False
12+
sutra , 4.0 , True , https://water.usgs.gov/water-resources/software/sutra/4.0/SUTRA_4_0_0.zip , SutraSuite , SUTRA_4_0/source , True , False , False
13+
mf2000 , 1.19.01 , True , https://water.usgs.gov/nrp/gwsoftware/modflow2000/mf2k1_19_01.tar.gz , mf2k.1_19 , src , True , False , False
14+
mf2005 , 1.12.00 , True , https://github.com/MODFLOW-ORG/mf2005/releases/download/v.1.12.00/MF2005.1_12u.zip , MF2005.1_12u , src , True , False , False
15+
mfusg , 1.5 , True , https://github.com/MODFLOW-ORG/mfusg/releases/download/v1.5.00/mfusg1_5.zip , mfusg1_5 , src , True , False , False
16+
zonbudusg , 1.5 , True , https://github.com/MODFLOW-ORG/mfusg/releases/download/v1.5.00/mfusg1_5.zip , mfusg1_5 , src/zonebudusg , True , False , False
17+
swtv4 , 4.00.05 , True , https://water.usgs.gov/water-resources/software/SEAWAT/swt_v4_00_05.zip , swt_v4_00_05 , source , False , True , False
18+
mp6 , 6.0.1 , True , https://water.usgs.gov/water-resources/software/MODPATH/modpath.6_0_01.zip , modpath.6_0 , src , True , False , False
19+
mflgr , 2.0.0 , True , https://water.usgs.gov/ogw/modflow-lgr/modflow-lgr-v2.0.0/mflgrv2_0_00.zip , mflgr.2_0 , src , True , False , False
20+
zonbud3 , 3.01 , True , https://water.usgs.gov/water-resources/software/ZONEBUDGET/zonbud3_01.exe , Zonbud.3_01 , Src , True , False , False
21+
mfnwt1.1.4 , 1.1.4 , False , https://water.usgs.gov/water-resources/software/MODFLOW-NWT/MODFLOW-NWT_1.1.4.zip , MODFLOW-NWT_1.1.4 , src , True , False , False
22+
mfnwt , 1.3.0 , True , https://water.usgs.gov/water-resources/software/MODFLOW-NWT/MODFLOW-NWT_1.3.0.zip , MODFLOW-NWT , src , True , False , False
23+
mfusg_gsi , 2.5.0 , True , https://www.gsienv.com/wp-content/uploads/2025/04/USG_T_Version-2.5.0-2.zip , USGT_V2-5-0_Source_Code , . , True , False , False
24+
mf6dev , 6.7.0.dev3 , False , https://github.com/MODFLOW-ORG/modflow6/archive/refs/heads/develop.zip , modflow6-develop , src , True , False , False
25+
zbud6dev , 6.7.0.dev3 , False , https://github.com/MODFLOW-ORG/modflow6/archive/refs/heads/develop.zip , modflow6-develop , utils/zonebudget/src, True , False , False
26+
libmf6dev , 6.7.0.dev3 , False , https://github.com/MODFLOW-ORG/modflow6/archive/refs/heads/develop.zip , modflow6-develop , srcbmi , True , False , True

0 commit comments

Comments
 (0)