-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Include directory in CargoBuilder install path #6298
Conversation
Thanks for opening a pull request and helping make RubyGems and Bundler better! Someone from the RubyGems team will take a look at your pull request shortly and leave any feedback. Please make sure that your pull request has tests for any changes or added functionality. We use GitHub Actions to test and make sure your change works functionally and uses acceptable conventions, you can review the current progress of GitHub Actions in the PR status window below. If you have any questions or concerns that you wish to ask, feel free to leave a comment in this PR or join our #rubygems or #bundler channel on Slack. For more information about contributing to the RubyGems project feel free to review our CONTRIBUTING guide |
Thanks for the detailed info. If I understand it well, |
Windows CI seems unhappy. Any ideas how to fix that? Anything I can help with (I have access to Windows machine if needed)? |
So part of this change is calling out to {
"packages": [
{"name": "foo", "manifest_path": "path/to/foo/Cargo.toml", ...},
{"name": "bar", "manifest_path": "path/to/bar/Cargo.toml", ...},
]
} We know the path to the crate we're trying to build, as it's passed as the first argument to The error on Windows is happening right around this bit of code, and my guess is that Ruby and cargo aren't agreeing on the exact format of the paths on Windows, so they aren't matching. I've added a better error message in this case, which should hopefully confirm that's the issue. If it is it's probably just a case of figuring out how to normalise the paths. |
@matsadler feel free to check CI now |
TL;DR
full error
|
results | ||
end | ||
# Where's the Cargo.toml of the crate we're building | ||
cargo_toml = File.join(cargo_dir, "Cargo.toml") |
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 seems (thanks to failing specs message now) this produces wrong path on Windows.
D:/a/rubygems/rubygems/tmp/test_rubygems_20230127-4224-1i30256/ext/Cargo.toml
Since actually proper one is present int cargo metadata
output.
D:\a\rubygems\rubygems\tmp\test_rubygems_20230127-4224-1i30256\ext\Cargo.toml
This seems to be known Ruby limitation. I'll check on Windows machine if there's any way to produce proper Windows path in here. By looking at the other code, this could work (not tested).
cargo_toml = cargo_toml.tr(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
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 think that tr(ALT_SEPARATOR ...
trick should work. I've pushed a changed using that approach.
the final copying of the extension into place has been slimmed down, reflecting that it only needs to copy a single file, rather than replicating the more involved process used for a C ext this also refactors #build so that #cargo_crate_name only needs to be called once, and hopefully the build flow is easier to understand
@matsadler seems ok. Is this ready to merge for now? |
Yep, if there’s no more comments then I’m happy for this to be merged. |
Include directory in CargoBuilder install path (cherry picked from commit d17207c)
What was the end-user or developer problem that led to this PR?
This is an attempt to address issue #6204 "
bundle gem --ext=rust
generates gem that fails to load when installed".The
CargoBuilder
is installing Rust extensions inlib/gemname.dlext
, but the Rust extension template is set up expecting the extension to be installed inlib/gemname/gemname.dlext
.I don't think a concrete decision was made in that ticket, but my reading was that
lib/gemname/gemname.dlext
is the desired destination, and the bug is inCargoBuilder
, not the Rust extension template.Furthermore, it seems the consensus was that while this would be a breaking change to
CargoBuilder
, it has not ever been announced as stable, so it's fine to make the change.What is your fix for the problem, implemented in this PR?
Currently
CargoBuilder
installs extensions tolib/gemname.dlext
, these changes update that tolib/dirname/cratename.dlext
.dirname
is sourced from the extension path, dropping the first and last parts, for example "ext/foo/bar/Cargo.toml" becoming "foo/bar".cratename
is sourced by calling out to thecargo metadata
command.Using
dirname
as the first part should better match the directory structure and is analogous to how C extensions are built. Users have control over this as they can nest directories however they want.Using
cratename
instead ofgemname
makesCargoBuilder
more reliable, as it better detects the location of the extension once cargo has compiled it to move to the final install location. This also provides a benefit to users as they have more control over the crate name, and can choose to give it a different name to the gem if they wish. And it allows for multiple Rust extensions in a single gem, which might not be a common use case, but it matches what can be done with C extensions.There is also benefit to users of Magnus (as used by the Rust extension template) as the autogenerated
Init
function generated by Magnus will match the crate name, not the gem name, potentially saving confusing debugging.As I was making these changes I wanted to be able to only call
#cargo_crate_name
once, to avoid multiple calls out tocargo
. To do this I refactored#build
, inlining a number of helper methods only used a single time. Hopefully this makes the flow of#build
easier to understand.I also updated the gem spec validation to allow
Cargo.lock
to be anywhere in the gem, as requiring it to be in the root seemed to be a frustrating limitation.I updated the
CargoBuilder
tests, and reused thecustom_name
test extending it to cover the new behaviour. As I was updating the tests I found two files in the fixtures that seemed to be unused, so removed them.Make sure the following tasks are checked