-
Notifications
You must be signed in to change notification settings - Fork 898
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
Support custom "project local" crate group in group_imports
#4693
Comments
Thanks for reaching out with your request! Generally speaking, we're open to supporting any additional variants and associated groupings, but would have to rely on someone from the community to submit an implementation. The Style Guide, and thus rustfmt's default behavior, will continue to be a do-nothing/preserve on this front, so we can't really allocate any maintainer bandwidth into implementation. The other thing I want to emphasize (as alluded to in the issue description) is that rustfmt's only source of information is the AST provided by rustc which would indeed limit the ability to actually implement the requested grouping. I suppose an additional variant that attempted to take the original groupings into account could work in theory, but I imagine it could be more tricky than it may seem at first glance. For example, consider this as input: use alloc::alloc::Layout;
use core::f32;
use std::sync::Arc;
use chrono::Utc;
use uuid::Uuid;
use log::Level;
use super::schema::{Context, Payload};
use super::update::convert_publish_payload;
use crate::models::Event; or this use alloc::alloc::Layout;
use core::f32;
use std::sync::Arc;
use log::Level;
use super::schema::{Context, Payload};
use super::update::convert_publish_payload;
use crate::models::Event;
use chrono::Utc;
use uuid::Uuid; Should there be two ext groups since there was a separation between them, or should The current variant isn't infinitely flexible, but it's quite predictable and deterministic which is essentially a requirement given the AST/pretty-printing nature of rustfmt. If anyone's interested in seeing this requested grouping and can come up with such an implementation though we'll be happy to review! |
Thanks for the well thought out and detailed response @calebcartwright! My *gut* reaction to those ambiguous cases would be for use alloc::alloc::Layout;
use core::f32;
use std::sync::Arc;
use log::Level;
use chrono::Utc;
use uuid::Uuid;
use super::schema::{Context, Payload};
use super::update::convert_publish_payload;
use crate::models::Event; While this output would most likely not be what the developer indented,
Yep, totally fair! I opened this issue since I just wanted to get some more visibility on the While I'd love to contribute this feature myself, Rust AST munging isn't something I've done in the past, so I might not be the right man for the job 😅. That said, who knows? Maybe I'll find some free time at some point to take a crack at it. After all, |
Understood, it's just that there would be more of a "depends" factor with this variant vs.
No worries! For you, or anyone interested in working on this, most of the relevant code can be found in rustfmt/src/formatting/reorder.rs Lines 201 to 206 in 98f2347
https://github.com/rust-lang/rustfmt/blob/master/src/formatting/imports.rs |
I'll throw out another possibility — why not make the option accept an array? Then users could put local imports first if they so desired, for example. There could be the "Std", "External", and "Crate" options that currently exist, with a "Project" (name TBD) being considered "External" unless explicitly specified. The first three could be mandatory. |
Not sure I understand what you're suggesting @jhpratt, could you elaborate? |
group_imports = ["Std", "External", "Crate"] # currently "StdExternalCrate" In the above, "Crate" would include a proposed "Project", but it could be specified separately. group_imports = ["Std", "External", "Project", "Crate"] This would also let people reorder them however they'd like. group_imports = ["Crate", "External", "Std", "Project"] # not sure why, but to each their own |
Thank you for the additional detail, though I confess that I'm still unclear on the relevance to this particular issue so please let me know if there's simply some dots i'm not connecting! The type of the option as a string based array vs. enum variants is certainly a discussion we can have, but that feels orthogonal to (a) the fact that rustfmt can't actually make the "project" determination for the reasons discussed above and in other issues, and (b) the request for more granular/multi-groups for external. There's a need for an implementation to be developed within rustfmt to support the requested style, regardless of whether the type of the option were to be changed; switching the option type from an enum to an array doesn't change that, and if anything would add complexity that would have be resolved first. |
Just another possibility that would provide more flexibility, I guess. Not 100% relevant to this request admittedly. I'll step aside, noting that I'd use this option if it were supported 🙂 |
No worries! If you'd like to continue the discussion then I think a new issue would be best, to support respective focused conversations |
Extending jhpratt's idea of the list option slightly, I wonder if having some glob pattern to specify additional "project crates" would solve this neatly? For example, we could describe the current
This creates three possible groups, one matching any The desired outcome described in the initial comment would then by a slight tweak to this,
I think this would cover most of the setups described (project crates coming from crates.io etc), and doesn't rely on the original grouping so things are deterministic It would also allow some other more "specific" groupings, for example "group all the items from axum/tokio/tokio_util/futures together, separately from other external crates" Main part that I'm not clear about would be how the ordering of the matching would work (for example, if you just match the patterns in "group order", the second group's A simpler alternative might be to keep the |
This enables the `group_imports` option. With this rustfmt automatically groups the imports in `std`, `external`, and `crate. This is almost what we already wanted but we lose control of some things: * it is not able to differentiate between workspace and external so all our crates will go in that section, * it does not understand local import: ```rust mod foo { struct Foo; } use foo::Foo; use rand::random; ``` instead of having a separate group for `foo`. * It does not respect groups that we create manually ```rust use tokio; use itertools; ``` the imports will be merged. Looking at the changeset we are not too bad at maintaining this style. Most of the changes are the position of `crate` wr.t. to `self` or `super`, fusing groups, and moving our workspace crates to the external one. But this will be our only option to enforce this style with a tool. https://rust-lang.github.io/rustfmt/?version=v1.5.1&search=#group_imports rust-lang/rustfmt#4709 rust-lang/rustfmt#4693
📋 Description
For the sake of example, lets say a project is composed of the following crates:
coolapp-utils
,coolapp-backend
, andcoolapp-frontend
It would be great if
group_imports
supported a custom grouping between "external" crates (from crates.io) and "project local" crates:Note that different projects have different notions of what constitutes a "project local" crate. Some examples I've come across in the past have included:
Since there wouldn't be any way to automatically determine which crates fall into which category, one reasonable implementation might be to modify the current "External" crate grouping to support being arbitrarily divided into two (or more?) groups.
While this wouldn't be a *perfect* solution (after all, users could still inadvertently import "project local" crates above "external" crates), it would be a step in the right direction, and offer a much needed bit of flexibility to
group_imports
.The text was updated successfully, but these errors were encountered: