Skip to content
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

Prototype: Expose scripts to path #1097 #1117

Closed
wants to merge 3 commits into from

Conversation

jneuff
Copy link

@jneuff jneuff commented Dec 3, 2020

This PR is just intended as a basis for discussion. It provides a prototype for the feature I suggested in #1097.

For this I added two command line arguments:

  • --expose-entry-points to set entry points (e.g. pip:main) to be exposed on PATH.
  • --expose-scripts to set scripts (e.g. pip) to be exposed on PATH.

Also, to be able to call the PEX entry point (path to PEX file or path to unzipped PEX) I needed to record the PEX file's shebang in PEX-INFO.

If any exposed_entry_points or exposed_scripts are defined, they will be rendered as scripts under $PEX_ROOT/bin/<hash>/<name>. Where <hash> ensures the directory is unique with respect to PEX shebang, PEX entry point and exposed entry points/scripts.

For a regular PEX exposing the script pip such a file might look like:

#!/bin/sh

PEX_SCRIPT=pip exec /usr/bin/env python3.8 /home/user/scratch/pex-1097/my.pex $@

Or for an unzipped PEX exposing the entry point pip:main:

#!/bin/sh

PEX_MODULE=pip:main exec /usr/bin/env python3.8 /home/user/.pex/unzipped_pexes/d7e4fb19eea99444d4ce8b85e5cffb4aca950bca $@

It turned out, the main problem was how to call the PEX. Because when running an unzipped PEX, the path to the original PEX file is lost. That is why I had to record the shebang in PEX-INFO, to being able to call an unzipped PEX the same way as running the PEX file.

The exposed entry points work with this prototype:

~/scratch/pex-1097 » ./my.pex                                                                                                                                                                                           d0301508@kaxpi00000122
Python 3.8.6 (default, Sep 25 2020, 00:00:00) 
[GCC 10.2.1 20200826 (Red Hat 10.2.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import subprocess
>>> subprocess.check_call("pip:main")
WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.

Usage:   
  my.pex <command> [options]
..

Whereas exposed scripts do not:

>>> subprocess.check_call("pip")
Python 3.8.6 (default, Sep 25 2020, 00:00:00) 
[GCC 10.2.1 20200826 (Red Hat 10.2.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)

Calling pip dropped me into another Python interpreter. Probably, I broke resolving scripts. I'll dig into it.

Obviously, a lot is missing here, tests for instance. As I said this is just a prototype to serve as a basis for discussion. So, I'd be glad to get some feedback on this.

Copy link
Member

@jsirois jsirois left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a stab at this! IIUC you don't need the --exposed-entry-points functionality, just the --exposed-scripts. If so, I have a change coming this weekend to support #962 that creates a venv on from a PEX at runtime. To do this, all the .whl bin/ scripts that are python scripts (console scripts), are re-written to have a shebang that is the selected runtime interpreter. You should probably wait on tht to land and see if it doesn't solve your use case. I'll include you on the review.

from pathlib import Path


SCRIPT_TEMPLATE = """#!/bin/sh
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not ideal. For example, it would fail in any Python distroless image whereas the corresponding python console script it wraps would not.

import itertools
import os

from pathlib import Path
Copy link
Member

@jsirois jsirois Dec 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pex still supports Python 2.7 so you need to stick to those APIs - this will fail the 2.7 CI shards as-is.

hasher = hashlib.md5()
hasher.update(shebang.encode("utf-8"))
hasher.update(pex_path.encode("utf-8"))
for item in itertools.chain(entry_points, scripts):
Copy link
Member

@jsirois jsirois Dec 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hashing scheme is foiled by setting an entry_point for the module 'pex' today:
https://github.com/pantsbuild/pex/blob/c7c74cc607b83635063abc68cd613fb848b895d3/pex/__main__.py#L1-L8
and then changing that to be the 'pex' console script tomorrow:
https://github.com/pantsbuild/pex/blob/c7c74cc607b83635063abc68cd613fb848b895d3/pyproject.toml#L33-L34
You might form a dict using the key names corresponding to the 4 slots and then hash its sorted key json encoding.

@jsirois
Copy link
Member

jsirois commented Dec 8, 2020

@jneuff if you have time to look at #1128 and in particular this test working backwards to the --bin-path feature it tests, I'd be grateful: https://github.com/pantsbuild/pex/pull/1128/files#diff-f6529bfd4644104d30930f6bf2eeafdf75f87ae12659a9185ac45c3fcdb2b8f9R180

@jneuff
Copy link
Author

jneuff commented Dec 9, 2020

@jsirois Thanks for the feedback. Your venv feature sounds quite interesting! That should probably cover my use-cases. I'll take a look at your PR.

@jneuff
Copy link
Author

jneuff commented Dec 21, 2020

I am closing this PR as the intended use-cases are well covered by the new venv pex-tool feature.

@jneuff jneuff closed this Dec 21, 2020
@jsirois
Copy link
Member

jsirois commented Dec 21, 2020

Thanks for taking a stab at this @jneuff - it was definitely part of the motivation to finally implement #962 and solve #1097 along with other common issues running applications as PEX zip files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants