tools for building gleam projects with nix
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

gleam2nix/gen-app: refactor, include information from gleam.toml file

foxgirl.engineering ec2f6eac 259dc7e7

verified
+74 -48
+68 -18
src/app.rs
··· 2 2 // 3 3 // SPDX-License-Identifier: 0BSD 4 4 5 + use std::{fs, path::Path}; 6 + 5 7 use miette::{Context, IntoDiagnostic, Result, miette}; 6 8 7 - pub fn generate_app_file( 8 - name: &str, 9 - version: &str, 10 - otp_dependencies: &Vec<String>, 11 - out_path: &str, 12 - ) -> Result<String> { 13 - let otp_dependencies = otp_dependencies.join(","); 9 + use crate::{ 10 + Arguments, 11 + gleam_toml::{self, GleamToml}, 12 + }; 13 + 14 + pub struct AppSpec { 15 + pub name: String, 16 + pub contents: String, 17 + } 18 + 19 + fn get_applications(otp_dependencies: Vec<String>, gleam_toml: &GleamToml) -> Vec<String> { 20 + let extra_applications = gleam_toml 21 + .erlang 22 + .as_ref() 23 + .and_then(|e| e.extra_applications.clone()) 24 + .unwrap_or_default(); 25 + let mut applications = [otp_dependencies, extra_applications].concat(); 26 + applications.sort(); 27 + applications.dedup(); 28 + 29 + applications 30 + } 14 31 15 - let modules = std::fs::read_dir(&out_path) 32 + fn get_modules(out_dir: &str) -> Result<Vec<String>> { 33 + std::fs::read_dir(out_dir) 16 34 .into_diagnostic()? 17 35 .collect::<Result<Vec<_>, _>>() 18 36 .into_diagnostic() 19 - .wrap_err(format!("While getting files in \"{out_path}\":"))? 37 + .wrap_err(format!("While getting files in \"{out_dir}\":"))? 20 38 .iter() 21 39 .filter(|path| { 22 40 path.path() ··· 31 49 .map(|p| p.to_string()) 32 50 .ok_or(miette!("Non UTF-8 filename in directory")) 33 51 }) 34 - .collect::<Result<Vec<_>, _>>()? 35 - .join(","); 52 + .collect::<Result<Vec<_>, _>>() 53 + } 36 54 37 - Ok(format!( 38 - r#"{{application, {name}, [ 39 - {{vsn, "{version}"}}, 40 - {{applications, [{otp_dependencies}]}}, 41 - {{description, ""}}, 55 + fn generate_app_spec(otp_dependencies: Vec<String>, out_dir: &str) -> Result<AppSpec> { 56 + let gleam_toml = gleam_toml::parse("gleam.toml")?; 57 + 58 + let applications = get_applications(otp_dependencies, &gleam_toml).join(","); 59 + let modules = get_modules(out_dir)?.join(","); 60 + let start_module = gleam_toml 61 + .erlang 62 + .and_then(|e| e.application_start_module) 63 + .map(|module| format!("{{mod, {{'{module}', []}}}},\n")) 64 + .unwrap_or_default(); 65 + 66 + Ok(AppSpec { 67 + name: gleam_toml.name.clone(), 68 + contents: format!( 69 + r#"{{application, {0}, [ 70 + {{vsn, "{1}"}}, 71 + {start_module}{{applications, [{applications}]}}, 72 + {{description, "{2}"}}, 42 73 {{modules, [{modules}]}}, 43 74 {{registered, []}} 44 - ]}}."# 45 - )) 75 + ]}}."#, 76 + gleam_toml.name, 77 + gleam_toml.version, 78 + gleam_toml.description.unwrap_or_default() 79 + ), 80 + }) 81 + } 82 + 83 + pub fn generate_app_file(args: Arguments) -> Result<()> { 84 + let out_path = args 85 + .rest 86 + .first() 87 + .ok_or(miette!("No output path specified"))? 88 + .to_string(); 89 + 90 + let app_spec = generate_app_spec(args.otp_dependencies, &out_path)?; 91 + 92 + fs::write(Path::new(&out_path).join(&app_spec.name), app_spec.contents).into_diagnostic()?; 93 + println!("Successfully generated {}", app_spec.name); 94 + 95 + Ok(()) 46 96 }
+6 -30
src/main.rs
··· 2 2 // 3 3 // SPDX-License-Identifier: 0BSD 4 4 5 - use std::{fs, path::Path}; 5 + use std::fs; 6 6 7 7 use facet::Facet; 8 8 use miette::{IntoDiagnostic, Result, miette}; ··· 34 34 } 35 35 36 36 #[derive(Debug, Facet)] 37 - struct Arguments { 37 + pub struct Arguments { 38 38 #[facet(positional, default)] 39 - command: String, 39 + pub command: String, 40 40 41 41 #[facet(positional, default)] 42 - rest: Vec<String>, 43 - 44 - #[facet(named, default, short = "n")] 45 - name: Option<String>, 46 - 47 - #[facet(named, default, short = "v")] 48 - version: Option<String>, 42 + pub rest: Vec<String>, 49 43 50 44 #[facet(named, default, short = "d")] 51 - otp_dependencies: Vec<String>, 45 + pub otp_dependencies: Vec<String>, 52 46 } 53 47 54 48 fn gen_nix(args: Arguments) -> Result<()> { ··· 72 66 Ok(()) 73 67 } 74 68 75 - fn gen_app(args: Arguments) -> Result<()> { 76 - let name = args.name.ok_or(miette!("No app name specified"))?; 77 - let version = args.version.ok_or(miette!("No version specified"))?; 78 - let out_path = args 79 - .rest 80 - .first() 81 - .ok_or(miette!("No output path specified"))? 82 - .to_string(); 83 - 84 - let app_contents = app::generate_app_file(&name, &version, &args.otp_dependencies, &out_path)?; 85 - let app_file_name = format!("{}.app", name); 86 - 87 - fs::write(Path::new(&out_path).join(&app_file_name), app_contents).into_diagnostic()?; 88 - println!("Successfully generated {app_file_name}"); 89 - 90 - Ok(()) 91 - } 92 - 93 69 fn main() -> Result<()> { 94 70 let args: Arguments = facet_args::from_std_args()?; 95 71 ··· 100 76 .ok_or(miette!("No module name specified"))?, 101 77 ), 102 78 Command::GenNix => gen_nix(args), 103 - Command::GenApp => gen_app(args), 79 + Command::GenApp => app::generate_app_file(args), 104 80 Command::NotFound => Err(miette!("Command not found")), 105 81 } 106 82 }