@@ -228,50 +228,137 @@ async function _resolveVersion(
228228 let result = await requestJson ( searchQueryServiceUrlWithQuery , requestOptions ) ;
229229 const findPreRelease = common . isLatestPreRelease ( packageVersion ) ;
230230
231+ resolvedVersion = findLatestVersion ( result , findPreRelease ) ;
232+
233+ if ( resolvedVersion == null ) {
234+ throw new Error ( `Package not found: ${ packageName } ` ) ;
235+ }
236+
237+ return resolvedVersion ;
238+ }
239+
240+ /**
241+ * Finds the latest version in a SearchQueryService response.
242+ *
243+ * @param result A JSON object returned from the SearchQueryService
244+ * @param findPreRelease Whether or not to find a pre-release version
245+ * @returns The latest version of the package
246+ */
247+ function findLatestVersion (
248+ result : object ,
249+ findPreRelease : boolean ) : string {
250+ let latestVersion = null ;
251+ let latestVersionParts = null ;
252+ let latestIsPreRelease = false ;
253+ let latestPreReleaseFlag = null ;
254+
255+ if ( result == null || result [ 'items' ] == null ) {
256+ return latestVersion ;
257+ }
258+
259+ let currentCatalogEntry = null ;
260+ let currentVersion = null ;
261+ let currentVersionParts = null ;
262+ let currentFullVersionParts = null ;
263+ let currentVersionNumbersString = null ;
264+ let currentIsLatest = false ;
265+ let currentIsPreRelease = false ;
266+ let currentPreReleaseFlag = null ;
267+
231268 for ( let packageGroup of result [ 'items' ] ) {
232269 for ( let packageInfo of packageGroup [ 'items' ] ) {
233- let catalogEntry = packageInfo [ 'catalogEntry' ] ;
234- if ( catalogEntry [ 'listed' ] != true ) {
270+ currentCatalogEntry = packageInfo [ 'catalogEntry' ] ;
271+
272+ if ( currentCatalogEntry [ 'listed' ] != true ) {
235273 // skip delisted packages
236274 continue ;
237275 }
238276
239- if ( ! findPreRelease && common . isPreRelease ( catalogEntry [ 'version' ] ) ) {
277+ currentVersion = currentCatalogEntry [ 'version' ] ;
278+ currentIsPreRelease = common . isPreRelease ( currentVersion ) ;
279+
280+ if ( ! findPreRelease && currentIsPreRelease ) {
240281 // skip prerelease packages if we're looking for a stable version
241282 continue ;
242283 }
243284
244- resolvedVersion = catalogEntry [ 'version' ] ;
245- break ;
246- }
285+ currentFullVersionParts = currentVersion . split ( "-" ) ;
286+ if ( currentIsPreRelease ) {
287+ currentPreReleaseFlag = currentFullVersionParts [ 1 ] ;
288+ }
247289
248- if ( resolvedVersion != null ) {
249- break ;
250- }
251- }
252-
253- if ( resolvedVersion == null ) {
254- throw new Error ( `Package not found: ${ packageName } ` ) ;
255- }
290+ currentVersionNumbersString = currentFullVersionParts [ 0 ] ;
291+ currentVersionParts = currentVersionNumbersString . split ( "." ) ;
292+ currentIsLatest = latestVersion == null ;
256293
257- return resolvedVersion ;
258- }
294+ if ( ! currentIsLatest ) {
295+ // Evaluate the current version against the latest version
296+
297+ // Handle comparisons of separate level versions
298+ // Some packages exclude Patch or include Revisions up to two levels (Rev1 and Rev2)
299+ let maxVersionParts = currentVersionParts . length ;
300+ if ( currentVersionParts . length < maxVersionParts ) {
301+ maxVersionParts = latestVersionParts . length ;
302+ }
259303
260- function rampedDeployment (
261- datetime : Date ,
262- rampMinutes : number ) : boolean {
263- let ramped = false ;
304+ for ( let versionPartIndex = 0 ; versionPartIndex < currentVersionParts . length ; versionPartIndex ++ ) {
305+ let versionPart = 0 ;
306+ let latestVersionPart = 0 ;
264307
265- let curDate = new Date ( ) ;
308+ let isLastVersionPart = versionPartIndex == ( maxVersionParts - 1 ) ;
266309
267- let diff = curDate . getTime ( ) - datetime . getTime ( ) ;
310+ if ( versionPartIndex < currentVersionParts . length ) {
311+ versionPart = parseInt ( currentVersionParts [ versionPartIndex ] ) ;
312+ }
268313
269- datetime . setMinutes
270-
271-
272- return Math . random ( ) > diff ;
314+ if ( versionPartIndex < latestVersionParts . length ) {
315+ latestVersionPart = parseInt ( latestVersionParts [ versionPartIndex ] ) ;
316+ }
317+
318+ if ( versionPart > latestVersionPart ) {
319+ currentIsLatest = true ;
320+ } else if ( versionPart == latestVersionPart ) {
321+ currentIsLatest = isLastVersionPart
322+ &&
323+ (
324+ ( currentIsPreRelease && latestIsPreRelease && currentPreReleaseFlag > latestPreReleaseFlag )
325+ ||
326+ ( ! currentIsPreRelease && latestIsPreRelease )
327+ ) ;
328+ } else {
329+ // Current version is less than latest found
330+ break ;
331+ }
332+
333+ if ( currentIsLatest ) {
334+ break ;
335+ }
336+ }
337+ }
338+
339+ if ( currentIsLatest ) {
340+ latestVersion = currentVersion ;
341+ latestVersionParts = currentVersionParts ;
342+ latestIsPreRelease = currentIsPreRelease ;
343+ latestPreReleaseFlag = currentPreReleaseFlag ;
344+ }
345+ }
346+ }
347+
348+ tl . debug ( `latestVersion = ${ latestVersion } ` ) ;
349+ return latestVersion ;
273350}
274351
352+ // function rampedDeployment(
353+ // datetime: Date,
354+ // rampMinutes: number): boolean {
355+ // let ramped = false;
356+ // let curDate = new Date();
357+ // let diff = curDate.getTime() - datetime.getTime();
358+ // datetime.setMinutes
359+ // return Math.random() > diff;
360+ // }
361+
275362/**
276363 * Top level service call to download a package from a NuGet server.
277364 *
0 commit comments