-
-
Notifications
You must be signed in to change notification settings - Fork 395
provision: Give a better error message; ensure the correct version of pip. #128
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
Conversation
Without this tweak, running the script results in a vague "No such file or directory" error if the virtualenv package is not installed.
if subprocess.call(['virtualenv', '-p', python_interpreter, venv_dir]): | ||
raise OSError("The command `virtualenv -p {} {}` failed. Virtualenv not created!" | ||
.format(python_interpreter, venv_dir)) | ||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than try-except, there is a way to detect specifically whether virtualenv has been installed. Ref: https://stackoverflow.com/questions/1871549/python-determine-if-running-inside-virtualenv/1883251#1883251.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds great, I'll look into that. Thanks for the feedback!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, I don't see how this can be applied here. This is a good way to check whether the code is running inside a virtual environment. What would be helpful in this case is a way to check whether the virtualenv
package is installed (before using it to create an environment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is how it is checked in one of the tool in the Zulip webapp/server:
https://github.com/zulip/zulip/blob/master/tools/update-locked-requirements#L4-L7
If the venv_dir
is known, a check along this line can be done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is already being done one line above:
if not os.path.isdir(venv_dir):
...
But what if the environment doesn't exist? We run the following code to create it:
subprocess.call(['virtualenv', '-p', python_interpreter, venv_dir])
To do it successfully we need to have the virtualenv
package installed. On Ubuntu it can be done by running this command in the terminal:
sudo apt-get install python-virtualenv
If we make the subprocess
call before the virtualenv
package is installed the script will exit with an error and print the traceback I included above.
What I'm trying to do here is to replace this traceback with an error message that tells people exactly what's going on: they need to install the package to run the script.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the idea of checking if virtualenv
is installed as the first step, makes the logic easier. Instead of which virtualenv
, I suggest checking the exit code of command -v virtualenv
, since its a shell built-in and part of posix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rht @derAnfaenger Thanks for the suggestions! I agree that checking if the virtualenv
package is installed before using it makes more sense than a try-except block. I'll make use of command -v virtualenv
too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, the subprocess
call fails when I use command -v virtualenv
:
Traceback (most recent call last):
File "./tools/provision", line 76, in <module>
main()
File "./tools/provision", line 26, in main
if subprocess.call(['command', '-v', 'virtualenv']):
File "/usr/lib/python2.7/subprocess.py", line 522, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Should I keep using which virtualenv
or wrap it in a try-except block, perhaps?
try:
subprocess.call(['command', '-v', 'virtualenv'])
except OSError:
print("{red}Please install the virtualenv package and try again.{end_format}"
.format(red='\033[91m', end_format='\033[0m'))
sys.exit(1)
if subprocess.call(['virtualenv', '-p', python_interpreter, venv_dir]):
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This discussion had a lot of suggestions that didn't actually work. @rht next time, I'd encourage you to read the code more closely before commenting; e.g. https://stackoverflow.com/questions/1871549/python-determine-if-running-inside-virtualenv/1883251#1883251 was totally irrelevant to the problem at hand :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(my mistake :( )
Another little tweak I suggest is to ensure that I used a clean Ubuntu 14.04 (a pretty common setup I think) and tried installing the |
Hmm, according to http://www.python3statement.org/practicalities/, the safe recommended version of |
@rht This is a good point, thanks! I'll update the commit. |
d0d8c24
to
ce3ff50
Compare
pip 8.0+ is required to successfully run the script (otherwise, the prefix option doesn't work). pip 9.0+ is installed because of the safety features.
ce3ff50
to
ec1ccd9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this @alenavolk ! Left two comments - the rest looks good to me.
if subprocess.call([os.path.join(venv_dir, venv_exec_dir, 'pip'), | ||
'install', '--prefix', venv_dir, '-r', os.path.join(base_dir, requirements_filename)]): | ||
pip_path = os.path.join(venv_dir, venv_exec_dir, 'pip') | ||
subprocess.call([pip_path, 'install', 'pip>=9.0']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of making another call, could we add pip>=9.0
to requirements.txt
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pip
must be updated first so that the >=9.0 version of it can take effect when installing the packages.
if subprocess.call(['virtualenv', '-p', python_interpreter, venv_dir]): | ||
raise OSError("The command `virtualenv -p {} {}` failed. Virtualenv not created!" | ||
.format(python_interpreter, venv_dir)) | ||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the idea of checking if virtualenv
is installed as the first step, makes the logic easier. Instead of which virtualenv
, I suggest checking the exit code of command -v virtualenv
, since its a shell built-in and part of posix.
Heads up @alenavolk, we just merged some commits that conflict with the changes your made in this pull request! You can review this repository's recent commits to see where the conflicts occur. Please rebase your feature branch against the |
Awesome, thanks for doing this @alenavolk! This looks great, I merged this, with one tweak to add a comment explaining why we do the pip upgrade. Thanks again for doing this! |
Let us know if you're looking for a next project! There's lots to do. |
@timabbott Awesome! I was planning to get busy with these tasks in the main Zulip repo, then work on this issue. If there is something more urgent I could do, let me know :) |
Sounds great! |
Right now when the
virtualenv
package is not installed the relatedsubprocess
call results in an error with the following traceback:I think it would be great to have a more beginner-friendly error message for this easy-to-fix (and potentially frequent) case.