1
- import { chain , FileEntry , Rule , SchematicContext , Tree } from '@angular-devkit/schematics' ;
1
+ import { FileEntry , Rule , SchematicContext , Tree } from '@angular-devkit/schematics' ;
2
2
import {
3
3
NodePackageInstallTask ,
4
4
RunSchematicTask ,
5
5
TslintFixTask
6
6
} from '@angular-devkit/schematics/tasks' ;
7
7
import * as path from 'path' ;
8
+ import { existsSync , readFileSync } from 'fs' ;
9
+ import { getProjectFromWorkspace , getWorkspace } from '../utils/devkit-utils/config' ;
8
10
9
11
const schematicsSrcPath = 'node_modules/@angular/material/schematics' ;
10
12
const schematicsTmpPath = 'node_modules/_tmp_angular_material_schematics' ;
11
13
12
14
/** Entry point for `ng update` from Angular CLI. */
13
15
export default function ( ) : Rule {
14
16
return ( tree : Tree , context : SchematicContext ) => {
17
+ // If this script failed in an earlier run, clear out the temporary files from that failed
18
+ // run before doing anything else.
19
+ tree . getDir ( schematicsTmpPath ) . visit ( ( _ , entry ) => tree . delete ( entry . path ) ) ;
20
+
15
21
// Copy the update schematics to a temporary directory.
16
22
const updateSrcs : FileEntry [ ] = [ ] ;
17
23
tree . getDir ( schematicsSrcPath ) . visit ( ( _ , entry ) => updateSrcs . push ( entry ) ) ;
@@ -25,48 +31,52 @@ export default function(): Rule {
25
31
packageName : '@angular/cdk@">=5 <6" @angular/material@">=5 <6"'
26
32
} ) ) ;
27
33
28
- // Run the update tslint rules.
29
- const updateTask = context . addTask ( new TslintFixTask ( {
30
- rulesDirectory : path . join ( schematicsTmpPath , 'update/rules' ) ,
31
- rules : {
32
- // Automatic fixes.
33
- "switch-identifiers" : true ,
34
- "switch-property-names" : true ,
35
- "switch-string-literal-attribute-selectors" : true ,
36
- "switch-string-literal-css-names" : true ,
37
- "switch-string-literal-element-selectors" : true ,
38
- "switch-stylesheet-attribute-selectors" : true ,
39
- "switch-stylesheet-css-names" : true ,
40
- "switch-stylesheet-element-selectors" : true ,
41
- "switch-stylesheet-input-names" : true ,
42
- "switch-stylesheet-output-names" : true ,
43
- "switch-template-attribute-selectors" : true ,
44
- "switch-template-css-names" : true ,
45
- "switch-template-element-selectors" : true ,
46
- "switch-template-export-as-names" : true ,
47
- "switch-template-input-names" : true ,
48
- "switch-template-output-names" : true ,
34
+ const allTsConfigPaths = getTsConfigPaths ( tree ) ;
35
+ const allUpdateTasks = [ ] ;
36
+ for ( const tsconfig of allTsConfigPaths ) {
37
+ // Run the update tslint rules.
38
+ allUpdateTasks . push ( context . addTask ( new TslintFixTask ( {
39
+ rulesDirectory : path . join ( schematicsTmpPath , 'update/rules' ) ,
40
+ rules : {
41
+ // Automatic fixes.
42
+ "switch-identifiers" : true ,
43
+ "switch-property-names" : true ,
44
+ "switch-string-literal-attribute-selectors" : true ,
45
+ "switch-string-literal-css-names" : true ,
46
+ "switch-string-literal-element-selectors" : true ,
47
+ "switch-stylesheet-attribute-selectors" : true ,
48
+ "switch-stylesheet-css-names" : true ,
49
+ "switch-stylesheet-element-selectors" : true ,
50
+ "switch-stylesheet-input-names" : true ,
51
+ "switch-stylesheet-output-names" : true ,
52
+ "switch-template-attribute-selectors" : true ,
53
+ "switch-template-css-names" : true ,
54
+ "switch-template-element-selectors" : true ,
55
+ "switch-template-export-as-names" : true ,
56
+ "switch-template-input-names" : true ,
57
+ "switch-template-output-names" : true ,
49
58
50
- // Additional issues we can detect but not automatically fix.
51
- "check-class-declaration-misc" : true ,
52
- "check-identifier-misc" : true ,
53
- "check-import-misc" : true ,
54
- "check-inheritance" : true ,
55
- "check-method-calls" : true ,
56
- "check-property-access-misc" : true ,
57
- "check-template-misc" : true
58
- }
59
- } , {
60
- silent : false ,
61
- ignoreErrors : true ,
62
- tsConfigPath : './src/tsconfig.json' ,
63
- } ) , [ downgradeTask ] ) ;
59
+ // Additional issues we can detect but not automatically fix.
60
+ "check-class-declaration-misc" : true ,
61
+ "check-identifier-misc" : true ,
62
+ "check-import-misc" : true ,
63
+ "check-inheritance" : true ,
64
+ "check-method-calls" : true ,
65
+ "check-property-access-misc" : true ,
66
+ "check-template-misc" : true
67
+ }
68
+ } , {
69
+ silent : false ,
70
+ ignoreErrors : true ,
71
+ tsConfigPath : tsconfig ,
72
+ } ) , [ downgradeTask ] ) ) ;
73
+ }
64
74
65
75
// Upgrade @angular /material back to 6.x.
66
76
const upgradeTask = context . addTask ( new NodePackageInstallTask ( {
67
77
// TODO(mmalerba): Change "next" to ">=6 <7".
68
78
packageName : '@angular/cdk@next @angular/material@next'
69
- } ) , [ updateTask ] ) ;
79
+ } ) , allUpdateTasks ) ;
70
80
71
81
// Delete the temporary schematics directory.
72
82
context . addTask (
@@ -94,3 +104,36 @@ export function postPostUpdate(): Rule {
94
104
'\nComplete! Please check the output above for any issues that were detected but could not' +
95
105
' be automatically fixed.' ) ;
96
106
}
107
+
108
+ /** Gets the first tsconfig path from possibile locations based on the history of the CLI. */
109
+ function getTsConfigPaths ( tree : Tree ) : string [ ] {
110
+ // Start with some tsconfig paths that are generally used.
111
+ const tsconfigPaths = [
112
+ './tsconfig.json' ,
113
+ './src/tsconfig.json' ,
114
+ './src/tsconfig.app.json' ,
115
+ ] ;
116
+
117
+ // Add any tsconfig directly referenced in a build or test task of the angular.json workspace.
118
+ const workspace = getWorkspace ( tree ) ;
119
+ for ( const project of Object . values ( workspace . projects ) ) {
120
+ if ( project && project . architect ) {
121
+ for ( const taskName of [ 'build' , 'test' ] ) {
122
+ const task = project . architect [ taskName ] ;
123
+ if ( task && task . options && task . options . tsConfig ) {
124
+ const tsConfigOption = project . architect . tsConfig ;
125
+ if ( typeof tsConfigOption === 'string' ) {
126
+ tsconfigPaths . push ( tsConfigOption ) ;
127
+ } else if ( Array . isArray ( tsConfigOption ) ) {
128
+ tsconfigPaths . push ( ...tsConfigOption ) ;
129
+ }
130
+ }
131
+ }
132
+ }
133
+ }
134
+
135
+ // Filter out tsconfig files that don't exist and remove any duplicates.
136
+ return tsconfigPaths
137
+ . filter ( p => existsSync ( p ) )
138
+ . filter ( ( value , index , self ) => self . indexOf ( value ) === index ) ;
139
+ }
0 commit comments