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