Skip to content

Commit 308e5a5

Browse files
authored
Download and Install Progress Window for Packages (#1806)
* Adding progress bar * Updating vscode requirement and package version * Updating message
1 parent e2b5bf9 commit 308e5a5

File tree

3 files changed

+40
-53
lines changed

3 files changed

+40
-53
lines changed

Extension/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
},
1313
"license": "SEE LICENSE IN LICENSE.txt",
1414
"engines": {
15-
"vscode": "^1.17.0"
15+
"vscode": "^1.22.0"
1616
},
1717
"bugs": {
1818
"url": "https://github.com/Microsoft/vscode-cpptools/issues",
@@ -1128,7 +1128,7 @@
11281128
"tslint-no-unused-expression-chai": "0.0.3",
11291129
"tslint": "5.8.0",
11301130
"typescript": "^2.5.3",
1131-
"vscode": "^1.1.6"
1131+
"vscode": "^1.1.14"
11321132
},
11331133
"dependencies": {
11341134
"http-proxy-agent": "~2.0.0",

Extension/src/main.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,22 @@ async function downloadAndInstallPackages(info: PlatformInformation): Promise<vo
114114
let outputChannelLogger: Logger = getOutputChannelLogger();
115115
outputChannelLogger.appendLine("Updating C/C++ dependencies...");
116116

117-
let statusItem: vscode.StatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
118-
let packageManager: PackageManager = new PackageManager(info, outputChannelLogger, statusItem);
117+
let packageManager: PackageManager = new PackageManager(info, outputChannelLogger);
119118

120-
outputChannelLogger.appendLine('');
121-
setInstallationStage('downloadPackages');
122-
await packageManager.DownloadPackages();
119+
return vscode.window.withProgress({
120+
location: vscode.ProgressLocation.Notification,
121+
title: "C/C++ Extension",
122+
cancellable: false
123+
}, async (progress, token) => {
123124

124-
outputChannelLogger.appendLine('');
125-
setInstallationStage('installPackages');
126-
await packageManager.InstallPackages();
125+
outputChannelLogger.appendLine('');
126+
setInstallationStage('downloadPackages');
127+
await packageManager.DownloadPackages(progress);
127128

128-
statusItem.dispose();
129+
outputChannelLogger.appendLine('');
130+
setInstallationStage('installPackages');
131+
await packageManager.InstallPackages(progress);
132+
});
129133
}
130134

