Skip to content

Commit cbc3e2a

Browse files
committed
Switch to build_packages.py
This replaces build_package.bash, automatically figures out the required dev labels, and generates the configs that it needs on the fly.
1 parent 91d91ab commit cbc3e2a

11 files changed

+139
-89
lines changed

recipes/e3sm-unified/build_package.bash

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import shutil
4+
import subprocess
5+
import argparse
6+
from jinja2 import Template
7+
import yaml
8+
9+
LABELS = {
10+
"chemdyg": "chemdyg_dev",
11+
"e3sm_diags": "e3sm_diags_dev",
12+
"e3sm_to_cmip": "e3sm_to_cmip_dev",
13+
"mache": "mache_dev",
14+
"mpas-analysis": "mpas_analysis_dev",
15+
"mpas_tools": "mpas_tools_dev",
16+
"xcdat": "xcdat_dev",
17+
"zppy": "zppy_dev",
18+
"zstash": "zstash_dev",
19+
}
20+
21+
DEV_PYTHON_VERSIONS = ["3.10"]
22+
DEV_MPI_VERSIONS = ["nompi", "hpc"]
23+
24+
RELEASE_PYTHON_VERSIONS = ["3.9", "3.10"]
25+
RELEASE_MPI_VERSIONS = ["nompi", "mpich", "openmpi", "hpc"]
26+
27+
28+
def generate_matrix_files(dev):
29+
with open("configs/template.yaml") as f:
30+
template_text = f.read()
31+
template = Template(template_text)
32+
if dev:
33+
python_versions = DEV_PYTHON_VERSIONS
34+
mpi_versions = DEV_MPI_VERSIONS
35+
else:
36+
python_versions = RELEASE_PYTHON_VERSIONS
37+
mpi_versions = RELEASE_MPI_VERSIONS
38+
matrix_files = []
39+
for python in python_versions:
40+
for mpi in mpi_versions:
41+
script = template.render(python=python, mpi=mpi)
42+
filename = f"configs/mpi_{mpi}_python{python}.yaml"
43+
with open(filename, "w") as handle:
44+
handle.write(script)
45+
matrix_files.append(filename)
46+
return matrix_files
47+
48+
49+
def get_rc_dev_labels(meta_yaml_path, labels_dict):
50+
"""Parse meta.yaml and return a list of dev labels for RC dependencies."""
51+
# Render the jinja template with dummy/default values
52+
with open(meta_yaml_path) as f:
53+
template_text = f.read()
54+
# Provide dummy/default values for all jinja variables used in meta.yaml
55+
template = Template(template_text)
56+
rendered = template.render(
57+
mpi='mpich', # or any valid value
58+
py='310', # or any valid value
59+
CONDA_PY='310', # used in build string
60+
)
61+
meta = yaml.safe_load(rendered)
62+
dev_labels = []
63+
run_reqs = meta.get("requirements", {}).get("run", [])
64+
for req in run_reqs:
65+
# req can be a string like "pkgname version" or just "pkgname"
66+
if isinstance(req, str):
67+
parts = req.split()
68+
pkg = parts[0]
69+
version = " ".join(parts[1:]) if len(parts) > 1 else ""
70+
# Only match 'rc' in version, not in pkg name
71+
if "rc" in version and pkg in labels_dict:
72+
label = labels_dict[pkg]
73+
if label not in dev_labels:
74+
dev_labels.append(label)
75+
return dev_labels
76+
77+
78+
def get_version_from_meta(meta_yaml_path):
79+
"""Parse the version from the {% set version = ... %} line in meta.yaml."""
80+
with open(meta_yaml_path) as f:
81+
for line in f:
82+
if line.strip().startswith("{% set version"):
83+
# e.g., {% set version = "1.11.1rc1" %}
84+
parts = line.split("=")
85+
if len(parts) >= 2:
86+
version = (
87+
parts[1].strip().strip('%}').strip().strip(
88+
'"').strip("'")
89+
)
90+
return version
91+
raise ValueError("Could not find version in meta.yaml")
92+
93+
94+
def main():
95+
parser = argparse.ArgumentParser(
96+
description="Build E3SM-Unified conda packages."
97+
)
98+
parser.add_argument(
99+
"--conda",
100+
type=str,
101+
default=os.path.expanduser("~/miniforge3"),
102+
help="Path to the conda base directory (default: ~/miniforge3)."
103+
)
104+
args = parser.parse_args()
105+
106+
conda_dir = os.path.expanduser(args.conda)
107+
meta_yaml_path = os.path.join(os.path.dirname(__file__), "meta.yaml")
108+
version = get_version_from_meta(meta_yaml_path)
109+
dev = "rc" in version
110+
111+
# Remove conda-bld directory if it exists
112+
bld_dir = os.path.join(conda_dir, "conda-bld")
113+
if os.path.exists(bld_dir):
114+
shutil.rmtree(bld_dir)
115+
116+
# Generate matrix files on the fly
117+
matrix_files = generate_matrix_files(dev)
118+
119+
dev_labels = []
120+
if dev:
121+
dev_labels = get_rc_dev_labels(meta_yaml_path, LABELS)
122+
123+
channels = []
124+
for label in dev_labels:
125+
channels.extend(["-c", f"conda-forge/label/{label}"])
126+
channels += [
127+
"-c", "conda-forge"
128+
]
129+
130+
for file in matrix_files:
131+
cmd = [
132+
"conda", "build", "-m", file, "--override-channels"
133+
] + channels + ["."]
134+
print("Running:", " ".join(cmd))
135+
subprocess.run(cmd, check=True)
136+
137+
138+
if __name__ == "__main__":
139+
main()

recipes/e3sm-unified/configs/generate.py

Lines changed: 0 additions & 15 deletions
This file was deleted.

recipes/e3sm-unified/configs/mpi_hpc_python3.10.yaml

Lines changed: 0 additions & 5 deletions
This file was deleted.

recipes/e3sm-unified/configs/mpi_hpc_python3.9.yaml

Lines changed: 0 additions & 5 deletions
This file was deleted.

recipes/e3sm-unified/configs/mpi_mpich_python3.10.yaml

Lines changed: 0 additions & 5 deletions
This file was deleted.

recipes/e3sm-unified/configs/mpi_mpich_python3.9.yaml

Lines changed: 0 additions & 5 deletions
This file was deleted.

recipes/e3sm-unified/configs/mpi_nompi_python3.10.yaml

Lines changed: 0 additions & 5 deletions
This file was deleted.

recipes/e3sm-unified/configs/mpi_nompi_python3.9.yaml

Lines changed: 0 additions & 5 deletions
This file was deleted.

recipes/e3sm-unified/configs/mpi_openmpi_python3.10.yaml

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)