Repository: xonsh/xonsh

Issue:
-l and -i command line options
If xonsh should be BASHwards compatible, maybe it could be worth introducing -l (login) and -i (interactive) options? At least as fake arguments, because when I set xonsh as my default shell (Linux Mint) and run [Spacemacs](https://github.com/syl20bnr/spacemacs) I get error:

```
Error (use-package): exec-path-from-shell :init: Non-zero exit code from shell /usr/local/bin/xonsh invoked with args ("-l" "-i" "-c" "/usr/bin/printf '__RESULT\\000%s\\000%s' \"${PATH-a421311e83eccdcf118d7f98b41e20d8}\" \"${MANPATH-a421311e83eccdcf118d7f98b41e20d8}\"").  Output was:
"usage: xonsh [-h] [-V] [-c COMMAND] [--no-rc] [-D [ITEM [ITEM ...]]]
             [--shell-type {readline,prompt_toolkit}]
             [script-file] [args [args ...]]
xonsh: error: unrecognized arguments: -l -i
"
```



Discussion:
Thanks for reporting @tkossak. Gladly accept a PR that implemented this.  It shouldn't be too hard.


Resolving patch:
diff --git a/xonsh/environ.py b/xonsh/environ.py
--- a/xonsh/environ.py
+++ b/xonsh/environ.py
@@ -71,6 +71,7 @@ def lc_converter(val):
     'XONSH_ENCODING': (is_string, ensure_string, ensure_string),
     'XONSH_ENCODING_ERRORS': (is_string, ensure_string, ensure_string),
     'XONSH_HISTORY_SIZE': (is_history_tuple, to_history_tuple, history_tuple_to_str),
+    'XONSH_LOGIN': (is_bool, to_bool, bool_to_str),
     'XONSH_STORE_STDOUT': (is_bool, to_bool, bool_to_str),
     'VI_MODE': (is_bool, to_bool, bool_to_str),
 }
@@ -171,6 +172,7 @@ def xonshconfig(env):
     'XONSH_ENCODING_ERRORS': 'surrogateescape',
     'XONSH_HISTORY_FILE': os.path.expanduser('~/.xonsh_history.json'),
     'XONSH_HISTORY_SIZE': (8128, 'commands'),
+    'XONSH_LOGIN': False,
     'XONSH_SHOW_TRACEBACK': False,
     'XONSH_STORE_STDOUT': False,
 }
diff --git a/xonsh/main.py b/xonsh/main.py
--- a/xonsh/main.py
+++ b/xonsh/main.py
@@ -24,6 +24,16 @@
                     dest='command',
                     required=False,
                     default=None)
+parser.add_argument('-i',
+                    help='force running in interactive mode',
+                    dest='force_interactive',
+                    action='store_true',
+                    default=False)
+parser.add_argument('-l',
+                    help='run as a login shell',
+                    dest='login',
+                    action='store_true',
+                    default=False)
 parser.add_argument('--no-rc',
                     help="Do not load the .xonshrc file",
                     dest='norc',
@@ -75,6 +85,8 @@ def premain(argv=None):
     env = builtins.__xonsh_env__
     if args.defines is not None:
         env.update([x.split('=', 1) for x in args.defines])
+    if args.login:
+        env['XONSH_LOGIN'] = True
     env['XONSH_INTERACTIVE'] = False
     return args
 
@@ -98,7 +110,7 @@ def main(argv=None):
             shell.execer.exec(code, mode='exec', glbs=shell.ctx)
         else:
             print('xonsh: {0}: No such file or directory.'.format(args.file))
-    elif not sys.stdin.isatty():
+    elif not sys.stdin.isatty() and not args.force_interactive:
         # run a script given on stdin
         code = sys.stdin.read()
         code = code if code.endswith('\n') else code + '\n'


Test patch:
diff --git a/tests/test_main.py b/tests/test_main.py
new file mode 100644
--- /dev/null
+++ b/tests/test_main.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+"""Tests the xonsh main function."""
+from __future__ import unicode_literals, print_function
+
+import builtins
+from unittest.mock import patch
+
+import nose
+from nose.tools import assert_true, assert_false
+
+import xonsh.main
+
+from tools import mock_xonsh_env
+
+
+def test_login_shell():
+    def Shell(*args, **kwargs):
+        pass
+
+    with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
+        xonsh.main.premain([])
+        assert_false(builtins.__xonsh_env__.get('XONSH_LOGIN'))
+
+    with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
+        xonsh.main.premain(['-l'])
+        assert_true(builtins.__xonsh_env__.get('XONSH_LOGIN'))
+
+if __name__ == '__main__':
+    nose.runmodule()
diff --git a/tests/test_man.py b/tests/test_man.py
--- a/tests/test_man.py
+++ b/tests/test_man.py
@@ -8,7 +8,7 @@
 from xonsh.tools import ON_WINDOWS
 from xonsh.completer import ManCompleter
 
-from tools import mock_xonsh_env
+from tests.tools import mock_xonsh_env
 
 _OLD_MANPATH = None