Skip to content

Commit a591a0e

Browse files
committed
refactor(distscripts): use pathlib
* use pathlib for path manipulations * construct paths relative to script locn instead of cwd (allows running from project root)
1 parent 5869d4a commit a591a0e

4 files changed

Lines changed: 132 additions & 174 deletions

File tree

distribution/build_makefiles.py

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import sys
33
from contextlib import contextmanager
4+
from pathlib import Path
45

56
import pymake
67

@@ -16,28 +17,31 @@
1617
fc = sys.argv[idx + 1]
1718

1819
# if compiler not set by command line argument
19-
# use environmental variable or set to default compiler (gfortran)
20+
# use environment variable or set to default compiler (gfortran)
2021
if fc is None:
2122
if "FC" in os.environ:
2223
fc = os.getenv("FC")
2324
else:
2425
fc = "gfortran"
2526

27+
# assumes this file is in <project root>/distribution
28+
root_path = Path(__file__).parent.parent
29+
2630

2731
@contextmanager
2832
def cwd(path):
29-
oldpwd = os.getcwd()
33+
prev = os.getcwd()
3034
os.chdir(path)
3135
try:
3236
yield
3337
finally:
34-
os.chdir(oldpwd)
38+
os.chdir(prev)
3539

3640

3741
def run_makefile(target):
38-
assert os.path.isfile(
42+
assert Path(
3943
"makefile"
40-
), f"makefile does not exist in {os.getcwd()}"
44+
).is_file(), f"makefile does not exist in {os.getcwd()}"
4145

