Skip to content

Commit

Permalink
Merge pull request NCAR#195 from samsrabin/publish-website
Browse files Browse the repository at this point in the history
Add support (and documentation) for web publishing
  • Loading branch information
TeaganKing authored Mar 3, 2025
2 parents 42589e4 + 8bb3688 commit c6ead53
Show file tree
Hide file tree
Showing 7 changed files with 451 additions and 29 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ cupid.egg-info
# Documentation
/docs/_build/
/docs/README.md
/docs/NCAR_tips.md
/docs/contributors.md
/docs/NCARtips.md
/docs/Contributors.md
172 changes: 146 additions & 26 deletions cupid/cupid_webpage.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,123 @@
import os
import shutil
import subprocess
from urllib.parse import quote

import click
import yaml
from git_helper import GitHelper
from util import get_control_dict
from util import is_bad_env


def github_pages_publish(
github_pages_dir,
github_pages_dir_thisversion,
name,
overwrite,
git_repo,
html_output_path,
):
"""
Publishes a version of the site to GitHub Pages.
Copies the HTML output to the GitHub Pages directory, add prefix to `index.html`
with a link to the new version, and pushes changes to the repository.
Args:
github_pages_dir (str): Root directory for GitHub Pages.
github_pages_dir_thisversion (str): Directory for the specific version.
name (str): Version name.
overwrite (bool): Whether to overwrite existing files.
git_repo (GitHelper): Git repository helper instance.
html_output_path (str): Path to the generated HTML files.
"""
parent_dir = os.path.split(github_pages_dir_thisversion)[-1]
if not os.path.exists(parent_dir):
os.makedirs(parent_dir)
shutil.copytree(
html_output_path,
github_pages_dir_thisversion,
dirs_exist_ok=overwrite,
)

# Handle special characters, converting e.g. ^ to %5E
name_url = quote(name)

# Write to index.html, if needed
index_html_file = os.path.join(github_pages_dir, "index.html")
new_line = f'<a href="versions/{name_url}/index.html"/>{name}</a><p>\n'
do_write = True
if os.path.exists(index_html_file):
with open(index_html_file) as f:
for line in f:
if line.strip() == new_line.strip():
do_write = False
break
if do_write:
with open(index_html_file, "a") as f:
f.write(new_line)

# Publish to GitHub.io
git_repo.publish()


def github_pages_args(github_pages_dir, name, overwrite):
"""
Prepares the GitHub Pages directory for publishing.
Ensures a name is provided, initializes a `GitHelper` object,
and checks if the version directory exists, handling overwrite conditions.
Args:
github_pages_dir (str): Root directory for GitHub Pages.
name (str): Version name.
overwrite (bool): Whether to overwrite an existing version directory.
Returns:
tuple: (str, GitHelper) - The version directory path and `GitHelper` instance.
Raises:
RuntimeError: If no name is provided.
FileExistsError: If the directory exists and overwrite is not allowed.
"""
# Check that you gave a name
if not name:
raise RuntimeError(
"When specifying -g/--github-pages-dir, you must also provide -n/--name",
)

# Set up GitHelper object
git_repo = GitHelper(github_pages_dir, name)
this_version_dir = os.path.join(github_pages_dir, "versions", name)
if os.path.exists(this_version_dir) and not overwrite:
raise FileExistsError(
f"Add -o to overwrite existing directory '{this_version_dir}'",
)
print(f"Publishing to '{this_version_dir}'")
return this_version_dir, git_repo


@click.command()
@click.argument("config_path", default="config.yml")
def build(config_path):
@click.option(
"--github-pages-dir",
"-g",
default="",
help="For publishing to GitHub pages:\n"
"Directory where the HTML outputs should be copied (into a new sub-directory in versions/ given by -n/--name)",
)
@click.option(
"--name",
"-n",
default="",
help="Name of version to publish",
)
@click.option(
"--overwrite",
"-o",
is_flag=True,
help="Overwrite existing publish directory",
)
def build(config_path, github_pages_dir, name, overwrite):
"""
Build a Jupyter book based on the TOC in CONFIG_PATH. Called by `cupid-webpage`.
Expand All @@ -37,40 +146,51 @@ def build(config_path):
None
"""

with open(config_path) as fid:
control = yaml.safe_load(fid)
control = get_control_dict(config_path)

# Check and process arguments
github_pages_dir = os.path.realpath(github_pages_dir)
if github_pages_dir:
github_pages_dir_thisversion, git_repo = github_pages_args(
github_pages_dir,
name,
overwrite,
)

run_dir = control["data_sources"]["run_dir"]

subprocess.run(["jupyter-book", "clean", f"{run_dir}/computed_notebooks"])
subprocess.run(
["jupyter-book", "build", f"{run_dir}/computed_notebooks", "--all"],
)
html_output_path = os.path.join(run_dir, "computed_notebooks", "_build", "html")
for component in control["compute_notebooks"]:
for notebook in control["compute_notebooks"][component]:
# Skip this notebook if it wasn't run due to bad environment
info = control["compute_notebooks"][component][notebook]
if is_bad_env(control, info):
print(f"Skipping {notebook}: Not run due to bad environment")
continue

if "external_tool" in control["compute_notebooks"][component][notebook]:
if (
control["compute_notebooks"][component][notebook][
"external_tool"
].get("tool_name")
== "ADF"
):
if os.path.exists(f"{run_dir}/ADF_output"):
shutil.copytree(
f"{run_dir}/ADF_output",
f"{run_dir}/computed_notebooks/_build/html/ADF",
)
elif (
control["compute_notebooks"][component][notebook][
"external_tool"
].get("tool_name")
== "ILAMB"
):
if os.path.exists(f"{run_dir}/ILAMB_output"):
shutil.copytree(
f"{run_dir}/ILAMB_output",
f"{run_dir}/computed_notebooks/_build/html/ILAMB",
)
tool_name = control["compute_notebooks"][component][notebook][
"external_tool"
].get("tool_name")
if tool_name in ["ADF", "ILAMB"]:
shutil.copytree(
f"{run_dir}/{tool_name}_output",
os.path.join(html_output_path, tool_name),
)

if github_pages_dir:
github_pages_publish(
github_pages_dir,
github_pages_dir_thisversion,
name,
overwrite,
git_repo,
html_output_path,
)

# Originally used this code to copy jupyter book HTML to a location to host it online

Expand Down
Loading

0 comments on commit c6ead53

Please sign in to comment.