Skip to content

Commit

Permalink
Adds README for environments
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonb5 committed Jun 25, 2024
1 parent 6f96980 commit a00849e
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 1 deletion.
5 changes: 4 additions & 1 deletion dockerfiles/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

NAMESPACE ?= ghcr.io/esgf-nimbus

build push run: REPOSITORY = $(lastword $(subst /, ,$(PWD)))
build push run readme: REPOSITORY = $(lastword $(subst /, ,$(PWD)))

build:
docker build $(ARGS) -t $(NAMESPACE)/$(REPOSITORY):$(VERSION) . $(if $(POST_BUILD),&& $(POST_BUILD),)
Expand All @@ -18,3 +18,6 @@ changelog:

bump-%:
tbump --no-tag --no-push $(shell pysemver bump $* $(shell tbump current-version)) && make changelog && git add changelog.md && git commit -m "Updates changelog"

readme:
docker run -it --rm --entrypoint python -v $(PWD):/host -w /host $(NAMESPACE)/$(REPOSITORY):$(VERSION) /host/generate.py $(ENVIRONMENT_FILE)
2 changes: 2 additions & 0 deletions dockerfiles/climate-notebook-gpu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ VERSION = 0.1.5

run: ARGS = -p 8888:8888

ENVIRONMENT_FILE = base.yaml

include ../Makefile
6 changes: 6 additions & 0 deletions dockerfiles/climate-notebook-gpu/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Packages

| ML packages |
| ----------- |
| rapids 0.0.1 |
| cupy 13.2.0 |
104 changes: 104 additions & 0 deletions dockerfiles/climate-notebook-gpu/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import json
import re
import subprocess
import itertools
import argparse


def main():
parser = argparse.ArgumentParser()
parser.add_argument("file", help="Conda environment file")

kwargs = vars(parser.parse_args())

categories = get_categories(**kwargs)

search_args = "|".join(
[f"^{x}$" for packages in categories.values() for x in packages]
)

output = subprocess.run(
f"mamba list {search_args!r} --json",
capture_output=True,
shell=True
)

output_json = json.loads(output.stdout)

versions = {
package["name"]: package["version"] for package in output_json
}

table = []
categories = list(categories.items())

for i in range(0, len(categories), 3):
header = " | ".join([x[0] for x in categories[i:i+3]])
separator = " | ".join([f"{'-'*len(x[0])}" for x in categories[i:i+3]])
header = f"| {header} |\n| {separator} |"

rows = itertools.zip_longest(*[x[1] for x in categories[i:i+3]])
rows = [
" | ".join(
[
"" if y is None else f"{y} {get_version(y, versions)}"
for y in x
]
) for x in rows
]
rows = "\n".join(f"| {x} |" for x in rows)

table.append(f"{header}\n{rows}")

table = "\n".join(table)

data = f"""# Packages
{table}"""

with open("README.md", "w") as fd:
fd.write(data)


def get_version(package, versions):
m = re.search(r"([^<>=]*)(?:(?:<|>|<=|>=|==).*)?", package)

if m is None:
raise Exception("Could not parse ", package)

name = m.group(1)

return versions[name]


def get_categories(file, **_):
with open(file) as fd:
lines = fd.readlines()

category = None
packages = {}

for line in lines:
if "#" in line:
m = re.search("# (.*)(?: packages)?", line)

if m is None:
continue

category = m.group(1)
elif category != "ignore" and category is not None:
m = re.search("- (.*)", line)

if m is None:
continue

if category in packages:
packages[category].append(m.group(1))
else:
packages[category] = [m.group(1)]

return packages


if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions dockerfiles/climate-notebook/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ export-env: ENTRYPOINT = /bin/bash
export-env: COMMAND = -c "cp /base.yaml /conda-envs/"
export-env: run

ENVIRONMENT_FILE = base.yaml

include ../Makefile
16 changes: 16 additions & 0 deletions dockerfiles/climate-notebook/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Packages

| Data packages | Climate packages | Plotting packages |
| ------------- | ---------------- | ----------------- |
| xarray 2024.6.0 | xcdat 0.7.0 | matplotlib 3.8.4 |
| xarray-datatree 0.0.14 | xesmf 0.8.5 | holoviews 1.17.1 |
| pandas 2.2.2 | xgcm 0.8.1 | hvplot 0.10.0 |
| flox 0.9.8 | pcmdi_metrics 3.4.1 | geoviews 1.9.6 |
| netcdf4 1.6.5 | gsw-xarray 0.4.0 | seaborn 0.13.2 |
| s3fs 2024.6.0 | | cartopy 0.23.0 |
| zarr 2.18.2 | | datashader 0.16.2 |
| Computing packages | Discovery packages |
| ------------------ | ------------------ |
| dask-gateway 2024.1.0 | intake-esm 2024.2.6 |
| | intake-stac 0.4.0 |
| | intake-xarray 0.7.0 |
104 changes: 104 additions & 0 deletions dockerfiles/climate-notebook/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import json
import re
import subprocess
import itertools
import argparse


def main():
parser = argparse.ArgumentParser()
parser.add_argument("file", help="Conda environment file")

kwargs = vars(parser.parse_args())

categories = get_categories(**kwargs)

search_args = "|".join(
[f"^{x}$" for packages in categories.values() for x in packages]
)

output = subprocess.run(
f"mamba list {search_args!r} --json",
capture_output=True,
shell=True
)

output_json = json.loads(output.stdout)

versions = {
package["name"]: package["version"] for package in output_json
}

table = []
categories = list(categories.items())

for i in range(0, len(categories), 3):
header = " | ".join([x[0] for x in categories[i:i+3]])
separator = " | ".join([f"{'-'*len(x[0])}" for x in categories[i:i+3]])
header = f"| {header} |\n| {separator} |"

rows = itertools.zip_longest(*[x[1] for x in categories[i:i+3]])
rows = [
" | ".join(
[
"" if y is None else f"{y} {get_version(y, versions)}"
for y in x
]
) for x in rows
]
rows = "\n".join(f"| {x} |" for x in rows)

table.append(f"{header}\n{rows}")

table = "\n".join(table)

data = f"""# Packages
{table}"""

with open("README.md", "w") as fd:
fd.write(data)


def get_version(package, versions):
m = re.search(r"([^<>=]*)(?:(?:<|>|<=|>=|==).*)?", package)

if m is None:
raise Exception("Could not parse ", package)

name = m.group(1)

return versions[name]


def get_categories(file, **_):
with open(file) as fd:
lines = fd.readlines()

category = None
packages = {}

for line in lines:
if "#" in line:
m = re.search("# (.*)(?: packages)?", line)

if m is None:
continue

category = m.group(1)
elif category != "ignore" and category is not None:
m = re.search("- (.*)", line)

if m is None:
continue

if category in packages:
packages[category].append(m.group(1))
else:
packages[category] = [m.group(1)]

return packages


if __name__ == "__main__":
main()

0 comments on commit a00849e

Please sign in to comment.