aboutsummaryrefslogtreecommitdiff
path: root/mling/src/proj_mgr
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-06-07 15:40:53 +0800
committer魏曹先生 <1992414357@qq.com>2026-06-07 15:40:53 +0800
commit86647e7b5057826d7bb85381044d5b691fbbafa3 (patch)
tree69a1768c3c8f571bfde426948bb58fe2e3e93bf2 /mling/src/proj_mgr
parent8aa276beb88086b866be8a446289106be237348a (diff)
Move error handling into its own module and add show.binaries command
Diffstat (limited to 'mling/src/proj_mgr')
-rw-r--r--mling/src/proj_mgr/metadata.rs2
-rw-r--r--mling/src/proj_mgr/mod.rs3
-rw-r--r--mling/src/proj_mgr/show_binaries.rs70
3 files changed, 74 insertions, 1 deletions
diff --git a/mling/src/proj_mgr/metadata.rs b/mling/src/proj_mgr/metadata.rs
index c44ed46..84da69f 100644
--- a/mling/src/proj_mgr/metadata.rs
+++ b/mling/src/proj_mgr/metadata.rs
@@ -5,7 +5,7 @@ use std::path::PathBuf;
use std::process::Command;
/// Read cargo metadata by running `cargo metadata` with the given manifest path.
-pub fn read_metadata(cargo_toml: PathBuf) -> Result<CargoLockFile, std::io::Error> {
+pub fn read_metadata(cargo_toml: &PathBuf) -> Result<CargoLockFile, std::io::Error> {
let output = Command::new("cargo")
.arg("metadata")
.arg("--format-version")
diff --git a/mling/src/proj_mgr/mod.rs b/mling/src/proj_mgr/mod.rs
index 07a9910..3e94a3f 100644
--- a/mling/src/proj_mgr/mod.rs
+++ b/mling/src/proj_mgr/mod.rs
@@ -6,6 +6,9 @@ use mingling::{
pub mod metadata;
+mod show_binaries;
+pub use show_binaries::*;
+
dispatcher!("show.binaries");
dispatcher!("show.workspace");
dispatcher!("show.target-dir",
diff --git a/mling/src/proj_mgr/show_binaries.rs b/mling/src/proj_mgr/show_binaries.rs
new file mode 100644
index 0000000..384d8a4
--- /dev/null
+++ b/mling/src/proj_mgr/show_binaries.rs
@@ -0,0 +1,70 @@
+use std::path::PathBuf;
+
+use colored::Colorize;
+use mingling::{
+ Groupped,
+ macros::{chain, pack, r_print, r_println, renderer},
+};
+use serde::Serialize;
+
+use crate::{
+ EntryShowBinaries, Next,
+ metadata::{CargoLockFile, read_metadata},
+ res::ResManifestPath,
+};
+
+#[derive(Serialize, Groupped)]
+pub struct ResultBinaries {
+ pub binaries: Vec<DataBinary>,
+}
+
+#[derive(Serialize)]
+pub struct DataBinary {
+ pub name: String,
+ pub path: PathBuf,
+}
+
+#[chain]
+pub fn handle_show_binaries(_args: EntryShowBinaries, manifest_path: &ResManifestPath) -> Next {
+ let metadata = read_metadata(manifest_path.resolved()).unwrap();
+ let CargoLockFile {
+ packages,
+ workspace_members,
+ ..
+ } = metadata;
+
+ let binaries: Vec<DataBinary> = packages
+ .into_iter()
+ .filter(|pkg| workspace_members.contains(&pkg.id))
+ .flat_map(|pkg| {
+ pkg.targets
+ .into_iter()
+ .filter(|target| target.kind.iter().any(|k| k == "bin"))
+ .map(move |target| DataBinary {
+ name: target.name,
+ path: PathBuf::from(pkg.manifest_path.clone())
+ .parent()
+ .unwrap_or(&PathBuf::from("."))
+ .join("src")
+ .join(&target.src_path),
+ })
+ })
+ .collect();
+
+ ResultBinaries { binaries }.to_render()
+}
+
+#[renderer]
+pub fn render_binaries(binaries: ResultBinaries) -> String {
+ r_println!("{}", "Binaries:".bright_cyan().bold());
+ if let Some(max_name_len) = binaries.binaries.iter().map(|b| b.name.len()).max() {
+ for binary in &binaries.binaries {
+ r_println!(
+ " {:width$} `{}`",
+ binary.name.bright_yellow().bold(),
+ binary.path.display().to_string().italic(),
+ width = max_name_len
+ );
+ }
+ }
+}