131135
function makeBinariesExecutable(): Promise<void> {

Extension/src/packageManager.ts

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -67,24 +67,33 @@ export class PackageManager {
6767

6868
public constructor(
6969
private platformInfo: PlatformInformation,
70-
private outputChannel?: Logger,
71-
private statusItem?: vscode.StatusBarItem) {
70+
private outputChannel?: Logger) {
7271
// Ensure our temp files get cleaned up in case of error
7372
tmp.setGracefulCleanup();
7473
}
7574

76-
public DownloadPackages(): Promise<void> {
75+
public DownloadPackages(progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
7776
return this.GetPackages()
7877
.then((packages) => {
79-
return this.BuildPromiseChain(packages, (pkg) => this.DownloadPackage(pkg));
78+
let count: number = 1;
79+
return this.BuildPromiseChain(packages, (pkg): Promise<void> => {
80+
const p: Promise<void> = this.DownloadPackage(pkg, `${count}/${packages.length}`, progress);
81+
count += 1;
82+
return p;
83+
});
8084
});
8185
}
8286

83-
public InstallPackages(): Promise<void> {
87+
public InstallPackages(progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
8488
return this.GetPackages()
85-
.then((packages) => {
86-
return this.BuildPromiseChain(packages, (pkg) => this.InstallPackage(pkg));
89+
.then((packages) => {
90+
let count: number = 1;
91+
return this.BuildPromiseChain(packages, (pkg): Promise<void> => {
92+
const p: Promise<void> = this.InstallPackage(pkg, `${count}/${packages.length}`, progress);
93+
count += 1;
94+
return p;
8795
});
96+
});
8897
}
8998

9099
/** Builds a chain of promises by calling the promiseBuilder function once per item in the list.
@@ -137,14 +146,13 @@ export class PackageManager {
137146
});
138147
}
139148

140-
private async DownloadPackage(pkg: IPackage): Promise<void> {
149+
private async DownloadPackage(pkg: IPackage, progressCount: string, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
141150
this.AppendChannel(`Downloading package '${pkg.description}' `);
142151

143-
this.SetStatusText("$(cloud-download) Downloading packages...");
144-
this.SetStatusTooltip(`Downloading package '${pkg.description}'...`);
152+
progress.report({message: `Downloading ${progressCount}: ${pkg.description}`});
145153

146154
const tmpResult: tmp.SyncResult = await this.CreateTempFile(pkg);
147-
await this.DownloadPackageWithRetries(pkg, tmpResult);
155+
await this.DownloadPackageWithRetries(pkg, tmpResult, progress);
148156
}
149157

150158
private async CreateTempFile(pkg: IPackage): Promise<tmp.SyncResult> {
@@ -159,7 +167,7 @@ export class PackageManager {
159167
});
160168
}
161169

162-
private async DownloadPackageWithRetries(pkg: IPackage, tmpResult: tmp.SyncResult): Promise<void> {
170+
private async DownloadPackageWithRetries(pkg: IPackage, tmpResult: tmp.SyncResult, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
163171
pkg.tmpFile = tmpResult;
164172

165173
let success: boolean = false;
@@ -170,7 +178,7 @@ export class PackageManager {
170178
// Retry the download at most MAX_RETRIES times with 2-32 seconds delay.
171179
do {
172180
try {
173-
await this.DownloadFile(pkg.url, pkg, retryCount);
181+
await this.DownloadFile(pkg.url, pkg, retryCount, progress);
174182
success = true;
175183
} catch (error) {
176184
retryCount += 1;
@@ -208,7 +216,7 @@ export class PackageManager {
208216
}
209217

210218
// reloadCpptoolsJson in main.ts uses ~25% of this function.
211-
private DownloadFile(urlString: any, pkg: IPackage, delay: number): Promise<void> {
219+
private DownloadFile(urlString: any, pkg: IPackage, delay: number, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
212220
let parsedUrl: url.Url = url.parse(urlString);
213221
let proxyStrictSSL: any = vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true);
214222

@@ -241,7 +249,7 @@ export class PackageManager {
241249
} else {
242250
redirectUrl = response.headers.location[0];
243251
}
244-
return resolve(this.DownloadFile(redirectUrl, pkg, 0));
252+
return resolve(this.DownloadFile(redirectUrl, pkg, 0, progress));
245253
} else if (response.statusCode !== 200) {
246254
// Download failed - print error message
247255
let errorMessage: string = `failed (error code '${response.statusCode}')`;
@@ -255,23 +263,13 @@ export class PackageManager {
255263
contentLength = response.headers['content-length'][0];
256264
}
257265
let packageSize: number = parseInt(contentLength, 10);
258-
let downloadedBytes: number = 0;
259266
let downloadPercentage: number = 0;
260267
let dots: number = 0;
261268
let tmpFile: fs.WriteStream = fs.createWriteStream(null, { fd: pkg.tmpFile.fd });
262269

263270
this.AppendChannel(`(${Math.ceil(packageSize / 1024)} KB) `);
264271

265272
response.on('data', (data) => {
266-
downloadedBytes += data.length;
267-
268-
// Update status bar item with percentage
269-
let newPercentage: number = Math.ceil(100 * (downloadedBytes / packageSize));
270-
if (newPercentage !== downloadPercentage) {
271-
this.SetStatusTooltip(`Downloading package '${pkg.description}'... ${downloadPercentage}%`);
272-
downloadPercentage = newPercentage;
273-
}
274-
275273
// Update dots after package name in output console
276274
let newDots: number = Math.ceil(downloadPercentage / 5);
277275
if (newDots > dots) {
@@ -305,11 +303,10 @@ export class PackageManager {
305303
});
306304
}
307305

308-
private InstallPackage(pkg: IPackage): Promise<void> {
306+
private InstallPackage(pkg: IPackage, progressCount: string, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
309307
this.AppendLineChannel(`Installing package '${pkg.description}'`);
310308

311-
this.SetStatusText("$(desktop-download) Installing packages...");
312-
this.SetStatusTooltip(`Installing package '${pkg.description}'`);
309+
progress.report({message: `Installing ${progressCount}: ${pkg.description}`});
313310

314311
return new Promise<void>((resolve, reject) => {
315312
if (!pkg.tmpFile || pkg.tmpFile.fd === 0) {
@@ -424,18 +421,4 @@ export class PackageManager {
424421
this.outputChannel.appendLine(text);
425422
}
426423
}
427-
428-
private SetStatusText(text: string): void {
429-
if (this.statusItem) {
430-
this.statusItem.text = text;
431-
this.statusItem.show();
432-
}
433-
}
434-
435-
private SetStatusTooltip(text: string): void {
436-
if (this.statusItem) {
437-
this.statusItem.tooltip = text;
438-
this.statusItem.show();
439-
}
440-
}
441424
}

0 commit comments

Comments
 (0)