build.py

0b2895a90c7751ce06e4b26d4db41005ea2f40a9
cleberg.net/build.py history · blame · raw

136 lines · 4078 bytes

  1#!/usr/bin/env python3
  2import os
  3import shutil
  4import subprocess
  5import sys
  6from pathlib import Path
  7
  8def prompt(prompt_text):
  9    try:
 10        return input(prompt_text).strip()
 11    except EOFError:
 12        return ''
 13
 14def remove_build_directory(build_dir):
 15    if build_dir.exists():
 16        print(f"Removing previous build directory: {build_dir}/")
 17        shutil.rmtree(build_dir)
 18    build_dir.mkdir(parents=True, exist_ok=True)
 19
 20def minify_css(src_css, dest_css):
 21    print(f"Minifying CSS: {src_css} → {dest_css}")
 22    result = subprocess.run(
 23        ["minify", "-o", str(dest_css), str(src_css)],
 24        stdout=subprocess.PIPE,
 25        stderr=subprocess.PIPE,
 26        text=True,
 27    )
 28    if result.returncode != 0:
 29        print("Error during CSS minification:")
 30        print(result.stderr, file=sys.stderr)
 31        sys.exit(1)
 32
 33def run_emacs_publish(dev_mode=True):
 34    if dev_mode:
 35        print("Running Emacs publish script (development)...")
 36        result = subprocess.run(
 37            ["emacs", "--script", "publish.el"],
 38            stdout=subprocess.PIPE,
 39            stderr=subprocess.PIPE,
 40            text=True,
 41        )
 42    else:
 43        print("Running Emacs publish script (production)...")
 44        result = subprocess.run(
 45            ["emacs", "--script", "publish.el"],
 46            stdout=subprocess.DEVNULL,
 47            stderr=subprocess.DEVNULL,
 48            text=True,
 49        )
 50
 51    if result.returncode != 0:
 52        print("Error running publish.el:")
 53        print(result.stderr, file=sys.stderr)
 54        sys.exit(1)
 55
 56def deploy_to_server(build_dir, server):
 57    remote_path = f"{server}:/var/www/cleberg.net/"
 58    print(f"Deploying .build/ → {remote_path}")
 59    result = subprocess.run(
 60        ["rsync", "-r", "--delete-before", f"{build_dir}/", remote_path],
 61        stdout=subprocess.PIPE,
 62        stderr=subprocess.PIPE,
 63        text=True,
 64    )
 65    if result.returncode != 0:
 66        print("Error during rsync deployment:")
 67        print(result.stderr, file=sys.stderr)
 68        sys.exit(1)
 69
 70def start_dev_server(build_dir):
 71    print(f"Starting development HTTP server from {build_dir}/ on port 8000")
 72    os.chdir(build_dir)
 73    # This will run until interrupted (Ctrl+C)
 74    try:
 75        subprocess.run(
 76            [sys.executable, "-m", "http.server", "8000"],
 77            check=True
 78        )
 79    except KeyboardInterrupt:
 80        print("\nDevelopment server stopped.")
 81    except subprocess.CalledProcessError as e:
 82        print(f"Error starting development server: {e}", file=sys.stderr)
 83        sys.exit(1)
 84
 85def main():
 86    build_dir = Path(".build")
 87    theme_dir = Path("theme/static")
 88    css_src = theme_dir / "styles.css"
 89    css_min = theme_dir / "styles.min.css"
 90
 91    answer = prompt("Did you update the 'Recent Blog Posts' section? [yn] ")
 92    if not answer.lower().startswith("y"):
 93        print("Please update the 'Recent Blog Posts' section before publishing!")
 94        sys.exit(0)
 95
 96    env = os.environ.get("ENV", "").lower()
 97    if env == "prod":
 98        print("Environment: Production")
 99        method = prompt("Publishing on remote or LAN? [r|l] ").lower()
100        if method == "r":
101            homelab_server = "homelab-remote"
102        elif method == "l":
103            homelab_server = "homelab"
104        else:
105            print("Invalid input. Assuming LAN (homelab)")
106            homelab_server = "homelab"
107
108        # Remove previous build
109        remove_build_directory(build_dir)
110
111        # Minify CSS
112        minify_css(css_src, css_min)
113
114        # Run publishing script (silenced output)
115        run_emacs_publish(dev_mode=False)
116
117        # Deploy changes
118        deploy_to_server(build_dir, homelab_server)
119
120    else:
121        print("Environment: Development")
122
123        # Remove previous build
124        remove_build_directory(build_dir)
125
126        # Minify CSS
127        minify_css(css_src, css_min)
128
129        # Run publishing script (with console output)
130        run_emacs_publish(dev_mode=True)
131
132        # Launch development web server
133        start_dev_server(build_dir)
134
135if __name__ == "__main__":
136    main()