lux_cli/
format.rs

1use std::path::PathBuf;
2
3use clap::Args;
4use eyre::{OptionExt, Result};
5use lux_lib::project::Project;
6use stylua_lib::Config;
7use walkdir::WalkDir;
8
9#[derive(Args)]
10pub struct Fmt {
11    /// Optional path to a workspace or Lua file to format
12    workspace_or_file: Option<PathBuf>,
13}
14
15// TODO: Add `PathBuf` parameter that describes what directory or file to format here.
16pub fn format(args: Fmt) -> Result<()> {
17    let project = Project::current()?.ok_or_eyre(
18        "`lx fmt` can only be executed in a lux project! Run `lx new` to create one.",
19    )?;
20
21    let config: Config = std::fs::read_to_string("stylua.toml")
22        .or_else(|_| std::fs::read_to_string(".stylua.toml"))
23        .map(|config: String| toml::from_str(&config).unwrap_or_default())
24        .unwrap_or_default();
25
26    WalkDir::new(project.root().join("src"))
27        .into_iter()
28        .chain(WalkDir::new(project.root().join("lua")))
29        .chain(WalkDir::new(project.root().join("lib")))
30        .filter_map(Result::ok)
31        .filter(|file| {
32            args.workspace_or_file
33                .as_ref()
34                .is_none_or(|workspace_or_file| {
35                    file.path().to_path_buf().starts_with(workspace_or_file)
36                })
37        })
38        .try_for_each(|file| {
39            if PathBuf::from(file.file_name())
40                .extension()
41                .is_some_and(|ext| ext == "lua")
42            {
43                let formatted_code = stylua_lib::format_code(
44                    &std::fs::read_to_string(file.path())?,
45                    config,
46                    None,
47                    stylua_lib::OutputVerification::Full,
48                )?;
49
50                std::fs::write(file.into_path(), formatted_code)?;
51            };
52            Ok::<_, eyre::Report>(())
53        })?;
54
55    // Format the rockspec
56
57    let rockspec = project.root().join("extra.rockspec");
58
59    if rockspec.exists() {
60        let formatted_code = stylua_lib::format_code(
61            &std::fs::read_to_string(&rockspec)?,
62            config,
63            None,
64            stylua_lib::OutputVerification::Full,
65        )?;
66
67        std::fs::write(rockspec, formatted_code)?;
68    }
69
70    Ok(())
71}