willbe/command/crate_doc.rs
1// module/move/willbe/src/command/crate_doc.rs
2mod private
3{
4 #[ allow( clippy::wildcard_imports ) ]
5 use crate::*;
6
7 use std::path::PathBuf;
8 use wca::VerifiedCommand;
9 use error::untyped::Error; // Use untyped::Error for the command return
10 use entity::{ Workspace, WorkspaceInitError, PathError }; // Import Workspace, WorkspaceInitError, PathError
11 use path::{ AbsolutePath, CurrentPath }; // Import AbsolutePath and CurrentPath from pth
12
13 ///
14 /// Generate documentation for a crate in a single Markdown file.
15 ///
16 /// # Errors
17 /// Returns an error if the command arguments are invalid, the workspace cannot be loaded,
18 /// or if the documentation generation action fails.
19 #[allow(clippy::needless_pass_by_value)]
20 pub fn crate_doc( o : VerifiedCommand ) -> error::untyped::Result< () >
21 {
22 let path_arg : PathBuf = o.args.get_owned( 0 ).unwrap_or_else( || "./".into() );
23
24 // qqq : xxx : refactor this block
25 // Use the requested `pth::absolute::join` function (see qqq in pth/src/lib.rs)
26 // to simplify this path resolution. The call should look something like:
27 // `let absolute_path = pth::absolute::join( ( CurrentPath, path_arg.clone() ) )?`
28 // This assumes `join_absolute` takes a tuple and handles the logic internally.
29 // Determine the absolute path explicitly
30 let absolute_path = if path_arg.is_relative()
31 {
32 // If relative, resolve it against the current directory
33 let current_dir = AbsolutePath::try_from( CurrentPath )
34 .map_err( | e | Error::new( e ).context( "Failed to get current directory" ) )?;
35 current_dir.join( path_arg.clone() ) // Clone path_arg as join consumes it
36 }
37 else
38 {
39 // If already absolute, try to create AbsolutePath directly
40 AbsolutePath::try_from( path_arg.clone() )
41 .map_err( | e | Error::new( e ).context( format!( "Invalid absolute path provided: {}", path_arg.display() ) ) )?
42 };
43 // Note: AbsolutePath::try_from also performs canonicalization implicitly via path::canonicalize
44
45 // Create CrateDir from the verified AbsolutePath
46 let crate_dir = CrateDir::try_from( absolute_path ) // This should now work as AbsolutePath is canonical
47 .map_err( | e : PathError | Error::new( e ).context( "Failed to identify crate directory (does Cargo.toml exist?)" ) )?;
48
49 // Load the workspace based on the crate directory
50 let workspace = Workspace::try_from( crate_dir.clone() )
51 .map_err( | e : WorkspaceInitError | Error::new( e ).context( "Failed to load workspace information" ) )?;
52
53 // Parse output property
54 let output_path_req : Option< PathBuf > = o.props.get_owned( "output" );
55
56 // Call the action, passing the workspace reference
57 match action::crate_doc::doc( &workspace, &crate_dir, output_path_req )
58 {
59 Ok( report ) =>
60 {
61 println!( "{report}" ); // Print the success report
62 Ok( () )
63 }
64 Err( ( report, e ) ) =>
65 {
66 eprintln!( "{report}" ); // Print the report even on failure
67 // Convert the specific CrateDocError into a general untyped::Error for the command return
68 Err( Error::new( e ).context( "Documentation generation failed" ) )
69 }
70 }
71 }
72}
73
74crate::mod_interface!
75{
76 /// Generate documentation for a crate.
77 orphan use crate_doc;
78}