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

Treewide Nix reformat pass 1 [skip treewide] #322537

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

infinisil
Copy link
Member

@infinisil infinisil commented Jun 26, 2024

Note

Enforcement of formatting has been split into this separate PR: #326407

Description of changes

This is the next step towards accepted NixOS/rfcs#166 after #322512, see also #322520 and NixOS/nixfmt#153 🎉.

The @NixOS/nix-formatting will approve/merge this PR.

This PR formats all "inactive" files using nixfmt-rfc-style, where "inactive" means that there are no open PRs with activity in the last ~2 months that touch those files.

Doing it this way makes ensures that we don't cause any conflicts for recently active PRs that would be ready to merge. Only once those PRs get updated, CI will kick in and require the files to be formatted.

A bunch later, we can do another pass to get the rest.

Furthermore, this makes sure that we can merge this PR without having to constantly rebase it!

Verification

It's impossible to review this, but that's not necessary because you can review the code that generated it instead, which can be found here. At the same time this can be used to verify the contents of this PR by:

  1. Checking out this PR in your Nixpkgs clone (with the GitHub CLI here):
    cd ~/src/nixpkgs
    gh co 322537
    
  2. Building the verification script:
    nix-build https://github.com/infinisil/treewide-nixpkgs-reformat-script/archive/5439e16eda66856aed747db3b45ed595835de7c6.tar.gz \
      --argstr baseRev 5180ff0970d05347aa87492f64ed84a6e1e24b33
    
  3. Running it on your clone (no worries if your tree is dirty, it uses a separate worktree and cleans up behind itself):
    result/bin/apply-formatting .
    
  4. Verifying that the diff only contains the revision in .git-blame-ignore-revs (which changes because the date of the commit it creates changes)

Things done


This work is sponsored by Antithesis

Add a 👍 reaction to pull requests you find important.

@infinisil infinisil mentioned this pull request Jun 26, 2024
7 tasks
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/formatting-team-meeting-2024-06-25/47661/1

@infinisil infinisil added the significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc. label Jun 26, 2024
@oxalica
Copy link
Contributor

oxalica commented Jun 28, 2024

I'd say we should block on NixOS/nixfmt#153. There are also many issues about either awkward formatting result or implementation correctness. It's no good to race reformatting everything before that.

This was done with this script in ~40 seconds

This sounds too long to me. If the whole-repo checking takes too long, it blocks auto-checking in git commit hook.
fd -e nix --exec-batch nixfmt takes 1:49.27 (~110s) on my machine and nixfmt is single-threaded. nixfmt --check on formatted files takes almost the same time.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/tweag-nix-dev-update-57/47823/1

@infinisil
Copy link
Member Author

@oxalica The reason I'm pushing for this is because there's a lot of churn from people reformatting individual parts on their own, @mweinelt can attest to that. Let's not let perfect be the enemy of good, the formatter works and is unlikely to change drastically. We should definitely block on correctness bugs like NixOS/nixfmt#197 though, this is being worked on :)

Regarding the time it takes for a full format, the solution I'd propose is to use a pre-commit hook that only formats files that were changed. This also nicely aligns with CI only requiring changed files to be formatted. I'd be okay with blocking on that for this PR, I'll add it to the TODO items.

In addition to that, if CI fails, it shows the nixfmt command needed to make CI pass, only listing the files that need reformatting, see here.

Alternative: treefmt

One could also imagine using treefmt because it caches results, but this will be slightly problematic when we change the formatter in the future and need to do the same multi-pass approach to avoid merge conflicts. There's going to be times when not the entire codebase is formatted in the same way, and treefmt would mess that up.

@oxalica
Copy link
Contributor

oxalica commented Jun 28, 2024

use a pre-commit hook that only formats files that were changed

That's kinda non-trivial to me, and you need to retrieve file list from git log on an unknown number of commits. Would be good to have an example (maybe in README) for copy-paste.

Also I opened NixOS/nixfmt#211 for tracking this.

@infinisil
Copy link
Member Author

That's kinda non-trivial to me, and you need to retrieve file list from git log on an unknown number of commits. Would be good to have an example (maybe in README) for copy-paste.

Since it's the pre-commit hook, we only have to worry about the single commit that is being made, so I don't think it will be bad, but I'll see it when I try 😆. And we can use a shellHook automatically pre-commit hooks upon entering the shell, e.g. https://github.com/cachix/git-hooks.nix also works in that way.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/brainstorming-for-rfc-assimilate-home-manager-into-nixpkgs-monorepo/48230/13

@Aleksanaa
Copy link
Member

I'd say we should block on NixOS/nixfmt#153. There are also many issues about either awkward formatting result or implementation correctness. It's no good to race reformatting everything before that.

The good thing here is we can skip formatting if something weird really happens, because it doesn't make subsequent CI check fail.

@emilazy
Copy link
Member

emilazy commented Jul 8, 2024

I’d like to recommend a pre-push hook instead of a pre-commit one. It would still check all the commits that are to be pushed. The advantage is that it is easier to slice and dice existing commits and make imperfect work‐in‐progress commits to clean up later without having the formatting step get in the way. It also prevents making committing any slower, whereas pushes are already slow. For me, the experience of using a pre-commit hook is like having to satisfy a pedantic spell‐checker while trying to get into a flow state writing a stream‐of‐consciousness draft.

Another advantage is that tools like git-revise cannot necessarily run hooks due to their in‐memory design, which wouldn’t affect a pre-push hook; it’s more reliable to do the checks at the actual publication bottleneck.

If you need any help writing an efficient and correct Git hook for this, please ping me.

@infinisil infinisil force-pushed the enforce-nixfmt-changed-files branch from a22dc49 to a826121 Compare July 11, 2024 23:44
@infinisil infinisil force-pushed the enforce-nixfmt-changed-files branch 2 times, most recently from 174e6e4 to 00d4895 Compare July 12, 2024 00:09
@infinisil infinisil changed the title Enforce nixfmt for new/changed files, treewide reformat pass 1 [skip treewide] Treewide Nix reformat pass 1 [skip treewide] Jul 12, 2024
@infinisil
Copy link
Member Author

To make this PR easier to review, I split off the enforcement for new files into #326407. So this PR is only for the treewide format now! Also note:

  • I added instructions to the PR description on how the entire contents of this PR can be reproduced, allowing anybody to easily check it
  • Some nixfmt fixes should be merged and propagated before this is merged, see the PR description

Inactive means that there are no open PRs with activity in the
last month that touch those files.
A bunch later, we can do another pass to get the rest.

Doing it this way makes ensures that we don't cause any conflicts for
recently active PRs that would be ready to merge.
Only once those PRs get updated, CI will kick in and require the files
to be formatted.

Furthermore, this makes sure that we can merge this PR without having
to constantly rebase it!

This can be verified using

    nix-build https://gist.github.com/infinisil/4b7a1a1e5db681d04446e73e39048aec/archive/5439e16eda66856aed747db3b45ed595835de7c6.tar.gz \
      --argstr baseRev 5180ff0
    result/bin/apply-formatting $NIXPKGS_PATH
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/enforcing-nix-formatting-in-nixpkgs/49506/1

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/enforcing-nix-formatting-in-nixpkgs/49506/8

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/formatting-team-meeting-2024-08-06/50222/1

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/formatting-team-meeting-2024-09-03/51584/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: merge conflict 10.rebuild-darwin: 1-10 10.rebuild-linux: 11-100 significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc.
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.

7 participants