@@ -551,6 +551,86 @@ export class PackageJsonUpdater {
551551 }
552552 }
553553
554+ private async _getRemoteLatestVersionAsync ( packageName : string ) : Promise < string > {
555+ let selectedVersion : string | undefined ;
556+ this . _terminal . writeLine ( `Querying NPM registry for latest version of "${ packageName } "...` ) ;
557+
558+ let commandArgs : string [ ] ;
559+ if ( this . _rushConfiguration . packageManager === 'yarn' ) {
560+ commandArgs = [ 'info' , packageName , 'dist-tags.latest' , '--silent' ] ;
561+ } else {
562+ commandArgs = [ 'view' , `${ packageName } @latest` , 'version' ] ;
563+ }
564+
565+ selectedVersion = (
566+ await Utilities . executeCommandAndCaptureOutputAsync (
567+ this . _rushConfiguration . packageManagerToolFilename ,
568+ commandArgs ,
569+ this . _rushConfiguration . commonTempFolder
570+ )
571+ ) . trim ( ) ;
572+
573+ this . _terminal . writeLine ( ) ;
574+ this . _terminal . writeLine ( `Found latest version: ${ Colorize . cyan ( selectedVersion ) } ` ) ;
575+
576+ return selectedVersion ;
577+ }
578+
579+ private async _getRemoteSpecifiedVersionAsync (
580+ packageName : string ,
581+ initialSpec : string = 'latest'
582+ ) : Promise < string > {
583+ let selectedVersion : string | undefined ;
584+ this . _terminal . writeLine ( `Querying registry for all versions of "${ packageName } "...` ) ;
585+
586+ let commandArgs : string [ ] ;
587+ if ( this . _rushConfiguration . packageManager === 'yarn' ) {
588+ commandArgs = [ 'info' , packageName , 'versions' , '--json' ] ;
589+ } else {
590+ commandArgs = [ 'view' , packageName , 'versions' , '--json' ] ;
591+ }
592+
593+ const allVersions : string = await Utilities . executeCommandAndCaptureOutputAsync (
594+ this . _rushConfiguration . packageManagerToolFilename ,
595+ commandArgs ,
596+ this . _rushConfiguration . commonTempFolder
597+ ) ;
598+
599+ let versionList : string [ ] ;
600+ if ( this . _rushConfiguration . packageManager === 'yarn' ) {
601+ versionList = JSON . parse ( allVersions ) . data ;
602+ } else {
603+ versionList = JSON . parse ( allVersions ) ;
604+ }
605+
606+ this . _terminal . writeLine ( Colorize . gray ( `Found ${ versionList . length } available versions.` ) ) ;
607+
608+ for ( const version of versionList ) {
609+ if ( semver . satisfies ( version , initialSpec ) ) {
610+ selectedVersion = initialSpec ;
611+ this . _terminal . writeLine ( `Found a version that satisfies ${ initialSpec } : ${ Colorize . cyan ( version ) } ` ) ;
612+ break ;
613+ }
614+ }
615+
616+ if ( ! selectedVersion ) {
617+ throw new Error (
618+ `Unable to find a version of "${ packageName } " that satisfies` +
619+ ` the version specifier "${ initialSpec } "`
620+ ) ;
621+ }
622+
623+ return selectedVersion ;
624+ }
625+
626+ private async _getRemoteVersionAsync ( packageName : string , initialSpec : string = 'latest' ) : Promise < string > {
627+ if ( initialSpec === 'latest' ) {
628+ return this . _getRemoteLatestVersionAsync ( packageName ) ;
629+ }
630+
631+ return this . _getRemoteSpecifiedVersionAsync ( packageName , initialSpec ) ;
632+ }
633+
554634 /**
555635 * Selects an appropriate version number for a particular package, given an optional initial SemVer spec.
556636 * If ensureConsistentVersions, tries to pick a version that will be consistent.
@@ -659,7 +739,9 @@ export class PackageJsonUpdater {
659739 if ( semver . satisfies ( version , initialSpec ) ) {
660740 // For workspaces, assume that specifying the exact version means you always want to consume
661741 // the local project. Otherwise, use the exact local package version
662- if ( useWorkspaces && ! localProject . installRemotely ) {
742+ if ( localProject . installRemotely ) {
743+ selectedVersion = await this . _getRemoteVersionAsync ( packageName , initialSpec ) ;
744+ } else if ( useWorkspaces ) {
663745 selectedVersion = initialSpec === version ? '*' : initialSpec ;
664746 selectedVersionPrefix = workspacePrefix ;
665747 } else {
@@ -675,52 +757,26 @@ export class PackageJsonUpdater {
675757 ) ;
676758 }
677759 } else {
678- this . _terminal . writeLine ( `Querying registry for all versions of "${ packageName } "...` ) ;
679-
680- let commandArgs : string [ ] ;
681- if ( this . _rushConfiguration . packageManager === 'yarn' ) {
682- commandArgs = [ 'info' , packageName , 'versions' , '--json' ] ;
683- } else {
684- commandArgs = [ 'view' , packageName , 'versions' , '--json' ] ;
685- }
686-
687- const allVersions : string = await Utilities . executeCommandAndCaptureOutputAsync (
688- this . _rushConfiguration . packageManagerToolFilename ,
689- commandArgs ,
690- this . _rushConfiguration . commonTempFolder
691- ) ;
692-
693- let versionList : string [ ] ;
694- if ( this . _rushConfiguration . packageManager === 'yarn' ) {
695- versionList = JSON . parse ( allVersions ) . data ;
696- } else {
697- versionList = JSON . parse ( allVersions ) ;
698- }
699-
700- this . _terminal . writeLine ( Colorize . gray ( `Found ${ versionList . length } available versions.` ) ) ;
701-
702- for ( const version of versionList ) {
703- if ( semver . satisfies ( version , initialSpec ) ) {
704- selectedVersion = initialSpec ;
705- this . _terminal . writeLine (
706- `Found a version that satisfies ${ initialSpec } : ${ Colorize . cyan ( version ) } `
707- ) ;
708- break ;
709- }
710- }
711-
712- if ( ! selectedVersion ) {
713- throw new Error (
714- `Unable to find a version of "${ packageName } " that satisfies` +
715- ` the version specifier "${ initialSpec } "`
716- ) ;
717- }
760+ // if the package is not a project in the local repository, then we need to query the registry
761+ // to find the latest version that satisfies the spec
762+ selectedVersion = await this . _getRemoteVersionAsync ( packageName , initialSpec ) ;
718763 }
719764 } else {
720765 if ( localProject !== undefined ) {
721766 // For workspaces, assume that no specified version range means you always want to consume
722767 // the local project. Otherwise, use the exact local package version
723- if ( useWorkspaces && ! localProject . installRemotely ) {
768+ if ( localProject . installRemotely ) {
769+ selectedVersion = await this . _getRemoteVersionAsync ( packageName , localProject . versionRange ) ;
770+ this . _terminal . writeLine (
771+ Colorize . green ( 'Assigning "' ) +
772+ Colorize . cyan ( selectedVersion ) +
773+ Colorize . green (
774+ `" for "${ packageName } " because it is the preferred version defined by ${ RushConstants . rushJsonFilename } .`
775+ )
776+ ) ;
777+
778+ return selectedVersion ;
779+ } else if ( useWorkspaces ) {
724780 selectedVersion = '*' ;
725781 selectedVersionPrefix = workspacePrefix ;
726782 } else {
@@ -736,27 +792,10 @@ export class PackageJsonUpdater {
736792 this . _terminal . writeLine ( ) ;
737793 }
738794
739- this . _terminal . writeLine ( `Querying NPM registry for latest version of "${ packageName } "...` ) ;
740-
741- let commandArgs : string [ ] ;
742- if ( this . _rushConfiguration . packageManager === 'yarn' ) {
743- commandArgs = [ 'info' , packageName , 'dist-tags.latest' , '--silent' ] ;
744- } else {
745- commandArgs = [ 'view' , `${ packageName } @latest` , 'version' ] ;
746- }
747-
748- selectedVersion = (
749- await Utilities . executeCommandAndCaptureOutputAsync (
750- this . _rushConfiguration . packageManagerToolFilename ,
751- commandArgs ,
752- this . _rushConfiguration . commonTempFolder
753- )
754- ) . trim ( ) ;
795+ // if the package is not a project in the local repository with no spec defined, then we need to
796+ // query the registry to find the latest version
797+ selectedVersion = await this . _getRemoteVersionAsync ( packageName ) ;
755798 }
756-
757- this . _terminal . writeLine ( ) ;
758-
759- this . _terminal . writeLine ( `Found latest version: ${ Colorize . cyan ( selectedVersion ) } ` ) ;
760799 }
761800
762801 this . _terminal . writeLine ( ) ;
0 commit comments