2018-04-17 23:19:42 +02:00
// @ts-check
const path = require ( "path" ) ;
const fs = require ( "fs" ) ;
2019-01-28 06:56:56 +01:00
const log = require ( "fancy-log" ) ;
2018-04-17 23:19:42 +02:00
const newer = require ( "gulp-newer" ) ;
const sourcemaps = require ( "gulp-sourcemaps" ) ;
const del = require ( "del" ) ;
const fold = require ( "travis-fold" ) ;
2018-06-19 07:45:13 +02:00
const rename = require ( "gulp-rename" ) ;
2019-01-28 06:56:56 +01:00
const concat = require ( "gulp-concat" ) ;
const merge2 = require ( "merge2" ) ;
const mkdirp = require ( "mkdirp" ) ;
const { src , dest , task , parallel , series , watch } = require ( "gulp" ) ;
const { append , transform } = require ( "gulp-insert" ) ;
const { prependFile } = require ( "./scripts/build/prepend" ) ;
2019-03-01 22:44:14 +01:00
const { exec , readJson , needsUpdate , getDiffTool , getDirSize , rm } = require ( "./scripts/build/utils" ) ;
2019-03-08 19:34:35 +01:00
const { runConsoleTests , refBaseline , localBaseline , refRwcBaseline , localRwcBaseline } = require ( "./scripts/build/tests" ) ;
2019-01-28 06:56:56 +01:00
const { buildProject , cleanProject , watchProject } = require ( "./scripts/build/projects" ) ;
const cmdLineOptions = require ( "./scripts/build/options" ) ;
2016-06-10 02:44:59 +02:00
const copyright = "CopyrightNotice.txt" ;
2019-01-28 06:56:56 +01:00
const cleanTasks = [ ] ;
const buildScripts = ( ) = > buildProject ( "scripts" ) ;
const cleanScripts = ( ) = > cleanProject ( "scripts" ) ;
cleanTasks . push ( cleanScripts ) ;
const libraries = readJson ( "./src/lib/libs.json" ) ;
const libs = libraries . libs . map ( lib = > {
const relativeSources = [ "header.d.ts" ] . concat ( libraries . sources && libraries . sources [ lib ] || [ lib + ".d.ts" ] ) ;
const relativeTarget = libraries . paths && libraries . paths [ lib ] || ( "lib." + lib + ".d.ts" ) ;
const sources = relativeSources . map ( s = > path . posix . join ( "src/lib" , s ) ) ;
const target = ` built/local/ ${ relativeTarget } ` ;
return { target , relativeTarget , sources } ;
} ) ;
const generateLibs = ( ) = > {
return merge2 ( libs . map ( ( { sources , target , relativeTarget } ) = >
src ( [ copyright , . . . sources ] )
. pipe ( newer ( target ) )
. pipe ( concat ( relativeTarget , { newLine : "\n\n" } ) )
. pipe ( dest ( "built/local" ) ) ) ) ;
} ;
task ( "lib" , generateLibs )
task ( "lib" ) . description = "Builds the library targets" ;
const cleanLib = ( ) = > del ( libs . map ( lib = > lib . target ) ) ;
cleanTasks . push ( cleanLib ) ;
const watchLib = ( ) = > watch ( [ "src/lib/**/*" ] , generateLibs ) ;
2018-06-19 07:45:13 +02:00
const diagnosticInformationMapTs = "src/compiler/diagnosticInformationMap.generated.ts" ;
const diagnosticMessagesJson = "src/compiler/diagnosticMessages.json" ;
const diagnosticMessagesGeneratedJson = "src/compiler/diagnosticMessages.generated.json" ;
2019-01-28 06:56:56 +01:00
const generateDiagnostics = async ( ) = > {
2018-06-19 07:45:13 +02:00
if ( needsUpdate ( diagnosticMessagesJson , [ diagnosticMessagesGeneratedJson , diagnosticInformationMapTs ] ) ) {
2019-01-28 06:56:56 +01:00
await exec ( process . execPath , [ "scripts/processDiagnosticMessages.js" , diagnosticMessagesJson ] ) ;
2018-06-19 07:45:13 +02:00
}
2019-01-28 06:56:56 +01:00
} ;
task ( "generate-diagnostics" , series ( buildScripts , generateDiagnostics ) ) ;
task ( "generate-diagnostics" ) . description = "Generates a diagnostic file in TypeScript based on an input JSON file" ;
2018-06-19 07:45:13 +02:00
2019-01-28 06:56:56 +01:00
const cleanDiagnostics = ( ) = > del ( [ diagnosticInformationMapTs , diagnosticMessagesGeneratedJson ] ) ;
cleanTasks . push ( cleanDiagnostics ) ;
2016-06-10 02:44:59 +02:00
2019-01-28 06:56:56 +01:00
const watchDiagnostics = ( ) = > watch ( [ "src/compiler/diagnosticMessages.json" ] , task ( "generate-diagnostics" ) ) ;
2016-06-10 02:44:59 +02:00
2018-06-19 07:45:13 +02:00
// Localize diagnostics
2017-10-19 00:46:09 +02:00
/ * *
* . lcg file is what localization team uses to know what messages to localize .
2018-06-19 07:45:13 +02:00
* The file is always generated in 'enu/diagnosticMessages.generated.json.lcg'
2017-10-19 00:46:09 +02:00
* /
2018-06-19 07:45:13 +02:00
const generatedLCGFile = "built/local/enu/diagnosticMessages.generated.json.lcg" ;
2017-10-19 00:46:09 +02:00
/ * *
* The localization target produces the two following transformations :
* 1 . 'src\loc\lcl\<locale>\diagnosticMessages.generated.json.lcl' = > 'built\local\<locale>\diagnosticMessages.generated.json'
* convert localized resources into a . json file the compiler can understand
* 2 . 'src\compiler\diagnosticMessages.generated.json' = > 'built\local\ENU\diagnosticMessages.generated.json.lcg'
* generate the lcg file ( source of messages to localize ) from the diagnosticMessages . generated . json
* /
2018-12-10 23:19:53 +01:00
const localizationTargets = [ "cs" , "de" , "es" , "fr" , "it" , "ja" , "ko" , "pl" , "pt-br" , "ru" , "tr" , "zh-cn" , "zh-tw" ]
. map ( f = > f . toLowerCase ( ) )
2018-06-19 07:45:13 +02:00
. map ( f = > ` built/local/ ${ f } /diagnosticMessages.generated.json ` )
2017-11-03 23:08:50 +01:00
. concat ( generatedLCGFile ) ;
2017-10-19 00:46:09 +02:00
2019-01-28 06:56:56 +01:00
const localize = async ( ) = > {
2018-06-19 07:45:13 +02:00
if ( needsUpdate ( diagnosticMessagesGeneratedJson , generatedLCGFile ) ) {
2019-01-28 06:56:56 +01:00
return exec ( process . execPath , [ "scripts/generateLocalizedDiagnosticMessages.js" , "src/loc/lcl" , "built/local" , diagnosticMessagesGeneratedJson ] , { ignoreExitCode : true } ) ;
2017-10-03 02:16:08 +02:00
}
2019-01-28 06:56:56 +01:00
} ;
// Pre-build steps when targeting the LKG compiler
const lkgPreBuild = parallel ( generateLibs , series ( buildScripts , generateDiagnostics ) ) ;
const buildTsc = ( ) = > buildProject ( "src/tsc" ) ;
task ( "tsc" , series ( lkgPreBuild , buildTsc ) ) ;
task ( "tsc" ) . description = "Builds the command-line compiler" ;
const cleanTsc = ( ) = > cleanProject ( "src/tsc" ) ;
cleanTasks . push ( cleanTsc ) ;
task ( "clean-tsc" , cleanTsc ) ;
task ( "clean-tsc" ) . description = "Cleans outputs for the command-line compiler" ;
const watchTsc = ( ) = > watchProject ( "src/tsc" ) ;
task ( "watch-tsc" , series ( lkgPreBuild , parallel ( watchLib , watchDiagnostics , watchTsc ) ) ) ;
task ( "watch-tsc" ) . description = "Watch for changes and rebuild the command-line compiler only." ;
// Pre-build steps when targeting the built/local compiler.
const localPreBuild = parallel ( generateLibs , series ( buildScripts , generateDiagnostics , buildTsc ) ) ;
2017-10-03 02:16:08 +02:00
2019-01-28 06:56:56 +01:00
// Pre-build steps to use based on supplied options.
const preBuild = cmdLineOptions . lkg ? lkgPreBuild : localPreBuild ;
2016-06-10 02:44:59 +02:00
2019-01-28 06:56:56 +01:00
const buildServices = ( ( ) = > {
// build typescriptServices.out.js
2019-03-01 22:44:14 +01:00
const buildTypescriptServicesOut = ( ) = > buildProject ( "src/typescriptServices/tsconfig.json" , cmdLineOptions ) ;
2019-02-23 00:32:42 +01:00
2019-01-28 06:56:56 +01:00
// create typescriptServices.js
const createTypescriptServicesJs = ( ) = > src ( "built/local/typescriptServices.out.js" )
. pipe ( newer ( "built/local/typescriptServices.js" ) )
. pipe ( sourcemaps . init ( { loadMaps : true } ) )
. pipe ( prependFile ( copyright ) )
. pipe ( rename ( "typescriptServices.js" ) )
. pipe ( sourcemaps . write ( "." , { includeContent : false , destPath : "built/local" } ) )
. pipe ( dest ( "built/local" ) ) ;
// create typescriptServices.d.ts
const createTypescriptServicesDts = ( ) = > src ( "built/local/typescriptServices.out.d.ts" )
. pipe ( newer ( "built/local/typescriptServices.d.ts" ) )
. pipe ( prependFile ( copyright ) )
. pipe ( transform ( content = > content . replace ( /^(\s*)(export )?const enum (\S+) {(\s*)$/gm , "$1$2enum $3 {$4" ) ) )
. pipe ( rename ( "typescriptServices.d.ts" ) )
. pipe ( dest ( "built/local" ) ) ;
// create typescript.js
const createTypescriptJs = ( ) = > src ( "built/local/typescriptServices.js" )
. pipe ( newer ( "built/local/typescript.js" ) )
. pipe ( sourcemaps . init ( { loadMaps : true } ) )
2018-06-19 07:45:13 +02:00
. pipe ( rename ( "typescript.js" ) )
2019-01-28 06:56:56 +01:00
. pipe ( sourcemaps . write ( "." , { includeContent : false , destPath : "built/local" } ) )
. pipe ( dest ( "built/local" ) ) ;
2018-06-19 07:45:13 +02:00
2019-01-28 06:56:56 +01:00
// create typescript.d.ts
const createTypescriptDts = ( ) = > src ( "built/local/typescriptServices.d.ts" )
. pipe ( newer ( "built/local/typescript.d.ts" ) )
2018-06-19 07:45:13 +02:00
. pipe ( append ( "\nexport = ts;" ) )
. pipe ( rename ( "typescript.d.ts" ) )
2019-01-28 06:56:56 +01:00
. pipe ( dest ( "built/local" ) ) ;
2018-06-19 07:45:13 +02:00
2019-01-28 06:56:56 +01:00
// create typescript_standalone.d.ts
const createTypescriptStandaloneDts = ( ) = > src ( "built/local/typescriptServices.d.ts" )
. pipe ( newer ( "built/local/typescript_standalone.d.ts" ) )
. pipe ( transform ( content = > content . replace ( /declare (namespace|module) ts/g , 'declare module "typescript"' ) ) )
2018-06-19 07:45:13 +02:00
. pipe ( rename ( "typescript_standalone.d.ts" ) )
2019-01-28 06:56:56 +01:00
. pipe ( dest ( "built/local" ) ) ;
return series (
buildTypescriptServicesOut ,
createTypescriptServicesJs ,
createTypescriptServicesDts ,
createTypescriptJs ,
createTypescriptDts ,
2019-02-23 00:32:42 +01:00
createTypescriptStandaloneDts ,
) ;
2019-01-28 06:56:56 +01:00
} ) ( ) ;
task ( "services" , series ( preBuild , buildServices ) ) ;
task ( "services" ) . description = "Builds the language service" ;
task ( "services" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
const cleanServices = async ( ) = > {
if ( fs . existsSync ( "built/local/typescriptServices.tsconfig.json" ) ) {
await cleanProject ( "built/local/typescriptServices.tsconfig.json" ) ;
}
await del ( [
"built/local/typescriptServices.out.js" ,
"built/local/typescriptServices.out.d.ts" ,
2019-03-01 22:44:14 +01:00
"built/local/typescriptServices.out.tsbuildinfo" ,
2019-01-28 06:56:56 +01:00
"built/local/typescriptServices.js" ,
"built/local/typescript.js" ,
"built/local/typescript.d.ts" ,
2019-03-01 22:44:14 +01:00
"built/local/typescript_standalone.d.ts"
2019-01-28 06:56:56 +01:00
] ) ;
} ;
cleanTasks . push ( cleanServices ) ;
task ( "clean-services" , cleanServices ) ;
task ( "clean-services" ) . description = "Cleans outputs for the language service" ;
const watchServices = ( ) = > watch ( [
"src/compiler/tsconfig.json" ,
"src/compiler/**/*.ts" ,
"src/jsTyping/tsconfig.json" ,
"src/jsTyping/**/*.ts" ,
"src/services/tsconfig.json" ,
"src/services/**/*.ts" ,
] , series ( preBuild , buildServices ) ) ;
task ( "watch-services" , series ( preBuild , parallel ( watchLib , watchDiagnostics , watchServices ) ) ) ;
task ( "watch-services" ) . description = "Watches for changes and rebuild language service only" ;
task ( "watch-services" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
const buildServer = ( ) = > buildProject ( "src/tsserver" , cmdLineOptions ) ;
task ( "tsserver" , series ( preBuild , buildServer ) ) ;
task ( "tsserver" ) . description = "Builds the language server" ;
task ( "tsserver" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
const cleanServer = ( ) = > cleanProject ( "src/tsserver" ) ;
cleanTasks . push ( cleanServer ) ;
task ( "clean-tsserver" , cleanServer ) ;
task ( "clean-tsserver" ) . description = "Cleans outputs for the language server" ;
const watchServer = ( ) = > watchProject ( "src/tsserver" , cmdLineOptions ) ;
task ( "watch-tsserver" , series ( preBuild , parallel ( watchLib , watchDiagnostics , watchServer ) ) ) ;
task ( "watch-tsserver" ) . description = "Watch for changes and rebuild the language server only" ;
task ( "watch-tsserver" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
2019-02-21 00:32:15 +01:00
task ( "min" , series ( preBuild , parallel ( buildTsc , buildServer ) ) ) ;
2019-01-28 06:56:56 +01:00
task ( "min" ) . description = "Builds only tsc and tsserver" ;
task ( "min" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
task ( "clean-min" , series ( cleanTsc , cleanServer ) ) ;
task ( "clean-min" ) . description = "Cleans outputs for tsc and tsserver" ;
task ( "watch-min" , series ( preBuild , parallel ( watchLib , watchDiagnostics , watchTsc , watchServer ) ) ) ;
task ( "watch-min" ) . description = "Watches for changes to a tsc and tsserver only" ;
task ( "watch-min" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
const buildLssl = ( ( ) = > {
// build tsserverlibrary.out.js
2019-03-01 22:44:14 +01:00
const buildServerLibraryOut = ( ) = > buildProject ( "src/tsserverlibrary/tsconfig.json" , cmdLineOptions ) ;
2019-02-23 00:32:42 +01:00
2019-01-28 06:56:56 +01:00
// create tsserverlibrary.js
const createServerLibraryJs = ( ) = > src ( "built/local/tsserverlibrary.out.js" )
. pipe ( newer ( "built/local/tsserverlibrary.js" ) )
. pipe ( sourcemaps . init ( { loadMaps : true } ) )
. pipe ( prependFile ( copyright ) )
. pipe ( rename ( "tsserverlibrary.js" ) )
. pipe ( sourcemaps . write ( "." , { includeContent : false , destPath : "built/local" } ) )
. pipe ( dest ( "built/local" ) ) ;
// create tsserverlibrary.d.ts
const createServerLibraryDts = ( ) = > src ( "built/local/tsserverlibrary.out.d.ts" )
. pipe ( newer ( "built/local/tsserverlibrary.d.ts" ) )
. pipe ( prependFile ( copyright ) )
. pipe ( transform ( content = > content . replace ( /^(\s*)(export )?const enum (\S+) {(\s*)$/gm , "$1$2enum $3 {$4" ) ) )
. pipe ( append ( "\nexport = ts;\nexport as namespace ts;" ) )
. pipe ( rename ( "tsserverlibrary.d.ts" ) )
. pipe ( dest ( "built/local" ) ) ;
return series (
buildServerLibraryOut ,
createServerLibraryJs ,
2019-02-23 00:32:42 +01:00
createServerLibraryDts ,
) ;
2019-01-28 06:56:56 +01:00
} ) ( ) ;
task ( "lssl" , series ( preBuild , buildLssl ) ) ;
task ( "lssl" ) . description = "Builds language service server library" ;
task ( "lssl" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
const cleanLssl = async ( ) = > {
if ( fs . existsSync ( "built/local/tsserverlibrary.tsconfig.json" ) ) {
await cleanProject ( "built/local/tsserverlibrary.tsconfig.json" ) ;
}
await del ( [
"built/local/tsserverlibrary.out.js" ,
"built/local/tsserverlibrary.out.d.ts" ,
2019-03-01 22:44:14 +01:00
"built/local/tsserverlibrary.out.tsbuildinfo" ,
2019-01-28 06:56:56 +01:00
"built/local/tsserverlibrary.js" ,
"built/local/tsserverlibrary.d.ts" ,
] ) ;
} ;
cleanTasks . push ( cleanLssl ) ;
task ( "clean-lssl" , cleanLssl ) ;
task ( "clean-lssl" ) . description = "Clean outputs for the language service server library" ;
const watchLssl = ( ) = > watch ( [
"src/compiler/tsconfig.json" ,
"src/compiler/**/*.ts" ,
"src/jsTyping/tsconfig.json" ,
"src/jsTyping/**/*.ts" ,
"src/services/tsconfig.json" ,
"src/services/**/*.ts" ,
"src/server/tsconfig.json" ,
"src/server/**/*.ts" ,
"src/tsserver/tsconfig.json" ,
"src/tsserver/**/*.ts" ,
] , buildLssl ) ;
task ( "watch-lssl" , series ( preBuild , parallel ( watchLib , watchDiagnostics , watchLssl ) ) ) ;
task ( "watch-lssl" ) . description = "Watch for changes and rebuild tsserverlibrary only" ;
task ( "watch-lssl" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
const buildTests = ( ) = > buildProject ( "src/testRunner" ) ;
task ( "tests" , series ( preBuild , parallel ( buildLssl , buildTests ) ) ) ;
task ( "tests" ) . description = "Builds the test infrastructure" ;
task ( "tests" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
const cleanTests = ( ) = > cleanProject ( "src/testRunner" ) ;
cleanTasks . push ( cleanTests ) ;
task ( "clean-tests" , cleanTests ) ;
task ( "clean-tests" ) . description = "Cleans the outputs for the test infrastructure" ;
const watchTests = ( ) = > watchProject ( "src/testRunner" , cmdLineOptions ) ;
const buildRules = ( ) = > buildProject ( "scripts/tslint" ) ;
task ( "build-rules" , buildRules ) ;
task ( "build-rules" ) . description = "Compiles tslint rules to js" ;
const cleanRules = ( ) = > cleanProject ( "scripts/tslint" ) ;
cleanTasks . push ( cleanRules ) ;
task ( "clean-rules" , cleanRules ) ;
task ( "clean-rules" ) . description = "Cleans the outputs for the lint rules" ;
const lintFoldStart = async ( ) = > { if ( fold . isTravis ( ) ) console . log ( fold . start ( "lint" ) ) ; } ;
const lintFoldEnd = async ( ) = > { if ( fold . isTravis ( ) ) console . log ( fold . end ( "lint" ) ) ; } ;
const lint = series ( [
lintFoldStart ,
. . . [ "scripts/tslint/tsconfig.json" , "src/tsconfig-base.json" ] . map ( project = > {
const lintOne = ( ) = > {
const args = [ "node_modules/tslint/bin/tslint" , "--project" , project , "--formatters-dir" , "./built/local/tslint/formatters" , "--format" , "autolinkableStylish" ] ;
if ( cmdLineOptions . fix ) args . push ( "--fix" ) ;
log ( ` Linting: node ${ args . join ( " " ) } ` ) ;
return exec ( process . execPath , args ) ;
} ;
lintOne . dispayName = ` lint( ${ project } ) ` ;
return lintOne ;
} ) ,
lintFoldEnd
] ) ;
lint . displayName = "lint" ;
task ( "lint" , series ( buildRules , lint ) ) ;
task ( "lint" ) . description = "Runs tslint on the compiler sources." ;
task ( "lint" ) . flags = {
" --f[iles]=<regex>" : "pattern to match files to lint" ,
} ;
2019-02-26 01:33:20 +01:00
const buildCancellationToken = ( ) = > buildProject ( "src/cancellationToken" ) ;
const cleanCancellationToken = ( ) = > cleanProject ( "src/cancellationToken" ) ;
cleanTasks . push ( cleanCancellationToken ) ;
const buildTypingsInstaller = ( ) = > buildProject ( "src/typingsInstaller" ) ;
const cleanTypingsInstaller = ( ) = > cleanProject ( "src/typingsInstaller" ) ;
cleanTasks . push ( cleanTypingsInstaller ) ;
const buildWatchGuard = ( ) = > buildProject ( "src/watchGuard" ) ;
const cleanWatchGuard = ( ) = > cleanProject ( "src/watchGuard" ) ;
cleanTasks . push ( cleanWatchGuard ) ;
const generateTypesMap = ( ) = > src ( "src/server/typesMap.json" )
. pipe ( newer ( "built/local/typesMap.json" ) )
. pipe ( transform ( contents = > ( JSON . parse ( contents ) , contents ) ) ) // validates typesMap.json is valid JSON
. pipe ( dest ( "built/local" ) ) ;
task ( "generate-types-map" , generateTypesMap ) ;
const cleanTypesMap = ( ) = > del ( "built/local/typesMap.json" ) ;
cleanTasks . push ( cleanTypesMap ) ;
const buildOtherOutputs = parallel ( buildCancellationToken , buildTypingsInstaller , buildWatchGuard , generateTypesMap ) ;
task ( "other-outputs" , series ( preBuild , buildOtherOutputs ) ) ;
task ( "other-outputs" ) . description = "Builds miscelaneous scripts and documents distributed with the LKG" ;
2019-01-28 06:56:56 +01:00
const buildFoldStart = async ( ) = > { if ( fold . isTravis ( ) ) console . log ( fold . start ( "build" ) ) ; } ;
const buildFoldEnd = async ( ) = > { if ( fold . isTravis ( ) ) console . log ( fold . end ( "build" ) ) ; } ;
2019-02-26 01:33:20 +01:00
task ( "local" , series ( buildFoldStart , preBuild , parallel ( localize , buildTsc , buildServer , buildServices , buildLssl , buildOtherOutputs ) , buildFoldEnd ) ) ;
2019-01-28 06:56:56 +01:00
task ( "local" ) . description = "Builds the full compiler and services" ;
task ( "local" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
task ( "watch-local" , series ( preBuild , parallel ( watchLib , watchDiagnostics , watchTsc , watchServices , watchServer , watchLssl ) ) ) ;
task ( "watch-local" ) . description = "Watches for changes to projects in src/ (but does not execute tests)." ;
task ( "watch-local" ) . flags = {
" --built" : "Compile using the built version of the compiler."
}
const generateCodeCoverage = ( ) = > exec ( "istanbul" , [ "cover" , "node_modules/mocha/bin/_mocha" , "--" , "-R" , "min" , "-t" , "" + cmdLineOptions . testTimeout , "built/local/run.js" ] ) ;
task ( "generate-code-coverage" , series ( preBuild , buildTests , generateCodeCoverage ) ) ;
task ( "generate-code-coverage" ) . description = "Generates code coverage data via istanbul" ;
const preTest = parallel ( buildRules , buildTests , buildServices , buildLssl ) ;
preTest . displayName = "preTest" ;
const postTest = ( done ) = > cmdLineOptions . lint ? lint ( done ) : done ( ) ;
const runTests = ( ) = > runConsoleTests ( "built/local/run.js" , "mocha-fivemat-progress-reporter" , /*runInParallel*/ false , /*watchMode*/ false ) ;
task ( "runtests" , series ( preBuild , preTest , runTests , postTest ) ) ;
task ( "runtests" ) . description = "Runs the tests using the built run.js file." ;
task ( "runtests" ) . flags = {
"-t --tests=<regex>" : "Pattern for tests to run." ,
" --failed" : "Runs tests listed in '.failed-tests'." ,
"-r --reporter=<reporter>" : "The mocha reporter to use." ,
"-d --debug" : "Runs tests in debug mode (NodeJS 6 and earlier)" ,
"-i --inspect" : "Runs tests in inspector mode (NodeJS 8 and later)" ,
" --keepFailed" : "Keep tests in .failed-tests even if they pass" ,
" --light" : "Run tests in light mode (fewer verifications, but tests run faster)" ,
" --dirty" : "Run tests without first cleaning test output directories" ,
" --stackTraceLimit=<limit>" : "Sets the maximum number of stack frames to display. Use 'full' to show all frames." ,
" --no-color" : "Disables color" ,
" --no-lint" : "Disables lint" ,
" --timeout=<ms>" : "Overrides the default test timeout." ,
" --built" : "Compile using the built version of the compiler." ,
}
const runTestsParallel = ( ) = > runConsoleTests ( "built/local/run.js" , "min" , /*runInParallel*/ true , /*watchMode*/ false ) ;
task ( "runtests-parallel" , series ( preBuild , preTest , runTestsParallel , postTest ) ) ;
task ( "runtests-parallel" ) . description = "Runs all the tests in parallel using the built run.js file." ;
task ( "runtests-parallel" ) . flags = {
" --no-lint" : "disables lint." ,
" --light" : "Run tests in light mode (fewer verifications, but tests run faster)." ,
" --keepFailed" : "Keep tests in .failed-tests even if they pass." ,
" --dirty" : "Run tests without first cleaning test output directories." ,
" --stackTraceLimit=<limit>" : "Sets the maximum number of stack frames to display. Use 'full' to show all frames." ,
" --workers=<number>" : "The number of parallel workers to use." ,
" --timeout=<ms>" : "Overrides the default test timeout." ,
" --built" : "Compile using the built version of the compiler." ,
} ;
task ( "diff" , ( ) = > exec ( getDiffTool ( ) , [ refBaseline , localBaseline ] , { ignoreExitCode : true } ) ) ;
task ( "diff" ) . description = "Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable" ;
task ( "diff-rwc" , ( ) = > exec ( getDiffTool ( ) , [ refRwcBaseline , localRwcBaseline ] , { ignoreExitCode : true } ) ) ;
task ( "diff-rwc" ) . description = "Diffs the RWC baselines using the diff tool specified by the 'DIFF' environment variable" ;
2019-02-22 22:12:11 +01:00
/ * *
* @param { string } localBaseline Path to the local copy of the baselines
* @param { string } refBaseline Path to the reference copy of the baselines
* /
const baselineAccept = ( localBaseline , refBaseline ) = > merge2 (
src ( [ ` ${ localBaseline } /** ` , ` ! ${ localBaseline } /**/*.delete ` ] , { base : localBaseline } )
2019-01-28 06:56:56 +01:00
. pipe ( dest ( refBaseline ) ) ,
2019-02-22 22:12:11 +01:00
src ( [ ` ${ localBaseline } /**/*.delete ` ] , { base : localBaseline , read : false } )
2019-01-28 06:56:56 +01:00
. pipe ( rm ( ) )
. pipe ( rename ( { extname : "" } ) )
. pipe ( rm ( refBaseline ) ) ) ;
2019-02-22 22:12:11 +01:00
task ( "baseline-accept" , ( ) = > baselineAccept ( localBaseline , refBaseline ) ) ;
2019-01-28 06:56:56 +01:00
task ( "baseline-accept" ) . description = "Makes the most recent test results the new baseline, overwriting the old baseline" ;
2019-02-22 22:12:11 +01:00
task ( "baseline-accept-rwc" , ( ) = > baselineAccept ( localRwcBaseline , refRwcBaseline ) ) ;
2019-01-28 06:56:56 +01:00
task ( "baseline-accept-rwc" ) . description = "Makes the most recent rwc test results the new baseline, overwriting the old baseline" ;
const buildLoggedIO = async ( ) = > {
mkdirp . sync ( "built/local/temp" ) ;
await exec ( process . execPath , [ "lib/tsc" , "--types" , "--target" , "es5" , "--lib" , "es5" , "--outdir" , "built/local/temp" , "src/harness/loggedIO.ts" ] ) ;
fs . renameSync ( "built/local/temp/harness/loggedIO.js" , "built/local/loggedIO.js" ) ;
await del ( "built/local/temp" ) ;
} ;
const cleanLoggedIO = ( ) = > del ( "built/local/temp/loggedIO.js" ) ;
cleanTasks . push ( cleanLoggedIO ) ;
const buildInstrumenter = ( ) = > buildProject ( "src/instrumenter" ) ;
const cleanInstrumenter = ( ) = > cleanProject ( "src/instrumenter" ) ;
cleanTasks . push ( cleanInstrumenter ) ;
const tscInstrumented = ( ) = > exec ( process . execPath , [ "built/local/instrumenter.js" , "record" , cmdLineOptions . tests || "iocapture" , "built/local" ] ) ;
task ( "tsc-instrumented" , series ( lkgPreBuild , parallel ( localize , buildTsc , buildServer , buildServices , buildLssl , buildLoggedIO , buildInstrumenter ) , tscInstrumented ) ) ;
task ( "tsc-instrumented" ) . description = "Builds an instrumented tsc.js" ;
task ( "tsc-instrumented" ) . flags = {
"-t --tests=<testname>" : "The test to run."
}
// TODO(rbuckton): Determine if we still need this task. Depending on a relative
// path here seems like a bad idea.
const updateSublime = ( ) = > src ( [ "built/local/tsserver.js" , "built/local/tsserver.js.map" ] )
. pipe ( dest ( "../TypeScript-Sublime-Plugin/tsserver/" ) ) ;
task ( "update-sublime" , updateSublime ) ;
task ( "update-sublime" ) . description = "Updates the sublime plugin's tsserver" ;
const buildImportDefinitelyTypedTests = ( ) = > buildProject ( "scripts/importDefinitelyTypedTests" ) ;
const cleanImportDefinitelyTypedTests = ( ) = > cleanProject ( "scripts/importDefinitelyTypedTests" ) ;
cleanTasks . push ( cleanImportDefinitelyTypedTests ) ;
// TODO(rbuckton): Should the path to DefinitelyTyped be configurable via an environment variable?
const importDefinitelyTypedTests = ( ) = > exec ( process . execPath , [ "scripts/importDefinitelyTypedTests/importDefinitelyTypedTests.js" , "./" , "../DefinitelyTyped" ] ) ;
task ( "importDefinitelyTypedTests" , series ( buildImportDefinitelyTypedTests , importDefinitelyTypedTests ) ) ;
task ( "importDefinitelyTypedTests" ) . description = "Runs the importDefinitelyTypedTests script to copy DT's tests to the TS-internal RWC tests" ;
const buildReleaseTsc = ( ) = > buildProject ( "src/tsc/tsconfig.release.json" ) ;
const cleanReleaseTsc = ( ) = > cleanProject ( "src/tsc/tsconfig.release.json" ) ;
cleanTasks . push ( cleanReleaseTsc ) ;
const cleanBuilt = ( ) = > del ( "built" ) ;
const produceLKG = async ( ) = > {
2018-06-21 03:24:12 +02:00
const expectedFiles = [
2019-01-28 06:56:56 +01:00
"built/local/tsc.release.js" ,
"built/local/typescriptServices.js" ,
"built/local/typescriptServices.d.ts" ,
"built/local/tsserver.js" ,
"built/local/typescript.js" ,
"built/local/typescript.d.ts" ,
"built/local/tsserverlibrary.js" ,
"built/local/tsserverlibrary.d.ts" ,
"built/local/typingsInstaller.js" ,
"built/local/cancellationToken.js"
] . concat ( libs . map ( lib = > lib . target ) ) ;
2018-06-21 03:24:12 +02:00
const missingFiles = expectedFiles
. concat ( localizationTargets )
. filter ( f = > ! fs . existsSync ( f ) ) ;
if ( missingFiles . length > 0 ) {
throw new Error ( "Cannot replace the LKG unless all built targets are present in directory 'built/local/'. The following files are missing:\n" + missingFiles . join ( "\n" ) ) ;
}
const sizeBefore = getDirSize ( "lib" ) ;
2019-01-28 06:56:56 +01:00
await exec ( process . execPath , [ "scripts/produceLKG.js" ] ) ;
const sizeAfter = getDirSize ( "lib" ) ;
if ( sizeAfter > ( sizeBefore * 1.10 ) ) {
throw new Error ( "The lib folder increased by 10% or more. This likely indicates a bug." ) ;
}
} ;
2019-02-26 01:33:20 +01:00
task ( "LKG" , series ( lkgPreBuild , parallel ( localize , buildTsc , buildServer , buildServices , buildLssl , buildOtherOutputs , buildReleaseTsc ) , produceLKG ) ) ;
2019-01-28 06:56:56 +01:00
task ( "LKG" ) . description = "Makes a new LKG out of the built js files" ;
task ( "LKG" ) . flags = {
" --built" : "Compile using the built version of the compiler." ,
}
const generateSpec = ( ) = > exec ( "cscript" , [ "//nologo" , "scripts/word2md.js" , path . resolve ( "doc/TypeScript Language Specification.docx" ) , path . resolve ( "doc/spec.md" ) ] ) ;
task ( "generate-spec" , series ( buildScripts , generateSpec ) ) ;
task ( "generate-spec" ) . description = "Generates a Markdown version of the Language Specification" ;
task ( "clean" , series ( parallel ( cleanTasks ) , cleanBuilt ) ) ;
task ( "clean" ) . description = "Cleans build outputs" ;
const configureNightly = ( ) = > exec ( process . execPath , [ "scripts/configurePrerelease.js" , "dev" , "package.json" , "src/compiler/core.ts" ] )
task ( "configure-nightly" , series ( buildScripts , configureNightly ) ) ;
task ( "configure-nightly" ) . description = "Runs scripts/configurePrerelease.ts to prepare a build for nightly publishing" ;
2019-02-14 02:27:28 +01:00
const configureInsiders = ( ) = > exec ( process . execPath , [ "scripts/configurePrerelease.js" , "insiders" , "package.json" , "src/compiler/core.ts" ] )
task ( "configure-insiders" , series ( buildScripts , configureInsiders ) ) ;
task ( "configure-insiders" ) . description = "Runs scripts/configurePrerelease.ts to prepare a build for insiders publishing" ;
2019-04-22 22:20:34 +02:00
const configureExperimental = ( ) = > exec ( process . execPath , [ "scripts/configurePrerelease.js" , "experimental" , "package.json" , "src/compiler/core.ts" ] )
task ( "configure-experimental" , series ( buildScripts , configureExperimental ) ) ;
task ( "configure-experimental" ) . description = "Runs scripts/configurePrerelease.ts to prepare a build for experimental publishing" ;
2019-01-28 06:56:56 +01:00
const publishNightly = ( ) = > exec ( "npm" , [ "publish" , "--tag" , "next" ] ) ;
task ( "publish-nightly" , series ( task ( "clean" ) , task ( "LKG" ) , task ( "clean" ) , task ( "runtests-parallel" ) , publishNightly ) ) ;
task ( "publish-nightly" ) . description = "Runs `npm publish --tag next` to create a new nightly build on npm" ;
// TODO(rbuckton): The problem with watching in this way is that a change in compiler/ will result
// in cascading changes in other projects that may take differing amounts of times to complete. As
// a result, the watch may accidentally trigger early, so we have to set a significant delay. An
// alternative approach would be to leverage a builder API, or to have 'tsc -b' have an option to
// write some kind of trigger file that indicates build completion that we could listen for instead.
const watchRuntests = ( ) = > watch ( [ "built/local/*.js" , "tests/cases/**/*.ts" , "tests/cases/**/tsconfig.json" ] , { delay : 5000 } , async ( ) = > {
if ( cmdLineOptions . tests || cmdLineOptions . failed ) {
await runConsoleTests ( "built/local/run.js" , "mocha-fivemat-progress-reporter" , /*runInParallel*/ false , /*watchMode*/ true ) ;
}
else {
await runConsoleTests ( "built/local/run.js" , "min" , /*runInParallel*/ true , /*watchMode*/ true ) ;
}
2018-06-19 07:45:13 +02:00
} ) ;
2019-01-28 06:56:56 +01:00
task ( "watch" , series ( preBuild , preTest , parallel ( watchLib , watchDiagnostics , watchServices , watchLssl , watchTests , watchRuntests ) ) ) ;
task ( "watch" ) . description = "Watches for changes and rebuilds and runs tests in parallel." ;
task ( "watch" ) . flags = {
"-t --tests=<regex>" : "Pattern for tests to run. Forces tests to be run in a single worker." ,
" --failed" : "Runs tests listed in '.failed-tests'. Forces tests to be run in a single worker." ,
"-r --reporter=<reporter>" : "The mocha reporter to use." ,
" --keepFailed" : "Keep tests in .failed-tests even if they pass" ,
" --light" : "Run tests in light mode (fewer verifications, but tests run faster)" ,
" --dirty" : "Run tests without first cleaning test output directories" ,
" --stackTraceLimit=<limit>" : "Sets the maximum number of stack frames to display. Use 'full' to show all frames." ,
" --no-color" : "Disables color" ,
" --no-lint" : "Disables lint" ,
" --timeout=<ms>" : "Overrides the default test timeout." ,
" --workers=<number>" : "The number of parallel workers to use." ,
" --built" : "Compile using the built version of the compiler." ,
} ;
task ( "default" , series ( "local" ) ) ;
task ( "default" ) . description = "Runs 'local'" ;
task ( "help" , ( ) = > exec ( "gulp" , [ "--tasks" , "--depth" , "1" , "--sort-tasks" ] , { hidePrompt : true } ) ) ;
task ( "help" ) . description = "Prints the top-level tasks." ;