8
8
* SPDX-License-Identifier: EPL-2.0
9
9
**********************************************************************/
10
10
11
- import { injectable } from 'inversify' ;
11
+ import { injectable , inject } from 'inversify' ;
12
12
import * as theia from '@theia/plugin' ;
13
+ import * as startPoint from '../task-plugin-backend' ;
14
+ import { che as cheApi } from '@eclipse-che/api' ;
13
15
import { TaskConfiguration } from '@eclipse-che/plugin' ;
14
16
import { resolve } from 'path' ;
15
- import { readFileSync , writeFileSync , format , modify , parse } from '../utils' ;
17
+ import { writeFileSync , modify } from '../utils' ;
18
+ import { CheTaskConfigsExtractor } from '../extract/che-task-configs-extractor' ;
19
+ import { VsCodeTaskConfigsExtractor } from '../extract/vscode-task-configs-extractor' ;
16
20
import { ConfigurationsExporter } from './export-configs-manager' ;
21
+ import { ConfigFileTasksExtractor } from '../extract/config-file-task-configs-extractor' ;
17
22
18
23
const CONFIG_DIR = '.theia' ;
19
24
const TASK_CONFIG_FILE = 'tasks.json' ;
@@ -24,42 +29,97 @@ export const VSCODE_TASK_TYPE = 'vscode-task';
24
29
/** Exports configurations of tasks in the config file. */
25
30
@injectable ( )
26
31
export class TaskConfigurationsExporter implements ConfigurationsExporter {
27
- readonly type : string = VSCODE_TASK_TYPE ;
28
32
29
- export ( tasksContent : string , workspaceFolder : theia . WorkspaceFolder ) : void {
33
+ @inject ( ConfigFileTasksExtractor )
34
+ protected readonly configFileTasksExtractor : ConfigFileTasksExtractor ;
35
+
36
+ @inject ( CheTaskConfigsExtractor )
37
+ protected readonly cheTaskConfigsExtractor : CheTaskConfigsExtractor ;
38
+
39
+ @inject ( VsCodeTaskConfigsExtractor )
40
+ protected readonly vsCodeTaskConfigsExtractor : VsCodeTaskConfigsExtractor ;
41
+
42
+ export ( workspaceFolder : theia . WorkspaceFolder , commands : cheApi . workspace . Command [ ] ) : void {
30
43
const tasksConfigFileUri = this . getConfigFileUri ( workspaceFolder . uri . path ) ;
31
- const existingContent = readFileSync ( tasksConfigFileUri ) ;
32
- if ( tasksContent === existingContent ) {
33
- return ;
34
- }
44
+ const configFileTasks = this . configFileTasksExtractor . extract ( tasksConfigFileUri ) ;
45
+
46
+ const cheTasks = this . cheTaskConfigsExtractor . extract ( commands ) ;
47
+ const vsCodeTasks = this . vsCodeTaskConfigsExtractor . extract ( commands ) ;
48
+ const devfileConfigs = this . merge ( cheTasks , vsCodeTasks . configs , this . getOutputChannelConflictLogger ( ) ) ;
35
49
36
- const tasksJson = parse ( tasksContent ) ;
37
- if ( ! tasksJson || ! tasksJson . tasks ) {
50
+ const configFileContent = configFileTasks . content ;
51
+ if ( configFileContent ) {
52
+ this . saveConfigs ( tasksConfigFileUri , configFileContent , this . merge ( configFileTasks . configs , devfileConfigs , this . getConsoleConflictLogger ( ) ) ) ;
38
53
return ;
39
54
}
40
55
41
- const existingJson = parse ( existingContent ) ;
42
- if ( ! existingJson || ! existingJson . tasks ) {
43
- writeFileSync ( tasksConfigFileUri , format ( tasksContent , formattingOptions ) ) ;
56
+ const vsCodeTasksContent = vsCodeTasks . content ;
57
+ if ( vsCodeTasksContent ) {
58
+ this . saveConfigs ( tasksConfigFileUri , vsCodeTasksContent , devfileConfigs ) ;
44
59
return ;
45
60
}
46
61
47
- const mergedConfigs = this . merge ( existingJson . tasks , tasksJson . tasks ) ;
48
- const result = modify ( tasksContent , [ 'tasks' ] , mergedConfigs , formattingOptions ) ;
49
- writeFileSync ( tasksConfigFileUri , result ) ;
62
+ if ( cheTasks ) {
63
+ this . saveConfigs ( tasksConfigFileUri , '' , cheTasks ) ;
64
+ }
50
65
}
51
66
52
- private merge ( existingConfigs : TaskConfiguration [ ] , newConfigs : TaskConfiguration [ ] ) : TaskConfiguration [ ] {
53
- const result : TaskConfiguration [ ] = Object . assign ( [ ] , newConfigs ) ;
54
- for ( const existing of existingConfigs ) {
55
- if ( ! newConfigs . some ( config => config . label === existing . label ) ) {
56
- result . push ( existing ) ;
67
+ private merge ( configurations1 : TaskConfiguration [ ] ,
68
+ configurations2 : TaskConfiguration [ ] ,
69
+ conflictHandler : ( config1 : TaskConfiguration , config2 : TaskConfiguration ) => void ) : TaskConfiguration [ ] {
70
+
71
+ const result : TaskConfiguration [ ] = Object . assign ( [ ] , configurations1 ) ;
72
+
73
+ for ( const config2 of configurations2 ) {
74
+ const conflict = configurations1 . find ( config1 => config1 . label === config2 . label ) ;
75
+ if ( ! conflict ) {
76
+ result . push ( config2 ) ;
77
+ continue ;
57
78
}
79
+
80
+ if ( this . areEqual ( config2 , conflict ) ) {
81
+ continue ;
82
+ }
83
+
84
+ conflictHandler ( conflict , config2 ) ;
58
85
}
86
+
59
87
return result ;
60
88
}
61
89
90
+ private areEqual ( config1 : TaskConfiguration , config2 : TaskConfiguration ) : boolean {
91
+ const { type : type1 , label : label1 , ...properties1 } = config1 ;
92
+ const { type : type2 , label : label2 , ...properties2 } = config2 ;
93
+
94
+ if ( type1 !== type2 || label1 !== label2 ) {
95
+ return false ;
96
+ }
97
+
98
+ return JSON . stringify ( properties1 ) === JSON . stringify ( properties2 ) ;
99
+ }
100
+
62
101
private getConfigFileUri ( rootDir : string ) : string {
63
102
return resolve ( rootDir . toString ( ) , CONFIG_DIR , TASK_CONFIG_FILE ) ;
64
103
}
104
+
105
+ private saveConfigs ( tasksConfigFileUri : string , content : string , configurations : TaskConfiguration [ ] ) : void {
106
+ const result = modify ( content , [ 'tasks' ] , configurations , formattingOptions ) ;
107
+ writeFileSync ( tasksConfigFileUri , result ) ;
108
+ }
109
+
110
+ private getOutputChannelConflictLogger ( ) : ( config1 : TaskConfiguration , config2 : TaskConfiguration ) => void {
111
+ return ( config1 : TaskConfiguration , config2 : TaskConfiguration ) => {
112
+ const outputChannel = startPoint . getOutputChannel ( ) ;
113
+ outputChannel . show ( ) ;
114
+ outputChannel . appendLine ( `Conflict at exporting task configurations: ${ JSON . stringify ( config1 ) } and ${ JSON . stringify ( config2 ) } ` ) ;
115
+ outputChannel . appendLine ( `The configuration: ${ JSON . stringify ( config2 ) } is ignored` ) ;
116
+ } ;
117
+ }
118
+
119
+ private getConsoleConflictLogger ( ) : ( config1 : TaskConfiguration , config2 : TaskConfiguration ) => void {
120
+ return ( config1 : TaskConfiguration , config2 : TaskConfiguration ) => {
121
+ console . warn ( `Conflict at exporting task configurations: ${ JSON . stringify ( config1 ) } and ${ JSON . stringify ( config2 ) } ` ,
122
+ `The configuration: ${ JSON . stringify ( config2 ) } is ignored` ) ;
123
+ } ;
124
+ }
65
125
}
0 commit comments