Support pyenv?
futursolo opened this issue · comments
Currently formatters-python
supports setting a global binary path or relative to project dir.
However, I am using pyenv and pyenv puts all virtualenvs inside ~/.pyenv/versions/
.
I have tried to set the global binary to ~/.pyenv/shims/isort
and end up getting:
formatters-python: /Users/futursolo/.pyenv/shims/isort,--quiet,--settings-path,/path-to-my-project/pyproject.toml,"/path-to-my-project/test.py"
pyenv: isort: command not found
formatters-python: /Users/futursolo/.pyenv/shims/isort,--quiet,--settings-path,/path-to-my-project/pyproject.toml,"/path-to-my-project/test.py"
The `isort' command exists in these Python versions:
I tried to invoke this from within shell and it gets me the expected result.
I saw some other projects uses the %PROJECT_NAME
to help on deciding the binary path.
Technically shims should work as-is if current working directory of the command is set to the root directory of the project.
It would be nice if formatters-python
could support %PROJECT_NAME
in binary path or invoke command inside project root.
Hey, are you sure this is not related to PATH issues? I haven't used pyenv so I don't know much about it.
Yes. It does not have anything to do with PATH. pyenv
determines which virtualenv to activate by current working directory.
In the meantime, I was able to put together a shim to workaround the issue in a fairly stupid way by attempting to look for a project dir in args and pass it to pyenv
as environment variables.
Hope this helps.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Optional
import sys
import subprocess
import pathlib
import os
exec_name = pathlib.Path(sys.argv[0]).name. # either save as the binary name or ln -s
shim_dir = pathlib.Path("~/.pyenv/shims/").expanduser()
projects_dir = pathlib.Path("/path-to-my-projects/")
def find_project_dir() -> Optional[str]:
for arg in sys.argv[1:]:
if arg.find("/") == -1: # unlikely to be a path
continue
path = pathlib.Path(arg).resolve()
try:
rel_path = path.relative_to(projects_dir)
except ValueError:
continue
try:
proj_name = rel_path.parts[0]
except IndexError:
continue
return str(projects_dir / proj_name)
return None
def main() -> None:
bin_path = shim_dir / exec_name
env = dict(**os.environ)
project_dir = find_project_dir() or "/"
env["PWD"] = project_dir
env["PYENV_DIR"] = project_dir # shouldn't need this if no-shell were spawned before Python shim is called.
del env["PYENV_VERSION"] # shouldn't need this if no-shell were spawned before Python shim is called.
proc = subprocess.run(
[str(bin_path), *sys.argv[1:]],
cwd=project_dir,
env=env,
stdin=None,
stdout=None,
stderr=None,
check=False,
)
sys.exit(proc.returncode)
if __name__ == "__main__":
main()
Hey, I've pushed a commit to pass cwd to the atom BufferedProcess,
Can you test it to see if it is working?
Steps:
- clone this repo
- cd into it
npm i
apm link
- restart atom
Yes, it works perfectly.
Thank you for the fast fix!
Nice. Are you aware of any other environments which will need the same change?
No, I am not aware of other environment that has the same behaviour. Sorry about that.
Fixed with v1.2.1