blob: ad2e86a5d66a7a5fecc500cf32af99a48572f75a [file] [log] [blame]
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
/// The expected extension of rustfmt manifest files generated by `rustfmt_aspect`.
pub const RUSTFMT_MANIFEST_EXTENSION: &str = "rustfmt";
/// Generate an absolute path to a file without resolving symlinks
fn absolutify_existing<T: AsRef<Path>>(path: &T) -> std::io::Result<PathBuf> {
let absolute_path = if path.as_ref().is_absolute() {
path.as_ref().to_owned()
} else {
std::env::current_dir()
.expect("Failed to get working directory")
.join(path)
};
std::fs::metadata(&absolute_path).map(|_| absolute_path)
}
/// A struct containing details used for executing rustfmt.
#[derive(Debug)]
pub struct RustfmtConfig {
/// The rustfmt binary from the currently active toolchain
pub rustfmt: PathBuf,
/// The rustfmt config file containing rustfmt settings.
/// https://rust-lang.github.io/rustfmt/
pub config: PathBuf,
}
/// Parse command line arguments and environment variables to
/// produce config data for running rustfmt.
pub fn parse_rustfmt_config() -> RustfmtConfig {
RustfmtConfig {
rustfmt: absolutify_existing(&env!("RUSTFMT")).expect("Unable to find rustfmt binary"),
config: absolutify_existing(&env!("RUSTFMT_CONFIG"))
.expect("Unable to find rustfmt config file"),
}
}
/// A struct of target specific information for use in running `rustfmt`.
#[derive(Debug)]
pub struct RustfmtManifest {
/// The Rust edition of the Bazel target
pub edition: String,
/// A list of all (non-generated) source files for formatting.
pub sources: Vec<String>,
}
/// Parse rustfmt flags from a manifest generated by builds using `rustfmt_aspect`.
pub fn parse_rustfmt_manifest(manifest: &Path) -> RustfmtManifest {
let content = fs::read_to_string(manifest)
.unwrap_or_else(|_| panic!("Failed to read rustfmt manifest: {}", manifest.display()));
let mut lines: Vec<String> = content
.split('\n')
.into_iter()
.filter(|s| !s.is_empty())
.map(|s| s.to_owned())
.collect();
let edition = lines
.pop()
.expect("There should always be at least 1 line in the manifest");
edition
.parse::<i32>()
.expect("The edition should be a numeric value. eg `2018`.");
RustfmtManifest {
edition,
sources: lines,
}
}