-
-
Notifications
You must be signed in to change notification settings - Fork 631
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
An export goal for exporting data to be read by IDEs. #13415
Conversation
So far this creates a symlink to an appropriate venv in To see it in action: |
I suspect this is a red herring (perhaps just from using the cutting edge pants), but it's worth sharing. I get this output when running it:
The double-free is probably of note (even if unrelated). I'm just going to delete the file for now to move on. |
Wow, it's everything I imagined 🤩 Two non-blocking feature requests (which could always be filed as issues and followed up on after this PR):
|
Of course for feature request 1 I could make a symlink myself to the export dir, so it's really just a "nice-to-have". |
FWIW I saw the |
Thanks for the feedback! An option to set the output dir is definitely part of this, just haven't added it yet. As for it running automatically, if you run
That invocation will run in a loop and update the symlink whenever anything relevant changes. Would that work? |
thanks for noting the double free error (you're running directly against HEAD in the development branch, so expect some rough edges...) We'll take a look at that one. And the conftest.py error is fixable, as the error message says, by adding an appropriate Also, is "path/to" an actual path you're testing on, or is that a screwed up error message? :) |
|
Yeah, And for |
Re doing this implicitly, do you mean when the user runs unrelated pants commands for example? What would trigger an update? |
Basically any time the path the symlink points to would need to change (due to the hashes in the path), the symlink would also be updated to the new path. |
Make sense. Today |
I would honestly settle for just what's in this PR, lol. Anything extra is just gravy. |
One side-effect of this current dir structure is the virtual environment thinks it's name is
|
Hrm. This is because Benjy is re-using auto-created venvs never intended to be directly used. You can also create a venv for direct use (sourcing activate, mutating with pip, etc) via |
Yeah, I'm using those venvs for performance reasons. Having Pex always set the prompt to something readable would be great. And if a user happens to be using Python 3.5, then apologies... |
|
33e9596
to
19bf49a
Compare
This change provides: 1) A generic extensible mechanism for backends to add exportable data. 2) An implementation in the python backend that exports a venv with all the target set's 3rdparty deps. [ci skip-rust] [ci skip-build-wheels]
This is ready for initial review, thanks. |
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.
Tests would be great, but this looks right to me.
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.
Works for me. :)
Possible future feature that I would like is to also be able to get any 1st party distribution in "editable" mode in the venv..
IIUC editable mode installs are just symlinks to live sources. Here we use copies and - per PR discussion - |
For 3rd party code only. There's no 1st party code in this export (from what I could tell in my case, at least) Of course, a normal install would work too, in tandem with loop. |
Re: First-party. That's something I didn't think of (but not required for my use-case). If you're using source roots (E.g. |
I was thinking of exporting IDE config that points to source roots, since the IDE (at least pycharm) will treat sources in the venv as third-party. |
That will work for simple cases with consistent global resolves which you already ~limit this too anyhow. For other cases we'll need link farms just containing the sources compatible with the given resolve to avoid red-squiggleys. |
[ci skip-rust] [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
@rule | ||
async def export_venv( | ||
request: ExportedVenvRequest, python_setup: PythonSetup, pex_env: PexEnvironment | ||
) -> ExportableData: |
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 creating a virtualenv in the dest, this is symlinking from PEX's private cache of venvs into a destination... that seems maybe a bit dangerous, as someone who activated this venv and then fiddled with it would cause reproducibility issues by mutating PEX's cache.
Should this actually create a brand new venv instead, using pex-tool
's facilities for that?
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 a valid concern. We're walking a perf line here,
Note that the fiddling would have to be editing by hand since these venvs don't get Pip installed into them (unlike PEX_TOOLS=1 ./my.pex venv here
venvs, which do by default.).
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.
Mm... that does alleviate the concern quite a bit. Not a blocker then probably.
[ci skip-rust] [ci skip-build-wheels]
Addressed the comments and added tests. PTAL. In a follow up I can optionally change symlinking to copying, to give the user a tradeoff between safety and performance (with the default on the side of safety). |
[ci skip-rust] [ci skip-build-wheels]
[ci skip-rust] [ci skip-build-wheels]
|
||
|
||
class ExportSubsystem(GoalSubsystem): | ||
name = "export" |
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.
What's the story with export-codegen
? Should that still exist? I wonder if this should be something like export-ide
?
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.
We can probably get rid of export-codegen
once export
exports it. I don't want to call it export-ide
because it may be useful for other purposes. And that is a clunky name. This can be an "export various things" goal, with IDEs being a good use-case, but perhaps not the only one.
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'm interested to see the evolution of export
. Seems like it will have one-or-more subcommands for various (sub-?)subsystems.... sub-goals?.
I'm interested in possibly adding functionality to the export
goal for exporting a best-guess module_mapping
.
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.
How would this be consumed? That functionality would be awesome, but export
may not be the best place for it.
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.
By humans I suppose. You're probably right, let me switch hats: ... and I've forgotten my other use-case. Ignore me for now 😄
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 tend to agree, that export
could be a generic goal for getting anything out of the pants world to disk.
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.
Well, export is more about exporting internal information, for consumption by other tools, such as IDEs. We'd export codegen for that reason only - in normal use codegen is a build byproduct that is not visible to the end user. But since the user may want to manually inspect it, and may want to view it in their IDE, we'd export it.
Documentation, though, is a build product, like a PEX file or a distribution or a docker image or whatever. It is an actual formal output of the system that you can request. So I don't think export
is the right place for it, just as we don't use export
to get compiled code, or any other build product.
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.
Agree with @benjyw on this one... I expect that docs meet the bar for a dedicated goal. Likewise, I think that export
being "for anything you want to get out of pants" is probably too broad: focusing on the IDE usecase is valid (i.e., making this page as short as possible: https://www.pantsbuild.org/docs/setting-up-an-ide).
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.
Yeah OK I agree. But now you have me wondering if we should package
documentation 😂
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.
Good question!
[ci skip-rust] [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
This change provides:
A generic extensible mechanism for backends to add exportable data.
An implementation in the python backend that exports a venv with
all the target set's 3rdparty deps.
Follow-up changes can do things like export codegenned sources, or export
source roots into formats that PyCharm and VSCode can read.
[ci skip-rust]
[ci skip-build-wheels]