tools for building gleam projects with nix
at javascript 82 lines 2.1 kB view raw
1// SPDX-FileCopyrightText: 2025 Ruby Iris Juric <ruby@srxl.me> 2// 3// SPDX-License-Identifier: 0BSD 4 5use std::{fs, process::Command}; 6 7use miette::{Context, IntoDiagnostic, Result, miette}; 8 9use crate::gleam_toml; 10 11enum Target { 12 Erlang, 13 Javascript, 14} 15 16impl Target { 17 fn filename(&self) -> String { 18 match self { 19 Target::Erlang => "gleam_entrypoint.erl".to_string(), 20 Target::Javascript => "gleam_entrypoint.mjs".to_string(), 21 } 22 } 23} 24 25impl TryFrom<&str> for Target { 26 type Error = miette::Report; 27 28 fn try_from(target: &str) -> Result<Self, Self::Error> { 29 match target { 30 "erlang" => Ok(Self::Erlang), 31 "javascript" => Ok(Self::Javascript), 32 _ => Err(miette!("Unknown target {target}")), 33 } 34 } 35} 36 37fn generate_module_source(module_name: &str, target: &Target) -> String { 38 match target { 39 Target::Erlang => format!( 40 r#"-module('gleam_entrypoint'). 41-export([run/0]). 42 43run() -> 44 {{ok, _}} = application:ensure_all_started('{module_name}'), 45 {module_name}:main(), 46 erlang:halt(0). 47"# 48 ), 49 Target::Javascript => format!( 50 r#"import {{ main }} from "./{module_name}/{module_name}.mjs"; 51main(); 52"# 53 ), 54 } 55} 56 57pub fn generate_module(target: &str) -> Result<()> { 58 let target: Target = target.try_into()?; 59 let gleam_toml = gleam_toml::parse("gleam.toml")?; 60 let source = generate_module_source(&gleam_toml.name, &target); 61 62 fs::write(target.filename(), source) 63 .into_diagnostic() 64 .wrap_err("While writing entrypoint module source:")?; 65 66 match target { 67 Target::Javascript => Ok(()), 68 Target::Erlang => { 69 let compile_result = Command::new("erlc") 70 .arg(target.filename()) 71 .status() 72 .into_diagnostic() 73 .wrap_err("While running Erlang compiler:")?; 74 75 if compile_result.success() { 76 Ok(()) 77 } else { 78 Err(miette!("Entrypoint compilation failed")) 79 } 80 } 81 } 82}