Skip to content

Commit f167357

Browse files
Merge pull request #4404 from NativeScript/vladimirov/fix-CI-output
fix: errors from `tns doctor` are not visible in CI environment
2 parents 926957a + a7fec56 commit f167357

File tree

4 files changed

+83
-14
lines changed

4 files changed

+83
-14
lines changed

lib/common/helpers.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,27 @@ export function versionCompare(version1: string | IVersionData, version2: string
309309
}
310310

311311
export function isInteractive(): boolean {
312-
return process.stdout.isTTY && process.stdin.isTTY;
312+
const isInteractive = isRunningInTTY() && !isCIEnvironment();
313+
return isInteractive;
314+
}
315+
316+
/**
317+
* Checks if current process is running in Text Terminal (TTY)
318+
*/
319+
function isRunningInTTY(): boolean {
320+
return process.stdout &&
321+
process.stdout.isTTY &&
322+
process.stdin &&
323+
process.stdin.isTTY;
324+
}
325+
326+
function isCIEnvironment(): boolean {
327+
// The following CI environments set their own environment variables that we respect:
328+
// travis: "CI",
329+
// circleCI: "CI",
330+
// jenkins: "JENKINS_HOME"
331+
332+
return !!(process.env && (process.env.CI || process.env.JENKINS_HOME));
313333
}
314334

315335
export function toBoolean(str: any): boolean {

lib/common/test/unit-tests/helpers.ts

+51
Original file line numberDiff line numberDiff line change
@@ -861,4 +861,55 @@ const test = require("./test");`,
861861
});
862862
});
863863
});
864+
865+
describe("isInteractive", () => {
866+
const originalEnv = process.env;
867+
const originalStdoutIsTTY = process.stdout.isTTY;
868+
const originalStdinIsTTY = process.stdin.isTTY;
869+
beforeEach(() => {
870+
process.env.CI = "";
871+
process.env.JENKINS_HOME = "";
872+
});
873+
874+
afterEach(() => {
875+
process.env = originalEnv;
876+
process.stdout.isTTY = originalStdoutIsTTY;
877+
process.stdin.isTTY = originalStdinIsTTY;
878+
});
879+
880+
it("returns false when stdout is not TTY", () => {
881+
(<any>process.stdout).isTTY = false;
882+
(<any>process.stdin).isTTY = true;
883+
assert.isFalse(helpers.isInteractive());
884+
});
885+
886+
it("returns false when stdin is not TTY", () => {
887+
(<any>process.stdin).isTTY = false;
888+
(<any>process.stdout).isTTY = true;
889+
assert.isFalse(helpers.isInteractive());
890+
});
891+
892+
it("returns false when stdout and stdin are TTY, but CI env var is set", () => {
893+
(<any>process.stdout).isTTY = true;
894+
(<any>process.stdin).isTTY = true;
895+
process.env.CI = "true";
896+
897+
assert.isFalse(helpers.isInteractive());
898+
});
899+
900+
it("returns false when stdout and stdin are TTY, but JENKINS_HOME env var is set", () => {
901+
(<any>process.stdout).isTTY = true;
902+
(<any>process.stdin).isTTY = true;
903+
process.env.JENKINS_HOME = "/usr/local/lib/jenkins";
904+
905+
assert.isFalse(helpers.isInteractive());
906+
});
907+
908+
it("returns true when stdout and stdin are TTY and neither CI or JENKINS_HOME are set", () => {
909+
(<any>process.stdout).isTTY = true;
910+
(<any>process.stdin).isTTY = true;
911+
912+
assert.isTrue(helpers.isInteractive());
913+
});
914+
});
864915
});

test/services/doctor-service.ts

-11
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,6 @@ describe("doctorService", () => {
111111
filesContents: {
112112
file1: `const application = require("application");
113113
const Observable = require("data/observable").Observable;
114-
`
115-
},
116-
expectedShortImports: [
117-
{ file: "file1", line: 'const application = require("application");' },
118-
{ file: "file1", line: 'const Observable = require("data/observable").Observable;' },
119-
]
120-
},
121-
{
122-
filesContents: {
123-
file1: `const application = require("application");
124-
const Observable = require("data/observable").Observable;
125114
`
126115
},
127116
expectedShortImports: [

test/services/platform-environment-requirements.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { PlatformEnvironmentRequirements } from '../../lib/services/platform-env
33
import * as stubs from "../stubs";
44
import { assert } from "chai";
55
import { EOL } from "os";
6+
const helpers = require("../../lib/common/helpers");
67

8+
const originalIsInteractive = helpers.isInteractive;
79
const platform = "android";
810
const cloudBuildsErrorMessage = `In order to test your application use the $ tns login command to log in with your account and then $ tns cloud build command to build your app in the cloud.`;
911
const manuallySetupErrorMessage = `To be able to build for ${platform}, verify that your environment is configured according to the system requirements described at `;
@@ -34,6 +36,14 @@ function createTestInjector() {
3436
}
3537

3638
describe("platformEnvironmentRequirements ", () => {
39+
beforeEach(() => {
40+
helpers.isInteractive = () => true;
41+
});
42+
43+
afterEach(() => {
44+
helpers.isInteractive = originalIsInteractive;
45+
});
46+
3747
describe("checkRequirements", () => {
3848
let testInjector: IInjector = null;
3949
let platformEnvironmentRequirements: IPlatformEnvironmentRequirements = null;
@@ -221,8 +231,7 @@ describe("platformEnvironmentRequirements ", () => {
221231

222232
describe("when console is non interactive", () => {
223233
beforeEach(() => {
224-
(<any>process).stdout.isTTY = false;
225-
(<any>process.stdin).isTTY = false;
234+
helpers.isInteractive = () => false;
226235
mockDoctorService({ canExecuteLocalBuild: false });
227236
});
228237

0 commit comments

Comments
 (0)