build.py
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()