4246
base_target = os.path.basename(target)
4347
base_message = (
@@ -64,15 +68,13 @@ def run_makefile(target):
6468
print(f"clean {base_target} with makefile")
6569
os.system("make clean")
6670

67-
return
68-
6971

7072
def build_mf6_makefile():
71-
with cwd(os.path.join("..", "make")):
73+
with cwd(root_path / "make"):
7274
pm = pymake.Pymake()
7375
pm.target = "mf6"
74-
pm.srcdir = os.path.join("..", "src")
75-
pm.appdir = os.path.join("..", "bin")
76+
pm.srcdir = str(root_path / "src")
77+
pm.appdir = str(root_path / "bin")
7678
pm.include_subdirs = True
7779
pm.inplace = True
7880
pm.dryrun = True
@@ -85,16 +87,15 @@ def build_mf6_makefile():
8587
msg = f"could not create makefile for '{pm.target}'."
8688
assert pm.returncode == 0, msg
8789

88-
return
89-
9090

9191
def build_zbud6_makefile():
92-
with cwd(os.path.join("..", "utils", "zonebudget", "make")):
92+
util_path = root_path / "utils" / "zonebudget"
93+
with cwd(util_path / "make"):
9394
pm = pymake.Pymake()
9495
pm.target = "zbud6"
95-
pm.srcdir = os.path.join("..", "src")
96-
pm.appdir = os.path.join("..", "..", "..", "bin")
97-
pm.extrafiles = os.path.join("..", "pymake", "extrafiles.txt")
96+
pm.srcdir = str(util_path / "src")
97+
pm.appdir = str(root_path / "bin")
98+
pm.extrafiles = str(util_path / "pymake" / "extrafiles.txt")
9899
pm.inplace = True
99100
pm.makeclean = True
100101
pm.dryrun = True
@@ -107,14 +108,13 @@ def build_zbud6_makefile():
107108
msg = f"could not create makefile for '{pm.target}'."
108109
assert pm.returncode == 0, msg
109110

110-
return
111-
112111

113112
def build_mf5to6_makefile():
114-
with cwd(os.path.join("..", "utils", "mf5to6", "make")):
115-
srcdir = os.path.join("..", "src")
116-
target = os.path.join("..", "..", "..", "bin", "mf5to6")
117-
extrafiles = os.path.join("..", "pymake", "extrafiles.txt")
113+
util_path = root_path / "utils" / "mf5to6"
114+
with cwd(util_path / "make"):
115+
srcdir = str(util_path / "src")
116+
target = str(root_path / "bin" / "mf5to6")
117+
extrafiles = str(util_path / "pymake" / "extrafiles.txt")
118118

119119
# build modflow 5 to 6 converter
120120
returncode = pymake.main(
@@ -129,34 +129,31 @@ def build_mf5to6_makefile():
129129
fflags="-fall-intrinsics",
130130
)
131131

132-
msg = f"could not create makefile for '{os.path.basename(target)}'."
132+
msg = f"could not create makefile for '{target}'."
133133
assert returncode == 0, msg
134134

135-
return
136-
137135

138136
def test_build_mf6_wmake():
139-
target = os.path.join("..", "bin", f"mf6{ext}")
140-
with cwd(os.path.join("..", "make")):
137+
target = str(root_path / "bin" / f"mf6{ext}")
138+
with cwd(root_path / "make"):
141139
run_makefile(target)
142140

143141

144142
def test_build_zbud6_wmake():
145-
target = os.path.join("..", "..", "..", "bin", f"zbud6{ext}")
146-
with cwd(os.path.join("..", "utils", "zonebudget", "make")):
143+
target = str(root_path / "bin" / f"zbud6{ext}")
144+
util_path = root_path / "utils" / "zonebudget"
145+
with cwd(util_path / "make"):
147146
run_makefile(target)
148147

149148

150149
def test_build_mf5to6_wmake():
151-
target = os.path.join("..", "..", "..", "bin", f"mf5to6{ext}")
152-
with cwd(os.path.join("..", "utils", "mf5to6", "make")):
150+
target = str(root_path / "bin" / f"mf5to6{ext}")
151+
util_path = root_path / "utils" / "mf5to6"
152+
with cwd(util_path / "make"):
153153
run_makefile(target)
154154

155155

156156
if __name__ == "__main__":
157157
build_mf6_makefile()
158158
build_zbud6_makefile()
159159
build_mf5to6_makefile()
160-
# test_build_mf6_wmake()
161-
# test_build_zbud6_wmake()
162-
# test_build_mf5to6_wmake()

distribution/build_nightly.py

Lines changed: 52 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import os
2-
import pathlib
1+
from os import PathLike, chdir, X_OK
2+
from pathlib import Path
33
import platform
4-
import shutil
4+
from shutil import which
5+
import subprocess
56
import sys
67

78
import flopy
89
import pymake
910

10-
# add path to build script in autotest directory and reuse mf6 build scripts
11-
sys.path.append(os.path.join("..", "autotest"))
12-
from build_exes import meson_build
11+
from make_release import update_version
12+
from mkdist import update_mf6io_tex_files
1313

1414
# make sure exe extension is used on windows
1515
eext = ""
@@ -18,10 +18,6 @@
1818
eext = ".exe"
1919
soext = ".dll"
2020

21-
bin_path = os.path.abspath(os.path.join("..", "bin"))
22-
example_path = os.path.abspath(os.path.join("temp"))
23-
zip_path = os.path.abspath(os.path.join("temp_zip"))
24-
2521

2622
def get_zipname():
2723
zipname = sys.platform.lower()
@@ -35,78 +31,58 @@ def get_zipname():
3531
return zipname
3632

3733

38-
def relpath_fallback(pth):
39-
try:
40-
# throws ValueError on Windows if pth is on a different drive
41-
return os.path.relpath(pth)
42-
except ValueError:
43-
return os.path.abspath(pth)
44-
45-
46-
def create_dir(pth):
47-
# remove pth directory if it exists
48-
if os.path.exists(pth):
49-
print(f"removing... {os.path.abspath(pth)}")
50-
shutil.rmtree(pth)
51-
52-
# create pth directory
53-
print(f"creating... {os.path.abspath(pth)}")
54-
os.makedirs(pth)
55-
56-
msg = f"could not create... {os.path.abspath(pth)}"
57-
assert os.path.exists(pth), msg
58-
59-
60-
def test_update_version():
61-
from make_release import update_version
62-
63-
update_version()
64-
65-
66-
def test_create_dirs():
67-
for pth in (
68-
bin_path,
69-
zip_path,
70-
):
71-
create_dir(pth)
34+
def create_nightly_build(workspace_path: PathLike, zip_path: PathLike):
35+
chdir(Path(workspace_path))
7236

37+
# build release source files with Meson
38+
cmd = (
39+
f"meson setup builddir "
40+
+ f"--bindir=bin "
41+
+ f"--libdir=bin "
42+
+ f"--prefix={('%CD%' if platform.system() == 'Windows' else '$(pwd)')}"
43+
+ (" --wipe" if Path("builddir").is_dir() else "")
44+
)
45+
print(f"Running meson setup command: {cmd}")
46+
subprocess.run(cmd, shell=True, check=True)
7347

74-
def test_nightly_build():
75-
meson_build()
48+
cmd = "meson install -C builddir"
49+
print(f"Running meson install command: {cmd}")
50+
subprocess.run(cmd, shell=True, check=True)
7651

7752
# test if there are any executable files to zip
7853
binpth_files = [
79-
os.path.join(bin_path, f)
80-
for f in os.listdir(bin_path)
81-
if os.path.isfile(os.path.join(bin_path, f))
82-
and shutil.which(os.path.join(bin_path, f), mode=os.X_OK)
83-
and pathlib.Path(os.path.join(bin_path, f)).suffix
84-
not in (".a", ".lib", ".pdb")
54+
str(bin_path / f)
55+
for f in bin_path.glob('*')
56+
if (bin_path / f).is_file()
57+
and which(bin_path / f, mode=X_OK)
58+
and (bin_path / f).suffix not in (".a", ".lib", ".pdb")
8559
]
8660
if len(binpth_files) < 1:
8761
raise FileNotFoundError(
88-
f"No executable files present in {os.path.abspath(bin_path)}.\n"
89-
+ f"Available files:\n [{', '.join(os.listdir(bin_path))}]"
62+
f"No executable files present in {bin_path.absolute()}.\n"
63+
+ f"Available files:\n [{', '.join([str(p) for p in bin_path.glob('*')])}]"
9064
)
9165
else:
9266
print(f"Files to zip:\n [{', '.join(binpth_files)}]")
9367

94-
zip_pth = os.path.abspath(os.path.join(zip_path, get_zipname() + ".zip"))
95-
print(f"Zipping files to '{zip_pth}'")
96-
success = pymake.zip_all(zip_pth, file_pths=binpth_files)
97-
assert success, f"Could not create '{zip_pth}'"
68+
zip_path = (Path(zip_path) / (get_zipname() + ".zip")).absolute()
69+
print(f"Zipping files to '{zip_path}'")
70+
success = pymake.zip_all(str(zip_path), file_pths=binpth_files)
71+
assert success, f"Could not create '{zip_path}'"
9872

9973

100-
def test_update_mf6io():
101-
from mkdist import update_mf6io_tex_files
74+
def update_mf6io(bin_path: PathLike, example_path: PathLike):
75+
bin_path = Path(bin_path)
76+
example_path = Path(example_path)
10277

103-
# build simple model
10478
name = "mymodel"
105-
ws = os.path.join(example_path, name)
79+
ws = str(example_path / name)
10680
exe_name = "mf6"
10781
if sys.platform.lower() == "win32":
10882
exe_name += ".exe"
109-
exe_name = os.path.join(bin_path, exe_name)
83+
exe_name = str(bin_path / exe_name)
84+
85+
# build simple model
11086
sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=ws, exe_name=exe_name)
11187
tdis = flopy.mf6.ModflowTdis(sim)
11288
ims = flopy.mf6.ModflowIms(sim)
@@ -125,7 +101,16 @@ def test_update_mf6io():
125101

126102

127103
if __name__ == "__main__":
128-
test_update_version()
129-
test_create_dirs()
130-
test_nightly_build()
131-
test_update_mf6io()
104+
build_path = Path(__file__).parent.parent
105+
bin_path = build_path / "bin"
106+
example_path = build_path / "temp"
107+
zip_path = build_path / "distribution" / "temp_zip"
108+
109+
print(f"Building nightly MODFLOW 6 release")
110+
bin_path.mkdir(exist_ok=True, parents=True)
111+
example_path.mkdir(exist_ok=True, parents=True)
112+
zip_path.mkdir(exist_ok=True, parents=True)
113+
114+
update_version()
115+
create_nightly_build(build_path, zip_path)
116+
update_mf6io(bin_path, example_path)

0 commit comments

Comments
 (0)