Skip to content
This repository was archived by the owner on Feb 2, 2021. It is now read-only.

Commit 7b6baed

Browse files
Merge pull request #1040 from telerik/vladimirov/disable-spinners-in-ci
Add getSpinner method to $progressIndicator
2 parents e5d58ff + 93db157 commit 7b6baed

File tree

4 files changed

+100
-42
lines changed

4 files changed

+100
-42
lines changed

declarations.d.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,38 @@ interface IProgressIndicator {
15641564
* @return {Promise<T>}
15651565
*/
15661566
showProgressIndicator<T>(promise: Promise<T>, timeout: number, options?: { surpressTrailingNewLine?: boolean }): Promise<T>;
1567+
1568+
/**
1569+
* Returns a spinner instance that will print a specified message when spinner is started and will repeat it until spinner is stopped.
1570+
* In case the terminal is not interactive, a mocked instance is returned, so the spinner will print the required message a single time - when it is started.
1571+
* @param {string} message The message to be printed.
1572+
* @returns {ISpinner} Instance of clui.Spinner in case terminal is interactive, mocked instance otherwise.
1573+
*/
1574+
getSpinner(message: string): ISpinner;
1575+
}
1576+
1577+
/**
1578+
* Describes the clui spinner.
1579+
*/
1580+
interface ISpinner {
1581+
/**
1582+
* Sets the message that will be printed by spinner.
1583+
* @param {string} msg The new message.
1584+
* @returns {void}
1585+
*/
1586+
message(msg: string): void;
1587+
1588+
/**
1589+
* Starts the spinner.
1590+
* @returns {void}
1591+
*/
1592+
start(): void;
1593+
1594+
/**
1595+
* Stops the spinner.
1596+
* @returns {void}
1597+
*/
1598+
stop(): void;
15671599
}
15681600

