1
1
//===----------------------------------------------------------------------===//
2
2
//
3
- // This source file is part of the VSCode Swift open source project
3
+ // This source file is part of the VS Code Swift open source project
4
4
//
5
- // Copyright (c) 2021-2024 the VSCode Swift project authors
5
+ // Copyright (c) 2021-2024 the VS Code Swift project authors
6
6
// Licensed under Apache License v2.0
7
7
//
8
8
// See LICENSE.txt for license information
9
- // See CONTRIBUTORS.txt for the list of VSCode Swift project authors
9
+ // See CONTRIBUTORS.txt for the list of VS Code Swift project authors
10
10
//
11
11
// SPDX-License-Identifier: Apache-2.0
12
12
//
@@ -17,8 +17,12 @@ import * as path from "path";
17
17
import * as vscode from "vscode" ;
18
18
import { tmpdir } from "os" ;
19
19
import { exec } from "child_process" ;
20
+ import { Writable } from "stream" ;
20
21
import { SwiftOutputChannel } from "../ui/SwiftOutputChannel" ;
21
22
import { WorkspaceContext } from "../WorkspaceContext" ;
23
+ import { Version } from "../utilities/version" ;
24
+ import { execFileStreamOutput } from "../utilities/utilities" ;
25
+ import configuration from "../configuration" ;
22
26
23
27
export async function captureDiagnostics ( ctx : WorkspaceContext ) {
24
28
const diagnosticsDir = path . join (
@@ -30,7 +34,15 @@ export async function captureDiagnostics(ctx: WorkspaceContext) {
30
34
await fs . mkdir ( diagnosticsDir ) ;
31
35
await writeLogFile ( diagnosticsDir , "logs.txt" , extensionLogs ( ctx ) ) ;
32
36
await writeLogFile ( diagnosticsDir , "environment.txt" , environmentLogs ( ctx ) ) ;
33
- await writeLogFile ( diagnosticsDir , "sourcekit-lsp.txt" , sourceKitLogs ( ctx ) ) ;
37
+
38
+ if ( ctx . swiftVersion . isGreaterThanOrEqual ( new Version ( 6 , 0 , 0 ) ) ) {
39
+ // sourcekit-lsp diagnose command is only available in 6.0 and higher.
40
+ // await writeLogFile(diagnosticsDir, "sourcekit-lsp.txt", );
41
+ await sourcekitDiagnose ( ctx , diagnosticsDir ) ;
42
+ } else {
43
+ await writeLogFile ( diagnosticsDir , "sourcekit-lsp.txt" , sourceKitLogs ( ctx ) ) ;
44
+ }
45
+
34
46
await writeLogFile ( diagnosticsDir , "diagnostics.txt" , diagnosticLogs ( ) ) ;
35
47
36
48
ctx . outputChannel . log ( `Saved diagnostics to ${ diagnosticsDir } ` ) ;
@@ -71,7 +83,7 @@ function extensionLogs(ctx: WorkspaceContext): string {
71
83
}
72
84
73
85
function environmentLogs ( ctx : WorkspaceContext ) : string {
74
- const environmentOutputChannel = new SwiftOutputChannel ( "Swift" ) ;
86
+ const environmentOutputChannel = new SwiftOutputChannel ( "Swift" , false ) ;
75
87
ctx . toolchain . logDiagnostics ( environmentOutputChannel ) ;
76
88
environmentOutputChannel . log ( "Extension Settings:" ) ;
77
89
environmentOutputChannel . log (
@@ -97,6 +109,54 @@ function sourceKitLogs(ctx: WorkspaceContext) {
97
109
return ( ctx . languageClientManager . languageClientOutputChannel ?. logs ?? [ ] ) . join ( "\n" ) ;
98
110
}
99
111
112
+ async function sourcekitDiagnose ( ctx : WorkspaceContext , dir : string ) {
113
+ const sourcekitDiagnosticDir = path . join ( dir , "sourcekit-lsp" ) ;
114
+ await fs . mkdir ( sourcekitDiagnosticDir ) ;
115
+
116
+ const toolchainSourceKitLSP = ctx . toolchain . getToolchainExecutable ( "sourcekit-lsp" ) ;
117
+ const lspConfig = configuration . lsp ;
118
+ const serverPathConfig = lspConfig . serverPath ;
119
+ const serverPath = serverPathConfig . length > 0 ? serverPathConfig : toolchainSourceKitLSP ;
120
+
121
+ await vscode . window . withProgress (
122
+ {
123
+ location : vscode . ProgressLocation . Notification ,
124
+ } ,
125
+ async progress => {
126
+ progress . report ( { message : "Capturing Diagnostics..." } ) ;
127
+ const writableStream = progressUpdatingWritable ( percent =>
128
+ progress . report ( { message : `Capturing Diagnostics: ${ percent } %` } )
129
+ ) ;
130
+
131
+ await execFileStreamOutput (
132
+ serverPath ,
133
+ [ "diagnose" , "--bundle-output-path" , sourcekitDiagnosticDir ] ,
134
+ writableStream ,
135
+ writableStream ,
136
+ null ,
137
+ {
138
+ env : { ...process . env , ...configuration . swiftEnvironmentVariables } ,
139
+ maxBuffer : 16 * 1024 * 1024 ,
140
+ }
141
+ ) ;
142
+ }
143
+ ) ;
144
+ }
145
+
146
+ function progressUpdatingWritable ( updateProgress : ( str : string ) => void ) : Writable {
147
+ return new Writable ( {
148
+ write ( chunk , encoding , callback ) {
149
+ const str = ( chunk as Buffer ) . toString ( "utf8" ) . trim ( ) ;
150
+ const percent = / ^ ( [ 0 - 9 ] ) + % / . exec ( str ) ;
151
+ if ( percent && percent [ 1 ] ) {
152
+ updateProgress ( percent [ 1 ] ) ;
153
+ }
154
+
155
+ callback ( ) ;
156
+ } ,
157
+ } ) ;
158
+ }
159
+
100
160
function showDirectoryCommand ( dir : string ) : string {
101
161
switch ( process . platform ) {
102
162
case "win32" :
0 commit comments