@@ -126,31 +126,41 @@ async function getCrateName(packagePath: string): Promise<string> {
126126}
127127
128128const MISSING_CRATE_PATTERN = / n o m a t c h i n g p a c k a g e n a m e d ` ( [ ^ ` ] + ) ` f o u n d / ;
129+ const VERSION_MISMATCH_PATTERN =
130+ / f a i l e d t o s e l e c t a v e r s i o n f o r t h e r e q u i r e m e n t ` ( [ ^ = ` \s ] + ) / ;
129131
130132async function findUnpublishedSiblingDeps (
131133 packagePath : string ,
132- siblingPaths : string [ ] ,
134+ siblingKeys : string [ ] ,
135+ ctx : PubmContext ,
133136) : Promise < string [ ] > {
134137 const eco = new RustEcosystem ( packagePath ) ;
135138 const deps = await eco . dependencies ( ) ;
136139
137- const siblingNameToPath = new Map < string , string > ( ) ;
140+ const siblingNameToKey = new Map < string , string > ( ) ;
138141 await Promise . all (
139- siblingPaths . map ( async ( p ) => {
140- const name = await getCrateName ( p ) ;
141- siblingNameToPath . set ( name , p ) ;
142+ siblingKeys . map ( async ( k ) => {
143+ const name = await getCrateName ( pathFromKey ( k ) ) ;
144+ siblingNameToKey . set ( name , k ) ;
142145 } ) ,
143146 ) ;
144147
145- const siblingDeps = deps . filter ( ( d ) => siblingNameToPath . has ( d ) ) ;
148+ const siblingDeps = deps . filter ( ( d ) => siblingNameToKey . has ( d ) ) ;
146149
147150 const results = await Promise . all (
148151 siblingDeps . map ( async ( name ) => {
149- const siblingPath = siblingNameToPath . get ( name ) ;
150- if ( ! siblingPath ) {
151- throw new Error ( `Missing sibling crate path for dependency: ${ name } ` ) ;
152+ const siblingKey = siblingNameToKey . get ( name ) ;
153+ if ( ! siblingKey ) {
154+ throw new Error ( `Missing sibling crate key for dependency: ${ name } ` ) ;
152155 }
156+ const siblingPath = pathFromKey ( siblingKey ) ;
153157 const registry = await cratesPackageRegistry ( siblingPath ) ;
158+ const version = getPackageVersion ( ctx , siblingKey ) ;
159+ if ( version ) {
160+ const versionPublished = await registry . isVersionPublished ( version ) ;
161+ return versionPublished ? null : name ;
162+ }
163+ // Fallback: check if the crate exists at all
154164 const published = await registry . isPublished ( ) ;
155165 return published ? null : name ;
156166 } ) ,
@@ -164,7 +174,6 @@ export function createCratesDryRunPublishTask(
164174 siblingKeys ?: string [ ] ,
165175) : ListrTask < PubmContext > {
166176 const packagePath = pathFromKey ( key ) ;
167- const siblingPaths = siblingKeys ?. map ( pathFromKey ) ;
168177 return {
169178 title : t ( "task.dryRun.crates.title" , { path : packagePath } ) ,
170179 task : async ( ctx , task ) : Promise < void > => {
@@ -185,11 +194,12 @@ export function createCratesDryRunPublishTask(
185194 return task . skip ( ) ;
186195 }
187196
188- // Proactive: skip if any sibling dependency is not yet on crates.io
189- if ( siblingPaths ?. length ) {
197+ // Proactive: skip if any sibling dependency's new version is not yet on crates.io
198+ if ( siblingKeys ?. length ) {
190199 const unpublished = await findUnpublishedSiblingDeps (
191200 packagePath ,
192- siblingPaths ,
201+ siblingKeys ,
202+ ctx ,
193203 ) ;
194204 if ( unpublished . length > 0 ) {
195205 task . title = t ( "task.dryRun.crates.skippedSibling" , {
@@ -209,15 +219,18 @@ export function createCratesDryRunPublishTask(
209219 } catch ( error ) {
210220 // Reactive fallback: catch sibling-related errors
211221 const message = error instanceof Error ? error . message : String ( error ) ;
212- const match = message . match ( MISSING_CRATE_PATTERN ) ;
213- if ( match && siblingPaths ) {
222+ const missingMatch = message . match ( MISSING_CRATE_PATTERN ) ;
223+ const versionMatch = message . match ( VERSION_MISMATCH_PATTERN ) ;
224+ const crateName = missingMatch ?. [ 1 ] ?? versionMatch ?. [ 1 ] ?. trim ( ) ;
225+
226+ if ( crateName && siblingKeys ) {
214227 const siblingNames = await Promise . all (
215- siblingPaths . map ( ( p ) => getCrateName ( p ) ) ,
228+ siblingKeys . map ( ( k ) => getCrateName ( pathFromKey ( k ) ) ) ,
216229 ) ;
217- if ( siblingNames . includes ( match [ 1 ] ) ) {
230+ if ( siblingNames . includes ( crateName ) ) {
218231 task . title = t ( "task.dryRun.crates.skippedSibling" , {
219232 path : packagePath ,
220- crate : match [ 1 ] ,
233+ crate : crateName ,
221234 } ) ;
222235 return ;
223236 }
0 commit comments