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
Allow specifying external tool url template #11013
Allow specifying external tool url template #11013
Conversation
# 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]
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 Thales!
Other reviewers, see https://pantsbuild.slack.com/archives/C046T6T9U/p1603294293445900 for more context:
So… I can’t access any external network (aka internet 😕 ) from my CI
Thales's org requires hosting the pex
binary themselves and downloading from their URL.
default=cls.default_url_platform_mapping, | ||
advanced=True, | ||
help=( | ||
"A dictionary mapping platforms to strings to be used when generating the URL " |
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.
Other reviewers, this is the best that Thales and I could come up with, but please feel free to tweak. It's dense.
""" | ||
platform = self.url_platform_mapping[plat.value] if self.url_platform_mapping else "" |
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.
Unclear to me how eagerly we should validate the --url-platform-mapping
, e.g. ensure it aligns with the Platform
enum.
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 great stuff! I might suggest a slight refactoring: I would leave the base class as-is, and have a subclass called TemplatedExternalTool
or something like that, which implements generate_url()
via this mechanism.
That way, subclasses that need logic that can't be easily expressed using this templating can still do so, by overriding generate_url()
directly.
An alternative would be a single option that maps platform to a URL template (and then substitute version). That would reduce the number of options and no need to map platform names to a different name and then substitute. Thoughts? |
Hm, can you think of an example that needs more flexibility? My concern is that this might mean for that tool, an org like Thale's could never use the tool. They need the ability to specify the entire URL purely through the options system. We don't want to make them implement a Python plugin etc.
The challenge is that each platform mapping differs depending on the tool. Some use Edit: nvm, I misread your suggestion. I think that would work, with the downside that if platforms don't behave differently, you need to duplicate the URL twice. |
Or support a "default" key in the mapping that is used if a platform-specific key is not present. |
So you can either do:
Or
That might make sense. Although, I don't love needing to duplicate the rest of the URL, as often it's only a small portion that changes. Right now, we only have two platforms, but we know from #10620 that that is not robust and we need more (as soon as ARM macOS laptops come out...) |
Ah, Thales, you'll need to update the gRPC subsystem too: https://github.com/pantsbuild/pants/blob/master/src/python/pants/backend/codegen/protobuf/python/grpc_python_plugin.py. Looks like CI is failing because of that. |
# 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]
# 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]
[ci skip-rust] [ci skip-build-wheels]
@Eric-Arellano this is super hacky but...
that actually works.. lol EDIT: Oh, I just thought about users adding it to the pants.toml.. which needs to be string... nvm! |
I can imagine needing to do more specific inspection than just "is this macos vs. linux". E.g., using network proximity to make decisions. Even if we don't use that internally, an external user might need it. In fact someone might already be using it and we just broke the API... I would rather do the less present-breaking, more future-friendly thing. |
Hm, if we do that, then the tool will not work for any user who needs to download the tool through their own blessed host. Again, they need to be able to change the URL purely through the options system. How do you feel about updating this in the future if we do find the plugin author has that advanced requirement? We can identify either if we can tweak this templating mini-DSL, or allow them to ignore it and not support custom URLs. I'm concerned that this would otherwise be premature abstraction - we're speculating that someone needs that additional power. In the meantime, plugin authors can override the private method _generate_url() to be whatever they want. There is an escape valve, only, private, because we want people to bias towards allowing for changing the URL via options. |
If the worry is about backwards compatibility I think that adding back the Now for the TemplatedExternalTools I sort of don't see the purpose considering that I can easily change the url template and mappings directly from options at this moment. I'm biased about this but if we go this new class route I would have to re-write the Pex tool (I'm assuming that would work) using that new TemplatedExternalTools in order for pants to work on my CI, which from a user perspective kinda feels like it should just be already there available for an easy change. |
Well, I definitely don't want anyone to override I'm not sure what you mean by having to rewrite something to use TemplatedExternalTools? You would just subclass TemplatedExternalTools instead of ExternalTools, to get this template-based implementation. You already have to rewrite the subclasses to provide the templates, so making them extend a different class doesn't seem like an onerous change? I see the point about this possibly being premature, BUT - the issue with deeming this a premature abstraction is the cost of introducing it if we needed to. How would we do that exactly? This change bakes the templating behavior into the base class, which is the interface to this functionality, and leaves no straightforward possibility for extension or differing implementation. So this is prematurely anti-abstracting... I'm suggesting that ExternalTool is ~an interface, and TemplatedExternalTools would be its (currently only) implementation. If this were Scala and we had literally implemented it as a trait, this wouldn't be controversial. Python, unfortunately, muddies the waters... But note that |
Hm, I could buy that. A lingering concern of mine is how to document both the interface and this new subclass. How would you feel about documenting? Would we prefer one vs the other? I don't want to robustly document both and make the user decide which they want. |
Just to be clear that I understood what you meant - As a Plugin developer I can either choose the current TemplatedExternalTools implementation (and if needed tweak the functions I need) OR I can come up with my own MyClassExternalTools based on ExternalTools and implement the functionalities. ExternalTools wouldn't be used directly anymore. |
Yeah, I think it would look like this:
A benefit of this approach is that we don't break anything for plugin authors already using I think this is a good change. |
I'm fine with only documenting Also, @thamenato has just discovered that our use of |
# 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]
# 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]
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 iterating on this, Thales!
…ild#11013) ### Problem An org's proxy would not allow external access to Github's URL when `pants` tries to download the `pex` binary. They can only download from their blessed host. ### Solution Allow the user to pass a new URL, using template language, that contains the binary ### Result The user can set a new url by using the property `url_template` and if the binary has a different version based on platform one can also set that using `url_platform_mapping` dictionary. [ci skip-rust] [ci skip-build-wheels]
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.
LGTM, thanks!
Problem
An org's proxy would not allow external access to Github's URL when
pants
tries to download thepex
binary. They can only download from their blessed host.Solution
Allow the user to pass a new URL, using template language, that contains the binary
Result
The user can set a new url by using the property
url_template
and if the binary has a different version based on platform one can also set that usingurl_platform_mapping
dictionary.[ci skip-rust]
[ci skip-build-wheels]