@@ -63,14 +63,18 @@ pub fn change_to_repo_root(sh: &Shell) {
6363/// # Arguments
6464///
6565/// * `packages` - Optional filter for specific package names. If empty, returns all packages.
66+ ///
67+ /// # Errors
68+ ///
69+ /// Returns an error if any requested package name doesn't exist in the workspace.
6670pub fn get_packages (
6771 sh : & Shell ,
6872 packages : & [ String ] ,
6973) -> Result < Vec < ( String , PathBuf ) > , Box < dyn std:: error:: Error > > {
7074 let metadata = quiet_cmd ! ( sh, "cargo metadata --no-deps --format-version 1" ) . read ( ) ?;
7175 let json: serde_json:: Value = serde_json:: from_str ( & metadata) ?;
7276
73- let package_info : Vec < ( String , PathBuf ) > = json[ "packages" ]
77+ let all_packages : Vec < ( String , PathBuf ) > = json[ "packages" ]
7478 . as_array ( )
7579 . ok_or ( "Missing 'packages' field in cargo metadata" ) ?
7680 . iter ( )
@@ -81,15 +85,45 @@ pub fn get_packages(
8185 // e.g., "/path/to/repo/releases/Cargo.toml" -> "/path/to/repo/releases".
8286 let dir_path = manifest_path. trim_end_matches ( "/Cargo.toml" ) ;
8387
84- // Filter by package name if specified.
85- if !packages. is_empty ( ) && !packages. iter ( ) . any ( |p| p == package_name) {
86- return None ;
87- }
88-
8988 Some ( ( package_name. to_owned ( ) , PathBuf :: from ( dir_path) ) )
9089 } )
9190 . collect ( ) ;
9291
92+ // If no package filter specified, return all packages.
93+ if packages. is_empty ( ) {
94+ return Ok ( all_packages) ;
95+ }
96+
97+ // Validate that all requested packages exist in the workspace.
98+ let available_names: Vec < & str > = all_packages. iter ( ) . map ( |( name, _) | name. as_str ( ) ) . collect ( ) ;
99+ let mut invalid_packages = Vec :: new ( ) ;
100+
101+ for requested_package in packages {
102+ if !available_names. contains ( & requested_package. as_str ( ) ) {
103+ invalid_packages. push ( requested_package. clone ( ) ) ;
104+ }
105+ }
106+
107+ if !invalid_packages. is_empty ( ) {
108+ let mut error_msg = format ! (
109+ "Package not found in workspace: {}" ,
110+ invalid_packages. join( ", " )
111+ ) ;
112+
113+ error_msg. push_str ( "\n \n Available packages:" ) ;
114+ for name in & available_names {
115+ error_msg. push_str ( & format ! ( "\n - {}" , name) ) ;
116+ }
117+
118+ return Err ( error_msg. into ( ) ) ;
119+ }
120+
121+ // Filter to only requested packages.
122+ let package_info: Vec < ( String , PathBuf ) > = all_packages
123+ . into_iter ( )
124+ . filter ( |( name, _) | packages. iter ( ) . any ( |p| p == name) )
125+ . collect ( ) ;
126+
93127 Ok ( package_info)
94128}
95129
0 commit comments