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 rustfmt in a non-invasive manner #1040
Introduce rustfmt in a non-invasive manner #1040
Conversation
Might have been easier to start without 0f779e1, but the more the merrier if you ask me. :D |
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.
ACK 0f779e1
Thanks for the review! I can remove that patch if anyone else finds this too arduous to review. I was trying to walk the line between getting something done and being a real pain to review :) |
0f779e1
to
7b2f48b
Compare
Changes in force push: Just rebase on master fixing the merge conflicts in a call to |
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.
ACK 7b2f48b
Any more love for this one crew? |
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.
TBH, I'm still unconvinced. :( Wouldn't block if most people want this, just please at least consider practical implications of method call chains being on a single line and import reordering.
imports_granularity = "Module" # Default "Preserve" | ||
group_imports = "StdExternalCrate" # Default "Preserve" | ||
reorder_imports = true | ||
reorder_modules = true |
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 really don't like these much. Sometimes it may be nicer to logically group the imports, e.g. pub use
at top. Sadly, there's no way to implement such logic in rustfmt.
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.
IMO "reliable benefit of predictable ordering" > "barely ever used benefit of expressing some logical groups, that also has to be maintained over time (which it won't)".
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.
+1 for what @dpc said. I do understand the desire to have 'pub use' statements separate but its just another implicit policy for devs to have to remember and like dpc said such groupings never get maintained.
TBH I'm kind of disheartened by this discussion, taking care of the import statements is, IMO, a no-brainer. If we cannot come to some basic agreement that at some stage its better to use tools than developer time it is really hard to make progress on this PR.
Lets not become a project where no changes can be made because there is always some negative in any change - implying that we get stuck with negatives we are unable to address. rustfmt
is not perfect, nothing is, rustfmt
is, an can always be, constantly improved but refusing to use the tools we have just stagnates us.
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.
Honestly, I don't care about order being lexicographically sorted much and if there's no setting to put pub
items first (what I do in my projects) and enforcing is deemed to be too annoying, I don't care about these flags much. If there was a setting I'd want it on and don't care about the rest.
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, I remembered one more annoying thing about sorting: if you rename an item then you also have to move it so instead of clear -+ diffl lines being one after another you get them separated. Not saying that it's worth turning off sorting but if there was a nicer solution, that'd be great.
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.
Agree on the diff lines separated thing. So just to make sure I've got it, we can leave the two 'reorder' flags on and acknowledge that it is a desired improvement to rustfmt
to be able to separate 'pub use' statements from other imports?
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.
Yep, I was thinking about opening issues at their repo once we agree what we need.
.duration_since(UNIX_EPOCH) | ||
.expect("Time error") | ||
.as_secs(); | ||
let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time error").as_secs(); |
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 prefer these to be always on a new line. The practical consequence is that you can quickly comment out things if types match and diffs are easier to understand. I had real-life experience with long iterator chain where types were preserved (lot of map
s) and could easily experiment with the code by commenting/adding lines.
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.
Bleh, there's another practical consequence of such things - people miss context when reviewing/reading code
Cause
Things
End
Up
Too
Vertical.
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.
True :(
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.
IMO: If a chain of things is so long that it hinders your ability to see stuff, you have some other problems to address.
Like in this case the whole thing could be some fn get_current_unix_ts_secs()
, because why would anyone wanted to parse this lower-level 4 element implementation detail, when looking at the higher level code.
It's an example code, so 🤷 , but this whole function could be more idiomatically:
fn build_version_message(address: SocketAddr) -> message::NetworkMessage {
message::NetworkMessage::Version(
VersionMessage::new()
.service_flags(ServiceFlags::NONE),
.timestamp(get_current_unix_ts_secs() as i64),
.recv_addr(Address::new(&address, ServiceFlags::NONE)),
.from_addr(Address::new(&my_address, ServiceFlags::NONE)),
/* ... */
.build()
)
}
with comments about what each thing means on the builder methoder, instead of each variable, and 1/4 of the LoC size, while being much easier to understand.
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.
BTW. I wish Rust just made a typed builder a language thing, because in the absence of optional and named arguments, builders are a common necessity.
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.
IMO chain_width
should really be 100, I thought it was a concrete line length not % lol.
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 really, really, really dont understand the rust fascination with deliberately ensuring code is as
vertical
as
is
at
all
possible
to
make
sure
you
lose
all
context.
If we say we want lines up to 100 chars long, that should include chains, I'm not sure why chains are in any way special?
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.
ok, so that is a vote for
max_width = 100
use_small_heuristics = "Max"
And remove all the granular width configuration options, I don't believe we had previously considered that.
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.
Meh, neither is great and if there even exists optimal line, I don't think it can be expressed in code. So I give up on this discussion, do as you wish.
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.
EDIT: Deleted my comment after seeing more discussion on this below.
Thanks for the review and your opinions @Kixunil, this is a hard PR to get consensus on but I'm going to keep trying :) |
7b2f48b
to
ad71ae8
Compare
Changes in force push:
|
In rust-bitcoin/rust-miniscript#434 (comment) @sanket1729 aired a view that using |
Good point about merges but merging can lead to other issues - duplicated imports or conflicts on consecutive lines. IMO the best solution would be semantic merging but he only solution I know of doesn't support Rust, is proprietary and from my experience the UI is buggy at least on non-Windows platforms. It's free for FOSS and I wouldn't even mind paying if it had Rust support and higher reliability. Being proprietary doesn't bother me for Open Source code. |
I think that, even if we had a smarter merge tool, we'd still be unhappy with Github saying (falsely) that there were merge conflicts, since we can't control the algorithm they use for conflictt detection. Having said this, I honestly don't mind re-acking stuff where they were rebased and import stuff resolved ... I guess it's annoying for the person doing the rebase, and causes delays, but as a reviewer it's a very mechanical thing to run |
ad71ae8
to
e53e302
Compare
Thanks crew, this PR was pissing me off yesterday and today reading the responses I got two chuckles out of it - so top effort for bringing humour in arduous work. We are making progress :) Changes in force push:
|
Sorry just got to responding to the comments from yesterday. I'd actually really strongly prefer this be 100%. I'm really not at all sure why chains are somehow "special" compared to other code. If we're okay reading lines that are 100 chars long, I don't really get why we're not okay reading chains that are 100 chars long? Both are just as much mental overhead to read, and both have the same context-scanability tradeoffs. |
Seems like Matt is feeling most strongly about it and personally I would be happy with 100%. Doesn't bother me at all, as long as |
Just realized if we had all code |
@Kixunil well, it wouldn't help people trying to read diffs which are extra-dense due to people cramming tons of crap into one line ... but agreed with "don't care anymore, let's just do something". |
e53e302
to
b45060f
Compare
I think we are all getting to the same state of mind, lets push this through. |
I've set |
Needs #1063 to get green CI run. |
@apoelstra it'd be quite easy to create a script that formats both commits and runs diff. Might be less convenient but at least it's something. |
That's a neat idea, I'll try that sometime. |
@Kixunil are you ok with this or are you still wanting to explore the scripting idea? @TheBlueMatt would you be willing to sign off on this, at a minimum to show others that your views, as much as possible, have been taken into consideration? |
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.
ACK 1a8d127
Looks like lesser evil.
1a8d127
to
3099023
Compare
Sorry folks had to rebase to fix merge conflicts. |
Don't ack, needs another rebase :) |
Add a configuration file but explicitly ignore all source files. The aim of this is that we can then un-ignore files a few at a time and deal with issues in a small isolated manner.
Remove "examples" from the rustfmt ignore list.
In preparation for enabling rustfmt on `lib.rs` refactor the `compile_error` call so that the formatter does not touch it.
In preparation for running the formatter on root level modules and a submodule that holds all the macro calls in `hash_types` so we can configure rustfmt to skip formatting them.
In preparation for running the formatter on all source files at the root of the crate; skip formatting `prelude` module because we use unconventional import statements so they to save writing a million compiler attributes.
The local variable `formatter` can be shortened to `f` with no loss of clarity since it is so common. Done in preparation for running `rustfmt` on `src`.
In preparation for running the formatter on `src/` and a function local use statement for `$crate::serde::de::Unexpected`, this shortens the line of code that uses this type preventing the formatter for later munging that line.
Remove the ignore for the "src" directory, this enables the formatter for all source files in the `src/` directory.
3099023
to
ee9a3ec
Compare
Rebased on master, no other changes. |
Maybe we should pause merging all other PRs before merging this...? Linter/Formatter PRs are rebase magnets. |
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.
ACK ee9a3ec
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.
ACK ee9a3ec
I think it's alright :) people have been pretty active and ready to rebase lately. |
Can't believe this merged, rust-bitcoin has officially been dragged, kicking and screaming, into the 21st century :) |
…sive manner ee9a3ec Enable formatter for "src" (Tobin C. Harding) 743b197 Add use for Unexpected (Tobin C. Harding) fd217e7 Use f instead of formatter (Tobin C. Harding) 7b50a96 Do not format prelude module (Tobin C. Harding) 01471f7 Shield hash_newtypes from rustfmt (Tobin C. Harding) 65d19d9 Refactor compile_error message (Tobin C. Harding) 6461e2d Run formatter on examples/ (Tobin C. Harding) fd1c658 Add a rustfmt configuration file with explicit ignores (Tobin C. Harding) Pull request description: Looks like we are getting to a place that rustfmt _might_ be able to be used. In an effort to introduce `rustfmt` without requiring devs to do excessively mundane reviews introduce `rustfmt` in a non-invasive manner. What this means is - Add a fully fleshed out `rustfmt` config file that explicitly ignores all the source files - Enable sections of code one by one so review is easier (including preparatory patches before doing each section). This PR currently does `examples` and all the source files at the root level of the crate (i.e. excludes all directories in `src/`). The other directories can then be done one at a time. Please see discussion on: rust-bitcoin/rust-bitcoin#959 for more context. ACKs for top commit: sanket1729: ACK ee9a3ec apoelstra: ACK ee9a3ec Tree-SHA512: f4ff3c031b5d685777e09bac2df59ed8217576b807da7699f44fe00aa509d0b7fe47617a8b3eff00d3125aeece3e010b8f9dd8733d315ccb2adc0e9a7d7f07e3
Looks like we are getting to a place that rustfmt might be able to be used. In an effort to introduce
rustfmt
without requiring devs to do excessively mundane reviews introducerustfmt
in a non-invasive manner. What this means isrustfmt
config file that explicitly ignores all the source filesThis PR currently does
examples
and all the source files at the root level of the crate (i.e. excludes all directories insrc/
). The other directories can then be done one at a time.Please see discussion on: #959 for more context.