Created
September 21, 2024 04:45
-
-
Save augustine-tran/5f049940a9478620eb351125b21931f5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'fileutils' | |
require 'optparse' | |
# Helper function to prompt for user confirmation | |
def ask_override(message) | |
puts "#{message} (y/n):" | |
answer = gets.chomp.downcase | |
answer == 'y' | |
end | |
# Function to get input for project name and port | |
def get_project_details(options) | |
project_name = options[:project_name] | |
port = options[:port] | |
if project_name.nil? || project_name.strip.empty? | |
puts "Enter project name (e.g. shelob):" | |
project_name = gets.chomp | |
end | |
if port.nil? || port.strip.empty? | |
puts "Enter port number (e.g. 3000):" | |
port = gets.chomp | |
end | |
{ project_name: project_name, port: port } | |
end | |
# Function to update /etc/hosts idempotently, with option to override | |
def update_hosts_file(project_name, dry_run) | |
hosts_entry = "127.0.0.1 #{project_name}.test" | |
hosts_file = "/etc/hosts" | |
if File.read(hosts_file).include?(hosts_entry) | |
puts "/etc/hosts already contains entry for #{project_name}.test" | |
if ask_override("Do you want to override the /etc/hosts entry?") | |
unless dry_run | |
system("sudo sed -i '' '/#{project_name}.test/d' #{hosts_file}") | |
system("sudo sh -c 'echo \"#{hosts_entry}\" >> /etc/hosts'") | |
puts "Overwritten /etc/hosts entry with #{hosts_entry}" | |
else | |
puts "[Dry-run] Would overwrite /etc/hosts entry with #{hosts_entry}" | |
end | |
else | |
puts "Skipping /etc/hosts update." | |
end | |
else | |
if dry_run | |
puts "[Dry-run] Would append '#{hosts_entry}' to /etc/hosts" | |
else | |
system("sudo sh -c 'echo \"#{hosts_entry}\" >> /etc/hosts'") | |
puts "Updated /etc/hosts with #{hosts_entry}" | |
end | |
end | |
end | |
# Function to generate SSL certificates idempotently, with option to override | |
def generate_ssl_certificates(project_name, dry_run) | |
cert_dir = "/opt/caddy/certs" | |
cert_file = "#{cert_dir}/#{project_name}.test+1.pem" | |
key_file = "#{cert_dir}/#{project_name}.test+1-key.pem" | |
if File.exist?(cert_file) && File.exist?(key_file) | |
puts "SSL certificates for #{project_name}.test already exist." | |
if ask_override("Do you want to regenerate the SSL certificates?") | |
unless dry_run | |
system("rm -f #{cert_file} #{key_file}") | |
system("mkcert -cert-file #{cert_file} -key-file #{key_file} #{project_name}.test") | |
puts "Overwritten SSL certificates for #{project_name}.test" | |
else | |
puts "[Dry-run] Would overwrite SSL certificates for #{project_name}.test" | |
end | |
else | |
puts "Skipping SSL certificate generation." | |
end | |
else | |
if dry_run | |
puts "[Dry-run] Would generate SSL certificates for #{project_name}.test" | |
else | |
FileUtils.mkdir_p(cert_dir) unless File.directory?(cert_dir) | |
system("mkcert -cert-file #{cert_file} -key-file #{key_file} #{project_name}.test") | |
puts "Generated SSL certificates for #{project_name}.test and stored in #{cert_dir}" | |
end | |
end | |
end | |
# Function to update Caddyfile idempotently, with option to override | |
def update_caddyfile(project_name, port, dry_run) | |
caddyfile = "/opt/homebrew/etc/Caddyfile" | |
caddy_block = <<-CADDY | |
#{project_name}.test { | |
tls /opt/caddy/certs/#{project_name}.test+1.pem /opt/caddy/certs/#{project_name}.test+1-key.pem | |
reverse_proxy 127.0.0.1:#{port} { | |
header_up Host {host} | |
header_up Origin {scheme}://{host} | |
header_up X-Real-IP {remote} | |
header_up X-Forwarded-Host {host} | |
header_up X-Forwarded-Server {host} | |
header_up X-Forwarded-Port {port} | |
header_up X-Forwarded-For {remote} | |
header_up X-Forwarded-Proto {scheme} | |
} | |
} | |
CADDY | |
if File.exist?(caddyfile) && File.read(caddyfile).include?("#{project_name}.test") | |
puts "Caddyfile already contains entry for #{project_name}.test." | |
if ask_override("Do you want to overwrite the Caddy configuration for #{project_name}.test?") | |
unless dry_run | |
system("sed -i '' '/#{project_name}.test/,+12d' #{caddyfile}") | |
File.open(caddyfile, "a") { |f| f.puts caddy_block } | |
puts "Overwritten Caddy configuration for #{project_name}.test on port #{port}." | |
else | |
puts "[Dry-run] Would overwrite Caddy configuration for #{project_name}.test on port #{port}." | |
end | |
else | |
puts "Skipping Caddyfile update." | |
end | |
else | |
if dry_run | |
puts "[Dry-run] Would append Caddy configuration for #{project_name}.test on port #{port}" | |
else | |
File.open(caddyfile, "a") { |f| f.puts caddy_block } | |
puts "Appended Caddy configuration for #{project_name}.test on port #{port}." | |
end | |
end | |
end | |
# Main script logic | |
def main | |
# Parse options for project name, port, and dry-run mode | |
options = {} | |
OptionParser.new do |opts| | |
opts.banner = "Usage: setup_local_domain.rb [options]" | |
opts.on("--project-name NAME", "Project name (e.g., shelob)") do |name| | |
options[:project_name] = name | |
end | |
opts.on("--port PORT", "Port number (e.g., 3000)") do |port| | |
options[:port] = port | |
end | |
opts.on("--dry-run", "Run script in dry-run mode (no changes will be made)") do | |
options[:dry_run] = true | |
end | |
end.parse! | |
# Get project details from command line or prompt for them | |
project_details = get_project_details(options) | |
project_name = project_details[:project_name] | |
port = project_details[:port] | |
dry_run = options[:dry_run] || false | |
# Run the script with or without dry-run | |
update_hosts_file(project_name, dry_run) | |
generate_ssl_certificates(project_name, dry_run) | |
update_caddyfile(project_name, port, dry_run) | |
if dry_run | |
puts "Dry-run complete for #{project_name}.test on port #{port}. No changes were made." | |
else | |
puts "Setup complete for #{project_name}.test on port #{port}." | |
end | |
end | |
main if __FILE__ == $PROGRAM_NAME |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment