-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Introduce cargo metadata subcommand #2196
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
features: Vec<String>, | ||
no_default_features: bool) | ||
-> CargoResult<(Resolve, Vec<Package>)> { | ||
let mut source = try!(PathSource::for_path(manifest.parent().unwrap(), config)); |
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.
Is this unwrap
safe?
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 this should be fine
Another question is where should we put documentation for the format? Is the help message a right place? |
This hides `SerializedDependency` from general public, as requested [here](#1434 (comment)). It also hides `SerializedManifest` which was (wrongly?) exposed. This is required for #2196. I want to move in small steps this time, hence the separate PR. Technically this break backwards compatibility, because `SerializedDependency` and `SerializedManifest` were public (`SerializedPackage` was private however). Are such changes allowed in cargo?
@matklad how about inline code documentation in the relevant module file? |
Sure :) We want to use cargo metadata with a plugin for Intellij IDEA. IDEA based IDEs are "smart": they build a syntax tree from source code and perform "static analysis" (completion, navigation, refactorings, ...) using it. To build such tree across several files, we need to know some metadata about the project. The most vital piece of information is a list of crate roots that belong to the project. Only if you know crate roots ( Note that a rust project can include several cargo subprojects (path dependencies), so we need this information too. Another place where we need help from cargo is extren crates declarations. We need to resolve We don't use
Missing output is Ok, it will be easy to add more information later. Moreover, if we output too much, we may make changing the internal cargo structures harder, because the serialized output is currently tied to this structures.
I would argue that this also falls into "missing information" category. There are two pieces of data here: a flat list of known packages and a dependency DAG. At the moment,
This is an important piece of information, but it is not needed at least for our use case. It can be added later.
Hm, target serialization does include
Not sure what it is, but seems like it does not belong here :)
What is the relation between a |
@alexcrichton 1.5 is 🎉 released 🎉 so any feedback on this? :) Thinking of it more, I propose the following format: {
"packages": [
{
"name": "foo",
"package_id": "some_name some_version some_source_id",
//...
},
//...
],
"graph": [
"root": "some_name some_version some_source_id",
"edges": [
//...
]
]
} That is, we should include a So we can remove this from the output. A thing that bothers me a little is that |
Thanks for pushing on this again @matklad! Currently I'm at a work week in Orlando, but I hope to digest more of this first thing next week! |
flag_manifest_path: Option<String>, | ||
flag_no_default_features: bool, | ||
flag_output_format: OutputFormat, | ||
flag_output_path: OutputTo, |
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.
Perhaps this could just be Option<String>
? That way a custom Decodable
implementation isn't needed
Thanks @matklad! This is looking good to me. I think it's important to rely on the standard I've got a few bike-sheddy points that I'd like to discuss here:
Thoughts? To respond to some of your points as well, I agree that limiting the amount of information being printed is a good idea. I'd just want to make sure that this is useful in a first draft rather than restricting it too much in terms of the information being printed. For example I'm ok with not emitting the dependency graph for now, that can always be added later. |
Hm,
Will look at the
Does anybody uses |
Ah yes
Where all the packages in resolve are listed as package ids. That way tools can use resolve to figure out what the precise structure is, and then they can use the package metadata information in the packages array to figure out things like source paths and such. |
Also I'm not sure if there are too many users of |
Should we include both declared and resolved dependencies in the output? I'd say yes: this will help to detect issues like #2064 |
@alexcrichton I'm a bit worried that Package and Manifest have almost identical representation: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/manifest.rs#L47-L52 If I add Given this comment I'm not even sure that we need both a Package and a Manifest ;) |
I think we should, yeah, but in separate locations (to mirror what Cargo does)
An excellent point! I think it should be ok to actually just have the |
There is Particularly, there is no I'd better provide a separate |
Ah actually I think that's basically exactly what we want here, could you elaborate on what's missing from constructing it? (e.g. you've already got a I will say though idiomatically the implementation of |
The entry in the lock file looks like this:
Note that in Package id string can be reconstructed from this three things, but it does not feel right. |
4757aca
to
f8d5a21
Compare
Most of the work was done by @dan-t in rust-lang#1225 and by @winger in rust-lang#1434 Fixes rust-lang#2193
Most of the work was done by @dan-t in #1225 and by @winger in #1434 Fixes #2193 I failed to properly rebase previous attempts so I just salvaged this from bits and pieces. @alexcrichton are you sure that the default format should be TOML? I think that TOML is more suitable for humans, and JSON is better (at the moment at least) for tools. Maybe we should default to ~~TOML~~ JSON?
@alexcrichton what is the release schedule for cargo? Am I correct that |
☀️ Test successful - cargo-linux-32, cargo-linux-64, cargo-mac-32, cargo-mac-64, cargo-win-gnu-32, cargo-win-gnu-64, cargo-win-msvc-32, cargo-win-msvc-64 |
@matklad yeah this'll ride the normal release trains and will be available in Rust 1.8 |
Ouch, @alexcrichton, I think we've missed one rather major issue here, this one
The id's in {
"packages": [
{
"name": "geom",
"version": "0.1.0",
// This id is different
"id": "geom 0.1.0 (path+file:\/\/\/home\/matklad\/projects\/rustraytracer)",
"source": null,
...
},
...
],
"resolve": {
"root": {
"name": "rustraytracer",
"version": "0.1.0",
"source": null,
"dependencies": [
// from this id :(
"geom 0.1.0",
"rand 0.3.11 (registry+https:\/\/github.com\/rust-lang\/crates.io-index)",
"regex 0.1.41 (registry+https:\/\/github.com\/rust-lang\/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https:\/\/github.com\/rust-lang\/crates.io-index)",
"simple_parallel 0.3.0 (registry+https:\/\/github.com\/rust-lang\/crates.io-index)",
"time 0.1.33 (registry+https:\/\/github.com\/rust-lang\/crates.io-index)",
"utils 0.1.0"
]
},
...
},
} In |
Oh dear that is indeed not good! I can't seem to recall myself why there are two |
Probably not. The one from resolve is "context sensitive". Look at this function: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/resolver/encode.rs#L189. It creates an Unfortunately it depends on the |
Hm ok, so the requirements of resolve are indeed a little different. We don't want to emit filesystem paths to the lock file because otherwise they'd just oscillate over time as you migrate among machines. That being said there aren't too many uses for encoding package ids, and in general it amounts to an assertion that path-based source ids are omitted where everything else is included. It's probably fine for now to change the encodable implementation for package ids to ignore path sources and that way it'll match resolve (and resolve can use the same implementation) |
I've tried to do it here and the result is unsatisfactory. The crux of the problem is that
This makes me think again that maybe we should leave lock-file resolve serilization to lockfile only, and instead provide a simpler and more natural generic serialization for resolve :) And there is one more thing, |
Hm ok, I forgot that package ids were being encoded for Sorry for the roundabout way to conclude that! |
Experiment is a nice way to make a ( I hope so :) ) correct conclusion. here is a PR: #2331 |
Most of the work was done by @dan-t in #1225 and by @winger in #1434
Fixes #2193
I failed to properly rebase previous attempts so I just salvaged this from bits and pieces.
@alexcrichton are you sure that the default format should be TOML? I think that TOML is more suitable for humans, and JSON is better (at the moment at least) for tools. Maybe we should default to
TOMLJSON?