From fceb4ffa4219a8916ff9dbdb6108be6db8961d02 Mon Sep 17 00:00:00 2001 From: alexion Date: Thu, 17 Sep 2026 13:22:11 -0400 Subject: [PATCH] feat(xatu): collect Nix source files --- Cargo.lock | 1 + src/xatu/BUILD | 1 + src/xatu/Cargo.toml | 1 + src/xatu/xatu.rs | 16 ++++++--- src/xatu/xatu_main.rs | 77 +++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 89 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f469377..7db0b5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -256,6 +256,7 @@ name = "xatu" version = "0.1.0" dependencies = [ "clap", + "monorepo", ] [[package]] diff --git a/src/xatu/BUILD b/src/xatu/BUILD index 235452b..7eb3699 100644 --- a/src/xatu/BUILD +++ b/src/xatu/BUILD @@ -12,6 +12,7 @@ rust_binary( srcs = ["xatu_main.rs"], deps = [ ":xatu_lib", + "//src/monorepo:monorepo", "//third_party/crates:clap", ], ) diff --git a/src/xatu/Cargo.toml b/src/xatu/Cargo.toml index 35b9fb0..aa1d37b 100644 --- a/src/xatu/Cargo.toml +++ b/src/xatu/Cargo.toml @@ -12,3 +12,4 @@ path = "xatu_main.rs" [dependencies] clap = { workspace = true, features = ["derive"] } +monorepo = { workspace = true } diff --git a/src/xatu/xatu.rs b/src/xatu/xatu.rs index 1e67e84..ac8d3a5 100644 --- a/src/xatu/xatu.rs +++ b/src/xatu/xatu.rs @@ -1,8 +1,16 @@ -pub fn run() -> Result<()> { +use std::path::PathBuf; + +pub fn run(files: Vec) -> Result<()> { + for file in files { + println!("{}", file.path.display()); + } Ok(()) } -pub type Result = std::result::Result; +pub type Result = std::result::Result; -#[derive(Debug, PartialEq, Eq)] -pub enum Error {} +#[derive(Debug)] +pub struct SourceFile { + pub path: PathBuf, + pub source: String, +} diff --git a/src/xatu/xatu_main.rs b/src/xatu/xatu_main.rs index 28b0a58..567dfe1 100644 --- a/src/xatu/xatu_main.rs +++ b/src/xatu/xatu_main.rs @@ -1,9 +1,80 @@ use clap::Parser; +use std::path::{Path, PathBuf}; +use xatu::SourceFile; + +fn is_nix_file(path: &Path) -> bool { + path.extension().is_some_and(|extension| extension == "nix") +} + +// TODO: Add configurable exclusions. +fn is_excluded_dir(path: &Path) -> bool { + path.file_name() + .and_then(|name| name.to_str()) + .is_some_and(|name| { + matches!( + name, + ".git" + | "bazel-bin" + | "bazel-dev" + | "bazel-out" + | "bazel-testlogs" + | "target" + | "third_party" + ) || name == "result" + || name.starts_with("result-") + }) +} + +fn collect_source_files(path: &Path) -> xatu::Result> { + let metadata = std::fs::symlink_metadata(path)?; + + if metadata.file_type().is_dir() { + if is_excluded_dir(path) { + return Ok(Vec::new()); + } + + let mut files = Vec::new(); + + for entry in std::fs::read_dir(path)? { + let entry = entry?; + files.extend(collect_source_files(&entry.path())?); + } + + return Ok(files); + } + + if metadata.file_type().is_file() && is_nix_file(path) { + return Ok(vec![SourceFile { + path: path.to_path_buf(), + source: std::fs::read_to_string(path)?, + }]); + } + + Ok(Vec::new()) +} #[derive(Debug, Parser)] -struct Args {} +struct Args { + #[arg(value_name = "PATH", default_value = ".")] + paths: Vec, +} fn main() -> xatu::Result<()> { - let Args {} = Args::parse(); - xatu::run() + let args = Args::parse(); + + let paths: Vec = args + .paths + .into_iter() + .map(monorepo::workspace::resolve_workspace_path) + .collect(); + + let files: Vec = paths + .iter() + .map(|path| collect_source_files(path)) + .collect::>>()? + .into_iter() + .flatten() + .collect(); + + xatu::run(files) }