mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-11 19:17:09 +03:00
395 lines
13 KiB
JavaScript
395 lines
13 KiB
JavaScript
/** @babel */
|
|
'not strict';
|
|
|
|
import path from 'path';
|
|
import childProcess from 'child_process';
|
|
import {
|
|
updateProcessEnv,
|
|
shouldGetEnvFromShell
|
|
} from '../src/update-process-env';
|
|
import mockSpawn from 'mock-spawn';
|
|
const temp = require('temp').track();
|
|
|
|
describe('updateProcessEnv(launchEnv)', function() {
|
|
let originalProcessEnv, originalProcessPlatform, originalSpawn, spawn;
|
|
|
|
beforeEach(function() {
|
|
originalSpawn = childProcess.spawn;
|
|
spawn = mockSpawn();
|
|
childProcess.spawn = spawn;
|
|
originalProcessEnv = process.env;
|
|
originalProcessPlatform = process.platform;
|
|
process.env = {};
|
|
});
|
|
|
|
afterEach(function() {
|
|
if (originalSpawn) {
|
|
childProcess.spawn = originalSpawn;
|
|
}
|
|
process.env = originalProcessEnv;
|
|
process.platform = originalProcessPlatform;
|
|
try {
|
|
temp.cleanupSync();
|
|
} catch (e) {
|
|
// Do nothing
|
|
}
|
|
});
|
|
|
|
describe('when the launch environment appears to come from a shell', function() {
|
|
it('updates process.env to match the launch environment because PWD is set', async function() {
|
|
process.env = {
|
|
WILL_BE_DELETED: 'hi',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
};
|
|
|
|
const initialProcessEnv = process.env;
|
|
|
|
await updateProcessEnv({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir',
|
|
TERM: 'xterm-something',
|
|
KEY1: 'value1',
|
|
KEY2: 'value2'
|
|
});
|
|
expect(process.env).toEqual({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir',
|
|
TERM: 'xterm-something',
|
|
KEY1: 'value1',
|
|
KEY2: 'value2',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
});
|
|
|
|
// See #11302. On Windows, `process.env` is a magic object that offers
|
|
// case-insensitive environment variable matching, so we cannot replace it
|
|
// with another object.
|
|
expect(process.env).toBe(initialProcessEnv);
|
|
});
|
|
|
|
it('updates process.env to match the launch environment because PROMPT is set', async function() {
|
|
process.env = {
|
|
WILL_BE_DELETED: 'hi',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
};
|
|
|
|
const initialProcessEnv = process.env;
|
|
|
|
await updateProcessEnv({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PROMPT: '$P$G',
|
|
KEY1: 'value1',
|
|
KEY2: 'value2'
|
|
});
|
|
expect(process.env).toEqual({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PROMPT: '$P$G',
|
|
KEY1: 'value1',
|
|
KEY2: 'value2',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
});
|
|
|
|
// See #11302. On Windows, `process.env` is a magic object that offers
|
|
// case-insensitive environment variable matching, so we cannot replace it
|
|
// with another object.
|
|
expect(process.env).toBe(initialProcessEnv);
|
|
});
|
|
|
|
it('updates process.env to match the launch environment because PSModulePath is set', async function() {
|
|
process.env = {
|
|
WILL_BE_DELETED: 'hi',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
};
|
|
|
|
const initialProcessEnv = process.env;
|
|
|
|
await updateProcessEnv({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PSModulePath:
|
|
'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules\\',
|
|
KEY1: 'value1',
|
|
KEY2: 'value2'
|
|
});
|
|
expect(process.env).toEqual({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PSModulePath:
|
|
'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules\\',
|
|
KEY1: 'value1',
|
|
KEY2: 'value2',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
});
|
|
|
|
// See #11302. On Windows, `process.env` is a magic object that offers
|
|
// case-insensitive environment variable matching, so we cannot replace it
|
|
// with another object.
|
|
expect(process.env).toBe(initialProcessEnv);
|
|
});
|
|
|
|
it('allows ATOM_HOME to be overwritten only if the new value is a valid path', async function() {
|
|
let newAtomHomePath = temp.mkdirSync('atom-home');
|
|
|
|
process.env = {
|
|
WILL_BE_DELETED: 'hi',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
};
|
|
|
|
await updateProcessEnv({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir'
|
|
});
|
|
expect(process.env).toEqual({
|
|
PWD: '/the/dir',
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
});
|
|
|
|
await updateProcessEnv({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir',
|
|
ATOM_HOME: path.join(newAtomHomePath, 'non-existent')
|
|
});
|
|
expect(process.env).toEqual({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
});
|
|
|
|
await updateProcessEnv({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir',
|
|
ATOM_HOME: newAtomHomePath
|
|
});
|
|
expect(process.env).toEqual({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: newAtomHomePath
|
|
});
|
|
});
|
|
|
|
it('allows ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT to be preserved if set', async function() {
|
|
process.env = {
|
|
WILL_BE_DELETED: 'hi',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
};
|
|
|
|
await updateProcessEnv({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
});
|
|
expect(process.env).toEqual({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
});
|
|
|
|
await updateProcessEnv({
|
|
PWD: '/the/dir',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
});
|
|
expect(process.env).toEqual({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
PWD: '/the/dir',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
});
|
|
});
|
|
|
|
it('allows an existing env variable to be updated', async function() {
|
|
process.env = {
|
|
WILL_BE_UPDATED: 'old-value',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home'
|
|
};
|
|
|
|
await updateProcessEnv(process.env);
|
|
expect(process.env).toEqual(process.env);
|
|
|
|
let updatedEnv = {
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
WILL_BE_UPDATED: 'new-value',
|
|
NODE_ENV: 'the-node-env',
|
|
NODE_PATH: '/the/node/path',
|
|
ATOM_HOME: '/the/atom/home',
|
|
PWD: '/the/dir'
|
|
};
|
|
|
|
await updateProcessEnv(updatedEnv);
|
|
expect(process.env).toEqual(updatedEnv);
|
|
});
|
|
});
|
|
|
|
describe('when the launch environment does not come from a shell', function() {
|
|
describe('on macOS', function() {
|
|
it("updates process.env to match the environment in the user's login shell", async function() {
|
|
if (process.platform === 'win32') return; // TestsThatFailOnWin32
|
|
|
|
process.platform = 'darwin';
|
|
process.env.SHELL = '/my/custom/bash';
|
|
spawn.setDefault(
|
|
spawn.simple(
|
|
0,
|
|
'FOO=BAR=BAZ=QUUX\0MULTILINE\nNAME=multiline\nvalue\0TERM=xterm-something\0PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
|
|
)
|
|
);
|
|
await updateProcessEnv(process.env);
|
|
expect(spawn.calls.length).toBe(1);
|
|
expect(spawn.calls[0].command).toBe('/my/custom/bash');
|
|
expect(spawn.calls[0].args).toEqual([
|
|
'-ilc',
|
|
'command awk \'BEGIN{for(v in ENVIRON) printf("%s=%s%c", v, ENVIRON[v], 0)}\''
|
|
]);
|
|
expect(process.env).toEqual({
|
|
FOO: 'BAR=BAZ=QUUX',
|
|
'MULTILINE\nNAME': 'multiline\nvalue',
|
|
TERM: 'xterm-something',
|
|
PATH: '/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
|
|
});
|
|
|
|
// Doesn't error
|
|
await updateProcessEnv(null);
|
|
});
|
|
});
|
|
|
|
describe('on linux', function() {
|
|
it("updates process.env to match the environment in the user's login shell", async function() {
|
|
if (process.platform === 'win32') return; // TestsThatFailOnWin32
|
|
|
|
process.platform = 'linux';
|
|
process.env.SHELL = '/my/custom/bash';
|
|
spawn.setDefault(
|
|
spawn.simple(
|
|
0,
|
|
'FOO=BAR=BAZ=QUUX\0MULTILINE\nNAME=multiline\nvalue\0TERM=xterm-something\0PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
|
|
)
|
|
);
|
|
await updateProcessEnv(process.env);
|
|
expect(spawn.calls.length).toBe(1);
|
|
expect(spawn.calls[0].command).toBe('/my/custom/bash');
|
|
expect(spawn.calls[0].args).toEqual([
|
|
'-ilc',
|
|
'command awk \'BEGIN{for(v in ENVIRON) printf("%s=%s%c", v, ENVIRON[v], 0)}\''
|
|
]);
|
|
expect(process.env).toEqual({
|
|
FOO: 'BAR=BAZ=QUUX',
|
|
'MULTILINE\nNAME': 'multiline\nvalue',
|
|
TERM: 'xterm-something',
|
|
PATH: '/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path'
|
|
});
|
|
|
|
// Doesn't error
|
|
await updateProcessEnv(null);
|
|
});
|
|
});
|
|
|
|
describe('on windows', function() {
|
|
it('does not update process.env', async function() {
|
|
process.platform = 'win32';
|
|
spyOn(childProcess, 'spawn');
|
|
process.env = { FOO: 'bar' };
|
|
|
|
await updateProcessEnv(process.env);
|
|
expect(childProcess.spawn).not.toHaveBeenCalled();
|
|
expect(process.env).toEqual({ FOO: 'bar' });
|
|
});
|
|
});
|
|
|
|
describe('shouldGetEnvFromShell()', function() {
|
|
it('indicates when the environment should be fetched from the shell', function() {
|
|
if (process.platform === 'win32') return; // TestsThatFailOnWin32
|
|
|
|
process.platform = 'darwin';
|
|
expect(shouldGetEnvFromShell({ SHELL: '/bin/sh' })).toBe(true);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/usr/local/bin/sh' })).toBe(
|
|
true
|
|
);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/bin/bash' })).toBe(true);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/usr/local/bin/bash' })).toBe(
|
|
true
|
|
);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/bin/zsh' })).toBe(true);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/usr/local/bin/zsh' })).toBe(
|
|
true
|
|
);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/bin/fish' })).toBe(true);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/usr/local/bin/fish' })).toBe(
|
|
true
|
|
);
|
|
process.platform = 'linux';
|
|
expect(shouldGetEnvFromShell({ SHELL: '/bin/sh' })).toBe(true);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/usr/local/bin/sh' })).toBe(
|
|
true
|
|
);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/bin/bash' })).toBe(true);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/usr/local/bin/bash' })).toBe(
|
|
true
|
|
);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/bin/zsh' })).toBe(true);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/usr/local/bin/zsh' })).toBe(
|
|
true
|
|
);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/bin/fish' })).toBe(true);
|
|
expect(shouldGetEnvFromShell({ SHELL: '/usr/local/bin/fish' })).toBe(
|
|
true
|
|
);
|
|
});
|
|
|
|
it('returns false when the environment indicates that Atom was launched from a shell', function() {
|
|
process.platform = 'darwin';
|
|
expect(
|
|
shouldGetEnvFromShell({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
SHELL: '/bin/sh'
|
|
})
|
|
).toBe(false);
|
|
process.platform = 'linux';
|
|
expect(
|
|
shouldGetEnvFromShell({
|
|
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
|
SHELL: '/bin/sh'
|
|
})
|
|
).toBe(false);
|
|
});
|
|
|
|
it('returns false when the shell is undefined or empty', function() {
|
|
process.platform = 'darwin';
|
|
expect(shouldGetEnvFromShell(undefined)).toBe(false);
|
|
expect(shouldGetEnvFromShell({})).toBe(false);
|
|
|
|
process.platform = 'linux';
|
|
expect(shouldGetEnvFromShell(undefined)).toBe(false);
|
|
expect(shouldGetEnvFromShell({})).toBe(false);
|
|
});
|
|
});
|
|
});
|
|
});
|