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