@@ -143,9 +143,12 @@ function updateNpmWorkspacesDeps({patterns, allowRangeBumpFor0x, dryRun}) {
143143 return ;
144144 }
145145 // We use 'npm outdated -j ...' as a quick way to get the current
146- // installed version and latest published version of deps. The '-j'
147- // output shows a limited/random subset of data such that its `wanted`
148- // value cannot be used (see "npm outdated" perils above).
146+ // installed version and latest published version of deps.
147+ // Note: The '-j' output with npm@9 shows a limited/random subset of
148+ // data such that its `wanted` value cannot be used (see "npm outdated"
149+ // perils above). This has changed with npm@10 such that we might be
150+ // able to use the `wanted` values now.
151+ debug ( ` $ cd ${ wsDir } && npm outdated --json ${ depNames . join ( ' ' ) } ` ) ;
149152 const p = spawnSync ( 'npm' , [ 'outdated' , '--json' ] . concat ( depNames ) , {
150153 cwd : wsDir ,
151154 encoding : 'utf8' ,
@@ -156,13 +159,17 @@ function updateNpmWorkspacesDeps({patterns, allowRangeBumpFor0x, dryRun}) {
156159 }
157160
158161 const npmInstallArgs = [ ] ;
162+ let npmInstallingALocalDep = false ;
159163 for ( let depName of depNames ) {
160164 if ( ! ( depName in outdated ) ) {
161165 continue ;
162166 }
167+ const anOutdatedEntry = Array . isArray ( outdated [ depName ] )
168+ ? outdated [ depName ] [ 0 ]
169+ : outdated [ depName ] ;
163170 const summaryNote = localPkgNames . has ( depName ) ? ' (local)' : '' ;
164- const currVer = outdated [ depName ] . current ;
165- const latestVer = outdated [ depName ] . latest ;
171+ const currVer = anOutdatedEntry . current ;
172+ const latestVer = anOutdatedEntry . latest ;
166173 if ( semver . satisfies ( latestVer , info . deps [ depName ] ) ) {
167174 // `npm update` should suffice.
168175 npmUpdatePkgNames . add ( depName ) ;
@@ -172,6 +179,9 @@ function updateNpmWorkspacesDeps({patterns, allowRangeBumpFor0x, dryRun}) {
172179 } else if ( semver . lt ( currVer , '1.0.0' ) ) {
173180 if ( allowRangeBumpFor0x ) {
174181 npmInstallArgs . push ( `${ depName } @${ latestVer } ` ) ;
182+ if ( localPkgNames . has ( depName ) ) {
183+ npmInstallingALocalDep = true ;
184+ }
175185 summaryStrs . add (
176186 `${ currVer } -> ${ latestVer } ${ depName } (range-bump)${ summaryNote } `
177187 ) ;
@@ -192,6 +202,18 @@ function updateNpmWorkspacesDeps({patterns, allowRangeBumpFor0x, dryRun}) {
192202 cwd : wsDir ,
193203 argv : [ 'npm' , 'install' ] . concat ( npmInstallArgs ) ,
194204 } ) ;
205+ if ( npmInstallingALocalDep ) {
206+ // A surprise I've found with 'npm install ...': When the dep
207+ // being updated (e.g. '@otel/[email protected] ' to '@otel/[email protected] ') 208+ // is a *local* dep (i.e. it is another workspace in the same
209+ // repo) then updating successfully sometimes requires running the
210+ // 'npm install ...' **twice**.
211+ npmInstallTasks . push ( {
212+ cwd : wsDir ,
213+ argv : [ 'npm' , 'install' ] . concat ( npmInstallArgs ) ,
214+ comment : 'second time because "npm install"ing a *local* dep can take two tries'
215+ } ) ;
216+ }
195217 }
196218 } ) ;
197219
@@ -203,7 +225,7 @@ function updateNpmWorkspacesDeps({patterns, allowRangeBumpFor0x, dryRun}) {
203225 debug ( 'npmInstallTasks: ' , npmInstallTasks ) ;
204226 debug ( 'npmUpdatePkgNames: ' , npmUpdatePkgNames ) ;
205227 for ( let task of npmInstallTasks ) {
206- console . log ( ` $ cd ${ task . cwd } && ${ task . argv . join ( ' ' ) } ` ) ;
228+ console . log ( ` $ cd ${ task . cwd } && ${ task . argv . join ( ' ' ) } ${ task . comment ? `# ${ task . comment } ` : '' } ` ) ;
207229 if ( ! dryRun ) {
208230 const p = spawnSync ( task . argv [ 0 ] , task . argv . slice ( 1 ) , {
209231 cwd : task . cwd ,
0 commit comments