6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
+ import { existsSync } from 'fs' ;
10
+ import * as path from 'path' ;
9
11
import { Observable , of , throwError } from 'rxjs' ;
10
- import { concatMap , map , tap } from 'rxjs/operators' ;
12
+ import { concatMap , first , map , tap } from 'rxjs/operators' ;
11
13
import { BaseException } from '../exception' ;
12
14
import {
13
15
JsonObject ,
@@ -17,16 +19,22 @@ import {
17
19
} from '../json' ;
18
20
import {
19
21
Path ,
22
+ basename ,
23
+ dirname ,
20
24
isAbsolute ,
21
25
join ,
22
26
normalize ,
23
- relative ,
24
- resolve ,
25
- virtualFs ,
27
+ relative , resolve , virtualFs ,
26
28
} from '../virtual-fs' ;
27
29
import { WorkspaceProject , WorkspaceSchema , WorkspaceTool } from './workspace-schema' ;
28
30
29
31
32
+ export class WorkspaceFileNotFoundException extends BaseException {
33
+ constructor ( path : Path ) {
34
+ super ( `Workspace could not be found from path ${ path } .` ) ;
35
+ }
36
+ }
37
+
30
38
export class ProjectNotFoundException extends BaseException {
31
39
constructor ( name : string ) {
32
40
super ( `Project '${ name } ' could not be found in workspace.` ) ;
@@ -55,15 +63,69 @@ export class AmbiguousProjectPathException extends BaseException {
55
63
}
56
64
}
57
65
66
+ async function _findUp ( host : virtualFs . Host , names : string [ ] , from : Path ) : Promise < Path | null > {
67
+ if ( ! Array . isArray ( names ) ) {
68
+ names = [ names ] ;
69
+ }
70
+
71
+ do {
72
+ for ( const name of names ) {
73
+ const p = join ( from , name ) ;
74
+ if ( await host . exists ( p ) ) {
75
+ return p ;
76
+ }
77
+ }
78
+
79
+ from = dirname ( from ) ;
80
+ } while ( from && from !== dirname ( from ) ) ;
81
+
82
+ return null ;
83
+ }
84
+
58
85
export class Workspace {
86
+ protected static _workspaceFileNames = [
87
+ 'angular.json' ,
88
+ '.angular.json' ,
89
+ 'workspace.json' ,
90
+ '.workspace.json' ,
91
+ ] ;
92
+
59
93
private readonly _workspaceSchemaPath = normalize ( require . resolve ( './workspace-schema.json' ) ) ;
60
94
private _workspaceSchema : JsonObject ;
61
95
private _workspace : WorkspaceSchema ;
62
96
private _registry : schema . CoreSchemaRegistry ;
63
97
64
- constructor ( private _root : Path , private _host : virtualFs . Host < { } > ) {
65
- this . _registry = new schema . CoreSchemaRegistry ( ) ;
66
- this . _registry . addPostTransform ( schema . transforms . addUndefinedDefaults ) ;
98
+ constructor (
99
+ private _root : Path ,
100
+ private _host : virtualFs . Host < { } > ,
101
+ registry ?: schema . CoreSchemaRegistry ,
102
+ ) {
103
+ if ( registry ) {
104
+ this . _registry = registry ;
105
+ } else {
106
+ this . _registry = new schema . CoreSchemaRegistry ( ) ;
107
+ this . _registry . addPostTransform ( schema . transforms . addUndefinedDefaults ) ;
108
+ }
109
+ }
110
+
111
+ static async findWorkspaceFile ( host : virtualFs . Host < { } > , path : Path ) : Promise < Path | null > {
112
+ return await _findUp ( host , this . _workspaceFileNames , path ) ;
113
+ }
114
+ static async fromPath (
115
+ host : virtualFs . Host < { } > ,
116
+ path : Path ,
117
+ registry : schema . CoreSchemaRegistry ,
118
+ ) : Promise < Workspace > {
119
+ const maybePath = await this . findWorkspaceFile ( host , path ) ;
120
+
121
+ if ( ! maybePath ) {
122
+ throw new WorkspaceFileNotFoundException ( path ) ;
123
+ }
124
+
125
+ return new Workspace ( dirname ( maybePath ) , host , registry )
126
+ . loadWorkspaceFromHost ( basename ( maybePath ) )
127
+ . pipe ( first ( ) )
128
+ . toPromise ( ) ;
67
129
}
68
130
69
131
loadWorkspaceFromJson ( json : { } ) {
0 commit comments