diff --git a/docs/setup.rst b/docs/setup.rst index 55746b776..65700f241 100644 --- a/docs/setup.rst +++ b/docs/setup.rst @@ -37,7 +37,9 @@ Assuming one has ``conda`` in their path, then do the following:: conda activate fre-cli # add mkmf to your PATH - export PATH=$PATH:${PWD}/mkmf/bin + # mkmf PR 75 moved executables from bin/ to mkmf/bin/ within the mkmf repo; + # both paths are added here for backwards-compatibility with either version. + export PATH=$PATH:${PWD}/fre/mkmf/bin:${PWD}/fre/mkmf/mkmf/bin # now we pip install the local code under the `fre/` directory # the -e flag makes re-installing the code after editing not necessary diff --git a/fre/make/gfdlfremake/buildDocker.py b/fre/make/gfdlfremake/buildDocker.py index 87fbf1cfa..2d4cfc0ee 100644 --- a/fre/make/gfdlfremake/buildDocker.py +++ b/fre/make/gfdlfremake/buildDocker.py @@ -48,9 +48,11 @@ def __init__(self,base,exp,libs,RUNenv,target,mkTemplate,stage2base): self.setup.append(" && spack load "+l+" \\ \n") # Clone and copy mkmf through Dockerfile + # Backwards-compatible with both old mkmf (bin/) and mkmf PR 75 (mkmf/bin/) self.mkmfclone=["RUN cd /apps \\ \n", " && git clone --recursive https://github.com/NOAA-GFDL/mkmf \\ \n", - " && cp mkmf/bin/* /usr/local/bin \n"] + " && if [ -d mkmf/mkmf/bin ]; then cp mkmf/mkmf/bin/* /usr/local/bin;" + " else cp mkmf/bin/* /usr/local/bin; fi \n"] # Set bld_dir, src_dir, mkmf_template self.bldsetup=["RUN bld_dir="+self.bld+" \\ \n", diff --git a/fre/make/make_helpers.py b/fre/make/make_helpers.py index 5ecdc2cb1..73633ffa2 100644 --- a/fre/make/make_helpers.py +++ b/fre/make/make_helpers.py @@ -1,6 +1,7 @@ ''' this holds functions used across various parts of fre/make subtools ''' import logging +import os from pathlib import Path from typing import Optional @@ -28,9 +29,26 @@ def get_mktemplate_path(mk_template: str, container_flag: bool, model_root: Opti if not container_flag: if "/" not in mk_template: topdir = Path(__file__).resolve().parents[1] - template_path = str(topdir)+ "/mkmf/templates/"+mk_template + submodule_path = str(topdir) + "/mkmf/templates/" + mk_template - # Check in template path exists + # First, check the mkmf submodule location (backwards-compatible with both + # old mkmf structure and mkmf PR 75, since templates/ stays at repo root) + if Path(submodule_path).exists(): + template_path = submodule_path + else: + # Fall back to the conda package install location introduced by mkmf PR 75: + # templates are installed to $CONDA_PREFIX/share/mkmf/templates/ + conda_prefix = os.environ.get("CONDA_PREFIX") + if conda_prefix: + conda_path = conda_prefix + "/share/mkmf/templates/" + mk_template + if Path(conda_path).exists(): + template_path = conda_path + else: + template_path = submodule_path # use for the error message below + else: + template_path = submodule_path # use for the error message below + + # Check that the resolved template path exists if not Path(template_path).exists(): raise ValueError("Error w/ mkmf template. Created path from given " f"filename: {template_path} does not exist.") diff --git a/fre/make/tests/test_make_helpers.py b/fre/make/tests/test_make_helpers.py index b2cd24b28..9bd620425 100644 --- a/fre/make/tests/test_make_helpers.py +++ b/fre/make/tests/test_make_helpers.py @@ -1,6 +1,7 @@ """ Test fre make make_helpers """ +import os from pathlib import Path import pytest from fre.make import make_helpers @@ -93,3 +94,24 @@ def test_mktemplatepath_dne_with_name(test_variables): make_helpers.get_mktemplate_path(mk_template = template_path, model_root = None, container_flag = False) + +def test_mktemplate_name_conda_prefix(tmp_path, monkeypatch): + """ + Test that the right template_path is constructed from the conda package + install location ($CONDA_PREFIX/share/mkmf/templates/) when the mkmf + submodule template is not present but the conda package provides it. + This covers the mkmf PR 75 backwards-compatible behaviour. + """ + # Create a fake conda prefix with the template installed under share/mkmf/templates/ + conda_prefix = tmp_path / "conda_env" + template_dir = conda_prefix / "share" / "mkmf" / "templates" + template_dir.mkdir(parents=True) + fake_template = template_dir / "fake-template.mk" + fake_template.touch() + + monkeypatch.setenv("CONDA_PREFIX", str(conda_prefix)) + + template_path = make_helpers.get_mktemplate_path(mk_template = "fake-template.mk", + model_root = None, + container_flag = False) + assert str(fake_template) == template_path diff --git a/meta.yaml b/meta.yaml index 56b556b42..e684ee98a 100644 --- a/meta.yaml +++ b/meta.yaml @@ -8,9 +8,32 @@ source: build: script: - {{ PYTHON }} -m pip install . -vv - - cp fre/mkmf/bin/mkmf $PREFIX/bin - - cp fre/mkmf/bin/list_paths $PREFIX/bin - - cp fre/mkmf/bin/git-version-string $PREFIX/bin + - | + # Backwards-compatible copy of mkmf executables: + # mkmf PR 75 moved bin/ to mkmf/bin/ within the mkmf repository, + # so the submodule path changed from fre/mkmf/bin/ to fre/mkmf/mkmf/bin/. + # Try the new path first, fall back to the old path. + # If neither exists, warn but continue (mkmf may be a separate conda dependency). + for exe in mkmf list_paths git-version-string; do + if [ -f "fre/mkmf/mkmf/bin/$exe" ]; then + cp "fre/mkmf/mkmf/bin/$exe" "$PREFIX/bin/$exe" + elif [ -f "fre/mkmf/bin/$exe" ]; then + cp "fre/mkmf/bin/$exe" "$PREFIX/bin/$exe" + else + echo "Warning: $exe not found in mkmf submodule (checked fre/mkmf/mkmf/bin/ and fre/mkmf/bin/). Expected to be provided by a separate noaa-gfdl::mkmf conda dependency." + fi + done + # Install mkmf templates to the standard data-files location, mirroring what + # mkmf PR 75 does in the standalone mkmf conda package. This makes fre-cli + # self-contained: downstream tools (get_mktemplate_path) resolve a bare + # template name to $CONDA_PREFIX/share/mkmf/templates/.mk when the + # mkmf submodule templates/ directory is not present at runtime. + if [ -d "fre/mkmf/templates" ]; then + mkdir -p "$PREFIX/share/mkmf/templates" + cp -r fre/mkmf/templates/* "$PREFIX/share/mkmf/templates/" + else + echo "Warning: fre/mkmf/templates/ not found; mkmf templates not installed to $PREFIX/share/mkmf/templates/." + fi noarch: python channels: