Hi,
Script shortcuts are great and very helpful in project. But they are too simple and stupid for now. There are some features which will be great to implement to my mind:
[scripts]
cmd = [
"echo 1",
"echo 2"
]
Of course as workaround I can use bash -c "echo 1 && echo 2"
, but if I want to write something complex with two more command it will be like a mess.
tox
(http://tox.readthedocs.io/en/latest/config.html#substitutions-for-positional-arguments-in-commands). It's very useful for example in case of tests:[scripts]
test = py.test {posargs:tests/unit/}
And pyenv run test
to run all tests or pyenv run test -- tests/unit/test_utils.py
to run subset of tests.
This is just a proposal and I'm interesting in what you think about that.
Thanks!
The script section is kept as simple as possible because Pipenv does not want to go too far in the direction. There are already quite some mature command-handling tools out there, and we do not want to duplicate efforts at this front.
A common solution is to add Invoke to dev-packages, use it handle multiple commands, and point the script command to invoke <cmd>
. Makefiles are also very good at this if you don鈥檛 care about Windows. (Personally I cannot recommend Invoke enough; it is a really great tool.)
On the other hand, the posargs proposal is worth investigating IMO. I don鈥檛 think we want to support this directly (again, not a direction Pipenv wants to go too deep in), but it鈥檇 probably be a good idea if we can provide some support to help Invoke or other tools achieve this.
I don't want to use more tools like make
or invoke
(I'm trying to simplify my projects, for example, now I'm going to migrate to pipenv
and I would like to drop tox
from my projects because pipenv
covers all my needs). But I'd like you idea to use Pipfile
as declaration of scripts in some way and passing instructions to any other tools like invoke
or something else.
Maybe we can introduce optional Invoke integration like this
# Pipfile
[scripts]
command = "echo This is a regular command"
task = { task = "mytask" }
test = { task = "mytask", defaultargs = "tests/unit" }
# tasks.py
import invoke
@invoke.task()
def mytask(ctx):
print('This is an invoke task callable from Pipfile')
@invoke.task()
def test(ctx, mod):
# mod receives
# "tests/unit" if run with "pipenv run test"
# <arg> if run with "pipenv run test <arg>"
ctx.run(f'pytest {mod}')
Pipenv will not bundle Invoke, but simply converts the { task = "..." }
construct into a invoke ...
call, and show and error message if Invoke is not installed (either globally or in the virtualenv).
Thoughts @techalchemy?
Hello, I'm seizing the opportunity of this issue to ask for help.
Like this guy, I'm having a hard time using scripts shortcuts.
I tried the documentation example but I'm getting an error:
Error: the command printfoo could not be found within PATH.
I've browsed the documentation and the web to see if I'm missing something, but so far I'm out of luck.
So I'm slightly frustrated when I see @Gr1N talking about this feature as if all is working as it should for him.
Am I missing somtehing ? I would be grateful to be able to understand what I'm doing wrong.
Thanks for all the good work !
@remicmacs No way to provide insight without any information on your setup and environment. Head over to the #pipenv channel on PySlackers, and provide proper information so people can help.
(Sound like an old version)
@techalchemy My shame is limitless, it was an old version.
I forgot about user versions of pip packages and my sudo pip install pipenv --upgrade
only upgraded the system package, not the local one.
May my mistake to be of use for another person.
:D glad it was an easy fix! Thanks for your patience and sorry for the bug!
I think that there's a case to be made for including simple task running. For example, coverage doesn't print out the coverage report after the run, you have to run coverage report
. It's a bit overkill to write an Invoke script just for that, and shell scripts aren't cross-platform (and also overkill). And you can't just do coverage run pytest && coverage report
in your pipenv script.
Personally, I think that the posix runner is pretty over-engineered - why not just pass the string to the shell through subprocess.run()
or a similar function and let the shell sort it out like the the NT runner does?
We are a a dependency resolver and environment management tool. There are specialized tools that handle this, we have a small maintainer team. We aren't interested in adding the maintenance overhead of this.
The entire scripts section doesn't exactly fit within pipenv's specialization. If it's a feature that the team isn't interested in maintaining, maybe it should be removed.
@stevenhair that unfortunately isn't how it works. We are happy to maintain it the way it is. We are not interested in building an entire new application to support endless use cases around it. The current tooling provides a helper suite to supplement pipenv run
, but it's a little odd to tell us we need to either build more features into it or remove it entirely, isn't it?
@techalchemy my apologies, I misinterpreted your response.
Maybe we can introduce optional Invoke integration like this
# Pipfile [scripts] command = "echo This is a regular command" task = { task = "mytask" } test = { task = "mytask", defaultargs = "tests/unit" }
# tasks.py import invoke @invoke.task() def mytask(ctx): print('This is an invoke task callable from Pipfile') @invoke.task() def test(ctx, mod): # mod receives # "tests/unit" if run with "pipenv run test" # <arg> if run with "pipenv run test <arg>" ctx.run(f'pytest {mod}')
Pipenv will not bundle Invoke, but simply converts the
{ task = "..." }
construct into ainvoke ...
call, and show and error message if Invoke is not installed (either globally or in the virtualenv).Thoughts @techalchemy?
I think this would be really useful.
Most helpful comment
Maybe we can introduce optional Invoke integration like this
Pipenv will not bundle Invoke, but simply converts the
{ task = "..." }
construct into ainvoke ...
call, and show and error message if Invoke is not installed (either globally or in the virtualenv).Thoughts @techalchemy?