From 07d166ac3bb65a3e0f68325782f4b4693413ee26 Mon Sep 17 00:00:00 2001 From: Glen Smith Date: Fri, 28 Aug 2020 12:08:58 -0600 Subject: [PATCH 1/8] Add a `scripts` command and a test for it. - https://github.com/pypa/pipenv/issues/3686 --- pipenv/cli/command.py | 20 ++++++++++++++++++++ tests/integration/test_cli.py | 13 +++++++++++++ 2 files changed, 33 insertions(+) diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index 6b9c3392..eaf024a6 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -716,5 +716,25 @@ def clean(ctx, state, dry_run=False, bare=False, user=False): system=state.system) +@cli.command( + short_help="Lists scripts in current environment config.", + context_settings=subcommand_context_no_interspersion, +) +@common_options +@argument("args", nargs=-1) +@pass_state +def scripts(state, args): + """Lists scripts in current environment config.""" + from ..core import project + if not project: + print("project not found") + exit(1) + scripts = project.parsed_pipfile.get('scripts', []) + print("command\tscript") + for k, v in scripts.items(): + print(f"{k}\t{v}") + return + + if __name__ == "__main__": cli() diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py index 04253fc5..94d5b0dd 100644 --- a/tests/integration/test_cli.py +++ b/tests/integration/test_cli.py @@ -197,6 +197,19 @@ def test_bare_output(PipenvInstance): assert p.pipenv('').out +@pytest.mark.cli +def test_scripts(PipenvInstance): + with PipenvInstance() as p: + with open(p.pipfile_path, "w") as f: + contents = """ +[scripts] +pyver = "which python" + """.strip() + f.write(contents) + c = p.pipenv('scripts') + assert 'pyver' in c.out + + @pytest.mark.cli def test_help(PipenvInstance): with PipenvInstance() as p: From 4e3baf5713053b4497a8d817ab37fb31c2b1f06b Mon Sep 17 00:00:00 2001 From: Glen Smith Date: Fri, 28 Aug 2020 12:15:52 -0600 Subject: [PATCH 2/8] Fix command as `script`, not `scripts` --- pipenv/cli/command.py | 2 +- tests/integration/test_cli.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index eaf024a6..86e31454 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -723,7 +723,7 @@ def clean(ctx, state, dry_run=False, bare=False, user=False): @common_options @argument("args", nargs=-1) @pass_state -def scripts(state, args): +def script(state, args): """Lists scripts in current environment config.""" from ..core import project if not project: diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py index 94d5b0dd..e48c15de 100644 --- a/tests/integration/test_cli.py +++ b/tests/integration/test_cli.py @@ -202,11 +202,11 @@ def test_scripts(PipenvInstance): with PipenvInstance() as p: with open(p.pipfile_path, "w") as f: contents = """ -[scripts] +[script] pyver = "which python" """.strip() f.write(contents) - c = p.pipenv('scripts') + c = p.pipenv('script') assert 'pyver' in c.out From 622d119ea658b66baeaf5d64ba9205f34199d6d9 Mon Sep 17 00:00:00 2001 From: Glen Smith Date: Fri, 28 Aug 2020 15:14:35 -0600 Subject: [PATCH 3/8] Fix `script` command and testing: - Use string format compatible with python 2.7 - Use `click.echo`, not `print` - The command is `pipenv script` not `pipenv scripts` - The stanza label in Pipfile is `[scripts]`, not `[script]` - The default when getting from the pipfile should be dict, not a list --- pipenv/cli/command.py | 9 +++++---- tests/integration/test_cli.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index 86e31454..340e95b3 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -727,12 +727,13 @@ def script(state, args): """Lists scripts in current environment config.""" from ..core import project if not project: - print("project not found") + echo(u"project not found", err=True) exit(1) - scripts = project.parsed_pipfile.get('scripts', []) - print("command\tscript") + scripts = project.parsed_pipfile.get('scripts', {}) + rpt = u"command\tscript\n" for k, v in scripts.items(): - print(f"{k}\t{v}") + rpt += u"{0}\t{1}".format(k, v) + echo(rpt) return diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py index e48c15de..d37b4bf1 100644 --- a/tests/integration/test_cli.py +++ b/tests/integration/test_cli.py @@ -202,7 +202,7 @@ def test_scripts(PipenvInstance): with PipenvInstance() as p: with open(p.pipfile_path, "w") as f: contents = """ -[script] +[scripts] pyver = "which python" """.strip() f.write(contents) From c42f6094e9e33c3f7cb3dbb20a0cc82af52efc00 Mon Sep 17 00:00:00 2001 From: Glen Smith Date: Wed, 2 Sep 2020 10:35:20 -0600 Subject: [PATCH 4/8] Change the `script` command to `scripts` --- pipenv/cli/command.py | 4 ++-- tests/integration/test_cli.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index 340e95b3..ec39bcd4 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -723,14 +723,14 @@ def clean(ctx, state, dry_run=False, bare=False, user=False): @common_options @argument("args", nargs=-1) @pass_state -def script(state, args): +def scripts(state, args): """Lists scripts in current environment config.""" from ..core import project if not project: echo(u"project not found", err=True) exit(1) scripts = project.parsed_pipfile.get('scripts', {}) - rpt = u"command\tscript\n" + rpt = u"command\tscripts\n" for k, v in scripts.items(): rpt += u"{0}\t{1}".format(k, v) echo(rpt) diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py index 4dc2b539..5f31a5dd 100644 --- a/tests/integration/test_cli.py +++ b/tests/integration/test_cli.py @@ -206,7 +206,7 @@ def test_scripts(PipenvInstance): pyver = "which python" """.strip() f.write(contents) - c = p.pipenv('script') + c = p.pipenv('scripts') assert 'pyver' in c.out From 243e3005170be5d29cd383bcfd7065cd405cb045 Mon Sep 17 00:00:00 2001 From: Glen Smith Date: Thu, 3 Sep 2020 09:04:46 -0600 Subject: [PATCH 5/8] add inspection for 'which python' --- tests/integration/test_cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py index 5f31a5dd..f87a3723 100644 --- a/tests/integration/test_cli.py +++ b/tests/integration/test_cli.py @@ -208,6 +208,7 @@ pyver = "which python" f.write(contents) c = p.pipenv('scripts') assert 'pyver' in c.out + assert 'which python' in c.out @pytest.mark.cli From 6897ebffa31a025407b2e04658873de6b2229559 Mon Sep 17 00:00:00 2001 From: Glen Smith Date: Tue, 8 Sep 2020 08:41:48 -0600 Subject: [PATCH 6/8] Add documentation of new `scripts` command. --- README.md | 2 ++ docs/advanced.rst | 9 +++++++++ news/3686.feature.rst | 2 ++ 3 files changed, 13 insertions(+) create mode 100644 news/3686.feature.rst diff --git a/README.md b/README.md index 9b7ff6d0..ef08a525 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,8 @@ Fish is the best shell. You should use it. lock Generates Pipfile.lock. open View a given module in your editor. run Spawns a command installed into the virtualenv. + scripts Displays the shortcuts in the (optional) [scripts] section of + Pipfile. shell Spawns a shell within the virtualenv. sync Installs all packages specified in Pipfile.lock. uninstall Un-installs a provided package and removes it from Pipfile. diff --git a/docs/advanced.rst b/docs/advanced.rst index b2944da9..d8aff57a 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -428,6 +428,15 @@ For example: $ pipenv run echospam "indeed" I am really a very silly example indeed +You can then display the names and commands of your shortcuts by running ``pipenv scripts`` in your terminal. + +:: + + $ pipenv scripts + command script + echospam echo I am really a very silly example + + ☤ Support for Environment Variables ----------------------------------- diff --git a/news/3686.feature.rst b/news/3686.feature.rst new file mode 100644 index 00000000..101e369b --- /dev/null +++ b/news/3686.feature.rst @@ -0,0 +1,2 @@ +Add a new command ``pipenv scripts`` to display shortcuts from Pipfile. + From ceace4613307e7dc211976b61125e9d5545cde0e Mon Sep 17 00:00:00 2001 From: Glen Smith Date: Tue, 8 Sep 2020 08:42:37 -0600 Subject: [PATCH 7/8] Change report column header to singular case. --- pipenv/cli/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index ec39bcd4..9b2f0cad 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -730,7 +730,7 @@ def scripts(state, args): echo(u"project not found", err=True) exit(1) scripts = project.parsed_pipfile.get('scripts', {}) - rpt = u"command\tscripts\n" + rpt = u"command\tscript\n" for k, v in scripts.items(): rpt += u"{0}\t{1}".format(k, v) echo(rpt) From 99f4242bdf45951fe12e388cceeb4732c2461712 Mon Sep 17 00:00:00 2001 From: Glen Smith Date: Tue, 8 Sep 2020 08:43:20 -0600 Subject: [PATCH 8/8] Provide a success return value to the `scripts` command. --- pipenv/cli/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index 9b2f0cad..4864e6de 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -734,7 +734,7 @@ def scripts(state, args): for k, v in scripts.items(): rpt += u"{0}\t{1}".format(k, v) echo(rpt) - return + return 0 if __name__ == "__main__":