From 6bf785faa0b5f795e33d53b76eeec93b504f7c72 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Mon, 7 Mar 2016 15:42:11 -0800 Subject: [PATCH] :white_check_mark: Add test for error handling --- spec/project-spec.coffee | 37 ++++++++++++++++++++++++++----------- src/project.coffee | 19 +++++++++++++++++-- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index 61dd244e8..35cd0157f 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -539,7 +539,13 @@ describe "Project", -> expect(atom.project.contains(randomPath)).toBe false describe ".getEnv", -> + [originalTerm] = [] + + beforeEach -> + originalTerm = process.env.TERM + afterEach -> + process.env.TERM = originalTerm delete atom.project.env it "returns a copy of the environment", -> @@ -554,15 +560,17 @@ describe "Project", -> spyOn(process, "platform").andReturn("foo") describe "when TERM is not set", -> - it "returns the PATH unchanged", -> - spyOn(process.env, "TERM").andReturn(undefined) + beforeEach -> + delete process.env.TERM + it "returns the PATH unchanged", -> expect(atom.project.getEnv().PATH).toEqual process.env.PATH describe "when TERM is set", -> - it "returns the PATH unchanged", -> - spyOn(process.env, "TERM").andReturn("foo") + beforeEach -> + process.env.TERM = "foo" + it "returns the PATH unchanged", -> expect(atom.project.getEnv().PATH).toEqual process.env.PATH describe "on OS X", -> @@ -570,12 +578,10 @@ describe "Project", -> spyOn(process, "platform").andReturn("darwin") describe "when TERM is not set", -> + beforeEach -> + delete process.env.TERM + it "replaces the PATH with the one obtained from the shell", -> - env = _.clone(process.env) - delete env.TERM - - spyOn(process, "env").andReturn(env) - spyOn(atom.project, "getShellEnv").andReturn """ FOO=BAR TERM=xterm-something @@ -584,9 +590,18 @@ describe "Project", -> expect(atom.project.getShellPath()).toEqual "/usr/bin:/bin:/usr/sbin:/sbin:/some/crazy/path/entry/that/should/not/exist" expect(atom.project.getEnv().PATH).toEqual "/usr/bin:/bin:/usr/sbin:/sbin:/some/crazy/path/entry/that/should/not/exist" + expect(atom.project.getEnv().FOO).not.toEqual "BAR" + + it "does the best it can when there is an error retrieving the shell environment", -> + spyOn(atom.project, "getShellEnv").andReturn(undefined) + + expect(atom.project.getShellPath()).toBeUndefined() + expect(atom.project.getEnv().PATH).not.toBeUndefined() + expect(atom.project.getEnv().PATH).toEqual process.env.PATH describe "when TERM is set", -> - it "returns the PATH unchanged", -> - spyOn(process.env, "TERM").andReturn("foo") + beforeEach -> + process.env.TERM = "foo" + it "returns the PATH unchanged", -> expect(atom.project.getEnv().PATH).toEqual process.env.PATH diff --git a/src/project.coffee b/src/project.coffee index 5d5448dc7..c8fd3ddbe 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -288,7 +288,8 @@ class Project extends Model unless @env? @env = _.clone(process.env) if process.platform is "darwin" and not process.env.TERM? - @env.PATH = @getShellPath() + shellPath = @getShellPath() + @env.PATH = shellPath if shellPath? _.clone(@env) @@ -296,8 +297,13 @@ class Project extends Model Section: Private ### + # Gets the user's configured shell `PATH`. + # + # Returns the value of `PATH` or `undefined` if there was an error. getShellPath: -> shellEnvText = @getShellEnv() + return unless shellEnvText? + env = {} for line in shellEnvText.split(os.EOL) @@ -312,9 +318,18 @@ class Project extends Model env.PATH + # Gets a dump of the user's configured shell environment. + # + # Returns the output of the `env` command or `undefined` if there was an error. getShellEnv: -> shell = process.env.SHELL ? "/bin/bash" - results = child_process.spawnSync shell, ["--login", "--interactive"], input: "env", encoding: "utf8" + + # 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