diff --git a/module/move/willbe/src/command/list.rs b/module/move/willbe/src/command/list.rs index f88a15fa5d..e0a054286e 100644 --- a/module/move/willbe/src/command/list.rs +++ b/module/move/willbe/src/command/list.rs @@ -56,7 +56,21 @@ mod private return Err( err!( format!( "Unknown option 'type:{}'", list_type ) ) ); } - endpoint::workspace_list( path_to_workspace, root_crate, list_type ).context( "workspace list command" ) + match endpoint::workspace_list( path_to_workspace, root_crate, list_type ) + { + core::result::Result::Ok( report ) => + { + println!( "{report} "); + } + Err(( report, e )) => + { + eprintln!( "{report}" ); + + return Err( e.context( "workspace list command" ) ); + } + } + + Ok( () ) } } diff --git a/module/move/willbe/src/endpoint/list.rs b/module/move/willbe/src/endpoint/list.rs index e57cdea6dd..a31516cb97 100644 --- a/module/move/willbe/src/endpoint/list.rs +++ b/module/move/willbe/src/endpoint/list.rs @@ -1,7 +1,7 @@ /// Internal namespace. mod private { - use core::fmt::Formatter; + use std::fmt::Formatter; use crate::package::functions as package; use crate::manifest; @@ -81,18 +81,74 @@ mod private Ok( report ) } + #[ derive( Debug, Default, Clone ) ] + pub enum WorkspaceListReport + { + Tree + { + graph : petgraph::Graph< String, String >, + names : Vec< petgraph::stable_graph::NodeIndex >, + }, + List( Vec< String > ), + #[ default ] + Empty + } + + /// Wrapper to redirect output from `ptree` graph to `fmt::Write` + struct Io2FmtWrite< 'a, 'b > + { + f : &'a mut Formatter< 'b >, + } + + impl std::io::Write for Io2FmtWrite< '_, '_ > + { + fn write( &mut self, buf : &[ u8 ] ) -> std::io::Result< usize > + { + let size = buf.len(); + + self.f.write_str( std::str::from_utf8( buf ).unwrap() ).unwrap(); + + Ok( size ) + } + + fn flush( &mut self ) -> std::io::Result< () > + { + Ok( () ) + } + } + + impl std::fmt::Display for WorkspaceListReport + { + fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + { + match self + { + WorkspaceListReport::Tree { graph, names } => for n in names + { + ptree::graph::write_graph_with(&graph, *n, Io2FmtWrite { f }, &ptree::PrintConfig::from_env() ).unwrap(); + }, + WorkspaceListReport::List ( list ) => for ( i ,e ) in list.iter().enumerate() { writeln!( f, "{i}) {e}" )? }, + _ => {}, + } + + Ok( () ) + } + } + /// /// List workspace packages. /// - - pub fn workspace_list( path_to_workspace : PathBuf, root_crate : &str, list_type : &str ) -> Result< (), Error > + pub fn workspace_list( path_to_workspace : PathBuf, root_crate : &str, list_type : &str ) -> Result< WorkspaceListReport, ( WorkspaceListReport, Error ) > { + let mut report = WorkspaceListReport::default(); + let mut manifest = Manifest::new(); - let manifest_path = manifest.manifest_path_from_str( &path_to_workspace )?; + let manifest_path = manifest.manifest_path_from_str( &path_to_workspace ).map_err( | e | ( report.clone(), e.into() ) )?; let package_metadata = MetadataCommand::new() .manifest_path( &manifest_path ) .no_deps() - .exec()?; + .exec() + .map_err( | e | ( report.clone(), e.into() ) )?; let packages_map = package::filter( &package_metadata ); let graph = package::graph_build( &packages_map ); @@ -110,14 +166,17 @@ mod private names.push( *node ); } } - names.iter().for_each( | n | ptree::graph::print_graph( &graph, *n ).unwrap() ); + + report = WorkspaceListReport::Tree { graph : graph.map( | _, &n | String::from( n ), | _, &e | String::from( e ) ), names }; } else { - sorted + let names = sorted .iter() .filter_map( | idx | if graph.node_weight( *idx ).unwrap() == &root_crate { Some( *idx ) } else { None } ) - .for_each( | e | ptree::graph::print_graph( &graph, e ).unwrap() ); + .collect::< Vec< _ > >(); + + report = WorkspaceListReport::Tree { graph : graph.map( | _, &n | String::from( n ), | _, &e | String::from( e ) ), names }; } } else @@ -128,10 +187,10 @@ mod private .map( | dep_idx | graph.node_weight( *dep_idx ).unwrap().to_string() ) .collect::< Vec< String > >(); - names.iter().enumerate().for_each( | ( i, e ) | println!( "{i}) {e}" ) ); + report = WorkspaceListReport::List( names ); } - Ok( () ) + Ok( report ) } }