@@ -26,7 +26,11 @@ import {
2626import { PackageTreeNode , findNodeDependencies , readPackageTree } from '../utilities/package-tree' ;
2727import { Schema as UpdateCommandSchema } from './update' ;
2828
29- const npa = require ( 'npm-package-arg' ) ;
29+ const npa = require ( 'npm-package-arg' ) as ( selector : string ) => PackageIdentifier ;
30+ const pickManifest = require ( 'npm-pick-manifest' ) as (
31+ metadata : PackageMetadata ,
32+ selector : string ,
33+ ) => PackageManifest ;
3034
3135const oldConfigFileNames = [ '.angular-cli.json' , 'angular-cli.json' ] ;
3236
@@ -188,7 +192,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
188192 const packages : PackageIdentifier [ ] = [ ] ;
189193 for ( const request of options [ '--' ] || [ ] ) {
190194 try {
191- const packageIdentifier : PackageIdentifier = npa ( request ) ;
195+ const packageIdentifier = npa ( request ) ;
192196
193197 // only registry identifiers are supported
194198 if ( ! packageIdentifier . registry ) {
@@ -271,8 +275,19 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
271275
272276 this . logger . info ( `Found ${ Object . keys ( rootDependencies ) . length } dependencies.` ) ;
273277
274- if ( options . all || packages . length === 0 ) {
275- // Either update all packages or show status
278+ if ( options . all ) {
279+ // 'all' option and a zero length packages have already been checked.
280+ // Add all direct dependencies to be updated
281+ for ( const dep of Object . keys ( rootDependencies ) ) {
282+ const packageIdentifier = npa ( dep ) ;
283+ if ( options . next ) {
284+ packageIdentifier . fetchSpec = 'next' ;
285+ }
286+
287+ packages . push ( packageIdentifier ) ;
288+ }
289+ } else if ( packages . length === 0 ) {
290+ // Show status
276291 const { success } = await this . executeSchematic ( '@schematics/update' , 'update' , {
277292 force : options . force || false ,
278293 next : options . next || false ,
@@ -397,7 +412,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
397412
398413 const requests : {
399414 identifier : PackageIdentifier ;
400- node : PackageTreeNode | string ;
415+ node : PackageTreeNode ;
401416 } [ ] = [ ] ;
402417
403418 // Validate packages actually are part of the workspace
@@ -410,11 +425,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
410425 }
411426
412427 // If a specific version is requested and matches the installed version, skip.
413- if (
414- pkg . type === 'version' &&
415- typeof node === 'object' &&
416- node . package . version === pkg . fetchSpec
417- ) {
428+ if ( pkg . type === 'version' && node . package . version === pkg . fetchSpec ) {
418429 this . logger . info ( `Package '${ pkg . name } ' is already at '${ pkg . fetchSpec } '.` ) ;
419430 continue ;
420431 }
@@ -448,18 +459,34 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
448459 // Try to find a package version based on the user requested package specifier
449460 // registry specifier types are either version, range, or tag
450461 let manifest : PackageManifest | undefined ;
451- if ( requestIdentifier . type === 'version' ) {
452- manifest = metadata . versions . get ( requestIdentifier . fetchSpec ) ;
453- } else if ( requestIdentifier . type === 'range' ) {
454- const maxVersion = semver . maxSatisfying (
455- Array . from ( metadata . versions . keys ( ) ) ,
456- requestIdentifier . fetchSpec ,
457- ) ;
458- if ( maxVersion ) {
459- manifest = metadata . versions . get ( maxVersion ) ;
462+ if (
463+ requestIdentifier . type === 'version' ||
464+ requestIdentifier . type === 'range' ||
465+ requestIdentifier . type === 'tag'
466+ ) {
467+ try {
468+ manifest = pickManifest ( metadata , requestIdentifier . fetchSpec ) ;
469+ } catch ( e ) {
470+ if ( e . code === 'ETARGET' ) {
471+ // If not found and next was used and user did not provide a specifier, try latest.
472+ // Package may not have a next tag.
473+ if (
474+ requestIdentifier . type === 'tag' &&
475+ requestIdentifier . fetchSpec === 'next' &&
476+ ! requestIdentifier . rawSpec
477+ ) {
478+ try {
479+ manifest = pickManifest ( metadata , 'latest' ) ;
480+ } catch ( e ) {
481+ if ( e . code !== 'ETARGET' && e . code !== 'ENOVERSIONS' ) {
482+ throw e ;
483+ }
484+ }
485+ }
486+ } else if ( e . code !== 'ENOVERSIONS' ) {
487+ throw e ;
488+ }
460489 }
461- } else if ( requestIdentifier . type === 'tag' ) {
462- manifest = metadata . tags [ requestIdentifier . fetchSpec ] ;
463490 }
464491
465492 if ( ! manifest ) {
@@ -470,10 +497,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
470497 return 1 ;
471498 }
472499
473- if (
474- ( typeof node === 'string' && manifest . version === node ) ||
475- ( typeof node === 'object' && manifest . version === node . package . version )
476- ) {
500+ if ( manifest . version === node . package . version ) {
477501 this . logger . info ( `Package '${ packageName } ' is already up to date.` ) ;
478502 continue ;
479503 }
0 commit comments