Skip to main content

lux_cli/
generate_rockspec.rs

1use clap::Args;
2use lux_lib::{package::PackageName, project::Project, rockspec::Rockspec, workspace::Workspace};
3use miette::{IntoDiagnostic, Result};
4use std::path::PathBuf;
5
6use crate::args::OutputFormat;
7
8#[derive(Args)]
9pub struct GenerateRockspec {
10    /// Package to generate the rockspec for.
11    #[arg(short, long, visible_short_alias = 'p')]
12    package: Option<PackageName>,
13
14    #[arg(long, default_value = "text", value_enum, ignore_case = true)]
15    output_format: OutputFormat,
16}
17
18pub async fn generate_rockspec(data: GenerateRockspec) -> Result<()> {
19    let workspace = Workspace::current_or_err()?;
20
21    let targets: Vec<&Project> = match &data.package {
22        Some(package) => vec![workspace.select_member(package)?],
23        None => workspace.members().into_iter().collect(),
24    };
25
26    let mut generated_paths = Vec::new();
27
28    for project in targets {
29        let path = generate_project_rockspec(project).await?;
30
31        if data.output_format == OutputFormat::Text {
32            println!("Wrote rockspec to {}", path.display());
33        }
34
35        generated_paths.push(path.to_string_lossy().into_owned());
36    }
37
38    if data.output_format == OutputFormat::Json {
39        println!(
40            "{}",
41            serde_json::to_string(&generated_paths).into_diagnostic()?
42        );
43    }
44
45    Ok(())
46}
47
48async fn generate_project_rockspec(project: &Project) -> Result<PathBuf> {
49    let toml = project.toml().into_remote(None)?;
50    let rockspec = toml.to_lua_remote_rockspec_string()?;
51
52    let path = project
53        .root()
54        .join(format!("{}-{}.rockspec", toml.package(), toml.version()));
55
56    tokio::fs::write(&path, rockspec).await.into_diagnostic()?;
57
58    Ok(path)
59}