8
8
import { execSync } from 'child_process' ;
9
9
import * as fs from 'fs' ;
10
10
import * as path from 'path' ;
11
- import * as semver from 'semver' ;
12
11
import { Arguments , Option } from '../models/interface' ;
13
12
import { SchematicCommand } from '../models/schematic-command' ;
14
13
import { getPackageManager } from '../utilities/package-manager' ;
@@ -21,7 +20,11 @@ import {
21
20
import { PackageTreeNode , findNodeDependencies , readPackageTree } from '../utilities/package-tree' ;
22
21
import { Schema as UpdateCommandSchema } from './update' ;
23
22
24
- const npa = require ( 'npm-package-arg' ) ;
23
+ const npa = require ( 'npm-package-arg' ) as ( selector : string ) => PackageIdentifier ;
24
+ const pickManifest = require ( 'npm-pick-manifest' ) as (
25
+ metadata : PackageMetadata ,
26
+ selector : string ,
27
+ ) => PackageManifest ;
25
28
26
29
const oldConfigFileNames = [ '.angular-cli.json' , 'angular-cli.json' ] ;
27
30
@@ -37,7 +40,7 @@ export class UpdateCommand extends SchematicCommand<UpdateCommandSchema> {
37
40
const packages : PackageIdentifier [ ] = [ ] ;
38
41
for ( const request of options [ '--' ] || [ ] ) {
39
42
try {
40
- const packageIdentifier : PackageIdentifier = npa ( request ) ;
43
+ const packageIdentifier = npa ( request ) ;
41
44
42
45
// only registry identifiers are supported
43
46
if ( ! packageIdentifier . registry ) {
@@ -245,7 +248,7 @@ export class UpdateCommand extends SchematicCommand<UpdateCommandSchema> {
245
248
246
249
const requests : {
247
250
identifier : PackageIdentifier ;
248
- node : PackageTreeNode | string ;
251
+ node : PackageTreeNode ;
249
252
} [ ] = [ ] ;
250
253
251
254
// Validate packages actually are part of the workspace
@@ -258,11 +261,7 @@ export class UpdateCommand extends SchematicCommand<UpdateCommandSchema> {
258
261
}
259
262
260
263
// If a specific version is requested and matches the installed version, skip.
261
- if (
262
- pkg . type === 'version' &&
263
- typeof node === 'object' &&
264
- node . package . version === pkg . fetchSpec
265
- ) {
264
+ if ( pkg . type === 'version' && node . package . version === pkg . fetchSpec ) {
266
265
this . logger . info ( `Package '${ pkg . name } ' is already at '${ pkg . fetchSpec } '.` ) ;
267
266
continue ;
268
267
}
@@ -294,18 +293,34 @@ export class UpdateCommand extends SchematicCommand<UpdateCommandSchema> {
294
293
// Try to find a package version based on the user requested package specifier
295
294
// registry specifier types are either version, range, or tag
296
295
let manifest : PackageManifest | undefined ;
297
- if ( requestIdentifier . type === 'version' ) {
298
- manifest = metadata . versions . get ( requestIdentifier . fetchSpec ) ;
299
- } else if ( requestIdentifier . type === 'range' ) {
300
- const maxVersion = semver . maxSatisfying (
301
- Array . from ( metadata . versions . keys ( ) ) ,
302
- requestIdentifier . fetchSpec ,
303
- ) ;
304
- if ( maxVersion ) {
305
- manifest = metadata . versions . get ( maxVersion ) ;
296
+ if (
297
+ requestIdentifier . type === 'version' ||
298
+ requestIdentifier . type === 'range' ||
299
+ requestIdentifier . type === 'tag'
300
+ ) {
301
+ try {
302
+ manifest = pickManifest ( metadata , requestIdentifier . fetchSpec ) ;
303
+ } catch ( e ) {
304
+ if ( e . code === 'ETARGET' ) {
305
+ // If not found and next was used and user did not provide a specifier, try latest.
306
+ // Package may not have a next tag.
307
+ if (
308
+ requestIdentifier . type === 'tag' &&
309
+ requestIdentifier . fetchSpec === 'next' &&
310
+ ! requestIdentifier . rawSpec
311
+ ) {
312
+ try {
313
+ manifest = pickManifest ( metadata , 'latest' ) ;
314
+ } catch ( e ) {
315
+ if ( e . code !== 'ETARGET' && e . code !== 'ENOVERSIONS' ) {
316
+ throw e ;
317
+ }
318
+ }
319
+ }
320
+ } else if ( e . code !== 'ENOVERSIONS' ) {
321
+ throw e ;
322
+ }
306
323
}
307
- } else if ( requestIdentifier . type === 'tag' ) {
308
- manifest = metadata . tags [ requestIdentifier . fetchSpec ] ;
309
324
}
310
325
311
326
if ( ! manifest ) {
@@ -316,10 +331,7 @@ export class UpdateCommand extends SchematicCommand<UpdateCommandSchema> {
316
331
return 1 ;
317
332
}
318
333
319
- if (
320
- ( typeof node === 'string' && manifest . version === node ) ||
321
- ( typeof node === 'object' && manifest . version === node . package . version )
322
- ) {
334
+ if ( manifest . version === node . package . version ) {
323
335
this . logger . info ( `Package '${ packageName } ' is already up to date.` ) ;
324
336
continue ;
325
337
}
0 commit comments