def source_foreign(args, stdin=None): """Sources a file written in a foreign shell language.""" parser = _ensure_source_foreign_parser() ns = parser.parse_args(args) if ns.prevcmd is not None and not os.path.isfile(ns.files_or_code[0]): ns.prevcmd = ' '.join(ns.files_or_code) elif ns.prevcmd is None: ns.prevcmd = '{0} {1}'.format(ns.sourcer, ' '.join(ns.files_or_code)) foreign_shell_data.cache_clear() # make sure that we don't get prev src fsenv, fsaliases = foreign_shell_data(shell=ns.shell, login=ns.login, interactive=ns.interactive, envcmd=ns.envcmd, aliascmd=ns.aliascmd, extra_args=ns.extra_args, safe=ns.safe, prevcmd=ns.prevcmd, postcmd=ns.postcmd, funcscmd=ns.funcscmd, sourcer=ns.sourcer) # apply results env = builtins.__xonsh_env__ denv = env.detype() for k, v in fsenv.items(): if k in env and v == denv[k]: continue # no change from original env[k] = v baliases = builtins.aliases for k, v in fsaliases.items(): if k in baliases and v == baliases[k]: continue # no change from original baliases[k] = v
def source_foreign(args, stdin=None): """Sources a file written in a foreign shell language.""" parser = _ensure_source_foreign_parser() ns = parser.parse_args(args) if ns.prevcmd is not None: pass # don't change prevcmd if given explicitly elif os.path.isfile(ns.files_or_code[0]): # we have filename to source ns.prevcmd = '{0} {1}'.format(ns.sourcer, ' '.join(ns.files_or_code)) elif ns.prevcmd is None: ns.prevcmd = ' '.join(ns.files_or_code) # code to run, no files foreign_shell_data.cache_clear() # make sure that we don't get prev src fsenv, fsaliases = foreign_shell_data(shell=ns.shell, login=ns.login, interactive=ns.interactive, envcmd=ns.envcmd, aliascmd=ns.aliascmd, extra_args=ns.extra_args, safe=ns.safe, prevcmd=ns.prevcmd, postcmd=ns.postcmd, funcscmd=ns.funcscmd, sourcer=ns.sourcer) # apply results env = builtins.__xonsh_env__ denv = env.detype() for k, v in fsenv.items(): if k in env and v == denv[k]: continue # no change from original env[k] = v baliases = builtins.aliases for k, v in fsaliases.items(): if k in baliases and v == baliases[k]: continue # no change from original baliases[k] = v
def source_foreign(args, stdin=None, stdout=None, stderr=None): """Sources a file written in a foreign shell language.""" ns = _SOURCE_FOREIGN_PARSER.parse_args(args) if ns.prevcmd is not None: pass # don't change prevcmd if given explicitly elif os.path.isfile(ns.files_or_code[0]): # we have filename to source ns.prevcmd = '{} "{}"'.format(ns.sourcer, '" "'.join(ns.files_or_code)) elif ns.prevcmd is None: ns.prevcmd = ' '.join(ns.files_or_code) # code to run, no files foreign_shell_data.cache_clear() # make sure that we don't get prev src fsenv, fsaliases = foreign_shell_data(shell=ns.shell, login=ns.login, interactive=ns.interactive, envcmd=ns.envcmd, aliascmd=ns.aliascmd, extra_args=ns.extra_args, safe=ns.safe, prevcmd=ns.prevcmd, postcmd=ns.postcmd, funcscmd=ns.funcscmd, sourcer=ns.sourcer, use_tmpfile=ns.use_tmpfile, seterrprevcmd=ns.seterrprevcmd, seterrpostcmd=ns.seterrpostcmd, show=ns.show, dryrun=ns.dryrun) if fsenv is None: if ns.dryrun: return else: msg = 'xonsh: error: Source failed: {0!r}\n'.format(ns.prevcmd) msg += 'xonsh: error: Possible reasons: File not found or syntax error\n' return (None, msg, 1) # apply results env = builtins.__xonsh_env__ denv = env.detype() for k, v in fsenv.items(): if k in denv and v == denv[k]: continue # no change from original env[k] = v # Remove any env-vars that were unset by the script. for k in denv: if k not in fsenv: env.pop(k, None) # Update aliases baliases = builtins.aliases for k, v in fsaliases.items(): if k in baliases and v == baliases[k]: continue # no change from original elif ns.overwrite_aliases or k not in baliases: baliases[k] = v else: msg = ('Skipping application of {0!r} alias from {1!r} ' 'since it shares a name with an existing xonsh alias. ' 'Use "--overwrite-alias" option to apply it anyway.') print(msg.format(k, ns.shell), file=stderr)
def test_foreign_bash_data(): expenv = {"EMERALD": "SWORD", "MIGHTY": "WARRIOR"} expaliases = {"l": ["ls", "-CF"], "la": ["ls", "-A"], "ll": ["ls", "-a", "-lF"]} rcfile = os.path.join(os.path.dirname(__file__), "bashrc.sh") try: obsenv, obsaliases = foreign_shell_data("bash", currenv=(), extra_args=("--rcfile", rcfile), safe=False) except (subprocess.CalledProcessError, FileNotFoundError): raise SkipTest for key, expval in expenv.items(): yield assert_equal, expval, obsenv.get(key, False) yield assert_equal, expaliases, obsaliases
def source_foreign(args, stdin=None, stdout=None, stderr=None): """Sources a file written in a foreign shell language.""" ns = _SOURCE_FOREIGN_PARSER.parse_args(args) if ns.prevcmd is not None: pass # don't change prevcmd if given explicitly elif os.path.isfile(ns.files_or_code[0]): # we have filename to source ns.prevcmd = '{} "{}"'.format(ns.sourcer, '" "'.join(ns.files_or_code)) elif ns.prevcmd is None: ns.prevcmd = ' '.join(ns.files_or_code) # code to run, no files foreign_shell_data.cache_clear() # make sure that we don't get prev src fsenv, fsaliases = foreign_shell_data(shell=ns.shell, login=ns.login, interactive=ns.interactive, envcmd=ns.envcmd, aliascmd=ns.aliascmd, extra_args=ns.extra_args, safe=ns.safe, prevcmd=ns.prevcmd, postcmd=ns.postcmd, funcscmd=ns.funcscmd, sourcer=ns.sourcer, use_tmpfile=ns.use_tmpfile, seterrprevcmd=ns.seterrprevcmd, seterrpostcmd=ns.seterrpostcmd, show=ns.show, dryrun=ns.dryrun) if fsenv is None: if ns.dryrun: return else: msg = 'xonsh: error: Source failed: {}\n'.format(ns.prevcmd) return (None, msg, 1) # apply results env = builtins.__xonsh_env__ denv = env.detype() for k, v in fsenv.items(): if k in denv and v == denv[k]: continue # no change from original env[k] = v # Remove any env-vars that were unset by the script. for k in denv: if k not in fsenv: env.pop(k, None) # Update aliases baliases = builtins.aliases for k, v in fsaliases.items(): if k in baliases and v == baliases[k]: continue # no change from original elif ns.overwrite_aliases or k not in baliases: baliases[k] = v else: msg = ('Skipping application of {0!r} alias from {1!r} ' 'since it shares a name with an existing xonsh alias. ' 'Use "--overwrite-alias" option to apply it anyway.') print(msg.format(k, ns.shell), file=stderr)
def test_foreign_bash_data(): expenv = {"EMERALD": "SWORD", "MIGHTY": "WARRIOR"} expaliases = {"l": ["ls", "-CF"], "la": ["ls", "-A"], "ll": ["ls", "-a", "-lF"]} rcfile = os.path.join(os.path.dirname(__file__), "bashrc.sh") try: obsenv, obsaliases = foreign_shell_data( "bash", currenv=(), extra_args=("--rcfile", rcfile), safe=False ) except (subprocess.CalledProcessError, FileNotFoundError): return for key, expval in expenv.items(): assert expval == obsenv.get(key, False) for key, expval in expaliases.items(): assert expval == obsaliases.get(key, False)
def test_foreign_cmd_data(): env = (('ENV_TO_BE_REMOVED','test'),) batchfile = os.path.join(os.path.dirname(__file__), 'batch.bat') source_cmd ='call "{}"\necho off'.format(batchfile) try: obsenv, _ = foreign_shell_data('cmd',prevcmd=source_cmd, currenv=env, interactive =False, sourcer='call',envcmd='set', use_tmpfile=True, safe=False) except (subprocess.CalledProcessError, FileNotFoundError): return assert 'ENV_TO_BE_ADDED' in obsenv assert obsenv['ENV_TO_BE_ADDED']=='Hallo world' assert 'ENV_TO_BE_REMOVED' not in obsenv
def source_foreign(args, stdin=None): """Sources a file written in a foreign shell language.""" parser = _ensure_source_foreign_parser() ns = parser.parse_args(args) if ns.prevcmd is not None: pass # don't change prevcmd if given explicitly elif os.path.isfile(ns.files_or_code[0]): # we have filename to source ns.prevcmd = '{} "{}"'.format(ns.sourcer, '" "'.join(ns.files_or_code)) elif ns.prevcmd is None: ns.prevcmd = " ".join(ns.files_or_code) # code to run, no files foreign_shell_data.cache_clear() # make sure that we don't get prev src fsenv, fsaliases = foreign_shell_data( shell=ns.shell, login=ns.login, interactive=ns.interactive, envcmd=ns.envcmd, aliascmd=ns.aliascmd, extra_args=ns.extra_args, safe=ns.safe, prevcmd=ns.prevcmd, postcmd=ns.postcmd, funcscmd=ns.funcscmd, sourcer=ns.sourcer, use_tmpfile=ns.use_tmpfile, seterrprevcmd=ns.seterrprevcmd, seterrpostcmd=ns.seterrpostcmd, ) if fsenv is None: return (None, "xonsh: error: Source failed: " "{}\n".format(ns.prevcmd), 1) # apply results env = builtins.__xonsh_env__ denv = env.detype() for k, v in fsenv.items(): if k in denv and v == denv[k]: continue # no change from original env[k] = v # Remove any env-vars that were unset by the script. for k in denv: if k not in fsenv: env.pop(k, None) # Update aliases baliases = builtins.aliases for k, v in fsaliases.items(): if k in baliases and v == baliases[k]: continue # no change from original baliases[k] = v
def test_foreign_bash_data(): expenv = {"EMERALD": "SWORD", 'MIGHTY': 'WARRIOR'} expaliases = { 'l': ['ls', '-CF'], 'la': ['ls', '-A'], 'll': ['ls', '-a', '-lF'], } rcfile = os.path.join(os.path.dirname(__file__), 'bashrc.sh') try: obsenv, obsaliases = foreign_shell_data('bash', currenv=(), extra_args=('--rcfile', rcfile), safe=False) except (subprocess.CalledProcessError, FileNotFoundError): raise SkipTest for key, expval in expenv.items(): yield assert_equal, expval, obsenv.get(key, False) yield assert_equal, expaliases, obsaliases
def source_foreign(args, stdin=None): """Sources a file written in a foreign shell language.""" parser = _ensure_source_foreign_parser() ns = parser.parse_args(args) if ns.prevcmd is not None: pass # don't change prevcmd if given explicitly elif os.path.isfile(ns.files_or_code[0]): # we have filename to source ns.prevcmd = '{} "{}"'.format(ns.sourcer, '" "'.join(ns.files_or_code)) elif ns.prevcmd is None: ns.prevcmd = ' '.join(ns.files_or_code) # code to run, no files foreign_shell_data.cache_clear() # make sure that we don't get prev src fsenv, fsaliases = foreign_shell_data(shell=ns.shell, login=ns.login, interactive=ns.interactive, envcmd=ns.envcmd, aliascmd=ns.aliascmd, extra_args=ns.extra_args, safe=ns.safe, prevcmd=ns.prevcmd, postcmd=ns.postcmd, funcscmd=ns.funcscmd, sourcer=ns.sourcer, use_tmpfile=ns.use_tmpfile, seterrprevcmd=ns.seterrprevcmd, seterrpostcmd=ns.seterrpostcmd) if fsenv is None: return (None, 'xonsh: error: Source failed: ' '{}\n'.format(ns.prevcmd), 1) # apply results env = builtins.__xonsh_env__ denv = env.detype() for k, v in fsenv.items(): if k in denv and v == denv[k]: continue # no change from original env[k] = v # Remove any env-vars that were unset by the script. for k in denv: if k not in fsenv: env.pop(k, None) # Update aliases baliases = builtins.aliases for k, v in fsaliases.items(): if k in baliases and v == baliases[k]: continue # no change from original baliases[k] = v
def test_foreign_cmd_data(): env = (('ENV_TO_BE_REMOVED', 'test'), ) batchfile = os.path.join(os.path.dirname(__file__), 'batch.bat') source_cmd = 'call "{}"\necho off'.format(batchfile) try: obsenv, _ = foreign_shell_data('cmd', prevcmd=source_cmd, currenv=env, interactive=False, sourcer='call', envcmd='set', use_tmpfile=True, safe=False) except (subprocess.CalledProcessError, FileNotFoundError): return assert 'ENV_TO_BE_ADDED' in obsenv assert obsenv['ENV_TO_BE_ADDED'] == 'Hallo world' assert 'ENV_TO_BE_REMOVED' not in obsenv
def test_foreign_cmd_data(): env = (("ENV_TO_BE_REMOVED", "test"), ) batchfile = os.path.join(os.path.dirname(__file__), "batch.bat") source_cmd = 'call "{}"\necho off'.format(batchfile) try: obsenv, _ = foreign_shell_data( "cmd", prevcmd=source_cmd, currenv=env, interactive=False, sourcer="call", envcmd="set", use_tmpfile=True, safe=False, ) except (subprocess.CalledProcessError, FileNotFoundError): return assert "ENV_TO_BE_ADDED" in obsenv assert obsenv["ENV_TO_BE_ADDED"] == "Hallo world" assert "ENV_TO_BE_REMOVED" not in obsenv
def test_foreign_cmd_data(): env = (("ENV_TO_BE_REMOVED", "test"),) batchfile = os.path.join(os.path.dirname(__file__), "batch.bat") source_cmd = 'call "{}"\necho off'.format(batchfile) try: obsenv, _ = foreign_shell_data( "cmd", prevcmd=source_cmd, currenv=env, interactive=False, sourcer="call", envcmd="set", use_tmpfile=True, safe=False, ) except (subprocess.CalledProcessError, FileNotFoundError): return assert "ENV_TO_BE_ADDED" in obsenv assert obsenv["ENV_TO_BE_ADDED"] == "Hallo world" assert "ENV_TO_BE_REMOVED" not in obsenv
def source_foreign(args, stdin=None): """Sources a file written in a foreign shell language.""" parser = _ensure_source_foreign_parser() ns = parser.parse_args(args) prevcmd = '{0} {1}'.format(ns.sourcer, ' '.join(ns.filenames)) foreign_shell_data.cache_clear() # make sure that we don't get prev src fsenv, fsaliases = foreign_shell_data(shell=ns.shell, login=ns.login, interactive=ns.interactive, envcmd=ns.envcmd, aliascmd=ns.aliascmd, extra_args=ns.extra_args, safe=ns.safe, prevcmd=prevcmd) # apply results env = builtins.__xonsh_env__ denv = env.detype() for k, v in fsenv.items(): if k in env and v == denv[k]: continue # no change from original env[k] = v baliases = builtins.aliases for k, v in fsaliases.items(): if k in baliases and v == baliases[k]: continue # no change from original baliases[k] = v
def source_foreign(args, stdin=None, stdout=None, stderr=None): """Sources a file written in a foreign shell language.""" env = builtins.__xonsh__.env ns = _SOURCE_FOREIGN_PARSER.parse_args(args) ns.suppress_skip_message = ( env.get("FOREIGN_ALIASES_SUPPRESS_SKIP_MESSAGE") if ns.suppress_skip_message is None else ns.suppress_skip_message ) if ns.prevcmd is not None: pass # don't change prevcmd if given explicitly elif os.path.isfile(ns.files_or_code[0]): # we have filename to source ns.prevcmd = '{} "{}"'.format(ns.sourcer, '" "'.join(ns.files_or_code)) elif ns.prevcmd is None: ns.prevcmd = " ".join(ns.files_or_code) # code to run, no files foreign_shell_data.cache_clear() # make sure that we don't get prev src fsenv, fsaliases = foreign_shell_data( shell=ns.shell, login=ns.login, interactive=ns.interactive, envcmd=ns.envcmd, aliascmd=ns.aliascmd, extra_args=ns.extra_args, safe=ns.safe, prevcmd=ns.prevcmd, postcmd=ns.postcmd, funcscmd=ns.funcscmd, sourcer=ns.sourcer, use_tmpfile=ns.use_tmpfile, seterrprevcmd=ns.seterrprevcmd, seterrpostcmd=ns.seterrpostcmd, show=ns.show, dryrun=ns.dryrun, ) if fsenv is None: if ns.dryrun: return else: msg = "xonsh: error: Source failed: {0!r}\n".format(ns.prevcmd) msg += "xonsh: error: Possible reasons: File not found or syntax error\n" return (None, msg, 1) # apply results denv = env.detype() for k, v in fsenv.items(): if k in denv and v == denv[k]: continue # no change from original env[k] = v # Remove any env-vars that were unset by the script. for k in denv: if k not in fsenv: env.pop(k, None) # Update aliases baliases = builtins.aliases for k, v in fsaliases.items(): if k in baliases and v == baliases[k]: continue # no change from original elif ns.overwrite_aliases or k not in baliases: baliases[k] = v elif ns.suppress_skip_message: pass else: msg = ( "Skipping application of {0!r} alias from {1!r} " "since it shares a name with an existing xonsh alias. " 'Use "--overwrite-alias" option to apply it anyway.' 'You may prevent this message with "--suppress-skip-message" or ' '"$FOREIGN_ALIASES_SUPPRESS_SKIP_MESSAGE = True".' ) print(msg.format(k, ns.shell), file=stderr)
def source_foreign_fn( shell: str, files_or_code: Annotated[tp.List[str], Arg(nargs="+")], interactive=True, login=False, envcmd=None, aliascmd=None, extra_args="", safe=True, prevcmd="", postcmd="", funcscmd="", sourcer=None, use_tmpfile=False, seterrprevcmd=None, seterrpostcmd=None, overwrite_aliases=False, suppress_skip_message=False, show=False, dryrun=False, _stderr=None, ): """Sources a file written in a foreign shell language. Parameters ---------- shell Name or path to the foreign shell files_or_code file paths to source or code in the target language. interactive : -n, --non-interactive whether the sourced shell should be interactive login : -l, --login whether the sourced shell should be login envcmd : --envcmd command to print environment aliascmd : --aliascmd command to print aliases extra_args : --extra-args extra arguments needed to run the shell safe : -u, --unsafe whether the source shell should be run safely, and not raise any errors, even if they occur. prevcmd : -p, --prevcmd command(s) to run before any other commands, replaces traditional source. postcmd : --postcmd command(s) to run after all other commands funcscmd : --funcscmd code to find locations of all native functions in the shell language. sourcer : --sourcer the source command in the target shell language. If this is not set, a default value will attempt to be looked up based on the shell name. use_tmpfile : --use-tmpfile whether the commands for source shell should be written to a temporary file. seterrprevcmd : --seterrprevcmd command(s) to set exit-on-error before any other commands. seterrpostcmd : --seterrpostcmd command(s) to set exit-on-error after all other commands. overwrite_aliases : --overwrite-aliases flag for whether or not sourced aliases should replace the current xonsh aliases. suppress_skip_message : --suppress-skip-message flag for whether or not skip messages should be suppressed. show : --show show the script output. dryrun : -d, --dry-run Will not actually source the file. """ extra_args = tuple(extra_args.split()) env = XSH.env suppress_skip_message = (env.get("FOREIGN_ALIASES_SUPPRESS_SKIP_MESSAGE") if not suppress_skip_message else suppress_skip_message) files: tp.Tuple[str, ...] = () if prevcmd: pass # don't change prevcmd if given explicitly elif os.path.isfile(files_or_code[0]): if not sourcer: return (None, "xonsh: error: `sourcer` command is not mentioned.\n", 1) # we have filenames to source prevcmd = "".join([f"{sourcer} {f}\n" for f in files_or_code]) files = tuple(files_or_code) elif not prevcmd: prevcmd = " ".join(files_or_code) # code to run, no files foreign_shell_data.cache_clear() # make sure that we don't get prev src fsenv, fsaliases = foreign_shell_data( shell=shell, login=login, interactive=interactive, envcmd=envcmd, aliascmd=aliascmd, extra_args=extra_args, safe=safe, prevcmd=prevcmd, postcmd=postcmd, funcscmd=funcscmd or None, # the default is None in the called function sourcer=sourcer, use_tmpfile=use_tmpfile, seterrprevcmd=seterrprevcmd, seterrpostcmd=seterrpostcmd, show=show, dryrun=dryrun, files=files, ) if fsenv is None: if dryrun: return else: msg = f"xonsh: error: Source failed: {prevcmd!r}\n" msg += "xonsh: error: Possible reasons: File not found or syntax error\n" return (None, msg, 1) # apply results denv = env.detype() for k, v in fsenv.items(): if k in denv and v == denv[k]: continue # no change from original env[k] = v # Remove any env-vars that were unset by the script. for k in denv: if k not in fsenv: env.pop(k, None) # Update aliases baliases = XSH.aliases for k, v in fsaliases.items(): if k in baliases and v == baliases[k]: continue # no change from original elif overwrite_aliases or k not in baliases: baliases[k] = v elif suppress_skip_message: pass else: msg = ( "Skipping application of {0!r} alias from {1!r} " "since it shares a name with an existing xonsh alias. " 'Use "--overwrite-alias" option to apply it anyway.' 'You may prevent this message with "--suppress-skip-message" or ' '"$FOREIGN_ALIASES_SUPPRESS_SKIP_MESSAGE = True".') print(msg.format(k, shell), file=_stderr)