justinmayer / virtualfish

Fish shell tool for managing Python virtual environments
MIT License
1.07k stars 101 forks source link

vf upgrade: ‘sed’ cannot find [an undisclosed] file #234

Closed kseistrup closed 8 months ago

kseistrup commented 2 years ago

Issue

TL;DR: vf upgrade fails with “sed: can't read : No such file or directory” and I have no idea which file vf is talking about.

I have exactly one virtual environment, toot, that holds the newest version on the PyPI package by the same name.

$ cat ~/.virtualenvs/global_requirements.txt
pip
wheel
setuptools

When I attempted to upgrade the envuironment, all I got was an unhelpful error:

$ vf upgrade toot
Upgrading toot from 3.10.8 to 3.10.8
sed: can't read : No such file or directory

I'm unsure how to proceed.

justinmayer commented 8 months ago

Hi Klaus. Sorry for the long delay in responding to your query. I can't reproduce this error. If you can reproduce it reliably, would you please comment here so I can re-open the issue? Thanks!

kseistrup commented 8 months ago

Fresh from the oven:

» vf upgrade toot42  # toot42 is an existing venv
Upgrading toot42 from 3.11.8 to 3.11.8
sed: can't read : No such file or directory

The interesting thing here is the 3.11.8, which is the currently installed version of Python. Last time it must have been 3.10.8.

So when I look in the virtual.fish script in the function __vf_upgrade(), I see (around line 623):

    command sed -i '' -e "s/$old_py_fv/$new_py_fv/g" "$venv_path/pyvenv.cfg"

which, as far as I can tell is the only place in upgrade() that invokes sed. Andf the only empty string there is what is supposed to be the “suffix” for backups: -i ''

Anyway, if I invoke VirtualFish as vf upgrade --rebuild toot42, everything runs as expected (I just found out).

justinmayer commented 8 months ago

Perhaps it's a permissions issue? Maybe ~/.virtualenvs/toot42/pyvenv.cfg isn't writable by the sed call for some reason?

What happens if you run the same command manually? For example:

command sed -i '' -e "s/3.11.8/3.11.8/g" "$HOME/.virtualenvs/toot42/pyvenv.cfg"
kseistrup commented 8 months ago

The same thing happens: sed: can't read : No such file or directory

However, if I do like sed(1) says, and either omit the SPACE between -i and '': sed -i'' -e […], or omit the “suffix” altogether: sed -i -e […], sed's cool.


Fron sed(1) on Linux:

       -i[SUFFIX], --in-place[=SUFFIX]

              edit files in place (makes backup if SUFFIX supplied)
» sed --version | head -n1
sed (GNU sed) 4.9

edit: typo

kseistrup commented 8 months ago

PS: You could argue that if “suffix” is a separate empty string, then “SUFFIX [is] supplied“ and empty, whereas -i and -i'' would look the same to sed (once it gets hold of the argument) that would then treat it as an unsupplied suffix.


edit: clarification

justinmayer commented 8 months ago

Okay, so it sounds like perhaps the best course of action is to remove the empty string from this sed invocation, right?

kseistrup commented 8 months ago

That's what I would do, yes.

If you had asked me to use sed to make an on-the-fly replacement in a file, I would never have supplied an argument to -i. Truth be told, I had to look in the sed(1) man page to read about the optional suffix. :wink:

justinmayer commented 8 months ago

Fix released in VirtualFish 2.5.7 🎉

Thank you, Klaus, for helping track down the cause of the problem. Much appreciated!