From c7465f5f7e747b5d0b182a3c66f0bd0f67bf052d Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Tue, 8 Mar 2016 15:29:48 -0800 Subject: [PATCH] Add environment module for getting environment info --- spec/environment-spec.coffee | 27 ++++++++++++++++++++++++ src/environment.coffee | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 spec/environment-spec.coffee create mode 100644 src/environment.coffee diff --git a/spec/environment-spec.coffee b/spec/environment-spec.coffee new file mode 100644 index 000000000..484bdcc1a --- /dev/null +++ b/spec/environment-spec.coffee @@ -0,0 +1,27 @@ +child_process = require('child_process') +{getShellEnv} = require("../src/environment") + +describe "Environment handling", -> + describe "when things are configured properly", -> + beforeEach -> + spyOn(child_process, "spawnSync").andReturn + stdout: """ + FOO=BAR + TERM=xterm-something + PATH=/usr/bin:/bin:/usr/sbin:/sbin:/some/crazy/path/entry/that/should/not/exist + """ + + it "returns an object containing the information from the user's shell environment", -> + env = getShellEnv() + + expect(env.FOO).toEqual "BAR" + expect(env.TERM).toEqual "xterm-something" + expect(env.PATH).toEqual "/usr/bin:/bin:/usr/sbin:/sbin:/some/crazy/path/entry/that/should/not/exist" + + describe "when an error occurs", -> + beforeEach -> + spyOn(child_process, "spawnSync").andReturn + error: new Error + + it "returns undefined", -> + expect(getShellEnv()).toBeUndefined() diff --git a/src/environment.coffee b/src/environment.coffee new file mode 100644 index 000000000..f2b9bbf47 --- /dev/null +++ b/src/environment.coffee @@ -0,0 +1,41 @@ +child_process = require('child_process') +os = require('os') + +# Gets a dump of the user's configured shell environment. +# +# Returns the output of the `env` command or `undefined` if there was an error. +getRawShellEnv = -> + shell = process.env.SHELL ? "/bin/bash" + + # The `-ilc` set of options was tested to work with the OS X v10.11 + # default-installed versions of bash, zsh, sh, and ksh. It *does not* + # work with csh or tcsh. Given that bash and zsh should cover the + # vast majority of users and it gracefully falls back to prior behavior, + # this should be safe. + results = child_process.spawnSync shell, ["-ilc"], input: "env", encoding: "utf8" + return if results.error? + return unless results.stdout and results.stdout.length > 0 + + results.stdout + +module.exports = + # Gets the user's configured shell environment. + # + # Returns a copy of the user's shell enviroment. + getShellEnv: -> + shellEnvText = getRawShellEnv() + return unless shellEnvText? + + env = {} + + for line in shellEnvText.split(os.EOL) + if line.includes("=") + components = line.split("=") + if components.length is 2 + env[components[0]] = components[1] + else + k = components.shift() + v = components.join("=") + env[k] = v + + env