-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to specify the directory to run poetry in instead of always using current directory #2179
Comments
I did find a workaround though. I created the following helper script:
Where TOML_DIR is the path to the directory with your |
This works well if your module has an |
Just in case it helps someone, here's the script I used. It finds TOML_DIR from the location of the executable, so it doesn't need to be hardcoded. It also uses a function, like [tool.poetry.scripts].
|
I am a bit unclear on the issue here. Poetry, similar to git, will detect the Here is an example where $ tree .
.
├── poetry.lock
├── pyproject.toml
├── README.rst
├── src
│ ├── poetry
│ │ └── run
│ │ └── context
│ │ └── __init__.py
│ └── poetry_run_context.egg-info
│ ├── dependency_links.txt
│ ├── PKG-INFO
│ ├── SOURCES.txt
│ └── top_level.txt
└── tests
└── __init__.py
6 directories, 9 files
$ type pytest
bash: type: pytest: not found
$ cd src/
$ poetry run type pytest
pytest is /tmp/poetry-run-context/.venv/bin/pytest |
@noamraph something like this will also work. [tool.poetry.scripts]
foo = "foo.bar.main:main" And then execute the follwoing within the project context (any sub directory): poetry run foo Is the requirement here for you to be able to run poetry --project=/path/to/project-foo run foo |
@abn yes, a |
Yes, exactly. It would be like git's -C option, that allows you to run commands on a repository regardless of your working directory. |
@abn I want to describe my use case a bit more. I'm developing a command line script that depends on the working directory. It's actually a tool for working with git repositories, so it detects the repository using the working directory (and it also has a |
@abn I have the same sort of requirement, I am developing a CLI tool for which one of the functionalities is to build docker images. so for that, my working directory should be dir which I want to build my image and I want to remotely run my cli(managed by poetry). |
The reason why I am not a 100% sold on the This might not be the exact solution for the CLI development case, but here are a few options that might help till a better solution exists. All examples assume snippet from #2179 (comment).
poetry shell
source /path/to/project/.venv/bin/activate
source $(poetry env info --path)/bin/activate You can then do something like this. $ poetry shell
(.venv) $ cd ~/
(.venv) $ foo --help
$ echo "import setuptools; setuptools.setup()" > /path/to/project/setup.py
$ pip install --user /path/to/project |
@abn The issue I will have with the 'poetry shell' method is that my command-line script needs other environment variables outside of poetry's control to launch the tools that my script will use. As soon as I switch to poetry's virtual env, those will get cleared out. However, running 'poetry install' and then using @noamraph 's solution is ideal. |
@bphunter1972 option 1 (using |
@abn You're right! I don't know how I missed it before, but after 'poetry install' running '/path/to/project/.venv/bin/foo' just works from any directory! I feel like this should be more clearly documented, but I'm not complaining. Just happy to have resolved this. |
Explain that `poetry install` installs the scripts in the virtualenv. See python-poetry#2179 for the use case.
* Update pyproject.md Explain that `poetry install` installs the scripts in the virtualenv. See #2179 for the use case.
Pipenv allows you to do this by exporting |
Having the ability to point to the path of the One example would be to be able to run your scripts from outside the project folder. Lets say we have something like |
This |
Even |
I want to call IPython in virtual env that is managed by poetry. # I use zsh shell, therefore I wrote this in ~/.zshrc
function ipy() {
cd ~/pj/ipython_env # go to poetry project path that manage ipython's env
poetry run python -m IPython # call IPython in virtual env
cd - > /dev/null # return to previous path
} This function almost achieve my purpose. |
If you know the path to the virtual environment, then something like the following should work:
No need to call |
I have a use case other than i.e. find . -name 'pyproject.toml' -exec bash -c 'cd "$(dirname {})" && poetry update' \; Would become: find . -name 'pyproject.toml' -exec poetry update --target {} \; |
Perhaps tangentially, but germane to the issue at hand of "doing poetry things outside of the directory The immediate use case i can think of would be having a crontab entry of the form
but there are many other cases where activation or spawning a shell are less than desirable, but you still want to reach out and hit an entry point. |
Extremely needed feature for multirepos! |
GitHub Actions does not support setting |
For the case of a cron job the Installing the
Or if
Having to use a subshell to get the python path is inconvenient and prone to breaking. If some |
Being able to pass a
Would love to do:
Otherwise we currently have to do this, which is inconvenient:
|
I want to setup a pre-commit hook that runs
|
There's been a few example wrapper scripts shared in this issue. Here's mine for reference. Simply pass it the path to the directory containing the poetry project and then the command to run. It'll change back to the cwd within the poetry shell before running the command. |
I messed with that a bit, but ran into a cross-platform support issue. I need it to work on windows and linux. Seems like in Windows it was running in cmd or Powershell. |
Can't really help there. You could probably reimplement it in python, but my use case was linux so I just kept it in sh. Hopefully someone else has a similair cross platform script available. |
Understood, I'm more adding to the case that having the ability to identify the context the command is run in would simplify the user experience. |
There's also Note that |
Context and Prior ArtComing from working in Typescript for a few years I have become accustom to multi-project monorepos where we need to manage and deploy multiple projects in a very similar way, but within the same repo so we have a transaction of system wide changes that impact refactorings across all projects. The tooling we used there was:
Desired futureTrying to find similar tooling I have a combination of
I even have a Sub ProjectsEach sub-project has a Top level projectSo ideally in my root project, I am using Single project All projects Where this runs the same command over a cleaned up version of all_projects = [
p for p in os.listdir('.')
if os.path.is_dir(os.path.join('.', p)) and not p.startswith('.')
] ProblemIf I have started a
The only way around it so far is getting this This completely avoids, Conclusion / Summary
|
@neozenith You might have more luck here: #2270 |
@sinoroc Brilliant! Thank you so much 🙏 That thread of discussion looks promising. |
Actually after some experimentation I did wind up coercing a Can thank this stackoverflow answer for pointing out But also after some manipulation, it seems:
With those three components in place, the subprocess has everything needed to run independently. Below is a snippet from my root level import os
from pathlib import Path
from subprocess import run
from invoke import task
@task(aliases=["m"])
def manage(c, project=None, command="poetry run inv -l"):
"""Manage a task in a project or all projects."""
# Collect list of dirs that are valid projects
d = "."
all_projects = [
o
for o in os.listdir(d)
if os.path.isdir(os.path.join(d, o)) and not o.startswith(".")
]
# Reconcile list of projects to apply command to
if project is not None:
if project in all_projects:
projects = [project]
else:
raise ValueError(f"The project '{project}' is not one of {all_projects}")
else:
projects = all_projects
for p in projects:
target_venv_path = Path(os.environ["VIRTUAL_ENV"]).parent / p / ".venv"
target_bin_path = str(target_venv_path / "bin")
target_cwd = str(Path().cwd() / p)
target_path = ":".join([target_bin_path] + os.environ["PATH"].split(":"))
# Curate new ENV to coerce poetry into picking the subproject venv
ENV = {"VIRTUAL_ENV": str(target_venv_path), "PATH": target_path}
result = run(
command,
cwd=target_cwd,
shell=True,
capture_output=True,
env=ENV,
)
print(result.stdout.decode("utf-8"))
print(result.stderr.decode("utf-8")) With this format, I now have the power to run any arbitrary task like: poetry run inv manage -c 'poetry install' |
Could someone let me know if this issue has been fixed or if there is a simple workaround? This thread has grown to become quite huge and hard to go through in its entirety! |
@marcospgp global option |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Feature Request
I'd like to be able to run
poetry run X
while also setting the current directory to whatever I want. Right now, this appears to be impossible, since I have to set the current directory to wherever mypyproject.toml
file is located instead. Can there be a command line option to override this default?The text was updated successfully, but these errors were encountered: