2015-07-15 03:09:42 +02:00
/// <reference path="../src/compiler/sys.ts" />
/ * *
* A minimal description for a parsed package . json object .
* /
interface PackageJson {
name : string ;
version : string ;
keywords : string [ ] ;
}
function main ( ) : void {
const sys = ts . sys ;
2018-01-20 00:58:35 +01:00
if ( sys . args . length < 3 ) {
2015-07-15 03:09:42 +02:00
sys . write ( "Usage:" + sys . newLine )
2018-01-20 00:58:35 +01:00
sys . write ( "\tnode configureNightly.js <dev|insiders> <package.json location> <file containing version>" + sys . newLine ) ;
2015-07-15 03:09:42 +02:00
return ;
}
2018-01-20 00:58:35 +01:00
const tag = sys . args [ 0 ] ;
if ( tag !== "dev" && tag !== "insiders" ) {
throw new Error ( ` Unexpected tag name ' ${ tag } '. ` ) ;
}
2015-07-15 03:09:42 +02:00
// Acquire the version from the package.json file and modify it appropriately.
2018-01-20 00:58:35 +01:00
const packageJsonFilePath = ts . normalizePath ( sys . args [ 1 ] ) ;
2017-07-19 23:47:25 +02:00
const packageJsonValue : PackageJson = JSON . parse ( sys . readFile ( packageJsonFilePath ) ) ;
2015-07-15 03:09:42 +02:00
2017-07-19 23:47:25 +02:00
const { majorMinor , patch } = parsePackageJsonVersion ( packageJsonValue . version ) ;
2018-01-20 00:58:35 +01:00
const prereleasePatch = getPrereleasePatch ( tag , patch ) ;
2015-07-15 03:09:42 +02:00
// Acquire and modify the source file that exposes the version string.
2018-01-20 00:58:35 +01:00
const tsFilePath = ts . normalizePath ( sys . args [ 2 ] ) ;
2017-07-19 23:47:25 +02:00
const tsFileContents = ts . sys . readFile ( tsFilePath ) ;
2018-01-20 00:58:35 +01:00
const modifiedTsFileContents = updateTsFile ( tsFilePath , tsFileContents , majorMinor , patch , prereleasePatch ) ;
2015-07-15 03:09:42 +02:00
// Ensure we are actually changing something - the user probably wants to know that the update failed.
if ( tsFileContents === modifiedTsFileContents ) {
2018-01-20 00:58:35 +01:00
let err = ` \ n ' ${ tsFilePath } ' was not updated while configuring for a prerelease publish for ' ${ tag } '. \ n ` ;
2017-07-19 23:47:25 +02:00
err += ` Ensure that you have not already run this script; otherwise, erase your changes using 'git checkout -- " ${ tsFilePath } "'. ` ;
2018-01-20 00:58:35 +01:00
throw new Error ( err + "\n" ) ;
2015-07-15 03:09:42 +02:00
}
// Finally write the changes to disk.
2017-07-19 23:47:25 +02:00
// Modify the package.json structure
2018-01-20 00:58:35 +01:00
packageJsonValue . version = ` ${ majorMinor } . ${ prereleasePatch } ` ;
2015-07-15 03:09:42 +02:00
sys . writeFile ( packageJsonFilePath , JSON . stringify ( packageJsonValue , /*replacer:*/ undefined , /*space:*/ 4 ) )
sys . writeFile ( tsFilePath , modifiedTsFileContents ) ;
}
2017-07-19 23:47:25 +02:00
function updateTsFile ( tsFilePath : string , tsFileContents : string , majorMinor : string , patch : string , nightlyPatch : string ) : string {
const majorMinorRgx = /export const versionMajorMinor = "(\d+\.\d+)"/ ;
const majorMinorMatch = majorMinorRgx . exec ( tsFileContents ) ;
ts . Debug . assert ( majorMinorMatch !== null , "" , ( ) = > ` The file seems to no longer have a string matching ' ${ majorMinorRgx } '. ` ) ;
const parsedMajorMinor = majorMinorMatch [ 1 ] ;
ts . Debug . assert ( parsedMajorMinor === majorMinor , "versionMajorMinor does not match." , ( ) = > ` ${ tsFilePath } : ' ${ parsedMajorMinor } '; package.json: ' ${ majorMinor } ' ` ) ;
2018-02-08 08:45:37 +01:00
const versionRgx = /export const version = `\$\{versionMajorMinor\}\.(\d)(-dev)?`;/ ;
2017-07-19 23:47:25 +02:00
const patchMatch = versionRgx . exec ( tsFileContents ) ;
ts . Debug . assert ( patchMatch !== null , "The file seems to no longer have a string matching" , ( ) = > versionRgx . toString ( ) ) ;
const parsedPatch = patchMatch [ 1 ] ;
if ( parsedPatch !== patch ) {
throw new Error ( ` patch does not match. ${ tsFilePath } : ' ${ parsedPatch } ; package.json: ' ${ patch } ' ` ) ;
2015-07-15 03:09:42 +02:00
}
2017-07-19 23:47:25 +02:00
return tsFileContents . replace ( versionRgx , ` export const version = \` \ ${ versionMajorMinor } . ${ nightlyPatch } \` ; ` ) ;
}
function parsePackageJsonVersion ( versionString : string ) : { majorMinor : string , patch : string } {
const versionRgx = /(\d+\.\d+)\.(\d+)($|\-)/ ;
const match = versionString . match ( versionRgx ) ;
ts . Debug . assert ( match !== null , "package.json 'version' should match" , ( ) = > versionRgx . toString ( ) ) ;
return { majorMinor : match [ 1 ] , patch : match [ 2 ] } ;
}
/** e.g. 0-dev.20170707 */
2018-01-20 00:58:35 +01:00
function getPrereleasePatch ( tag : string , plainPatch : string ) : string {
2015-07-15 03:09:42 +02:00
// We're going to append a representation of the current time at the end of the current version.
// String.prototype.toISOString() returns a 24-character string formatted as 'YYYY-MM-DDTHH:mm:ss.sssZ',
2015-07-23 21:32:17 +02:00
// but we'd prefer to just remove separators and limit ourselves to YYYYMMDD.
// UTC time will always be implicit here.
2015-07-15 03:09:42 +02:00
const now = new Date ( ) ;
2015-07-23 21:32:17 +02:00
const timeStr = now . toISOString ( ) . replace ( /:|T|\.|-/g , "" ) . slice ( 0 , 8 ) ;
2015-07-15 03:09:42 +02:00
2018-01-20 00:58:35 +01:00
return ` ${ plainPatch } - ${ tag } . ${ timeStr } ` ;
2015-07-15 03:09:42 +02:00
}
2018-02-08 08:45:37 +01:00
main ( ) ;