15691601
/**

helpers.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,53 @@ import { ReadStream } from "tty";
55
import { Configurations } from "./constants";
66
import { EventEmitter } from "events";
77
import * as crypto from "crypto";
8+
import progress = require("progress-stream");
9+
import filesize = require("filesize");
10+
import * as util from "util";
811

912
const Table = require("cli-table");
1013

14+
export function trackDownloadProgress(destinationStream: NodeJS.WritableStream, url: string): NodeJS.ReadableStream {
15+
// \r for carriage return doesn't work on windows in node for some reason so we have to use it's hex representation \x1B[0G
16+
let lastMessageSize = 0;
17+
const carriageReturn = "\x1B[0G";
18+
let timeElapsed = 0;
19+
20+
const isInteractiveTerminal = isInteractive();
21+
const progressStream = progress({ time: 1000 }, (progress: any) => {
22+
timeElapsed = progress.runtime;
23+
24+
if (timeElapsed >= 1) {
25+
if (isInteractiveTerminal) {
26+
this.$logger.write("%s%s", carriageReturn, Array(lastMessageSize + 1).join(" "));
27+
28+
const message = util.format("%sDownload progress ... %s | %s | %s/s",
29+
carriageReturn,
30+
Math.floor(progress.percentage) + "%",
31+
filesize(progress.transferred),
32+
filesize(progress.speed));
33+
34+
this.$logger.write(message);
35+
lastMessageSize = message.length;
36+
}
37+
}
38+
});
39+
40+
progressStream.on("finish", () => {
41+
if (timeElapsed >= 1) {
42+
const msg = `Download of ${url} completed.`;
43+
if (isInteractiveTerminal) {
44+
this.$logger.out("%s%s%s%s", carriageReturn, Array(lastMessageSize + 1).join(" "), carriageReturn, msg);
45+
} else {
46+
this.$logger.out(msg);
47+
}
48+
}
49+
});
50+
51+
progressStream.pipe(destinationStream);
52+
return progressStream;
53+
}
54+
1155
export async function executeActionByChunks<T>(initialData: T[] | IDictionary<T>, chunkSize: number, elementAction: (element: T, key?: string | number) => Promise<any>): Promise<void> {
1256
let arrayToChunk: (T | string)[];
1357
let action: (key: string | T) => Promise<any>;

http-client.ts

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import { EOL } from "os";
33
import * as helpers from "./helpers";
44
import * as zlib from "zlib";
55
import * as util from "util";
6-
import progress = require("progress-stream");
7-
import filesize = require("filesize");
86
import { HttpStatusCodes } from "./constants";
97
import * as request from "request";
108

@@ -133,8 +131,6 @@ export class HttpClient implements Server.IHttpClient {
133131
this.setResponseResult(promiseActions, timerId, { response });
134132
});
135133

136-
pipeTo = this.trackDownloadProgress(pipeTo);
137-
138134
responseStream.pipe(pipeTo);
139135
} else {
140136
const data: string[] = [];
@@ -204,39 +200,6 @@ export class HttpClient implements Server.IHttpClient {
204200
}
205201
}
206202

207-
private trackDownloadProgress(pipeTo: NodeJS.WritableStream): NodeJS.ReadableStream {
208-
// \r for carriage return doesn't work on windows in node for some reason so we have to use it's hex representation \x1B[0G
209-
let lastMessageSize = 0;
210-
const carriageReturn = "\x1B[0G";
211-
let timeElapsed = 0;
212-
213-
const progressStream = progress({ time: 1000 }, (progress: any) => {
214-
timeElapsed = progress.runtime;
215-
216-
if (timeElapsed >= 1) {
217-
this.$logger.write("%s%s", carriageReturn, Array(lastMessageSize + 1).join(" "));
218-
219-
const message = util.format("%sDownload progress ... %s | %s | %s/s",
220-
carriageReturn,
221-
Math.floor(progress.percentage) + "%",
222-
filesize(progress.transferred),
223-
filesize(progress.speed));
224-
225-
this.$logger.write(message);
226-
lastMessageSize = message.length;
227-
}
228-
});
229-
230-
progressStream.on("finish", () => {
231-
if (timeElapsed >= 1) {
232-
this.$logger.out("%s%s%s%s", carriageReturn, Array(lastMessageSize + 1).join(" "), carriageReturn, "Download completed.");
233-
}
234-
});
235-
236-
progressStream.pipe(pipeTo);
237-
return progressStream;
238-
}
239-
240203
private getErrorMessage(statusCode: number, body: string): string {
241204
if (statusCode === HttpStatusCodes.PROXY_AUTHENTICATION_REQUIRED) {
242205
const clientNameLowerCase = this.$staticConfig.CLIENT_NAME.toLowerCase();

progress-indicator.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
1+
import { isInteractive } from './helpers';
2+
3+
const clui = require("clui");
4+
15
export class ProgressIndicator implements IProgressIndicator {
26
constructor(private $logger: ILogger) { }
37

48
public async showProgressIndicator<T>(promise: Promise<T>, timeout: number, options?: { surpressTrailingNewLine?: boolean }): Promise<T> {
59
const surpressTrailingNewLine = options && options.surpressTrailingNewLine;
610

7-
let isResolved = false;
11+
let isFulfilled = false;
812

913
const tempPromise = new Promise<T>((resolve, reject) => {
1014
promise.then((res) => {
11-
isResolved = true;
15+
isFulfilled = true;
1216
resolve(res);
1317
}, (err) => {
14-
isResolved = true;
18+
isFulfilled = true;
1519
reject(err);
1620
});
1721
});
1822

19-
while (!isResolved) {
20-
await this.$logger.printMsgWithTimeout(".", timeout);
23+
if (!isInteractive()) {
24+
while (!isFulfilled) {
25+
await this.$logger.printMsgWithTimeout(".", timeout);
26+
}
2127
}
2228

2329
if (!surpressTrailingNewLine) {
@@ -26,5 +32,18 @@ export class ProgressIndicator implements IProgressIndicator {
2632

2733
return tempPromise;
2834
}
35+
36+
public getSpinner(message: string): ISpinner {
37+
if (isInteractive()) {
38+
return new clui.Spinner(message);
39+
} else {
40+
let msg = message;
41+
return {
42+
start: () => this.$logger.info(msg),
43+
message: (newMsg: string) => msg = newMsg,
44+
stop: (): void => undefined
45+
};
46+
}
47+
}
2948
}
3049
$injector.register("progressIndicator", ProgressIndicator);

0 commit comments

Comments
 (0)