2016-06-14 21:39:13 +02:00
/// <reference path="scripts/types/ambient.d.ts" />
2016-06-10 02:44:59 +02:00
import * as cp from "child_process" ;
import * as path from "path" ;
import * as fs from "fs" ;
2016-06-14 21:39:13 +02:00
import originalGulp = require ( "gulp" ) ;
import helpMaker = require ( "gulp-help" ) ;
import runSequence = require ( "run-sequence" ) ;
import concat = require ( "gulp-concat" ) ;
2016-06-14 23:41:25 +02:00
import clone = require ( "gulp-clone" ) ;
2016-06-20 23:39:29 +02:00
import newer = require ( "gulp-newer" ) ;
2016-06-14 21:39:13 +02:00
import tsc = require ( "gulp-typescript" ) ;
declare module "gulp-typescript" {
interface Settings {
2016-07-11 19:32:35 +02:00
pretty? : boolean ;
2016-06-24 00:39:21 +02:00
newLine? : string ;
2016-07-11 19:32:35 +02:00
noImplicitThis? : boolean ;
stripInternal? : boolean ;
types? : string [ ] ;
2016-06-14 21:39:13 +02:00
}
2016-06-14 23:51:30 +02:00
interface CompileStream extends NodeJS . ReadWriteStream { } // Either gulp or gulp-typescript has some odd typings which don't reflect reality, making this required
2016-06-14 21:39:13 +02:00
}
import * as insert from "gulp-insert" ;
import * as sourcemaps from "gulp-sourcemaps" ;
2016-07-07 19:16:29 +02:00
import Q = require ( "q" ) ;
2016-06-10 02:44:59 +02:00
declare global {
2016-07-07 19:31:42 +02:00
// `del` further depends on `Promise` (and is also not included), so we just, patch the global scope's Promise to Q's (which we already include in our deps because gulp depends on it)
2016-06-10 02:44:59 +02:00
type Promise < T > = Q . Promise < T > ;
}
2016-06-14 21:39:13 +02:00
import del = require ( "del" ) ;
2016-06-23 21:49:20 +02:00
import mkdirP = require ( "mkdirp" ) ;
2016-06-14 21:39:13 +02:00
import minimist = require ( "minimist" ) ;
2016-06-23 19:12:14 +02:00
import browserify = require ( "browserify" ) ;
2016-06-14 23:41:25 +02:00
import through2 = require ( "through2" ) ;
2016-06-20 23:39:29 +02:00
import merge2 = require ( "merge2" ) ;
2016-06-14 23:41:25 +02:00
import intoStream = require ( "into-stream" ) ;
2016-06-10 02:44:59 +02:00
import * as os from "os" ;
2016-06-14 21:39:13 +02:00
import Linter = require ( "tslint" ) ;
2016-08-11 18:53:38 +02:00
import fold = require ( "travis-fold" ) ;
2016-06-10 02:44:59 +02:00
const gulp = helpMaker ( originalGulp ) ;
2016-06-14 22:09:48 +02:00
const mochaParallel = require ( "./scripts/mocha-parallel.js" ) ;
const { runTestsInParallel } = mochaParallel ;
2016-06-10 02:44:59 +02:00
const cmdLineOptions = minimist ( process . argv . slice ( 2 ) , {
boolean : [ "debug" , "light" , "colors" , "lint" , "soft" ] ,
2016-06-20 23:39:29 +02:00
string : [ "browser" , "tests" , "host" , "reporter" ] ,
2016-06-10 02:44:59 +02:00
alias : {
d : "debug" ,
t : "tests" ,
test : "tests" ,
r : "reporter" ,
color : "colors" ,
f : "files" ,
file : "files"
} ,
default : {
soft : false ,
colors : process.env.colors || process . env . color || true ,
debug : process.env.debug || process . env . d ,
host : process.env.TYPESCRIPT_HOST || process . env . host || "node" ,
browser : process.env.browser || process . env . b || "IE" ,
tests : process.env.test || process . env . tests || process . env . t ,
light : process.env.light || false ,
reporter : process.env.reporter || process . env . r ,
lint : process.env.lint || true ,
files : process.env.f || process . env . file || process . env . files || "" ,
}
} ) ;
function exec ( cmd : string , args : string [ ] , complete : ( ) = > void = ( ( ) = > { } ) , error : ( e : any , status : number ) = > void = ( ( ) = > { } ) ) {
console . log ( ` ${ cmd } ${ args . join ( " " ) } ` ) ;
2016-06-20 23:39:29 +02:00
// TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition
2016-06-23 22:08:27 +02:00
const subshellFlag = isWin ? "/c" : "-c" ;
2016-06-24 20:01:16 +02:00
const command = isWin ? [ possiblyQuote ( cmd ) , . . . args ] : [ ` ${ cmd } ${ args . join ( " " ) } ` ] ;
2016-06-23 22:08:27 +02:00
const ex = cp . spawn ( isWin ? "cmd" : "/bin/sh" , [ subshellFlag , . . . command ] , { stdio : "inherit" , windowsVerbatimArguments : true } as any ) ;
2016-06-10 02:44:59 +02:00
ex . on ( "exit" , ( code ) = > code === 0 ? complete ( ) : error ( /*e*/ undefined , code ) ) ;
ex . on ( "error" , error ) ;
}
2016-06-24 20:01:16 +02:00
function possiblyQuote ( cmd : string ) {
return cmd . indexOf ( " " ) >= 0 ? ` " ${ cmd } " ` : cmd ;
}
2016-06-10 02:44:59 +02:00
let useDebugMode = true ;
let host = cmdLineOptions [ "host" ] ;
// Constants
const compilerDirectory = "src/compiler/" ;
const harnessDirectory = "src/harness/" ;
const libraryDirectory = "src/lib/" ;
const scriptsDirectory = "scripts/" ;
const docDirectory = "doc/" ;
const builtDirectory = "built/" ;
const builtLocalDirectory = "built/local/" ;
const LKGDirectory = "lib/" ;
const copyright = "CopyrightNotice.txt" ;
const compilerFilename = "tsc.js" ;
const LKGCompiler = path . join ( LKGDirectory , compilerFilename ) ;
const builtLocalCompiler = path . join ( builtLocalDirectory , compilerFilename ) ;
const nodeModulesPathPrefix = path . resolve ( "./node_modules/.bin/" ) ;
const isWin = /^win/ . test ( process . platform ) ;
const mocha = path . join ( nodeModulesPathPrefix , "mocha" ) + ( isWin ? ".cmd" : "" ) ;
const es2015LibrarySources = [
"es2015.core.d.ts" ,
"es2015.collection.d.ts" ,
"es2015.generator.d.ts" ,
"es2015.iterable.d.ts" ,
"es2015.promise.d.ts" ,
"es2015.proxy.d.ts" ,
"es2015.reflect.d.ts" ,
"es2015.symbol.d.ts" ,
"es2015.symbol.wellknown.d.ts"
] ;
const es2015LibrarySourceMap = es2015LibrarySources . map ( function ( source ) {
return { target : "lib." + source , sources : [ "header.d.ts" , source ] } ;
} ) ;
const es2016LibrarySource = [ "es2016.array.include.d.ts" ] ;
const es2016LibrarySourceMap = es2016LibrarySource . map ( function ( source ) {
return { target : "lib." + source , sources : [ "header.d.ts" , source ] } ;
} ) ;
const es2017LibrarySource = [
"es2017.object.d.ts" ,
"es2017.sharedmemory.d.ts"
] ;
const es2017LibrarySourceMap = es2017LibrarySource . map ( function ( source ) {
return { target : "lib." + source , sources : [ "header.d.ts" , source ] } ;
} ) ;
const hostsLibrarySources = [ "dom.generated.d.ts" , "webworker.importscripts.d.ts" , "scripthost.d.ts" ] ;
const librarySourceMap = [
// Host library
{ target : "lib.dom.d.ts" , sources : [ "header.d.ts" , "dom.generated.d.ts" ] } ,
{ target : "lib.dom.iterable.d.ts" , sources : [ "header.d.ts" , "dom.iterable.d.ts" ] } ,
{ target : "lib.webworker.d.ts" , sources : [ "header.d.ts" , "webworker.generated.d.ts" ] } ,
{ target : "lib.scripthost.d.ts" , sources : [ "header.d.ts" , "scripthost.d.ts" ] } ,
// JavaScript library
{ target : "lib.es5.d.ts" , sources : [ "header.d.ts" , "es5.d.ts" ] } ,
{ target : "lib.es2015.d.ts" , sources : [ "header.d.ts" , "es2015.d.ts" ] } ,
{ target : "lib.es2016.d.ts" , sources : [ "header.d.ts" , "es2016.d.ts" ] } ,
{ target : "lib.es2017.d.ts" , sources : [ "header.d.ts" , "es2017.d.ts" ] } ,
// JavaScript + all host library
{ target : "lib.d.ts" , sources : [ "header.d.ts" , "es5.d.ts" ] . concat ( hostsLibrarySources ) } ,
{ target : "lib.es6.d.ts" , sources : [ "header.d.ts" , "es5.d.ts" ] . concat ( es2015LibrarySources , hostsLibrarySources , "dom.iterable.d.ts" ) }
] . concat ( es2015LibrarySourceMap , es2016LibrarySourceMap , es2017LibrarySourceMap ) ;
const libraryTargets = librarySourceMap . map ( function ( f ) {
return path . join ( builtLocalDirectory , f . target ) ;
} ) ;
for ( const i in libraryTargets ) {
const entry = librarySourceMap [ i ] ;
const target = libraryTargets [ i ] ;
const sources = [ copyright ] . concat ( entry . sources . map ( function ( s ) {
return path . join ( libraryDirectory , s ) ;
} ) ) ;
gulp . task ( target , false , [ ] , function ( ) {
2016-06-20 23:39:29 +02:00
return gulp . src ( sources )
. pipe ( newer ( target ) )
2016-06-23 21:39:20 +02:00
. pipe ( concat ( target , { newLine : "" } ) )
2016-06-20 23:39:29 +02:00
. pipe ( gulp . dest ( "." ) ) ;
2016-06-10 02:44:59 +02:00
} ) ;
}
const configureNightlyJs = path . join ( scriptsDirectory , "configureNightly.js" ) ;
const configureNightlyTs = path . join ( scriptsDirectory , "configureNightly.ts" ) ;
const packageJson = "package.json" ;
const programTs = path . join ( compilerDirectory , "program.ts" ) ;
function needsUpdate ( source : string | string [ ] , dest : string | string [ ] ) : boolean {
if ( typeof source === "string" && typeof dest === "string" ) {
if ( fs . existsSync ( dest ) ) {
const { mtime : outTime } = fs . statSync ( dest ) ;
const { mtime : inTime } = fs . statSync ( source ) ;
if ( + inTime <= + outTime ) {
return false ;
}
}
}
else if ( typeof source === "string" && typeof dest !== "string" ) {
const { mtime : inTime } = fs . statSync ( source ) ;
for ( const filepath of dest ) {
if ( fs . existsSync ( filepath ) ) {
const { mtime : outTime } = fs . statSync ( filepath ) ;
if ( + inTime > + outTime ) {
return true ;
}
}
else {
return true ;
}
}
return false ;
}
else if ( typeof source !== "string" && typeof dest === "string" ) {
if ( fs . existsSync ( dest ) ) {
const { mtime : outTime } = fs . statSync ( dest ) ;
for ( const filepath of source ) {
if ( fs . existsSync ( filepath ) ) {
const { mtime : inTime } = fs . statSync ( filepath ) ;
if ( + inTime > + outTime ) {
return true ;
}
}
else {
return true ;
}
}
return false ;
}
}
else if ( typeof source !== "string" && typeof dest !== "string" ) {
for ( let i = 0 ; i < source . length ; i ++ ) {
if ( ! dest [ i ] ) {
continue ;
}
if ( fs . existsSync ( dest [ i ] ) ) {
const { mtime : outTime } = fs . statSync ( dest [ i ] ) ;
const { mtime : inTime } = fs . statSync ( source [ i ] ) ;
if ( + inTime > + outTime ) {
return true ;
}
}
else {
return true ;
}
}
return false ;
}
return true ;
}
2016-06-20 23:39:29 +02:00
function getCompilerSettings ( base : tsc.Settings , useBuiltCompiler? : boolean ) : tsc . Settings {
2016-06-14 23:41:25 +02:00
const copy : tsc.Settings = { } ;
2016-07-11 18:30:58 +02:00
copy . noEmitOnError = true ;
2016-07-11 19:32:35 +02:00
copy . noImplicitAny = true ;
copy . noImplicitThis = true ;
copy . pretty = true ;
copy . types = [ ] ;
2016-06-14 23:41:25 +02:00
for ( const key in base ) {
copy [ key ] = base [ key ] ;
}
2016-06-14 21:39:13 +02:00
if ( ! useDebugMode ) {
if ( copy . removeComments === undefined ) copy . removeComments = true ;
2016-06-24 00:39:21 +02:00
copy . newLine = "lf" ;
2016-06-14 21:39:13 +02:00
}
else {
copy . preserveConstEnums = true ;
}
2016-06-20 23:39:29 +02:00
if ( useBuiltCompiler === true ) {
2016-06-14 21:39:13 +02:00
copy . typescript = require ( "./built/local/typescript.js" ) ;
}
2016-06-20 23:39:29 +02:00
else if ( useBuiltCompiler === false ) {
2016-06-14 21:39:13 +02:00
copy . typescript = require ( "./lib/typescript.js" ) ;
}
return copy ;
2016-06-10 02:44:59 +02:00
}
2016-06-14 21:39:13 +02:00
gulp . task ( configureNightlyJs , false , [ ] , ( ) = > {
const settings : tsc.Settings = {
declaration : false ,
removeComments : true ,
noResolve : false ,
stripInternal : false ,
} ;
return gulp . src ( configureNightlyTs )
. pipe ( sourcemaps . init ( ) )
. pipe ( tsc ( settings ) )
. pipe ( sourcemaps . write ( path . dirname ( configureNightlyJs ) ) )
2016-06-14 23:41:25 +02:00
. pipe ( gulp . dest ( path . dirname ( configureNightlyJs ) ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
// Nightly management tasks
gulp . task ( "configure-nightly" , "Runs scripts/configureNightly.ts to prepare a build for nightly publishing" , [ configureNightlyJs ] , ( done ) = > {
exec ( host , [ configureNightlyJs , packageJson , programTs ] , done , done ) ;
} ) ;
gulp . task ( "publish-nightly" , "Runs `npm publish --tag next` to create a new nightly build on npm" , [ "LKG" ] , ( ) = > {
return runSequence ( "clean" , "useDebugMode" , "runtests" , ( done ) = > {
exec ( "npm" , [ "publish" , "--tag" , "next" ] , done , done ) ;
} ) ;
} ) ;
const importDefinitelyTypedTestsDirectory = path . join ( scriptsDirectory , "importDefinitelyTypedTests" ) ;
const importDefinitelyTypedTestsJs = path . join ( importDefinitelyTypedTestsDirectory , "importDefinitelyTypedTests.js" ) ;
const importDefinitelyTypedTestsTs = path . join ( importDefinitelyTypedTestsDirectory , "importDefinitelyTypedTests.ts" ) ;
2016-06-14 21:39:13 +02:00
gulp . task ( importDefinitelyTypedTestsJs , false , [ ] , ( ) = > {
const settings : tsc.Settings = getCompilerSettings ( {
declaration : false ,
removeComments : true ,
noResolve : false ,
stripInternal : false ,
outFile : importDefinitelyTypedTestsJs
} , /*useBuiltCompiler*/ false ) ;
return gulp . src ( importDefinitelyTypedTestsTs )
. pipe ( sourcemaps . init ( ) )
. pipe ( tsc ( settings ) )
2016-06-14 22:09:48 +02:00
. pipe ( sourcemaps . write ( "." ) )
2016-06-14 23:41:25 +02:00
. pipe ( gulp . dest ( "." ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
gulp . task ( "importDefinitelyTypedTests" , "Runs scripts/importDefinitelyTypedTests/importDefinitelyTypedTests.ts to copy DT's tests to the TS-internal RWC tests" , [ importDefinitelyTypedTestsJs ] , ( done ) = > {
exec ( host , [ importDefinitelyTypedTestsJs , "./" , "../DefinitelyTyped" ] , done , done ) ;
} ) ;
gulp . task ( "lib" , "Builds the library targets" , libraryTargets ) ;
// Generate diagnostics
const processDiagnosticMessagesJs = path . join ( scriptsDirectory , "processDiagnosticMessages.js" ) ;
const processDiagnosticMessagesTs = path . join ( scriptsDirectory , "processDiagnosticMessages.ts" ) ;
const diagnosticMessagesJson = path . join ( compilerDirectory , "diagnosticMessages.json" ) ;
const diagnosticInfoMapTs = path . join ( compilerDirectory , "diagnosticInformationMap.generated.ts" ) ;
const generatedDiagnosticMessagesJSON = path . join ( compilerDirectory , "diagnosticMessages.generated.json" ) ;
const builtGeneratedDiagnosticMessagesJSON = path . join ( builtLocalDirectory , "diagnosticMessages.generated.json" ) ;
// processDiagnosticMessages script
2016-06-14 21:39:13 +02:00
gulp . task ( processDiagnosticMessagesJs , false , [ ] , ( ) = > {
const settings : tsc.Settings = getCompilerSettings ( {
declaration : false ,
removeComments : true ,
noResolve : false ,
stripInternal : false ,
2016-06-14 22:09:48 +02:00
outFile : processDiagnosticMessagesJs
2016-06-14 21:39:13 +02:00
} , /*useBuiltCompiler*/ false ) ;
2016-06-14 22:09:48 +02:00
return gulp . src ( processDiagnosticMessagesTs )
2016-06-20 23:39:29 +02:00
. pipe ( newer ( processDiagnosticMessagesJs ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
. pipe ( tsc ( settings ) )
2016-06-14 22:09:48 +02:00
. pipe ( sourcemaps . write ( "." ) )
2016-06-14 23:41:25 +02:00
. pipe ( gulp . dest ( "." ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
// The generated diagnostics map; built for the compiler and for the "generate-diagnostics" task
gulp . task ( diagnosticInfoMapTs , [ processDiagnosticMessagesJs ] , ( done ) = > {
if ( needsUpdate ( diagnosticMessagesJson , [ generatedDiagnosticMessagesJSON , diagnosticInfoMapTs ] ) ) {
exec ( host , [ processDiagnosticMessagesJs , diagnosticMessagesJson ] , done , done ) ;
}
else {
done ( ) ;
}
} ) ;
gulp . task ( builtGeneratedDiagnosticMessagesJSON , [ diagnosticInfoMapTs ] , ( done ) = > {
if ( fs . existsSync ( builtLocalDirectory ) && needsUpdate ( generatedDiagnosticMessagesJSON , builtGeneratedDiagnosticMessagesJSON ) ) {
fs . writeFileSync ( builtGeneratedDiagnosticMessagesJSON , fs . readFileSync ( generatedDiagnosticMessagesJSON ) ) ;
}
done ( ) ;
} ) ;
gulp . task ( "generate-diagnostics" , "Generates a diagnostic file in TypeScript based on an input JSON file" , [ diagnosticInfoMapTs ] ) ;
2016-06-15 03:00:25 +02:00
const servicesFile = path . join ( builtLocalDirectory , "typescriptServices.js" ) ;
const standaloneDefinitionsFile = path . join ( builtLocalDirectory , "typescriptServices.d.ts" ) ;
const nodePackageFile = path . join ( builtLocalDirectory , "typescript.js" ) ;
const nodeDefinitionsFile = path . join ( builtLocalDirectory , "typescript.d.ts" ) ;
const nodeStandaloneDefinitionsFile = path . join ( builtLocalDirectory , "typescript_standalone.d.ts" ) ;
2016-06-22 03:22:30 +02:00
let copyrightContent : string ;
function prependCopyright ( outputCopyright : boolean = ! useDebugMode ) {
return insert . prepend ( outputCopyright ? ( copyrightContent || ( copyrightContent = fs . readFileSync ( copyright ) . toString ( ) ) ) : "" ) ;
}
2016-06-21 02:54:38 +02:00
2016-06-15 03:00:25 +02:00
gulp . task ( builtLocalCompiler , false , [ servicesFile ] , ( ) = > {
2016-06-20 23:39:29 +02:00
const localCompilerProject = tsc . createProject ( "src/compiler/tsconfig.json" , getCompilerSettings ( { } , /*useBuiltCompiler*/ true ) ) ;
return localCompilerProject . src ( )
. pipe ( newer ( builtLocalCompiler ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
2016-06-20 23:39:29 +02:00
. pipe ( tsc ( localCompilerProject ) )
2016-06-22 03:22:30 +02:00
. pipe ( prependCopyright ( ) )
2016-06-20 23:39:29 +02:00
. pipe ( sourcemaps . write ( "." ) )
2016-06-14 23:41:25 +02:00
. pipe ( gulp . dest ( builtLocalDirectory ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
2016-06-21 02:54:38 +02:00
gulp . task ( servicesFile , false , [ "lib" , "generate-diagnostics" ] , ( ) = > {
2016-06-24 00:51:12 +02:00
const servicesProject = tsc . createProject ( "src/services/tsconfig.json" , getCompilerSettings ( { removeComments : false } , /*useBuiltCompiler*/ false ) ) ;
2016-06-20 23:39:29 +02:00
const { js , dts } = servicesProject . src ( )
. pipe ( newer ( servicesFile ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
2016-06-20 23:39:29 +02:00
. pipe ( tsc ( servicesProject ) ) ;
2016-06-22 03:22:30 +02:00
const completedJs = js . pipe ( prependCopyright ( ) )
2016-06-21 02:54:38 +02:00
. pipe ( sourcemaps . write ( "." ) ) ;
2016-06-22 03:22:30 +02:00
const completedDts = dts . pipe ( prependCopyright ( /*outputCopyright*/ true ) )
2016-06-21 02:54:38 +02:00
. pipe ( insert . transform ( ( contents , file ) = > {
file . path = standaloneDefinitionsFile ;
return contents . replace ( /^(\s*)(export )?const enum (\S+) {(\s*)$/gm , "$1$2enum $3 {$4" ) ;
} ) ) ;
return merge2 ( [
completedJs ,
completedJs . pipe ( clone ( ) )
. pipe ( insert . transform ( ( content , file ) = > ( file . path = nodePackageFile , content ) ) ) ,
completedDts ,
completedDts . pipe ( clone ( ) )
. pipe ( insert . transform ( ( content , file ) = > {
file . path = nodeDefinitionsFile ;
return content + "\r\nexport = ts;" ;
} ) )
. pipe ( gulp . dest ( builtLocalDirectory ) ) ,
completedDts . pipe ( clone ( ) )
. pipe ( insert . transform ( ( content , file ) = > {
file . path = nodeStandaloneDefinitionsFile ;
return content . replace ( /declare (namespace|module) ts/g , 'declare module "typescript"' ) ;
} ) )
] ) . pipe ( gulp . dest ( builtLocalDirectory ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
const serverFile = path . join ( builtLocalDirectory , "tsserver.js" ) ;
2016-06-14 21:39:13 +02:00
2016-06-14 23:41:25 +02:00
gulp . task ( serverFile , false , [ servicesFile ] , ( ) = > {
2016-06-20 23:39:29 +02:00
const serverProject = tsc . createProject ( "src/server/tsconfig.json" , getCompilerSettings ( { } , /*useBuiltCompiler*/ true ) ) ;
return serverProject . src ( )
. pipe ( newer ( serverFile ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
2016-06-20 23:39:29 +02:00
. pipe ( tsc ( serverProject ) )
2016-06-22 03:22:30 +02:00
. pipe ( prependCopyright ( ) )
2016-06-20 23:39:29 +02:00
. pipe ( sourcemaps . write ( "." ) )
. pipe ( gulp . dest ( builtLocalDirectory ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
const tsserverLibraryFile = path . join ( builtLocalDirectory , "tsserverlibrary.js" ) ;
const tsserverLibraryDefinitionFile = path . join ( builtLocalDirectory , "tsserverlibrary.d.ts" ) ;
2016-06-14 21:39:13 +02:00
2016-06-15 02:31:25 +02:00
gulp . task ( tsserverLibraryFile , false , [ servicesFile ] , ( done ) = > {
2016-07-12 01:00:16 +02:00
const serverLibraryProject = tsc . createProject ( "src/server/tsconfig.library.json" , getCompilerSettings ( { } , /*useBuiltCompiler*/ true ) ) ;
const { js , dts } : { js : NodeJS.ReadableStream , dts : NodeJS.ReadableStream } = serverLibraryProject . src ( )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
2016-06-20 23:39:29 +02:00
. pipe ( newer ( tsserverLibraryFile ) )
2016-07-12 01:00:16 +02:00
. pipe ( tsc ( serverLibraryProject ) ) ;
2016-06-20 23:39:29 +02:00
return merge2 ( [
2016-06-22 03:22:30 +02:00
js . pipe ( prependCopyright ( ) )
2016-06-20 23:39:29 +02:00
. pipe ( sourcemaps . write ( "." ) )
2016-07-12 01:00:16 +02:00
. pipe ( gulp . dest ( builtLocalDirectory ) ) ,
2016-06-22 03:22:30 +02:00
dts . pipe ( prependCopyright ( ) )
2016-07-12 01:00:16 +02:00
. pipe ( gulp . dest ( builtLocalDirectory ) )
2016-06-20 23:39:29 +02:00
] ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
gulp . task ( "lssl" , "Builds language service server library" , [ tsserverLibraryFile ] ) ;
2016-08-05 23:16:29 +02:00
gulp . task ( "local" , "Builds the full compiler and services" , [ builtLocalCompiler , servicesFile , serverFile , builtGeneratedDiagnosticMessagesJSON , tsserverLibraryFile ] ) ;
2016-06-10 02:44:59 +02:00
gulp . task ( "tsc" , "Builds only the compiler" , [ builtLocalCompiler ] ) ;
// Generate Markdown spec
const word2mdJs = path . join ( scriptsDirectory , "word2md.js" ) ;
const word2mdTs = path . join ( scriptsDirectory , "word2md.ts" ) ;
const specWord = path . join ( docDirectory , "TypeScript Language Specification.docx" ) ;
const specMd = path . join ( docDirectory , "spec.md" ) ;
2016-06-14 21:39:13 +02:00
gulp . task ( word2mdJs , false , [ ] , ( ) = > {
const settings : tsc.Settings = getCompilerSettings ( {
outFile : word2mdJs
} , /*useBuiltCompiler*/ false ) ;
return gulp . src ( word2mdTs )
2016-06-20 23:39:29 +02:00
. pipe ( newer ( word2mdJs ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
. pipe ( tsc ( settings ) )
2016-06-14 22:09:48 +02:00
. pipe ( sourcemaps . write ( "." ) )
. pipe ( gulp . dest ( "." ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
gulp . task ( specMd , false , [ word2mdJs ] , ( done ) = > {
const specWordFullPath = path . resolve ( specWord ) ;
const specMDFullPath = path . resolve ( specMd ) ;
const cmd = "cscript //nologo " + word2mdJs + " \"" + specWordFullPath + "\" " + "\"" + specMDFullPath + "\"" ;
console . log ( cmd ) ;
cp . exec ( cmd , function ( ) {
done ( ) ;
} ) ;
} ) ;
gulp . task ( "generate-spec" , "Generates a Markdown version of the Language Specification" , [ specMd ] ) ;
gulp . task ( "clean" , "Cleans the compiler output, declare files, and tests" , [ ] , ( ) = > {
return del ( [ builtDirectory ] ) ;
} ) ;
2016-06-24 00:39:21 +02:00
gulp . task ( "useDebugMode" , false , [ ] , ( done ) = > { useDebugMode = true ; done ( ) ; } ) ;
gulp . task ( "dontUseDebugMode" , false , [ ] , ( done ) = > { useDebugMode = false ; done ( ) ; } ) ;
2016-06-10 02:44:59 +02:00
gulp . task ( "VerifyLKG" , false , [ ] , ( ) = > {
const expectedFiles = [ builtLocalCompiler , servicesFile , serverFile , nodePackageFile , nodeDefinitionsFile , standaloneDefinitionsFile , tsserverLibraryFile , tsserverLibraryDefinitionFile ] . concat ( libraryTargets ) ;
const missingFiles = expectedFiles . filter ( function ( f ) {
return ! fs . existsSync ( f ) ;
} ) ;
if ( missingFiles . length > 0 ) {
throw new Error ( "Cannot replace the LKG unless all built targets are present in directory " + builtLocalDirectory +
". The following files are missing:\n" + missingFiles . join ( "\n" ) ) ;
}
// Copy all the targets into the LKG directory
return gulp . src ( expectedFiles ) . pipe ( gulp . dest ( LKGDirectory ) ) ;
} ) ;
2016-08-05 23:16:29 +02:00
gulp . task ( "LKGInternal" , false , [ "lib" , "local" ] ) ;
2016-06-15 02:40:33 +02:00
2016-06-24 00:48:09 +02:00
gulp . task ( "LKG" , "Makes a new LKG out of the built js files" , [ "clean" , "dontUseDebugMode" ] , ( ) = > {
2016-06-15 02:40:33 +02:00
return runSequence ( "LKGInternal" , "VerifyLKG" ) ;
2016-06-10 02:44:59 +02:00
} ) ;
// Task to build the tests infrastructure using the built compiler
const run = path . join ( builtLocalDirectory , "run.js" ) ;
2016-06-15 01:56:47 +02:00
gulp . task ( run , false , [ servicesFile ] , ( ) = > {
2016-07-12 01:00:16 +02:00
const testProject = tsc . createProject ( "src/harness/tsconfig.json" , getCompilerSettings ( { } , /*useBuiltCompiler*/ true ) ) ;
return testProject . src ( )
2016-06-20 23:39:29 +02:00
. pipe ( newer ( run ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
2016-07-12 01:00:16 +02:00
. pipe ( tsc ( testProject ) )
2016-06-23 21:39:20 +02:00
. pipe ( sourcemaps . write ( "." , { includeContent : false , sourceRoot : "../../" } ) )
2016-07-12 01:00:16 +02:00
. pipe ( gulp . dest ( builtLocalDirectory ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
const internalTests = "internal/" ;
const localBaseline = "tests/baselines/local/" ;
const refBaseline = "tests/baselines/reference/" ;
const localRwcBaseline = path . join ( internalTests , "baselines/rwc/local" ) ;
const refRwcBaseline = path . join ( internalTests , "baselines/rwc/reference" ) ;
const localTest262Baseline = path . join ( internalTests , "baselines/test262/local" ) ;
const refTest262Baseline = path . join ( internalTests , "baselines/test262/reference" ) ;
2016-06-14 22:09:48 +02:00
gulp . task ( "tests" , "Builds the test infrastructure using the built compiler" , [ run ] ) ;
2016-06-10 02:44:59 +02:00
gulp . task ( "tests-debug" , "Builds the test sources and automation in debug mode" , ( ) = > {
return runSequence ( "useDebugMode" , "tests" ) ;
} ) ;
function deleteTemporaryProjectOutput() {
return del ( path . join ( localBaseline , "projectOutput/" ) ) ;
}
let savedNodeEnv : string ;
function setNodeEnvToDevelopment() {
savedNodeEnv = process . env . NODE_ENV ;
process . env . NODE_ENV = "development" ;
}
function restoreSavedNodeEnv() {
process . env . NODE_ENV = savedNodeEnv ;
}
let testTimeout = 20000 ;
function runConsoleTests ( defaultReporter : string , runInParallel : boolean , done : ( e? : any ) = > void ) {
const lintFlag = cmdLineOptions [ "lint" ] ;
cleanTestDirs ( ( err ) = > {
if ( err ) { console . error ( err ) ; failWithStatus ( err , 1 ) ; }
const debug = cmdLineOptions [ "debug" ] ;
const tests = cmdLineOptions [ "tests" ] ;
const light = cmdLineOptions [ "light" ] ;
const testConfigFile = "test.config" ;
if ( fs . existsSync ( testConfigFile ) ) {
fs . unlinkSync ( testConfigFile ) ;
}
let workerCount , taskConfigsFolder ;
if ( runInParallel ) {
// generate name to store task configuration files
const prefix = os . tmpdir ( ) + "/ts-tests" ;
let i = 1 ;
do {
taskConfigsFolder = prefix + i ;
i ++ ;
} while ( fs . existsSync ( taskConfigsFolder ) ) ;
fs . mkdirSync ( taskConfigsFolder ) ;
workerCount = process . env . workerCount || os . cpus ( ) . length ;
}
if ( tests || light || taskConfigsFolder ) {
writeTestConfigFile ( tests , light , taskConfigsFolder , workerCount ) ;
}
if ( tests && tests . toLocaleLowerCase ( ) === "rwc" ) {
2016-07-01 18:59:30 +02:00
testTimeout = 400000 ;
2016-06-10 02:44:59 +02:00
}
const colors = cmdLineOptions [ "colors" ] ;
const reporter = cmdLineOptions [ "reporter" ] || defaultReporter ;
// timeout normally isn"t necessary but Travis-CI has been timing out on compiler baselines occasionally
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
if ( ! runInParallel ) {
const args = [ ] ;
if ( debug ) {
args . push ( "--debug-brk" ) ;
}
args . push ( "-R" , reporter ) ;
if ( tests ) {
args . push ( "-g" , ` " ${ tests } " ` ) ;
}
if ( colors ) {
args . push ( "--colors" ) ;
}
else {
args . push ( "--no-colors" ) ;
}
args . push ( "-t" , testTimeout ) ;
args . push ( run ) ;
setNodeEnvToDevelopment ( ) ;
exec ( mocha , args , lintThenFinish , function ( e , status ) {
finish ( e , status ) ;
} ) ;
}
else {
// run task to load all tests and partition them between workers
const args = [ ] ;
args . push ( "-R" , "min" ) ;
if ( colors ) {
args . push ( "--colors" ) ;
}
else {
args . push ( "--no-colors" ) ;
}
args . push ( run ) ;
setNodeEnvToDevelopment ( ) ;
runTestsInParallel ( taskConfigsFolder , run , { testTimeout : testTimeout , noColors : colors === " --no-colors " } , function ( err ) {
// last worker clean everything and runs linter in case if there were no errors
del ( taskConfigsFolder ) . then ( ( ) = > {
if ( ! err ) {
lintThenFinish ( ) ;
}
else {
finish ( err ) ;
}
} ) ;
} ) ;
}
} ) ;
function failWithStatus ( err? : any , status? : number ) {
if ( err ) {
console . log ( err ) ;
}
done ( err || status ) ;
process . exit ( status ) ;
}
function lintThenFinish() {
if ( lintFlag ) {
runSequence ( "lint" , finish ) ;
}
else {
finish ( ) ;
}
}
function finish ( error? : any , errorStatus? : number ) {
restoreSavedNodeEnv ( ) ;
deleteTemporaryProjectOutput ( ) . then ( ( ) = > {
if ( error !== undefined || errorStatus !== undefined ) {
failWithStatus ( error , errorStatus ) ;
}
else {
done ( ) ;
}
} ) ;
}
}
gulp . task ( "runtests-parallel" , "Runs all the tests in parallel using the built run.js file. Optional arguments are: --t[ests]=category1|category2|... --d[ebug]=true." , [ "build-rules" , "tests" ] , ( done ) = > {
runConsoleTests ( "min" , /*runInParallel*/ true , done ) ;
} ) ;
gulp . task ( "runtests" ,
"Runs the tests using the built run.js file. Optional arguments are: --t[ests]=regex --r[eporter]=[list|spec|json|<more>] --d[ebug]=true --color[s]=false --lint=true." ,
[ "build-rules" , "tests" ] ,
( done ) = > {
runConsoleTests ( "mocha-fivemat-progress-reporter" , /*runInParallel*/ false , done ) ;
} ) ;
const nodeServerOutFile = "tests/webTestServer.js" ;
const nodeServerInFile = "tests/webTestServer.ts" ;
2016-06-14 23:41:25 +02:00
gulp . task ( nodeServerOutFile , false , [ servicesFile ] , ( ) = > {
2016-06-23 21:39:20 +02:00
const settings : tsc.Settings = getCompilerSettings ( { module : "commonjs" } , /*useBuiltCompiler*/ true ) ;
2016-06-14 21:39:13 +02:00
return gulp . src ( nodeServerInFile )
2016-06-20 23:39:29 +02:00
. pipe ( newer ( nodeServerOutFile ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
. pipe ( tsc ( settings ) )
2016-06-14 23:41:25 +02:00
. pipe ( sourcemaps . write ( "." ) )
2016-06-14 21:39:13 +02:00
. pipe ( gulp . dest ( path . dirname ( nodeServerOutFile ) ) ) ;
} ) ;
2016-06-10 02:44:59 +02:00
2016-07-16 01:55:16 +02:00
import convertMap = require ( "convert-source-map" ) ;
import sorcery = require ( "sorcery" ) ;
declare module "convert-source-map" {
export function fromSource ( source : string , largeSource? : boolean ) : SourceMapConverter ;
}
2016-06-14 23:41:25 +02:00
gulp . task ( "browserify" , "Runs browserify on run.js to produce a file suitable for running tests in the browser" , [ servicesFile ] , ( done ) = > {
2016-07-12 01:00:16 +02:00
const testProject = tsc . createProject ( "src/harness/tsconfig.json" , getCompilerSettings ( { outFile : "built/local/bundle.js" } , /*useBuiltCompiler*/ true ) ) ;
return testProject . src ( )
2016-06-20 23:39:29 +02:00
. pipe ( newer ( "built/local/bundle.js" ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
2016-07-12 01:00:16 +02:00
. pipe ( tsc ( testProject ) )
2016-06-14 23:41:25 +02:00
. pipe ( through2 . obj ( ( file , enc , next ) = > {
2016-07-16 01:55:16 +02:00
const originalMap = file . sourceMap ;
const prebundledContent = file . contents . toString ( ) ;
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
2016-07-22 22:56:50 +02:00
originalMap . sources = originalMap . sources . map ( s = > path . resolve ( "src" , s ) ) ;
2016-07-16 01:55:16 +02:00
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
originalMap . file = "built/local/_stream_0.js" ;
browserify ( intoStream ( file . contents ) , { debug : true } )
2016-06-14 23:41:25 +02:00
. bundle ( ( err , res ) = > {
// assumes file.contents is a Buffer
2016-07-16 01:55:16 +02:00
const maps = JSON . parse ( convertMap . fromSource ( res . toString ( ) , /*largeSource*/ true ) . toJSON ( ) ) ;
delete maps . sourceRoot ;
maps . sources = maps . sources . map ( s = > path . resolve ( s === "_stream_0.js" ? "built/local/_stream_0.js" : s ) ) ;
// Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths)
file . contents = new Buffer ( convertMap . removeComments ( res . toString ( ) ) ) ;
const chain = sorcery . loadSync ( "built/local/bundle.js" , {
content : {
"built/local/_stream_0.js" : prebundledContent ,
"built/local/bundle.js" : file . contents . toString ( )
} ,
sourcemaps : {
"built/local/_stream_0.js" : originalMap ,
"built/local/bundle.js" : maps ,
}
} ) ;
const finalMap = chain . apply ( ) ;
file . sourceMap = finalMap ;
2016-06-14 23:41:25 +02:00
next ( undefined , file ) ;
} ) ;
2016-06-14 21:39:13 +02:00
} ) )
2016-07-16 01:55:16 +02:00
. pipe ( sourcemaps . write ( "." , { includeContent : false } ) )
2016-06-14 22:09:48 +02:00
. pipe ( gulp . dest ( "." ) ) ;
2016-06-10 02:44:59 +02:00
} ) ;
function cleanTestDirs ( done : ( e? : any ) = > void ) {
// Clean the local baselines & Rwc baselines directories
del ( [
localBaseline ,
localRwcBaseline ,
] ) . then ( ( ) = > {
mkdirP ( localRwcBaseline , ( err ) = > {
if ( err ) done ( err ) ;
mkdirP ( localTest262Baseline , ( ) = > {
if ( err ) done ( err ) ;
mkdirP ( localBaseline , ( err ) = > done ( err ) ) ;
} ) ;
} ) ;
} ) ;
}
// used to pass data from jake command line directly to run.js
function writeTestConfigFile ( tests : string , light : boolean , taskConfigsFolder? : string , workerCount? : number ) {
const testConfigContents = JSON . stringify ( { test : tests ? [ tests ] : undefined , light : light , workerCount : workerCount , taskConfigsFolder : taskConfigsFolder } ) ;
console . log ( "Running tests with config: " + testConfigContents ) ;
fs . writeFileSync ( "test.config" , testConfigContents ) ;
}
2016-07-28 22:40:05 +02:00
gulp . task ( "runtests-browser" , "Runs the tests using the built run.js file like 'gulp runtests'. Syntax is gulp runtests-browser. Additional optional parameters --tests=[regex], --browser=[chrome|IE]" , [ "browserify" , nodeServerOutFile ] , ( done ) = > {
2016-06-10 02:44:59 +02:00
cleanTestDirs ( ( err ) = > {
if ( err ) { console . error ( err ) ; done ( err ) ; process . exit ( 1 ) ; }
host = "node" ;
2016-06-14 23:41:25 +02:00
const tests = cmdLineOptions [ "tests" ] ;
2016-06-10 02:44:59 +02:00
const light = cmdLineOptions [ "light" ] ;
const testConfigFile = "test.config" ;
if ( fs . existsSync ( testConfigFile ) ) {
fs . unlinkSync ( testConfigFile ) ;
}
if ( tests || light ) {
writeTestConfigFile ( tests , light ) ;
}
const args = [ nodeServerOutFile ] ;
if ( cmdLineOptions [ "browser" ] ) {
args . push ( cmdLineOptions [ "browser" ] ) ;
}
if ( tests ) {
args . push ( JSON . stringify ( tests ) ) ;
}
exec ( host , args , done , done ) ;
} ) ;
} ) ;
2016-06-14 23:56:37 +02:00
gulp . task ( "generate-code-coverage" , "Generates code coverage data via istanbul" , [ "tests" ] , ( done ) = > {
2016-06-10 02:44:59 +02:00
exec ( "istanbul" , [ "cover" , "node_modules/mocha/bin/_mocha" , "--" , "-R" , "min" , "-t" , testTimeout . toString ( ) , run ] , done , done ) ;
} ) ;
function getDiffTool() {
const program = process . env [ "DIFF" ] ;
if ( ! program ) {
2016-06-14 23:56:37 +02:00
console . error ( "Add the 'DIFF' environment variable to the path of the program you want to use." ) ;
2016-06-10 02:44:59 +02:00
process . exit ( 1 ) ;
}
return program ;
}
2016-06-14 23:56:37 +02:00
gulp . task ( "diff" , "Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable" , ( done ) = > {
2016-06-10 02:44:59 +02:00
exec ( getDiffTool ( ) , [ refBaseline , localBaseline ] , done , done ) ;
} ) ;
2016-06-14 23:56:37 +02:00
gulp . task ( "diff-rwc" , "Diffs the RWC baselines using the diff tool specified by the 'DIFF' environment variable" , ( done ) = > {
2016-06-10 02:44:59 +02:00
exec ( getDiffTool ( ) , [ refRwcBaseline , localRwcBaseline ] , done , done ) ;
} ) ;
gulp . task ( "baseline-accept" , "Makes the most recent test results the new baseline, overwriting the old baseline" , ( done ) = > {
const softAccept = cmdLineOptions [ "soft" ] ;
if ( ! softAccept ) {
del ( refBaseline ) . then ( ( ) = > {
fs . renameSync ( localBaseline , refBaseline ) ;
done ( ) ;
} , done ) ;
}
else {
gulp . src ( localBaseline )
. pipe ( gulp . dest ( refBaseline ) )
. on ( "end" , ( ) = > {
del ( path . join ( refBaseline , "local" ) ) . then ( ( ) = > done ( ) , done ) ;
} ) ;
}
} ) ;
gulp . task ( "baseline-accept-rwc" , "Makes the most recent rwc test results the new baseline, overwriting the old baseline" , ( ) = > {
return del ( refRwcBaseline ) . then ( ( ) = > {
fs . renameSync ( localRwcBaseline , refRwcBaseline ) ;
} ) ;
} ) ;
gulp . task ( "baseline-accept-test262" , "Makes the most recent test262 test results the new baseline, overwriting the old baseline" , ( ) = > {
return del ( refTest262Baseline ) . then ( ( ) = > {
fs . renameSync ( localTest262Baseline , refTest262Baseline ) ;
} ) ;
} ) ;
// Webhost
const webhostPath = "tests/webhost/webtsc.ts" ;
const webhostJsPath = "tests/webhost/webtsc.js" ;
2016-06-14 23:41:25 +02:00
gulp . task ( webhostJsPath , false , [ servicesFile ] , ( ) = > {
2016-06-14 21:39:13 +02:00
const settings : tsc.Settings = getCompilerSettings ( {
outFile : webhostJsPath
} , /*useBuiltCompiler*/ true ) ;
return gulp . src ( webhostPath )
2016-06-20 23:39:29 +02:00
. pipe ( newer ( webhostJsPath ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
. pipe ( tsc ( settings ) )
2016-06-14 22:09:48 +02:00
. pipe ( sourcemaps . write ( "." ) )
2016-06-14 21:39:13 +02:00
. pipe ( gulp . dest ( path . dirname ( webhostJsPath ) ) ) ;
} ) ;
2016-06-10 02:44:59 +02:00
gulp . task ( "webhost" , "Builds the tsc web host" , [ webhostJsPath ] , ( ) = > {
return gulp . src ( path . join ( builtLocalDirectory , "lib.d.ts" ) ) . pipe ( gulp . dest ( "tests/webhost/" ) ) ;
} ) ;
// Perf compiler
const perftscPath = "tests/perftsc.ts" ;
const perftscJsPath = "built/local/perftsc.js" ;
2016-06-14 23:41:25 +02:00
gulp . task ( perftscJsPath , false , [ servicesFile ] , ( ) = > {
2016-06-14 21:39:13 +02:00
const settings : tsc.Settings = getCompilerSettings ( {
outFile : perftscJsPath
} , /*useBuiltCompiler*/ true ) ;
return gulp . src ( perftscPath )
2016-06-20 23:39:29 +02:00
. pipe ( newer ( perftscJsPath ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
. pipe ( tsc ( settings ) )
2016-06-14 22:09:48 +02:00
. pipe ( sourcemaps . write ( "." ) )
. pipe ( gulp . dest ( "." ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
gulp . task ( "perftsc" , "Builds augmented version of the compiler for perf tests" , [ perftscJsPath ] ) ;
// Instrumented compiler
const loggedIOpath = path . join ( harnessDirectory , "loggedIO.ts" ) ;
const loggedIOJsPath = path . join ( builtLocalDirectory , "loggedIO.js" ) ;
gulp . task ( loggedIOJsPath , false , [ ] , ( done ) = > {
const temp = path . join ( builtLocalDirectory , "temp" ) ;
mkdirP ( temp , ( err ) = > {
if ( err ) { console . error ( err ) ; done ( err ) ; process . exit ( 1 ) ; } ;
exec ( host , [ LKGCompiler , "--outdir" , temp , loggedIOpath ] , ( ) = > {
fs . renameSync ( path . join ( temp , "/harness/loggedIO.js" ) , loggedIOJsPath ) ;
del ( temp ) . then ( ( ) = > done ( ) , done ) ;
} , done ) ;
} ) ;
} ) ;
const instrumenterPath = path . join ( harnessDirectory , "instrumenter.ts" ) ;
const instrumenterJsPath = path . join ( builtLocalDirectory , "instrumenter.js" ) ;
2016-06-14 23:41:25 +02:00
gulp . task ( instrumenterJsPath , false , [ servicesFile ] , ( ) = > {
2016-06-14 21:39:13 +02:00
const settings : tsc.Settings = getCompilerSettings ( {
outFile : instrumenterJsPath
} , /*useBuiltCompiler*/ true ) ;
return gulp . src ( instrumenterPath )
2016-06-20 23:39:29 +02:00
. pipe ( newer ( instrumenterJsPath ) )
2016-06-14 21:39:13 +02:00
. pipe ( sourcemaps . init ( ) )
. pipe ( tsc ( settings ) )
2016-06-14 22:09:48 +02:00
. pipe ( sourcemaps . write ( "." ) )
. pipe ( gulp . dest ( "." ) ) ;
2016-06-14 21:39:13 +02:00
} ) ;
2016-06-10 02:44:59 +02:00
2016-06-14 23:41:25 +02:00
gulp . task ( "tsc-instrumented" , "Builds an instrumented tsc.js" , [ loggedIOJsPath , instrumenterJsPath , servicesFile ] , ( done ) = > {
2016-06-10 02:44:59 +02:00
exec ( host , [ instrumenterJsPath , "record" , "iocapture" , builtLocalDirectory , compilerFilename ] , done , done ) ;
} ) ;
gulp . task ( "update-sublime" , "Updates the sublime plugin's tsserver" , [ "local" , serverFile ] , ( ) = > {
return gulp . src ( [ serverFile , serverFile + ".map" ] ) . pipe ( gulp . dest ( "../TypeScript-Sublime-Plugin/tsserver/" ) ) ;
} ) ;
2016-07-26 22:29:53 +02:00
gulp . task ( "build-rules" , "Compiles tslint rules to js" , ( ) = > {
const settings : tsc.Settings = getCompilerSettings ( { module : "commonjs" } , /*useBuiltCompiler*/ false ) ;
const dest = path . join ( builtLocalDirectory , "tslint" ) ;
return gulp . src ( "scripts/tslint/**/*.ts" )
. pipe ( newer ( {
dest ,
ext : ".js"
} ) )
. pipe ( sourcemaps . init ( ) )
. pipe ( tsc ( settings ) )
. pipe ( sourcemaps . write ( "." ) )
. pipe ( gulp . dest ( dest ) ) ;
2016-06-10 02:44:59 +02:00
} ) ;
function getLinterOptions() {
return {
configuration : require ( "./tslint.json" ) ,
formatter : "prose" ,
formattersDirectory : undefined ,
rulesDirectory : "built/local/tslint"
} ;
}
function lintFileContents ( options , path , contents ) {
const ll = new Linter ( path , contents , options ) ;
console . log ( "Linting '" + path + "'." ) ;
return ll . lint ( ) ;
}
function lintFile ( options , path ) {
const contents = fs . readFileSync ( path , "utf8" ) ;
return lintFileContents ( options , path , contents ) ;
}
2016-07-12 01:00:16 +02:00
const lintTargets = [
"Gulpfile.ts" ,
"src/compiler/**/*.ts" ,
"src/harness/**/*.ts" ,
2016-07-12 02:42:52 +02:00
"!src/harness/unittests/services/formatting/**/*.ts" ,
2016-07-12 01:00:16 +02:00
"src/server/**/*.ts" ,
"scripts/tslint/**/*.ts" ,
"src/services/**/*.ts" ,
2016-07-27 16:26:28 +02:00
"tests/*.ts" , "tests/webhost/*.ts" // Note: does *not* descend recursively
2016-07-12 01:00:16 +02:00
] ;
2016-06-10 02:44:59 +02:00
gulp . task ( "lint" , "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex" , [ "build-rules" ] , ( ) = > {
2016-07-12 01:00:16 +02:00
const fileMatcher = RegExp ( cmdLineOptions [ "files" ] ) ;
2016-06-10 02:44:59 +02:00
const lintOptions = getLinterOptions ( ) ;
let failed = 0 ;
2016-08-11 18:53:38 +02:00
if ( fold . isTravis ( ) ) console . log ( fold . start ( "lint" ) ) ;
2016-07-12 01:00:16 +02:00
return gulp . src ( lintTargets )
. pipe ( insert . transform ( ( contents , file ) = > {
if ( ! fileMatcher . test ( file . path ) ) return contents ;
const result = lintFile ( lintOptions , file . path ) ;
2016-06-10 02:44:59 +02:00
if ( result . failureCount > 0 ) {
console . log ( result . output ) ;
failed += result . failureCount ;
}
2016-07-12 01:00:16 +02:00
return contents ; // TODO (weswig): Automatically apply fixes? :3
} ) )
. on ( "end" , ( ) = > {
2016-08-11 18:53:38 +02:00
if ( fold . isTravis ( ) ) console . log ( fold . end ( "lint" ) ) ;
2016-07-12 01:00:16 +02:00
if ( failed > 0 ) {
console . error ( "Linter errors." ) ;
process . exit ( 1 ) ;
}
} ) ;
2016-06-10 02:44:59 +02:00
} ) ;
gulp . task ( "default" , "Runs 'local'" , [ "local" ] ) ;
2016-06-21 00:35:32 +02:00
gulp . task ( "watch" , "Watches the src/ directory for changes and executes runtests-parallel." , [ ] , ( ) = > {
gulp . watch ( "src/**/*.*" , [ "runtests-parallel" ] ) ;
} ) ;