-
-
Notifications
You must be signed in to change notification settings - Fork 649
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 ExternalTool subsystem base for downloading external tools. #9625
Conversation
Useful, e.g., to unpack downloaded external binaries. [ci skip-rust-tests] [ci skip-jvm-tests]
A streamlined replacement for the existing BinaryTool. [ci skip-rust-tests] [ci skip-jvm-tests]
Note to reviewers: You can focus on just the second commit. The first is just #9624. |
[ci skip-rust-tests] [ci skip-jvm-tests]
[ci skip-rust-tests] [ci skip-jvm-tests]
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.
Very cool. Thank you!
[ci skip-rust-tests] [ci skip-jvm-tests]
[ci skip-rust-tests] [ci skip-jvm-tests]
[ci skip-rust-tests] [ci skip-jvm-tests]
[ci skip-rust-tests] [ci skip-jvm-tests]
# Delete this line to force CI to run Clippy and the Rust tests. [ci skip-rust-tests] # Delete this line to force CI to run the JVM tests. [ci skip-jvm-tests]
[ci skip-rust-tests] [ci skip-jvm-tests]
[ci skip-rust-tests] [ci skip-jvm-tests]
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!
def get_request(self, plat: Platform) -> ExternalToolRequest: | ||
"""Generate a request for this tool.""" | ||
return self.generate_request( | ||
plat, self.get_options().version, self.get_options().known_versions, | ||
) | ||
|
||
|
||
@rule | ||
async def download_external_tool(request: ExternalToolRequest) -> DownloadedExternalTool: |
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.
So, it's currently the case that the Platform is available as a singleton, here:
pants/src/python/pants/engine/platform.py
Lines 32 to 36 in aa2ed8b
# TODO We will want to allow users to specify the execution platform for rules, | |
# which means replacing this singleton rule with a RootRule populated by an option. | |
@rule | |
def materialize_platform() -> Platform: | |
return Platform.current |
So your rule signature could probably just be:
@rule
async def download_external_tool(request: ExternalToolRequest, platform: Platform) -> DownloadedExternalTool:
The plan shortly (via https://docs.google.com/document/d/1hS0n6vp-hBxy4Xo-q9QA_elofzQtOubjfN4nSeIgp90/edit#heading=h.jj08j7tn7x2d , which I have some initial patches for) is for the Platform to switch from being a singleton to being a Param. That won't change anything from the @rule
's perspective, but it will actually allow differentiating requests from one another.
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.
Gotcha. Will make this change.
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.
Hmm, so we need to know the Platform when we create the request, because it can affect the URL, so this would require more restructuring than I think we want right 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.
Not a blocker. Thanks!
I'll need to add a |
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.
Great! Thank you Benjy!
Subclass this to configure a specific tool. | ||
|
||
|
||
Idiomatic use: |
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 adding this.
ce0fa04
to
d67a3f9
Compare
abfea9f
to
626ead4
Compare
[ci skip-rust-tests] [ci skip-jvm-tests]
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.
Awesome work!!! binary_util.py
is horrible to change (and that's partially my fault). Thanks so much for diving in to repair this.
member_type=str, | ||
default=cls.default_known_versions, | ||
advanced=True, | ||
help=f"Known versions to verify downloads against. Each element is a " |
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.
Would something like:
dedent(f"""\
...
""")
Potentially be easier to read and change?
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.
Sorry I didn't address these comments Danny. I somehow missed them! Will look now and fix in my current change as needed.
Re this, I'm thinking the rendering code should figure this sort of thing out, as needed?
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.
Oh sure! I meant for the purposes of development, the result might look cleaner. I agree that the rendering code should be figuring out how to display the text.
|
||
|
||
A lightweight replacement for the code in binary_tool.py and binary_util.py, | ||
which can be deprecated in favor of this. |
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 would like to add this as a @deprecated_module
to those files, then -- we could potentially use deprecation_start_version
to delay it if we expect we'll need more than one release cycle to completely remove things.
I know binary_util.py
was also used to fetch some tools for rust bootstrapping. We'll probably want to add that before we can remove it entirely.
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, I would like to deprecate, but I'm going to transition all current uses first, to see what yelps.
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.
Yes, sounds great!
) -> ExternalToolRequest: | ||
for known_version in known_versions: | ||
try: | ||
ver, plat_val, sha256, length = (x.strip() for x in known_version.split("|")) |
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.
It might be useful to split this parsing out into a separate method in the future instead of having to hunt for the logic here.
def my_rule(my_external_tool: MyExternalTool): | ||
downloaded_tool = await Get[DownloadedExternalTool]( | ||
ExternalToolRequest, my_external_tool.get_request(Platform.current) | ||
) |
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.
It would be pretty cool to have this in the official engine README.md. I should also get #9446 in.
A streamlined replacement for the existing BinaryToolBase.
The existing code has served us really well for a long time, but has over the years evolved to be convoluted, leans on legacy util code, is biased towards pantsbuild-hosted binaries, has too many moving parts, and is no longer ergonomic.
This new code offers a simple and unified interface for version selection, URL computation,
and digest verification (possibly across multiple known versions). It integrates naturally
with the v2 engine, and supports automatic extraction from archives. Its design and functionality is inspired by the existing code, but cuts down the cruft.
The new
ExternalTool
subsystem base class is backwards compatible withBinaryToolBase
: A subclass of the latter can be rewritten to subclass the former,and its options will remain compatible (although there may be deprecation warnings).
This change demonstrates its use via the
ClocBinary
andProtoc
subsystems.A future change can migrate our other uses of
BinaryToolBase
.Note: requires #9624
[ci skip-rust-tests]
[ci skip-jvm-tests]