mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-05 06:40:56 -06:00
120 lines
2.5 KiB
JavaScript
120 lines
2.5 KiB
JavaScript
const _ = require('lodash')
|
|
const Promise = require('bluebird')
|
|
const execa = require('execa')
|
|
const os = require('os')
|
|
const commandExistsModule = require('command-exists')
|
|
const log = require('../log')
|
|
|
|
const isWindows = () => {
|
|
return os.platform() === 'win32'
|
|
}
|
|
|
|
const profiles = {
|
|
'~/.profile': /\/k?sh$/,
|
|
'~/.bash_profile': /\/bash$/,
|
|
'~/.cshrc': /\/csh$/,
|
|
'~/.zshrc': /\/zsh$/,
|
|
'~/.config/fish/config.fish': /\/fish$/,
|
|
}
|
|
|
|
let sourcedProfiles = []
|
|
|
|
// returns true if Cypress application has been started from
|
|
// the terminal shell.
|
|
// returns false if Cypress application has been started
|
|
// from the Finder / Windows Explorer list
|
|
// by double clicking its icon
|
|
const startedNormally = () => {
|
|
return Boolean(process.env._)
|
|
}
|
|
|
|
const getProfilePath = function (shellPath) {
|
|
for (let profilePath in profiles) {
|
|
const regex = profiles[profilePath]
|
|
|
|
if (regex.test(shellPath)) {
|
|
return profilePath
|
|
}
|
|
}
|
|
}
|
|
|
|
const sourceShellCommand = function (cmd, shell) {
|
|
if (!shell) {
|
|
return cmd
|
|
}
|
|
|
|
const profilePath = getProfilePath(shell)
|
|
|
|
log('shell %s profile %s', shell, profilePath)
|
|
if (sourcedProfiles.includes(profilePath)) {
|
|
log('profile has already been sourced')
|
|
|
|
return cmd
|
|
}
|
|
|
|
const haveShell = startedNormally()
|
|
|
|
if (haveShell) {
|
|
// we only need to source once
|
|
// IF THE APP HAS NOT BEEN STARTED BY
|
|
// DOUBLE CLICKING IT FROM FINDER / WINDOWS EXPLORER
|
|
// OTHERWISE NEED TO SOURCE EVERY COMMAND
|
|
sourcedProfiles.push(profilePath)
|
|
}
|
|
|
|
// sourcing the profile can output un-needed garbage,
|
|
// so suppress it by sending it to /dev/null and ignore
|
|
// any failures with this
|
|
return `source ${profilePath} > /dev/null 2>&1; ${cmd}`
|
|
}
|
|
|
|
const findBash = () => {
|
|
return execa.shell('which bash')
|
|
.then((val) => val.stdout)
|
|
}
|
|
|
|
const getShell = function (shell) {
|
|
if (shell) {
|
|
return Promise.resolve(shell)
|
|
}
|
|
|
|
// if we didn't get a shell such
|
|
// as when we're in docker
|
|
let s = process.env.SHELL
|
|
|
|
if (s) {
|
|
return Promise.resolve(s)
|
|
}
|
|
|
|
if (isWindows()) {
|
|
log('use default shell on Windows')
|
|
|
|
return Promise.resolve()
|
|
}
|
|
|
|
return findBash()
|
|
}
|
|
|
|
const commandExists = (command) => {
|
|
return Promise.resolve(commandExistsModule(command))
|
|
.return(true)
|
|
// commandExists rejects with no error if command does not exist
|
|
// otherwise, it's a legitimate error
|
|
.catchReturn(_.isNil, false)
|
|
}
|
|
|
|
// for testing
|
|
const reset = () => {
|
|
return sourcedProfiles = []
|
|
}
|
|
|
|
module.exports = {
|
|
reset,
|
|
findBash,
|
|
getShell,
|
|
getProfilePath,
|
|
sourceShellCommand,
|
|
startedNormally,
|
|
commandExists,
|
|
}
|