Skip to content

Commit

Permalink
refactor(distscripts): use pathlib, misc
Browse files Browse the repository at this point in the history
* use pathlib for path manipulations
* construct paths relative to script locn instead of cwd (permits running from project root)
* update dist script tests to use pytest tmpdirs and restore modified files
* remove unneeded step (move zip files) from test_night_build_script CI job
* don't run makefile creation/build tests in parallel (avoid state pollution)
  • Loading branch information
wpbonelli committed Oct 31, 2022
1 parent 5869d4a commit de0432f
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 195 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/ci-check-warnings-gfortran.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,3 @@ jobs:
working-directory: distribution
run: |
pytest -v -s build_nightly.py
- name: Move the build zip file
run: |
ls -l ./distribution/*
mv ./distribution/temp_zip/linux.zip ./linux.zip
ls -l ./
2 changes: 1 addition & 1 deletion .github/workflows/ci-tests-gfortran-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
- name: Test make for MODFLOW 6 programs
working-directory: ./distribution
run: |
pytest -v -n=auto build_makefiles.py
pytest -v build_makefiles.py
- name: Get regression test files
run: |
Expand Down
134 changes: 97 additions & 37 deletions distribution/build_makefiles.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from datetime import datetime
import os
import sys
from contextlib import contextmanager
from pathlib import Path

import pymake
import pytest

if sys.platform.lower() == "win32":
ext = ".exe"
Expand All @@ -16,28 +19,31 @@
fc = sys.argv[idx + 1]

# if compiler not set by command line argument
# use environmental variable or set to default compiler (gfortran)
# use environment variable or set to default compiler (gfortran)
if fc is None:
if "FC" in os.environ:
fc = os.getenv("FC")
else:
fc = "gfortran"

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


@contextmanager
def cwd(path):
oldpwd = os.getcwd()
prev = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(oldpwd)
os.chdir(prev)


def run_makefile(target):
assert os.path.isfile(
assert Path(
"makefile"
), f"makefile does not exist in {os.getcwd()}"
).is_file(), f"makefile does not exist in {os.getcwd()}"

base_target = os.path.basename(target)
base_message = (
Expand All @@ -60,19 +66,13 @@ def run_makefile(target):
f"{base_target} does not exist." + base_message
)

# clean after successful make
print(f"clean {base_target} with makefile")
os.system("make clean")

return


def build_mf6_makefile():
with cwd(os.path.join("..", "make")):
with cwd(root_path / "make"):
pm = pymake.Pymake()
pm.target = "mf6"
pm.srcdir = os.path.join("..", "src")
pm.appdir = os.path.join("..", "bin")
pm.srcdir = str(root_path / "src")
pm.appdir = str(root_path / "bin")
pm.include_subdirs = True
pm.inplace = True
pm.dryrun = True
Expand All @@ -85,16 +85,15 @@ def build_mf6_makefile():
msg = f"could not create makefile for '{pm.target}'."
assert pm.returncode == 0, msg

return


def build_zbud6_makefile():
with cwd(os.path.join("..", "utils", "zonebudget", "make")):
util_path = root_path / "utils" / "zonebudget"
with cwd(util_path / "make"):
pm = pymake.Pymake()
pm.target = "zbud6"
pm.srcdir = os.path.join("..", "src")
pm.appdir = os.path.join("..", "..", "..", "bin")
pm.extrafiles = os.path.join("..", "pymake", "extrafiles.txt")
pm.srcdir = str(util_path / "src")
pm.appdir = str(root_path / "bin")
pm.extrafiles = str(util_path / "pymake" / "extrafiles.txt")
pm.inplace = True
pm.makeclean = True
pm.dryrun = True
Expand All @@ -107,14 +106,13 @@ def build_zbud6_makefile():
msg = f"could not create makefile for '{pm.target}'."
assert pm.returncode == 0, msg

return


def build_mf5to6_makefile():
with cwd(os.path.join("..", "utils", "mf5to6", "make")):
srcdir = os.path.join("..", "src")
target = os.path.join("..", "..", "..", "bin", "mf5to6")
extrafiles = os.path.join("..", "pymake", "extrafiles.txt")
util_path = root_path / "utils" / "mf5to6"
with cwd(util_path / "make"):
srcdir = str(util_path / "src")
target = str(root_path / "bin" / "mf5to6")
extrafiles = str(util_path / "pymake" / "extrafiles.txt")

# build modflow 5 to 6 converter
returncode = pymake.main(
Expand All @@ -129,34 +127,96 @@ def build_mf5to6_makefile():
fflags="-fall-intrinsics",
)

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

return

def test_build_mf6_makefile():
makefile_paths = [root_path / "make" / "makefile"]
makefile_mtimes = [p.stat().st_mtime for p in makefile_paths]

build_mf6_makefile()

# check files were modified
for p, t in zip(makefile_paths, makefile_mtimes):
assert p.stat().st_mtime > t
os.system(f"git restore {p}")


def test_build_zbud6_makefile():
util_path = root_path / "utils" / "zonebudget"
makefile_paths = [util_path / "make" / "makefile"]
makefile_mtimes = [p.stat().st_mtime for p in makefile_paths]

build_zbud6_makefile()

# check files were modified
for p, t in zip(makefile_paths, makefile_mtimes):
assert p.stat().st_mtime > t
os.system(f"git restore {p}")


def test_build_mf5to6_makefile():
util_path = root_path / "utils" / "mf5to6"
makefile_paths = [util_path / "make" / "makefile"]
makefile_mtimes = [p.stat().st_mtime for p in makefile_paths]

build_mf5to6_makefile()

# check files were modified
for p, t in zip(makefile_paths, makefile_mtimes):
assert p.stat().st_mtime > t
os.system(f"git restore {p}")


def test_build_mf6_wmake():
target = os.path.join("..", "bin", f"mf6{ext}")
with cwd(os.path.join("..", "make")):
target = root_path / "bin" / f"mf6{ext}"
mtime = target.stat().st_mtime if target.is_file() else datetime.today().timestamp()

with cwd(root_path / "make"):
run_makefile(target)

# check executable was modified
assert target.stat().st_mtime > mtime

# clean after successful make
print(f"clean {target} with makefile")
os.system("make clean")


def test_build_zbud6_wmake():
target = os.path.join("..", "..", "..", "bin", f"zbud6{ext}")
with cwd(os.path.join("..", "utils", "zonebudget", "make")):
target = root_path / "bin" / f"zbud6{ext}"
util_path = root_path / "utils" / "zonebudget"
mtime = target.stat().st_mtime if target.is_file() else datetime.today().timestamp()

with cwd(util_path / "make"):
run_makefile(target)

# check executable was modified
assert target.stat().st_mtime > mtime

# clean after successful make
print(f"clean {target} with makefile")
os.system("make clean")


def test_build_mf5to6_wmake():
target = os.path.join("..", "..", "..", "bin", f"mf5to6{ext}")
with cwd(os.path.join("..", "utils", "mf5to6", "make")):
target = root_path / "bin" / f"mf5to6{ext}"
util_path = root_path / "utils" / "mf5to6"
mtime = target.stat().st_mtime if target.is_file() else datetime.today().timestamp()

with cwd(util_path / "make"):
run_makefile(target)

# check executable was modified
assert target.stat().st_mtime > mtime

# clean after successful make
print(f"clean {target} with makefile")
os.system("make clean")


if __name__ == "__main__":
build_mf6_makefile()
build_zbud6_makefile()
build_mf5to6_makefile()
# test_build_mf6_wmake()
# test_build_zbud6_wmake()
# test_build_mf5to6_wmake()
Loading

0 comments on commit de0432f

Please sign in to comment.