Skip to content

Commit

Permalink
fix: add tty helper to not ask for prompt in non tty/ci env (gatsbyjs…
Browse files Browse the repository at this point in the history
…#13290)

## Description
added a utility to check if isTTY is enabled so we don't ask for prompts.

In future PRs we might want to move it to gatsby or gatsby-utils package so we can use it in different packages like telemetry.
  • Loading branch information
wardpeet authored and pieh committed Apr 11, 2019
1 parent 6059bce commit efae20e
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 87 deletions.
1 change: 1 addition & 0 deletions packages/gatsby-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@babel/code-frame": "^7.0.0",
"@babel/runtime": "^7.0.0",
"bluebird": "^3.5.0",
"ci-info": "^2.0.0",
"common-tags": "^1.4.0",
"configstore": "^4.0.0",
"convert-hrtime": "^2.0.0",
Expand Down
54 changes: 25 additions & 29 deletions packages/gatsby-cli/src/init-starter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* @flow */
const { execSync } = require(`child_process`)
const Configstore = require(`configstore`)
const execa = require(`execa`)
const hostedGitInfo = require(`hosted-git-info`)
const fs = require(`fs-extra`)
Expand All @@ -9,23 +8,37 @@ const report = require(`./reporter`)
const url = require(`url`)
const existsSync = require(`fs-exists-cached`).sync
const { trackCli, trackError } = require(`gatsby-telemetry`)
const prompts = require(`prompts`)

const {
getPackageManager,
promptPackageManager,
} = require(`./util/configstore`)
const isTTY = require(`./util/is-tty`)
const spawn = (cmd: string, options: any) => {
const [file, ...args] = cmd.split(/\s+/)
return execa(file, args, { stdio: `inherit`, ...options })
}

const conf = new Configstore(`gatsby`, {}, { globalConfigPath: true })

// Checks the existence of yarn package
// Checks the existence of yarn package and user preference if it exists
// We use yarnpkg instead of yarn to avoid conflict with Hadoop yarn
// Refer to https://github.com/yarnpkg/yarn/issues/673
//
// Returns true if yarn exists, false otherwise
const shouldUseYarn = () => {
const shouldUseYarn = async () => {
try {
execSync(`yarnpkg --version`, { stdio: `ignore` })
return true

let packageManager = getPackageManager()
if (!packageManager) {
// if package manager is not set:
// - prompt user to pick package manager if in interactive console
// - default to yarn if not in interactive console
if (isTTY()) {
packageManager = (await promptPackageManager()) || `yarn`
} else {
packageManager = `yarn`
}
}

return packageManager === `yarn`
} catch (e) {
return false
}
Expand Down Expand Up @@ -71,30 +84,13 @@ const install = async rootPath => {
process.chdir(rootPath)

try {
const npmCmd = `npm install`
let response = npmCmd
if (shouldUseYarn()) {
const promptsAnswer = await prompts([
{
type: `select`,
name: `package_manager`,
message: `Which package manager would you like to use ?`,
choices: [
{ title: `yarn`, value: `yarnpkg` },
{ title: `npm`, value: npmCmd },
],
initial: 0,
},
])
response = promptsAnswer.package_manager
}
conf.set(`package_manager`, response)
if (response.includes(`yarn`)) {
if (await shouldUseYarn()) {
await fs.remove(`package-lock.json`)
await spawn(`yarnpkg`)
} else {
await fs.remove(`yarn.lock`)
await spawn(`npm install`)
}
await spawn(response)
} finally {
process.chdir(prevDir)
}
Expand Down
47 changes: 47 additions & 0 deletions packages/gatsby-cli/src/util/__tests__/is-tty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
describe(`isTTY`, () => {
let originalTTY
beforeEach(() => {
jest.resetModules()

originalTTY = process.stdout.isTTY
})
afterEach(() => {
process.stdout.isTTY = originalTTY
})

it(`returns true if not on ci & TTY is enabled`, () => {
process.stdout.isTTY = true
jest.mock(`ci-info`, () => {
return { isCI: false }
})
const isTTY = require(`../is-tty`)
expect(isTTY()).toBe(true)
})

it(`returns false if not on ci & TTY is disabled`, () => {
process.stdout.isTTY = false
jest.mock(`ci-info`, () => {
return { isCI: false }
})
const isTTY = require(`../is-tty`)
expect(isTTY()).toBe(false)
})

it(`returns false if on ci & TTY is enabled`, () => {
process.stdout.isTTY = true
jest.mock(`ci-info`, () => {
return { isCI: true }
})
const isTTY = require(`../is-tty`)
expect(isTTY()).toBe(false)
})

it(`returns false if on ci & TTY is disabled`, () => {
process.stdout.isTTY = false
jest.mock(`ci-info`, () => {
return { isCI: true }
})
const isTTY = require(`../is-tty`)
expect(isTTY()).toBe(false)
})
})
45 changes: 45 additions & 0 deletions packages/gatsby-cli/src/util/configstore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const Configstore = require(`configstore`)
const prompts = require(`prompts`)
const report = require(`../reporter`)

let conf
try {
conf = new Configstore(`gatsby`, {}, { globalConfigPath: true })
} catch (e) {
// This should never happen (?)
conf = {
settings: {
"cli.packageManager": undefined,
},
get: key => conf.settings[key],
set: (key, value) => (conf.settings[key] = value),
}
}

const packageMangerConfigKey = `cli.packageManager`
exports.getPackageManager = () => conf.get(packageMangerConfigKey)
const setPackageManager = packageManager => {
conf.set(packageMangerConfigKey, packageManager)
report.info(`Preferred package manager set to "${packageManager}"`)
}
exports.setPackageManager = setPackageManager

exports.promptPackageManager = async () => {
const promptsAnswer = await prompts([
{
type: `select`,
name: `package_manager`,
message: `Which package manager would you like to use ?`,
choices: [
{ title: `yarn`, value: `yarn` },
{ title: `npm`, value: `npm` },
],
initial: 0,
},
])
const response = promptsAnswer.package_manager
if (response) {
setPackageManager(response)
}
return response
}
6 changes: 6 additions & 0 deletions packages/gatsby-cli/src/util/is-tty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const isCI = require(`ci-info`).isCI

// Some CI pipelines incorrectly report process.stdout.isTTY status,
// which causes unwanted lines in the output. An additional check for isCI helps.
// @see https://github.com/prettier/prettier/blob/36aeb4ce4f620023c8174e826d7208c0c64f1a0b/src/utils/is-tty.js
module.exports = () => process.stdout.isTTY && !isCI
58 changes: 0 additions & 58 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4900,13 +4900,6 @@ bindings@^1.3.1:
dependencies:
file-uri-to-path "1.0.0"

bindings@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
dependencies:
file-uri-to-path "1.0.0"

bl@^1.0.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
Expand Down Expand Up @@ -14717,11 +14710,6 @@ nan@^2.10.0, nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==

nan@^2.13.1:
version "2.13.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7"
integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==

nan@^2.9.2:
version "2.11.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099"
Expand Down Expand Up @@ -14819,13 +14807,6 @@ node-abi@^2.2.0:
dependencies:
semver "^5.4.1"

node-abi@^2.7.0:
version "2.7.1"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.7.1.tgz#a8997ae91176a5fbaa455b194976e32683cda643"
integrity sha512-OV8Bq1OrPh6z+Y4dqwo05HqrRL9YNF7QVMRfq1/pguwKLG+q9UB/Lk0x5qXjO23JjJg+/jqCHSTaG1P3tfKfuw==
dependencies:
semver "^5.4.1"

[email protected]:
version "0.1.8"
resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d"
Expand Down Expand Up @@ -16743,28 +16724,6 @@ prebuild-install@^5.2.2:
tunnel-agent "^0.6.0"
which-pm-runs "^1.0.0"

prebuild-install@^5.2.5:
version "5.2.5"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.2.5.tgz#c7485911fe98950b7f7cd15bb9daee11b875cc44"
integrity sha512-6uZgMVg7yDfqlP5CPurVhtq3hUKBFNufiar4J5hZrlHTo59DDBEtyxw01xCdFss9j0Zb9+qzFVf/s4niayba3w==
dependencies:
detect-libc "^1.0.3"
expand-template "^2.0.3"
github-from-package "0.0.0"
minimist "^1.2.0"
mkdirp "^0.5.1"
napi-build-utils "^1.0.1"
node-abi "^2.7.0"
noop-logger "^0.1.1"
npmlog "^4.0.1"
os-homedir "^1.0.1"
pump "^2.0.1"
rc "^1.2.7"
simple-get "^2.7.0"
tar-fs "^1.13.0"
tunnel-agent "^0.6.0"
which-pm-runs "^1.0.0"

prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
Expand Down Expand Up @@ -18805,23 +18764,6 @@ sharp@^0.21.3:
tar "^4.4.8"
tunnel-agent "^0.6.0"

sharp@^0.22.0:
version "0.22.0"
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.22.0.tgz#cf4cfcb019941fd06ac24555d9f5bc84536d29be"
integrity sha512-yInpiWYvVbE0hJylso2Q2A7QaYFBxGdSlVVHGeUf1F9JsQNAUpmaqdnX54TImgKbSCy9mQpEAoGm1pcKCZhCsQ==
dependencies:
bindings "^1.5.0"
color "^3.1.0"
detect-libc "^1.0.3"
fs-copy-file-sync "^1.1.1"
nan "^2.13.1"
npmlog "^4.1.2"
prebuild-install "^5.2.5"
semver "^5.6.0"
simple-get "^3.0.3"
tar "^4.4.8"
tunnel-agent "^0.6.0"

shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
Expand Down

0 comments on commit efae20e

Please sign in to comment.