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

Use cargo-metadata instead of parsing TOMLs by hand #107

Merged
merged 33 commits into from
Oct 3, 2020

Conversation

roblabla
Copy link
Contributor

@roblabla roblabla commented Sep 30, 2020

Preface

This is a bit of a big PR, and the commits are currently a mess. I'm sorry.

Motivation

Currently, cargo wix manually parses TOML files, and tries to guess what the compiler is going to do based on this. This leads to a lot of issues: It doesn't properly support custom target directories, it fails to work in workspaces, it doesn't support cross-compilation (for instance to build 32-bit targets from a 64-bit host), it fails to find binaries under src/bin/*.rs. I'm sure there are more issues, but those are the ones I identified while trying to use cargo-wix in my own project.

Most of those issues could be fixed by asking cargo for the information we seek directly, instead of trying to guess them. This is exactly what the cargo metadata subcommand does: it allows us to query cargo for the metadata of a given project, for instance what packages are in the current workspace, which binaries that package contains, where those binaries will be built, etc...

Details

This PR does a few things:

First of all, it moves as much of the manual TOML parsing as possible to a call to cargo-metadata. If the current workspace has only one package, it will use this one, otherwise it requires the user to pass the package name via a command line parameter (--package).

Second, it uses the information from cargo-metadata to find all the binaries, including those in src/bin. Cargo is nice enough to give us all the implicit and explicit bin targets!

Third it removes all the hardcoded paths to target/. cargo-wix now injects a wix preprocessor variable, CargoTargetDir, that is set to the proper target directory (as found by cargo-metadata). The templates are updated to automatically use this variable.

TODO

  • Find a way to get the homepage. Cargo metadata doesn't provide it - we might need to parse the TOML to get that value :(.
    EDIT: I submitted a cargo PR to surface those values: Homepage doc cargo metadata rust-lang/cargo#8744. If/when this is merged, this will need to be followed by a PR to the cargo_metadata project. This will likely take a bit. In the meantime, I guess we could manually parse the TOML just to get this field.
  • Add a --package arg to all the subcommands
  • Add tests for --package
  • Add tests for multi-bin projects

}

#[test]
fn target_wix_with_existing_file_but_not_cargo_toml_fails() {
Copy link
Contributor Author

@roblabla roblabla Sep 30, 2020

Choose a reason for hiding this comment

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

This test was removed because it was testing for an error scenario that's... kinda wrong. It is 100% allowed to have a Cargo.toml whose name isn't Cargo.toml, if you pass it with --manifest-path.

I should probably re-add it, but explicitly check that it actually works instead of erroring.

src/create.rs Outdated
.join(TARGET_FOLDER_NAME)
.join(WIX)
.join(filename)
})
} else {
trace!("Using the current working directory (CWD) to build the WiX object files destination");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO: Change the trace to say it's relative to the cargo target dir

src/create.rs Outdated
@@ -929,7 +875,7 @@ impl Execution {
// for PathBuf, but it was unexpected and kind of annoying because I am
// not sure how to add a trailing slash in a cross-platform way with
// PathBuf, not that cargo-wix needs to be cross-platform.
dst.push(format!("{}\\", WIX));
let dst = target_directory.join("");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, I had the same problem to add a trailing backslash... I essentially found two ways, this one, or

let s = target_directory.as_os_string();
s.push("\\");
PathBuf::from(s)

@roblabla roblabla force-pushed the cargo-metadata branch 3 times, most recently from b1752e3 to 3c4e1af Compare September 30, 2020 15:28
@volks73
Copy link
Owner

volks73 commented Oct 1, 2020

Thank you for the excellent and detailed PR.

I have never been fond of the manual TOML parsing of the manifest, the guess work that was being used for project/package artifacts, and the hard-coded paths. I always thought there should be a better way to obtain package/project information from within a cargo subcommand. Side note, the "better way" is apparently a giant stream of (de)serialization: TOML->Cargo->JSON->cargo-metadata->cargo-wix. This feels a little cumbersome to me, but very much inline with command line interfaces. Despite this feeling, it is a much more robust and future-proof implementation; thus, I welcome and appreciate the relatively big PR.

You beat me to submitting an issue and PR to the Cargo project for the missing homepage field from the JSON output of the cargo metadata command. I agree, it will be a while before the change is propagated up to this project. Manual TOML parsing will still be needed for the homepage, unless you would prefer to wait until the change is available to eventually merge this PR?

Would it be possible for you to create an integration for a workspace project? Maybe this is what you mean by the "...multiple-bin" TODO?

I should be able to do a more in-depth review this weekend (Oct 3rd - Oct 4th). Did you want all of the TODOs completed before merging?

Thanks again and please keep the changes coming!

@roblabla
Copy link
Contributor Author

roblabla commented Oct 1, 2020

Haha, thanks a lot. And thanks for the great project :).

Manual TOML parsing will still be needed for the homepage, unless you would prefer to wait until the change is available to eventually merge this PR?

Honestly, even if cargo merges the pr today it will take ~6 weeks to end up in stable, so it'd be a breaking change. Parsing the manifest manually in the meantime isn't very complex, and cargo gives us the full path to the manifest so it should be robust enough. So I think we should just do that.

Would it be possible for you to create an integration for a workspace project? Maybe this is what you mean by the "...multiple-bin" TODO?

So what I had in mind for multiple-bin is a single package containing multiple implicit binary targets in src/bin/*.rs.

I do have plans for full workspace support, but I think it should be a follow-up PR because it will need a bit of design work which is still todo. I'll explain some of the problems I foresee in a full workspace support tomorrow.

I should be able to do a more in-depth review this weekend (Oct 3rd - Oct 4th). Did you want all of the TODOs completed before merging?

Yeah, hopefully I should have everything done before merging. The remaining bits are rather simple.

@volks73
Copy link
Owner

volks73 commented Oct 2, 2020

Would it be possible for you to create an integration for a workspace project? Maybe this is what you mean by the "...multiple-bin" TODO?

So what I had in mind for multiple-bin is a single package containing multiple implicit binary targets in src/bin/*.rs.

Cool, I understand and appreciate the inclusion of the test.

I do have plans for full workspace support, but I think it should be a follow-up PR because it will need a bit of design work which >is still todo. I'll explain some of the problems I foresee in a full workspace support tomorrow.

Yes! Implementing support for workspaces has been lagging but also I have never had a clear idea of how to implement it. There appears to be a lot of flexibility in organizing projcets with workspaces, so I would love to hear some ideas and approaches to addressing workspace support, but it makes sense to focus on that after this PR. I do not want to distract you.

Yeah, hopefully I should have everything done before merging. The remaining bits are rather simple.

You clearly are in the "flow" and making great progress on this PR. I will hold off and let you do your thing.

When passing a package to initialize, we should create the wix directory
in the subpackage folder.
}

#[test]
fn destination_is_correct_with_input() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All those tests are irrelevant now, since destination is always relative to the provided package.

@roblabla
Copy link
Contributor Author

roblabla commented Oct 2, 2020

So, I think this is ready for review, I fixed all the small bugs that I could find, but there might be more hiding :^).

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

Successfully merging this pull request may close these issues.

2 participants