From 8aa276beb88086b866be8a446289106be237348a Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sun, 7 Jun 2026 15:18:24 +0800 Subject: Add hformat_cargo, hprintln_cargo macros and help rendering --- mling/src/proj_mgr/metadata.rs | 142 +++++++++++++++++++++++++++++++++++++++++ mling/src/proj_mgr/mod.rs | 22 +++++-- 2 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 mling/src/proj_mgr/metadata.rs (limited to 'mling/src/proj_mgr') diff --git a/mling/src/proj_mgr/metadata.rs b/mling/src/proj_mgr/metadata.rs new file mode 100644 index 0000000..c44ed46 --- /dev/null +++ b/mling/src/proj_mgr/metadata.rs @@ -0,0 +1,142 @@ +use serde::Deserialize; +use serde::Serialize; + +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 { + let output = Command::new("cargo") + .arg("metadata") + .arg("--format-version") + .arg("1") + .arg("--manifest-path") + .arg(cargo_toml) + .output()?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!("cargo metadata failed: {}", stderr), + )); + } + + let lock_file: CargoLockFile = serde_json::from_slice(&output.stdout) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; + + Ok(lock_file) +} + +/// A cargo metadata lock file that serde can serialize and deserialize. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CargoLockFile { + pub packages: Vec, + #[serde(rename = "workspace_members")] + pub workspace_members: Vec, + #[serde(rename = "workspace_default_members")] + pub workspace_default_members: Vec, + pub resolve: Resolve, + #[serde(rename = "target_directory")] + pub target_directory: String, + #[serde(rename = "build_directory")] + pub build_directory: String, + pub version: u64, + #[serde(rename = "workspace_root")] + pub workspace_root: String, + pub metadata: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Package { + pub name: String, + pub version: String, + pub id: String, + pub license: Option, + #[serde(rename = "license_file")] + pub license_file: Option, + pub description: Option, + pub source: Option, + pub dependencies: Vec, + pub targets: Vec, + pub features: std::collections::BTreeMap>, + #[serde(rename = "manifest_path")] + pub manifest_path: String, + pub metadata: Option, + pub publish: Option, + pub authors: Vec, + pub categories: Vec, + pub keywords: Vec, + pub readme: Option, + pub repository: Option, + pub homepage: Option, + pub documentation: Option, + pub edition: String, + pub links: Option, + #[serde(rename = "default_run")] + pub default_run: Option, + #[serde(rename = "rust_version")] + pub rust_version: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Dependency { + pub name: String, + pub source: Option, + pub req: String, + pub kind: Option, + pub rename: Option, + pub optional: bool, + #[serde(rename = "uses_default_features")] + pub uses_default_features: bool, + pub features: Vec, + pub target: Option, + pub registry: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub path: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Target { + pub kind: Vec, + #[serde(rename = "crate_types")] + pub crate_types: Vec, + pub name: String, + #[serde(rename = "src_path")] + pub src_path: String, + pub edition: String, + pub doc: bool, + pub doctest: bool, + pub test: bool, + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "required-features")] + pub required_features: Option>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Resolve { + pub nodes: Vec, + pub root: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ResolveNode { + pub id: String, + pub dependencies: Vec, + pub deps: Vec, + pub features: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DepInfo { + pub name: String, + pub pkg: String, + #[serde(rename = "dep_kinds")] + pub dep_kinds: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DepKind { + pub kind: Option, + pub target: Option, +} diff --git a/mling/src/proj_mgr/mod.rs b/mling/src/proj_mgr/mod.rs index 381784c..07a9910 100644 --- a/mling/src/proj_mgr/mod.rs +++ b/mling/src/proj_mgr/mod.rs @@ -1,6 +1,20 @@ -use mingling::macros::dispatcher; +use crate::ThisProgram; +use mingling::{ + Program, + macros::{dispatcher, program_setup}, +}; -dispatcher!("install"); +pub mod metadata; -dispatcher!("ls.namespace", CMDListNamespace => EntryListNamespace); -dispatcher!("rm.namespace", CMDRemoveNamespace => EntryRemoveNamespace); +dispatcher!("show.binaries"); +dispatcher!("show.workspace"); +dispatcher!("show.target-dir", + CMDShowTargetDirectories => EntryShowTargetDirectories +); + +#[program_setup] +pub fn project_manager_setup(p: &mut Program) { + p.with_dispatcher(CMDShowBinaries); + p.with_dispatcher(CMDShowWorkspace); + p.with_dispatcher(CMDShowTargetDirectories); +} -- cgit