@@ -11,17 +11,23 @@ import { EventStream } from '../EventStream';
1111import * as Event from "../omnisharp/loggingEvents" ;
1212import NetworkSettings , { NetworkSettingsProvider } from '../NetworkSettings' ;
1313import { getBufferIntegrityHash } from '../packageManager/isValidDownload' ;
14+ const findVersions = require ( 'find-versions' ) ;
1415
15- interface PackageJSONFile
16- {
17- runtimeDependencies : Package [ ] ;
16+ interface PackageJSONFile {
17+ runtimeDependencies : Package [ ] ;
18+ defaults : {
19+ [ key : string ] : string ;
20+ } ;
1821}
1922
20- export async function updatePackageDependencies ( ) : Promise < void > {
23+ const dottedVersionRegExp = / [ 0 - 9 ] + \. [ 0 - 9 ] + \. [ 0 - 9 ] + / g;
24+ const dashedVersionRegExp = / [ 0 - 9 ] + - [ 0 - 9 ] + - [ 0 - 9 ] + / g;
25+
26+ export async function updatePackageDependencies ( ) : Promise < void > {
2127
2228 const newPrimaryUrls = process . env [ "NEW_DEPS_URLS" ] ;
2329 const newVersion = process . env [ "NEW_DEPS_VERSION" ] ;
24-
30+
2531 if ( ! newPrimaryUrls || ! newVersion ) {
2632 console . log ( ) ;
2733 console . log ( "'npm run gulp updatePackageDependencies' will update package.json with new URLs of dependencies." ) ;
@@ -46,9 +52,9 @@ export async function updatePackageDependencies() : Promise<void> {
4652 if ( ! / ^ [ 0 - 9 ] + \. [ 0 - 9 ] + \. [ 0 - 9 ] + $ / . test ( newVersion ) ) {
4753 throw new Error ( "Unexpected 'NEW_DEPS_VERSION' value. Expected format similar to: 1.2.3." ) ;
4854 }
49-
55+
5056 let packageJSON : PackageJSONFile = JSON . parse ( fs . readFileSync ( 'package.json' ) . toString ( ) ) ;
51-
57+
5258 // map from lowercase filename to Package
5359 const mapFileNameToDependency : { [ key : string ] : Package } = { } ;
5460
@@ -61,8 +67,8 @@ export async function updatePackageDependencies() : Promise<void> {
6167 }
6268 mapFileNameToDependency [ fileName ] = dependency ;
6369 } ) ;
64-
65- let findDependencyToUpdate = ( url : string ) : Package => {
70+
71+ let findDependencyToUpdate = ( url : string ) : Package => {
6672 let fileName = getLowercaseFileNameFromUrl ( url ) ;
6773 let dependency = mapFileNameToDependency [ fileName ] ;
6874 if ( dependency === undefined ) {
@@ -71,34 +77,13 @@ export async function updatePackageDependencies() : Promise<void> {
7177 return dependency ;
7278 } ;
7379
74- const dottedVersionRegExp = / [ 0 - 9 ] + \. [ 0 - 9 ] + \. [ 0 - 9 ] + / g;
75- const dashedVersionRegExp = / [ 0 - 9 ] + - [ 0 - 9 ] + - [ 0 - 9 ] + / g;
76-
77- const getMatchCount = ( regexp : RegExp , searchString : string ) : number => {
78- regexp . lastIndex = 0 ;
79- let retVal = 0 ;
80- while ( regexp . test ( searchString ) ) {
81- retVal ++ ;
82- }
83- regexp . lastIndex = 0 ;
84- return retVal ;
85- } ;
86-
8780 // First quickly make sure we could match up the URL to an existing item.
8881 for ( let urlToUpdate of newPrimaryUrlArray ) {
8982 const dependency = findDependencyToUpdate ( urlToUpdate ) ;
90- if ( dependency . fallbackUrl ) {
91- const dottedMatches : number = getMatchCount ( dottedVersionRegExp , dependency . fallbackUrl ) ;
92- const dashedMatches : number = getMatchCount ( dashedVersionRegExp , dependency . fallbackUrl ) ;
93- const matchCount : number = dottedMatches + dashedMatches ;
94-
95- if ( matchCount == 0 ) {
96- throw new Error ( `Version number not found in fallback URL '${ dependency . fallbackUrl } '.` ) ;
97- }
98- if ( matchCount > 1 ) {
99- throw new Error ( `Ambiguous version pattern found in fallback URL '${ dependency . fallbackUrl } '. Multiple version strings found.` ) ;
100- }
101- }
83+ //Fallback url should contain a version
84+ verifyVersionSubstringCount ( dependency . fallbackUrl , true ) ;
85+ verifyVersionSubstringCount ( dependency . installPath ) ;
86+ verifyVersionSubstringCount ( dependency . installTestPath ) ;
10287 }
10388
10489 // Next take another pass to try and update to the URL
@@ -110,33 +95,30 @@ export async function updatePackageDependencies() : Promise<void> {
11095 break ;
11196 }
11297 } ) ;
113- const networkSettingsProvider : NetworkSettingsProvider = ( ) => new NetworkSettings ( /*proxy:*/ null , /*stringSSL:*/ true ) ;
98+ const networkSettingsProvider : NetworkSettingsProvider = ( ) => new NetworkSettings ( /*proxy:*/ null , /*stringSSL:*/ true ) ;
11499
115- const downloadAndGetHash = async ( url :string ) : Promise < string > => {
116- console . log ( `Downlodaing from '${ url } '` ) ;
117- const buffer : Buffer = await DownloadFile ( url , eventStream , networkSettingsProvider , url , null ) ;
100+ const downloadAndGetHash = async ( url : string ) : Promise < string > => {
101+ console . log ( `Downloading from '${ url } '` ) ;
102+ const buffer : Buffer = await DownloadFile ( url , eventStream , networkSettingsProvider , url , null ) ;
118103 return getBufferIntegrityHash ( buffer ) ;
119104 } ;
120105
121106 for ( let urlToUpdate of newPrimaryUrlArray ) {
122107 let dependency = findDependencyToUpdate ( urlToUpdate ) ;
123108 dependency . url = urlToUpdate ;
124109 dependency . integrity = await downloadAndGetHash ( dependency . url ) ;
125-
126- if ( dependency . fallbackUrl ) {
127-
128- // NOTE: We already verified in the first loop that one of these patterns will work, grab the one that does
129- let regex : RegExp = dottedVersionRegExp ;
130- let newValue : string = newVersion ;
131- if ( ! dottedVersionRegExp . test ( dependency . fallbackUrl ) ) {
132- regex = dashedVersionRegExp ;
133- newValue = newVersion . replace ( / \. / g, "-" ) ;
110+ dependency . fallbackUrl = replaceVersion ( dependency . fallbackUrl , newVersion ) ;
111+ dependency . installPath = replaceVersion ( dependency . installPath , newVersion ) ;
112+ dependency . installTestPath = replaceVersion ( dependency . installTestPath , newVersion ) ;
113+ Object . keys ( packageJSON . defaults ) . forEach ( key => {
114+ //Update the version present in the defaults
115+ if ( key . toLowerCase ( ) == dependency . id . toLowerCase ( ) ) {
116+ packageJSON . defaults [ key ] = newVersion ;
134117 }
135- dottedVersionRegExp . lastIndex = 0 ;
118+ } ) ;
136119
137- dependency . fallbackUrl = dependency . fallbackUrl . replace ( regex , newValue ) ;
120+ if ( dependency . fallbackUrl ) {
138121 const fallbackUrlIntegrity = await downloadAndGetHash ( dependency . fallbackUrl ) ;
139-
140122 if ( dependency . integrity !== fallbackUrlIntegrity ) {
141123 throw new Error ( `File downloaded from primary URL '${ dependency . url } ' doesn't match '${ dependency . fallbackUrl } '.` ) ;
142124 }
@@ -155,7 +137,55 @@ export async function updatePackageDependencies() : Promise<void> {
155137 fs . writeFileSync ( 'package.json' , content ) ;
156138}
157139
158- function getLowercaseFileNameFromUrl ( url : string ) : string {
140+
141+ function replaceVersion ( fileName : string , newVersion : string ) : string {
142+ if ( ! fileName ) {
143+ return fileName ; //if the value is null or undefined return the same one
144+ }
145+
146+ let regex : RegExp = dottedVersionRegExp ;
147+ let newValue : string = newVersion ;
148+ if ( ! dottedVersionRegExp . test ( fileName ) ) {
149+ regex = dashedVersionRegExp ;
150+ newValue = newVersion . replace ( / \. / g, "-" ) ;
151+ }
152+ dottedVersionRegExp . lastIndex = 0 ;
153+
154+ if ( ! regex . test ( fileName ) ) {
155+ return fileName ; //If the string doesn't contain any version return the same string
156+ }
157+
158+ return fileName . replace ( regex , newValue ) ;
159+ }
160+
161+ function verifyVersionSubstringCount ( value : string , shouldContainVersion = false ) : void {
162+ const getMatchCount = ( regexp : RegExp , searchString : string ) : number => {
163+ regexp . lastIndex = 0 ;
164+ let retVal = 0 ;
165+ while ( regexp . test ( searchString ) ) {
166+ retVal ++ ;
167+ }
168+ regexp . lastIndex = 0 ;
169+ return retVal ;
170+ } ;
171+
172+ if ( ! value ) {
173+ return ;
174+ }
175+
176+ const dottedMatches : number = getMatchCount ( dottedVersionRegExp , value ) ;
177+ const dashedMatches : number = getMatchCount ( dashedVersionRegExp , value ) ;
178+ const matchCount : number = dottedMatches + dashedMatches ;
179+
180+ if ( shouldContainVersion && matchCount == 0 ) {
181+ throw new Error ( `Version number not found in '${ value } '.` ) ;
182+ }
183+ if ( matchCount > 1 ) {
184+ throw new Error ( `Ambiguous version pattern found in '${ value } '. Multiple version strings found.` ) ;
185+ }
186+ }
187+
188+ function getLowercaseFileNameFromUrl ( url : string ) : string {
159189
160190 if ( ! url . startsWith ( "https://" ) ) {
161191 throw new Error ( `Unexpected URL '${ url } '. URL expected to start with 'https://'.` ) ;
@@ -166,5 +196,18 @@ function getLowercaseFileNameFromUrl(url : string) : string {
166196 }
167197
168198 let index = url . lastIndexOf ( "/" ) ;
169- return url . substr ( index + 1 ) . toLowerCase ( ) ;
199+ let fileName = url . substr ( index + 1 ) . toLowerCase ( ) ;
200+ let versions = findVersions ( fileName ) ;
201+ if ( ! versions || versions . length == 0 ) {
202+ return fileName ;
203+ }
204+
205+ if ( versions . length > 1 ) {
206+ //we expect only one version string to be present in the last part of the url
207+ throw new Error ( `Ambiguous version pattern found URL '${ url } '. Multiple version strings found.` ) ;
208+ }
209+
210+ let versionIndex = fileName . indexOf ( versions [ 0 ] ) ;
211+ //remove the dash before the version number
212+ return fileName . substr ( 0 , versionIndex - 1 ) . toLowerCase ( ) ;
170213}
0 commit comments