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

Commit 39b20eb

Browse files
Merge pull request #1044 from telerik/vladimirov/merge-rel-master
chore: merge release in master
2 parents 22e0b43 + 95a2e73 commit 39b20eb

File tree

9 files changed

+390
-44
lines changed

9 files changed

+390
-44
lines changed

declarations.d.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,38 @@ interface IProgressIndicator {
15751575
* @return {Promise<T>}
15761576
*/
15771577
showProgressIndicator<T>(promise: Promise<T>, timeout: number, options?: { surpressTrailingNewLine?: boolean }): Promise<T>;
1578+
1579+
/**
1580+
* Returns a spinner instance that will print a specified message when spinner is started and will repeat it until spinner is stopped.
1581+
* 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.
1582+
* @param {string} message The message to be printed.
1583+
* @returns {ISpinner} Instance of clui.Spinner in case terminal is interactive, mocked instance otherwise.
1584+
*/
1585+
getSpinner(message: string): ISpinner;
1586+
}
1587+
1588+
/**
1589+
* Describes the clui spinner.
1590+
*/
1591+
interface ISpinner {
1592+
/**
1593+
* Sets the message that will be printed by spinner.
1594+
* @param {string} msg The new message.
1595+
* @returns {void}
1596+
*/
1597+
message(msg: string): void;
1598+
1599+
/**
1600+
* Starts the spinner.
1601+
* @returns {void}
1602+
*/
1603+
start(): void;
1604+
1605+
/**
1606+
* Stops the spinner.
1607+
* @returns {void}
1608+
*/
1609+
stop(): void;
15781610
}
15791611

15801612
/**
@@ -1715,6 +1747,25 @@ interface IVersionData {
17151747
patch: string;
17161748
}
17171749

1750+
interface IWaitForPortListenData {
1751+
/**
1752+
* Port to be checked.
1753+
* @type {number}
1754+
*/
1755+
port: number;
1756+
1757+
/**
1758+
* Max amount of time in milliseconds to wait.
1759+
* @type {number}
1760+
*/
1761+
timeout: number;
1762+
/**
1763+
* @optional The amount of time between each check.
1764+
* @type {number}
1765+
*/
1766+
interval?: number;
1767+
}
1768+
17181769
/**
17191770
* Wrapper for net module of Node.js.
17201771
*/
@@ -1740,6 +1791,13 @@ interface INet {
17401791
* @return {Promise<boolean>} true if the port is available.
17411792
*/
17421793
isPortAvailable(port: number): Promise<boolean>;
1794+
1795+
/**
1796+
* Waits for port to be in LISTEN state.
1797+
* @param {IWaitForPortListenData} waitForPortListenData Data describing port, timeout and interval.
1798+
* @returns {boolean} true in case port is in LISTEN state, false otherwise.
1799+
*/
1800+
waitForPortToListen(waitForPortListenData: IWaitForPortListenData): Promise<boolean>;
17431801
}
17441802

17451803
interface IProcessService {
@@ -1929,6 +1987,12 @@ interface IOsInfo {
19291987
* @return {string} A string identifying the operating system bitness.
19301988
*/
19311989
arch(): string;
1990+
1991+
/**
1992+
* Returns a string identifying the operating system platform.
1993+
* @return {string} A string identifying the operating system platform.
1994+
*/
1995+
platform(): string;
19321996
}
19331997

19341998
interface IPromiseActions<T> {

definitions/mobile.d.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,8 +580,34 @@ declare module Mobile {
580580
iOSSimPath: string;
581581
}
582582

583+
/**
584+
* Describes the information when trying to connect to port.
585+
*/
586+
interface IConnectToPortData {
587+
/**
588+
* The port to connect.
589+
* @type {number}
590+
*/
591+
port: number;
592+
593+
/**
594+
* Timeout in milliseconds.
595+
* @type {number}
596+
*/
597+
timeout?: number;
598+
}
599+
583600
interface IiOSSimulatorService extends IEmulatorPlatformServices {
584601
postDarwinNotification(notification: string): Promise<void>;
602+
603+
/**
604+
* Tries to connect to specified port for speciefied amount of time.
605+
* In case it succeeds, a socket is returned.
606+
* In case it fails, undefined is returned.
607+
* @param {IConnectToPortData} connectToPortData Data describing port and timeout to try to connect.
608+
* @returns {net.Socket} Returns instance of net.Socket when connection is successful, otherwise undefined is returned.
609+
*/
610+
connectToPort(connectToPortData: IConnectToPortData): Promise<any>;
585611
}
586612

587613
interface IEmulatorSettingsService {

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: 2 additions & 38 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();
@@ -262,7 +225,8 @@ export class HttpClient implements Server.IHttpClient {
262225
return err.Message;
263226
}
264227
} catch (parsingFailed) {
265-
return `The server returned unexpected response: ${parsingFailed.toString()}`;
228+
this.$logger.trace("Failed to get error from http request: ", parsingFailed);
229+
return `The server returned unexpected response: ${body}`;
266230
}
267231

268232
return body;

mobile/ios/simulator/ios-emulator-services.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
import * as net from "net";
2+
import { connectEventuallyUntilTimeout } from "../../../helpers";
3+
14
class IosEmulatorServices implements Mobile.IiOSSimulatorService {
5+
private static DEFAULT_TIMEOUT = 10000;
6+
27
constructor(private $logger: ILogger,
38
private $emulatorSettingsService: Mobile.IEmulatorSettingsService,
49
private $errors: IErrors,
@@ -58,6 +63,15 @@ class IosEmulatorServices implements Mobile.IiOSSimulatorService {
5863
await this.$childProcess.spawnFromEvent(nodeCommandName, iosSimArgs, "close", { stdio: "inherit" });
5964
}
6065

66+
public async connectToPort(data: Mobile.IConnectToPortData): Promise<net.Socket> {
67+
try {
68+
const socket = await connectEventuallyUntilTimeout(() => net.connect(data.port), data.timeout || IosEmulatorServices.DEFAULT_TIMEOUT);
69+
return socket;
70+
} catch (e) {
71+
this.$logger.debug(e);
72+
}
73+
}
74+
6175
private async runApplicationOnEmulatorCore(app: string, emulatorOptions?: Mobile.IEmulatorOptions): Promise<any> {
6276
this.$logger.info("Starting iOS Simulator");
6377
const iosSimPath = this.$iOSSimResolver.iOSSimPath;

os-info.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ export class OsInfo implements IOsInfo {
1212
public arch(): string {
1313
return os.arch();
1414
}
15+
16+
public platform(): string {
17+
return os.platform();
18+
}
1519
}
1620

1721
$injector.register("osInfo", OsInfo);

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)