@@ -14,78 +14,54 @@ const ts = require("../../lib/typescript");
14
14
const del = require ( "del" ) ;
15
15
const needsUpdate = require ( "./needsUpdate" ) ;
16
16
const mkdirp = require ( "./mkdirp" ) ;
17
- const prettyTime = require ( "pretty-hrtime" ) ;
18
17
const { reportDiagnostics } = require ( "./diagnostics" ) ;
19
- const { CountdownEvent, ManualResetEvent } = require ( "prex" ) ;
18
+ const { CountdownEvent, ManualResetEvent, Semaphore } = require ( "prex" ) ;
20
19
21
20
const workStartedEvent = new ManualResetEvent ( ) ;
22
21
const countdown = new CountdownEvent ( 0 ) ;
23
22
24
- class CompilationGulp extends gulp . Gulp {
25
- /**
26
- * @param {boolean } [verbose]
27
- */
28
- fork ( verbose ) {
29
- const child = new ForkedGulp ( this . tasks ) ;
30
- child . on ( "task_start" , e => {
31
- if ( countdown . remainingCount === 0 ) {
32
- countdown . reset ( 1 ) ;
33
- workStartedEvent . set ( ) ;
34
- workStartedEvent . reset ( ) ;
35
- }
36
- else {
37
- countdown . add ( ) ;
38
- }
39
- if ( verbose ) {
40
- log ( 'Starting' , `'${ chalk . cyan ( e . task ) } ' ${ chalk . gray ( `(${ countdown . remainingCount } remaining)` ) } ...` ) ;
41
- }
42
- } ) ;
43
- child . on ( "task_stop" , e => {
44
- countdown . signal ( ) ;
45
- if ( verbose ) {
46
- log ( 'Finished' , `'${ chalk . cyan ( e . task ) } ' after ${ chalk . magenta ( prettyTime ( /** @type {* }*/ ( e ) . hrDuration ) ) } ${ chalk . gray ( `(${ countdown . remainingCount } remaining)` ) } ` ) ;
47
- }
48
- } ) ;
49
- child . on ( "task_err" , e => {
50
- countdown . signal ( ) ;
51
- if ( verbose ) {
52
- log ( `'${ chalk . cyan ( e . task ) } ' ${ chalk . red ( "errored after" ) } ${ chalk . magenta ( prettyTime ( /** @type {* }*/ ( e ) . hrDuration ) ) } ${ chalk . gray ( `(${ countdown . remainingCount } remaining)` ) } ` ) ;
53
- log ( e . err ? e . err . stack : e . message ) ;
54
- }
55
- } ) ;
56
- return child ;
57
- }
58
-
59
- // @ts -ignore
60
- start ( ) {
61
- throw new Error ( "Not supported, use fork." ) ;
62
- }
63
- }
64
-
65
- class ForkedGulp extends gulp . Gulp {
66
- /**
67
- * @param {gulp.Gulp["tasks"] } tasks
68
- */
69
- constructor ( tasks ) {
70
- super ( ) ;
71
- this . tasks = tasks ;
72
- }
73
-
74
- // Do not reset tasks
75
- _resetAllTasks ( ) { }
76
- _resetSpecificTasks ( ) { }
77
- _resetTask ( ) { }
78
- }
79
-
80
23
// internal `Gulp` instance for compilation artifacts.
81
- const compilationGulp = new CompilationGulp ( ) ;
24
+ const compilationGulp = new gulp . Gulp ( ) ;
82
25
83
26
/** @type {Map<ResolvedProjectSpec, ProjectGraph> } */
84
27
const projectGraphCache = new Map ( ) ;
85
28
86
29
/** @type {Map<string, { typescript: string, alias: string, paths: ResolvedPathOptions }> } */
87
30
const typescriptAliasMap = new Map ( ) ;
88
31
32
+ // TODO: allow concurrent outer builds to be run in parallel
33
+ const sem = new Semaphore ( 1 ) ;
34
+
35
+ /**
36
+ * @param {string|string[] } taskName
37
+ * @param {() => any } [cb]
38
+ */
39
+ function start ( taskName , cb ) {
40
+ return sem . wait ( ) . then ( ( ) => new Promise ( ( resolve , reject ) => {
41
+ compilationGulp . start ( taskName , err => {
42
+ if ( err ) {
43
+ reject ( err ) ;
44
+ }
45
+ else if ( cb ) {
46
+ try {
47
+ resolve ( cb ( ) ) ;
48
+ }
49
+ catch ( e ) {
50
+ reject ( err ) ;
51
+ }
52
+ }
53
+ else {
54
+ resolve ( ) ;
55
+ }
56
+ } ) ;
57
+ } ) ) . then ( ( ) => {
58
+ sem . release ( )
59
+ } , e => {
60
+ sem . release ( ) ;
61
+ throw e ;
62
+ } ) ;
63
+ }
64
+
89
65
/**
90
66
* Defines a gulp orchestration for a TypeScript project, returning a callback that can be used to trigger compilation.
91
67
* @param {string } projectSpec The path to a tsconfig.json file or its containing directory.
@@ -98,9 +74,7 @@ function createCompiler(projectSpec, options) {
98
74
const projectGraph = getOrCreateProjectGraph ( resolvedProjectSpec , resolvedOptions . paths ) ;
99
75
projectGraph . isRoot = true ;
100
76
const taskName = compileTaskName ( ensureCompileTask ( projectGraph , resolvedOptions ) , resolvedOptions . typescript ) ;
101
- return ( ) => new Promise ( ( resolve , reject ) => compilationGulp
102
- . fork ( resolvedOptions . verbose )
103
- . start ( taskName , err => err ? reject ( err ) : resolve ( ) ) ) ;
77
+ return ( ) => start ( taskName ) ;
104
78
}
105
79
exports . createCompiler = createCompiler ;
106
80
@@ -139,9 +113,7 @@ function createCleaner(projectSpec, options) {
139
113
const projectGraph = getOrCreateProjectGraph ( resolvedProjectSpec , paths ) ;
140
114
projectGraph . isRoot = true ;
141
115
const taskName = cleanTaskName ( ensureCleanTask ( projectGraph ) ) ;
142
- return ( ) => new Promise ( ( resolve , reject ) => compilationGulp
143
- . fork ( )
144
- . start ( taskName , err => err ? reject ( err ) : resolve ( ) ) ) ;
116
+ return ( ) => start ( taskName ) ;
145
117
}
146
118
exports . createCleaner = createCleaner ;
147
119
@@ -811,7 +783,7 @@ function possiblyTriggerRecompilation(config, task) {
811
783
function triggerRecompilation ( task , config ) {
812
784
compilationGulp . _resetTask ( task ) ;
813
785
if ( config . watchers && config . watchers . size ) {
814
- compilationGulp . fork ( ) . start ( task . name , ( ) => {
786
+ start ( task . name , ( ) => {
815
787
/** @type {Set<string> } */
816
788
const taskNames = new Set ( ) ;
817
789
/** @type {((err?: any) => void)[] } */
@@ -831,7 +803,7 @@ function triggerRecompilation(task, config) {
831
803
} ) ;
832
804
}
833
805
else {
834
- compilationGulp . fork ( /*verbose*/ true ) . start ( task . name ) ;
806
+ start ( task . name ) ;
835
807
}
836
808
}
837
809
0 commit comments