{"action":"created","issue":{"url":"https://api.github.com/repos/atom/atom/issues/4126","labels_url":"https://api.github.com/repos/atom/atom/issues/4126/labels{/name}","comments_url":"https://api.github.com/repos/atom/atom/issues/4126/comments","events_url":"https://api.github.com/repos/atom/atom/issues/4126/events","html_url":"https://github.com/atom/atom/issues/4126","id":48251275,"number":4126,"title":"Inconsistent environment and behaviour","user":{"login":"lloeki","id":75445,"avatar_url":"https://avatars.githubusercontent.com/u/75445?v=3","gravatar_id":"","url":"https://api.github.com/users/lloeki","html_url":"https://github.com/lloeki","followers_url":"https://api.github.com/users/lloeki/followers","following_url":"https://api.github.com/users/lloeki/following{/other_user}","gists_url":"https://api.github.com/users/lloeki/gists{/gist_id}","starred_url":"https://api.github.com/users/lloeki/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lloeki/subscriptions","organizations_url":"https://api.github.com/users/lloeki/orgs","repos_url":"https://api.github.com/users/lloeki/repos","events_url":"https://api.github.com/users/lloeki/events{/privacy}","received_events_url":"https://api.github.com/users/lloeki/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/atom/atom/labels/help-wanted","name":"help-wanted","color":"159818"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2014-11-10T10:43:06Z","updated_at":"2015-08-18T08:32:30Z","closed_at":null,"body":"# Problem\r\n\r\nVarious tools don't operate correctly depending on the order and the manner with which Atom is started.\r\n\r\nAlso, persisted state is not restored consistently.\r\n\r\n# Cause\r\n\r\nDepending the manner in which Atom is started, a different environment is inherited.\r\n\r\n- **launchd event**: inherits launchd mostly blank env, which means no shell env vars\r\n- **`atom` in the terminal**: inherits currently set vars\r\n\r\nThis applied to when the app is *started*, not when a new window is opened, in which case that window will inherit the current process env (which is normal OS X behaviour)\r\n\r\nI venture the creation of the `atom` command this way is on purpose to work around the lack of env when run from launchd. But please, dear reader, continue on to the next step.\r\n\r\n# Current workaround / Anti-feature\r\n\r\nManually control Atom startup each time you want to use it in a specific environment.\r\n\r\nWhy is it an anti feature? If you want two projects open at the same time but with different environments, you're busted.\r\n\r\nAlso, long running sessions and *\"wait what env was that started with already?\"* (session can also mean the idiomatic \"document != app\" OS X way: \"Atom.app is started but no windows are opened\") .\r\n\r\nAlso also, frustration quickly sets in when you start it up the wrong way and have to quit and restart halfway through your work and notice your linter does not actually run (manual config does not cut it because 1. it's manual and 2. constantly changing versions means constantly changing path).\r\n\r\n# Possible solution\r\n\r\n1. wrap Atom.app startup in a login shell (i.e make `Atom.app/Contents/MacOS/Atom` a script that calls whatever the user shell is† as a login, non-interactive one before calling the real `Atom` binary), to inherit global env, so that chruby/rbenv/GOPATH/whatever works.\r\n2. make `atom` command send a signal to `Atom.app` instead of starting atom itself via `Contents/MacOS/Atom`. Basically, `atom foo/bar` has no reason to be different from `open -a Atom foo/bar`. ~~Precisely, it *does not* inherit the local environment.~~\r\n3. local environment management is bestowed to package implementor (meaning detection of `.git`, `Gemfile`, `.rubocop.yml`, `.gopath`, which they have to do anyway else at least starting via launchd is broken, if not more), not to manual handling by developer.\r\n\r\n# Consequences\r\n\r\n- `PATH` & al. is properly set and tools like linters can leverage the env to use chruby/rbenv/whatever.\r\n- Clicking the icon, starting via spotlight, opening a file from Finder, using `open -a Atom` and using `atom foo` on the terminal are all consistent, whatever the order they are executed in.\r\n- Everything is now consistent and we can now rejoice as glittery roses spontaneously bloom out of Bose-Einstein condensates.\r\n\r\n# Additional note\r\n\r\nPet peeve: `atom` is currently equivalent to `atom .`. While I can see how this could be ok on other platforms, this is subtly wrong on OS X as `atom` is expected to be equivalent to `open -a Atom`, i.e start the app and don't open anything (unless it's set up to open a new document when no document is opened, otherwise merely focus the app, and if the app is not started, start it)\r\n\r\nOn another planet, I don't know if this issue applies to other OSes as well besides OS X. Everything depends on how process management and app/doc/task GUI model is handled there.\r\n\r\n# Final word\r\n\r\nAll of this really matters daily when you juggle between projects and makes Atom feel like an unfinished, brittle product, making angry coworkers throwing nails at me for having pushed Atom on them.\r\n\r\n† think fish-shell or (god forbid) csh."},"comment":{"url":"https://api.github.com/repos/atom/atom/issues/comments/132119777","html_url":"https://github.com/atom/atom/issues/4126#issuecomment-132119777","issue_url":"https://api.github.com/repos/atom/atom/issues/4126","id":132119777,"user":{"login":"lloeki","id":75445,"avatar_url":"https://avatars.githubusercontent.com/u/75445?v=3","gravatar_id":"","url":"https://api.github.com/users/lloeki","html_url":"https://github.com/lloeki","followers_url":"https://api.github.com/users/lloeki/followers","following_url":"https://api.github.com/users/lloeki/following{/other_user}","gists_url":"https://api.github.com/users/lloeki/gists{/gist_id}","starred_url":"https://api.github.com/users/lloeki/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lloeki/subscriptions","organizations_url":"https://api.github.com/users/lloeki/orgs","repos_url":"https://api.github.com/users/lloeki/repos","events_url":"https://api.github.com/users/lloeki/events{/privacy}","received_events_url":"https://api.github.com/users/lloeki/received_events","type":"User","site_admin":false},"created_at":"2015-08-18T08:32:30Z","updated_at":"2015-08-18T08:32:30Z","body":"Testing with:\r\n\r\n```javascript\r\nnew (require(\"atom\").BufferedProcess)({\r\n  command: \"ruby\",\r\n  args: [\"-e\", 'puts ENV.map(&:to_s).join(\"\\n\")'],\r\n  stdout: function(out) { console.log(\"OUT:\\n\", out); },\r\n  stderr: function(out) { console.log(\"ERR:\\n\", out); },\r\n});\r\n```\r\n\r\nOutput on `atom` and `open -a Atom` don't differ (which is normal given `atom.sh` content) while output of either one with an icon launch differ significantly, the latter missing a lot of vars:\r\n\r\n```diff\r\n< [\"RBENV_VERSION\", \"2.2.2\"]\r\n< [\"TERM_PROGRAM\", \"Apple_Terminal\"]\r\n< [\"ANDROID_HOME\", \"/usr/local/opt/android-sdk\"]\r\n< [\"TERM\", \"xterm-256color\"]\r\n---\r\n>  [\"RBENV_VERSION\", \"2.2.2\"]\r\n6d2\r\n< [\"CLICOLOR\", \"1\"]\r\n9,10d4\r\n< [\"TERM_PROGRAM_VERSION\", \"360\"]\r\n< [\"TERM_SESSION_ID\", \"C06FFFD2-16C3-48CD-AE1D-9CF8A31C6DA2\"]\r\n18c12\r\n< [\"PATH\", \"/Users/lloeki/.rbenv/versions/2.2.2/bin:/usr/local/Cellar/rbenv/0.4.0/libexec:/Users/lloeki/.rbenv/shims:/Users/lloeki/.rbenv/bin:/usr/local/bin:/usr/local/sbin:/Users/lloeki/.local/bin:/Users/lloeki/.rbenv/shims:/Users/lloeki/.rbenv/bin:/Users/lloeki/Library/Python/2.7/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/share/npm/bin:/usr/local/opt/go/libexec/bin\"]\r\n---\r\n> [\"PATH\", \"/Users/lloeki/.rbenv/versions/2.2.2/bin:/usr/local/Cellar/rbenv/0.4.0/libexec:/Users/lloeki/.rbenv/shims:/Users/lloeki/.rbenv/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin\"]\r\n20,21d13\r\n< [\"EDITOR\", \"vim\"]\r\n< [\"LANG\", \"en_GB.UTF-8\"]\r\n26c18\r\n< [\"SHLVL\", \"2\"]\r\n---\r\n> [\"SHLVL\", \"0\"]\r\n28d19\r\n< [\"GREP_OPTIONS\", \"--color=auto\"]\r\n31,32d21\r\n< [\"VISUAL\", \"vim\"]\r\n< [\"HOMEBREW_NO_EMOJI\", \"you bet\"]\r\n```\r\n\r\nThen, using the following hack:\r\n\r\n```bash\r\nmv /Applications/Atom.app/Contents/MacOS/Atom{,.bin}\r\ncat > /Applications/Atom.app/Contents/MacOS/Atom <<<'#!/bin/bash -l\r\n\"$(dirname \"${BASH_SOURCE[0]}\")\"/Atom.bin \"$@\"'\r\nchmod +x /Applications/Atom.app/Contents/MacOS/Atom\r\n```\r\n\r\nDiffing the result of a \"atom\" invocation and a Spotlight opening of Atom:\r\n\r\n```diff\r\n2d1\r\n< [\"TERM_PROGRAM\", \"Apple_Terminal\"]\r\n4d2\r\n< [\"TERM\", \"xterm-256color\"]\r\n9,10d6\r\n< [\"TERM_PROGRAM_VERSION\", \"360\"]\r\n< [\"TERM_SESSION_ID\", \"C06FFFD2-16C3-48CD-AE1D-9CF8A31C6DA2\"]\r\n21d16\r\n< [\"LANG\", \"en_GB.UTF-8\"]\r\n26d20\r\n< [\"SHLVL\", \"2\"]\r\n27a22\r\n> [\"SHLVL\", \"1\"]\r\n```\r\n\r\nUpdating the hack:\r\n\r\n```bash\r\ncat > /Applications/Atom.app/Contents/MacOS/Atom <<<'#!/bin/bash -l\r\n[[ -z $LANG ]] && LANG=$(osascript -e \"user locale of (get system info)\" | sed -e \"s/@.*//\" -e \"s/\\$/.UTF-8/\")\r\n\"$(dirname \"${BASH_SOURCE[0]}\")\"/Atom.bin \"$@\"'\r\n```\r\n\r\nDiff becomes:\r\n\r\n```diff\r\n2d1\r\n< [\"TERM_PROGRAM\", \"Apple_Terminal\"]\r\n4d2\r\n< [\"TERM\", \"xterm-256color\"]\r\n9,10d6\r\n< [\"TERM_PROGRAM_VERSION\", \"360\"]\r\n< [\"TERM_SESSION_ID\", \"C06FFFD2-16C3-48CD-AE1D-9CF8A31C6DA2\"]\r\n26d21\r\n< [\"SHLVL\", \"2\"]\r\n27a23\r\n> [\"SHLVL\", \"1\"]\r\n```\r\n\r\n*Note*: The `sed` thing is because the `osascript` output looks like this on my machine (prefpane set as UK locale with custom currency):\r\n\r\n```\r\n$ osascript -e 'user locale of (get system info)'                                  \r\nen_GB@currency=EUR\r\n```\r\n\r\nAnd here is a more complete less-of-a-hack that keeps using the actual user shell:\r\n\r\n```\r\n#!/bin/bash\r\n\r\nif [[ -z $LANG ]]; then\r\n    LANG=$(osascript -e \"user locale of (get system info)\" | sed -e \"s/@.*//\" -e \"s/\\$/.UTF-8/\")\r\n    export LANG\r\nfi\r\n\r\nuser_shell=\"$(dscl . -read \"/Users/$USER\" UserShell | sed -e 's/UserShell: //')\"\r\ncase \"$user_shell\" in\r\n    */zsh|*/bash)\r\n        \"$user_shell\" -l -c \"$(dirname \"${BASH_SOURCE[0]}\")\"/Atom.bin \"$@\"\r\n        ;;\r\n    *)\r\n        echo \"Unsupported shell: $user_shell\"\r\n        exit 1\r\n        ;;\r\nesac\r\n```"}}