From 05574f6ad7119b09ede2ecbe45f185ae42bed467 Mon Sep 17 00:00:00 2001 From: Bob Tolbert Date: Sun, 23 Nov 2014 15:05:20 -0700 Subject: [PATCH] Implement -m command line flag to run a module by name --- docs/language/cli.rst | 10 ++++++++++ hy/cmdline.py | 33 +++++++++++++++++++++++++++++++-- tests/resources/bin/__init__.hy | 0 tests/test_bin.py | 24 ++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/resources/bin/__init__.hy diff --git a/docs/language/cli.rst b/docs/language/cli.rst index 98e853e..8eba855 100644 --- a/docs/language/cli.rst +++ b/docs/language/cli.rst @@ -23,6 +23,16 @@ Command line options Execute the Hy code in *command*, then stay in REPL. +.. cmdoption:: -m + + Execute the Hy code in *module*, including ``defmain`` if defined. + + The :option:`-m` flag terminates the options list so that + all arguments after the *module* name are passed to the module in + ``sys.argv``. + + .. versionadded:: 0.10.2 + .. cmdoption:: --spy Print equivalent Python code before executing. For example:: diff --git a/hy/cmdline.py b/hy/cmdline.py index 51417b2..84f8335 100644 --- a/hy/cmdline.py +++ b/hy/cmdline.py @@ -188,6 +188,18 @@ def run_command(source): return 0 +def run_module(mod_name): + from hy.importer import MetaImporter + pth = MetaImporter().find_on_path(mod_name) + if pth is not None: + sys.argv = [pth] + sys.argv + return run_file(pth) + + sys.stderr.write("{0}: module '{1}' not found.\n".format(hy.__appname__, + mod_name)) + return 1 + + def run_file(filename): from hy.importer import import_file_to_module try: @@ -230,9 +242,10 @@ def run_icommand(source, spy=False): return run_repl(hr) -USAGE = "%(prog)s [-h | -i cmd | -c cmd | file | -] [arg] ..." +USAGE = "%(prog)s [-h | -i cmd | -c cmd | -m module | file | -] [arg] ..." VERSION = "%(prog)s " + hy.__version__ EPILOG = """ file program read from script + module module to execute as main - program read from stdin [arg] ... arguments passed to program in sys.argv[1:] """ @@ -246,6 +259,8 @@ def cmdline_handler(scriptname, argv): epilog=EPILOG) parser.add_argument("-c", dest="command", help="program passed in as a string") + parser.add_argument("-m", dest="mod", + help="module to run, passed in as a string") parser.add_argument( "-i", dest="icommand", help="program passed in as a string, then stay in REPL") @@ -265,6 +280,16 @@ def cmdline_handler(scriptname, argv): # mimics Python sys.executable hy.executable = argv[0] + # need to split the args if using "-m" + # all args after the MOD are sent to the module + # in sys.argv + module_args = [] + if "-m" in argv: + mloc = argv.index("-m") + if len(argv) > mloc+2: + module_args = argv[mloc+2:] + argv = argv[:mloc+2] + options = parser.parse_args(argv[1:]) if options.show_tracebacks: @@ -272,12 +297,16 @@ def cmdline_handler(scriptname, argv): SIMPLE_TRACEBACKS = False # reset sys.argv like Python - sys.argv = options.args or [""] + sys.argv = options.args + module_args or [""] if options.command: # User did "hy -c ..." return run_command(options.command) + if options.mod: + # User did "hy -m ..." + return run_module(options.mod) + if options.icommand: # User did "hy -i ..." return run_icommand(options.icommand, spy=options.spy) diff --git a/tests/resources/bin/__init__.hy b/tests/resources/bin/__init__.hy new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_bin.py b/tests/test_bin.py index e8a0fc8..74561aa 100644 --- a/tests/test_bin.py +++ b/tests/test_bin.py @@ -173,3 +173,27 @@ def test_bin_hy_no_main(): ret = run_cmd("hy tests/resources/bin/nomain.hy") assert ret[0] == 0 assert "This Should Still Work" in ret[1] + + +def test_bin_hy_module_main(): + ret = run_cmd("hy -m tests.resources.bin.main") + assert ret[0] == 0 + assert "Hello World" in ret[1] + + +def test_bin_hy_module_main_args(): + ret = run_cmd("hy -m tests.resources.bin.main test 123") + assert ret[0] == 0 + assert "test" in ret[1] + assert "123" in ret[1] + + +def test_bin_hy_module_main_exitvalue(): + ret = run_cmd("hy -m tests.resources.bin.main exit1") + assert ret[0] == 1 + + +def test_bin_hy_module_no_main(): + ret = run_cmd("hy -m tests.resources.bin.nomain") + assert ret[0] == 0 + assert "This Should Still Work" in ret[1]