Incremental reformatting has significant costs #948

Open
opened 2025-08-01 17:50:37 +00:00 by emilazy · 7 comments
Member

This is a summary of my position on a Matrix discussion between @weethet, @raito, @cobaltcause, @qyriad, and I.

The current Lix codebase is not consistently formatted. There is a pre‐commit hook that formats only changed parts of files but CI does not check formatting.

Partial formatting has costs:

  • The codebase is in an inconsistent format, with the usual costs to readability.

  • Pre‐commit hooks can be intrusive to workflows, as they can cause creating draft commits to be a blocking or even fallible operation.

  • Pre‐commit hooks don’t even necessarily run: users of Jujutsu, git revise, git-branchless, or even the upstream git replay command will not get pre‐commit hooks run, as they are unsupported by design – because pre‐commit hooks are impossible to run in‐memory and depend on expensive, mutating checkouts. I know there are several Lix contributors who use Jujutsu and git revise.

    In combination with the lack of CI enforcement, this means that there is no guarantee of monotonic formatting progress, and contributors such as myself who do not want to send egregious diffs but whose workflow does not work with partial formatting may have to put avoidable manual toil into code formatting.

    (This is not to say people who like and can use pre‐commit hooks shouldn’t be able to use them. I’m fine with the pre‐commit hooks existing regardless of any of this; I just can’t use them and really didn’t want to even when I could.)

  • LSPs, editors with save‐on‐format functionality, treefmt, and jj fix don’t reliably support range formatting. The interface surface of something that has to rewrite diffs in context is much more complicated, and there is an inherent performance cost to computing diffs and rebasing patches in a snapshot‐based VCS, so the set of tooling that does support this scheme is a small subset of the set of tooling that can handle automated formatting. Although the Lix repository uses treefmt, it (surprisingly, to me) does not format the C++ code for this reason. In general, users are much more likely to have issues contributing formatted code, and resolving conflicts caused by formatting.

  • It will take indefinitely long for the entire codebase to become fully formatted, especially in the absence of any enforcement of formatting of changed hunks. (Enforcement, on the other hand, would remove the current fallback option available to people with tooling issues of just ignoring the formatting style.)

Full formatting has costs:

  • Conflicts will be caused when a change from before formatting is rebased, cherry‐picked, or reverted.

  • A .git-blame-ignore-revs would need to be configured, and git blame can still show formatting commits in the presence of significant whitespace churn.

  • There is a flag day where changes acceptable to submit before would not be acceptable to submit after (though there would be at the end of the partial formatting process, too, and Lix already requires changes to be based on the latest HEAD to submit).

There were some other potential costs of full formatting that were raised on Matrix, but I think they were all addressed (e.g. difficulty backporting changes to stable branches does not seem like a concern, as it would be easy and safe to format stable branches simultaneously).

I believe that the costs of partial formatting outweigh the costs of full formatting:

  • Conflicts caused solely by formatting are by definition trivially mechanically resolvable. This can be done by a Git mergetool, jj fix, or a rebase script like Nixpkgs has.

    This is a fully‐reliable process (you need only “format both sides”: format the tree before a change, format the tree after a change, and take the diff, and you have successfully rebased a patch across a reformat), so formatting changes alone can never cause more than one additional command’s worth of friction to a merge, rebase, or cherry‐pick; any remaining conflicts will be ones that would exist regardless of reformatting.

    This also means that (Gerrit integration surface permitting) the web‐based rebase button that is already required to avoid manual CLI work to submit changes that are not based on the latest HEAD could be augmented to trivially resolve any formatting issues for changes proposed before a tree‐wide reformatting.

    The tooling issues caused by partial formatting, on the other hand, are much less trivial to resolve than running a single command.

  • git blame is an invaluable tool, but the development shell can set up the .git-blame-ignore-revs in the same way it currently sets up pre‐commit hooks. It experienced an unfortunate slight reduction in convenience in Nixpkgs even in the presence of .git-blame-ignore-revs, but the style change there was drastic, involving touching the majority of the repository, drastically shifting the indentation of many definitions, and causing many lines to be split and merged. From what I have seen of the clang-format format used by Lix, the style change would be much less drastic, and it would therefore be much less common for git blame to have any issues attributing lines. This could of course be tested before such a reformat.

Based on the discussion, I believe the costs of partial formatting have been considerably underestimated and the costs of full formatting have been considerably overestimated.

(FWIW, Nix recently did a tree‐wide reformat.)

This is a summary of my position on a Matrix discussion between @weethet, @raito, @cobaltcause, @qyriad, and I. The current Lix codebase is not consistently formatted. There is a pre‐commit hook that formats only changed parts of files but CI does not check formatting. Partial formatting has costs: * The codebase is in an inconsistent format, with the usual costs to readability. * Pre‐commit hooks can be intrusive to workflows, as they can cause creating draft commits to be a blocking or even fallible operation. * Pre‐commit hooks don’t even necessarily run: users of Jujutsu, `git revise`, `git-branchless`, or even the upstream `git replay` command will not get pre‐commit hooks run, as they are unsupported by design – because pre‐commit hooks are impossible to run in‐memory and depend on expensive, mutating checkouts. I know there are several Lix contributors who use Jujutsu and `git revise`. In combination with the lack of CI enforcement, this means that there is no guarantee of monotonic formatting progress, and contributors such as myself who do not want to send egregious diffs but whose workflow does not work with partial formatting may have to put avoidable manual toil into code formatting. (This is not to say people who like and can use pre‐commit hooks shouldn’t be able to use them. I’m fine with the pre‐commit hooks existing regardless of any of this; I just can’t use them and really didn’t want to even when I could.) * LSPs, editors with save‐on‐format functionality, `treefmt`, and `jj fix` don’t reliably support range formatting. The interface surface of something that has to rewrite diffs in context is much more complicated, and there is an inherent performance cost to computing diffs and rebasing patches in a snapshot‐based VCS, so the set of tooling that does support this scheme is a small subset of the set of tooling that can handle automated formatting. Although the Lix repository uses `treefmt`, it (surprisingly, to me) does not format the C++ code for this reason. In general, users are much more likely to have issues contributing formatted code, and resolving conflicts caused by formatting. * It will take indefinitely long for the entire codebase to become fully formatted, especially in the absence of any enforcement of formatting of changed hunks. (Enforcement, on the other hand, would remove the current fallback option available to people with tooling issues of just ignoring the formatting style.) Full formatting has costs: * Conflicts will be caused when a change from before formatting is rebased, cherry‐picked, or reverted. * A `.git-blame-ignore-revs` would need to be configured, and `git blame` can still show formatting commits in the presence of significant whitespace churn. * There is a flag day where changes acceptable to submit before would not be acceptable to submit after (though there would be at the end of the partial formatting process, too, and Lix already requires changes to be based on the latest HEAD to submit). There were some other potential costs of full formatting that were raised on Matrix, but I think they were all addressed (e.g. difficulty backporting changes to stable branches does not seem like a concern, as it would be easy and safe to format stable branches simultaneously). I believe that the costs of partial formatting outweigh the costs of full formatting: * Conflicts caused solely by formatting are by definition trivially mechanically resolvable. This can be done by a [Git mergetool](https://github.com/emilio/clang-format-merge/blob/e871bab4de318363e9198586bd5c1c075eae3e89/clang-format-merge), `jj fix`, or [a rebase script like Nixpkgs has](https://github.com/NixOS/nixpkgs/blob/a0aa3f2454a2d1bbc80db9f0b14f77b8e7be9db0/maintainers/scripts/auto-rebase/run.sh). This is a fully‐reliable process (you need only “format both sides”: format the tree before a change, format the tree after a change, and take the diff, and you have successfully rebased a patch across a reformat), so formatting changes alone can never cause more than one additional command’s worth of friction to a merge, rebase, or cherry‐pick; any remaining conflicts will be ones that would exist regardless of reformatting. This also means that (Gerrit integration surface permitting) the web‐based rebase button that is already required to avoid manual CLI work to submit changes that are not based on the latest HEAD could be augmented to trivially resolve any formatting issues for changes proposed before a tree‐wide reformatting. The tooling issues caused by partial formatting, on the other hand, are much less trivial to resolve than running a single command. * `git blame` is an invaluable tool, but the development shell can set up the `.git-blame-ignore-revs` in the same way it currently sets up pre‐commit hooks. It experienced an unfortunate slight reduction in convenience in Nixpkgs even in the presence of `.git-blame-ignore-revs`, but the style change there was drastic, involving touching the majority of the repository, drastically shifting the indentation of many definitions, and causing many lines to be split and merged. From what I have seen of the `clang-format` format used by Lix, the style change would be much less drastic, and it would therefore be much less common for `git blame` to have any issues attributing lines. This could of course be tested before such a reformat. Based on the discussion, I believe the costs of partial formatting have been considerably underestimated and the costs of full formatting have been considerably overestimated. (FWIW, Nix recently did [a tree‐wide reformat](https://github.com/NixOS/nix/pull/13108).)
Owner

(Not in favor of this proposal but will do a more thorough answer later once time permits.)

Here's the diffstat of a full formatting for reference starting at revision a4717e1315ab62e089e912c2b95b1461f8e49680.

 lix/asan-options/asan-options.cc            |    6 +-
 lix/legacy/build-remote.cc                  |   49 ++--
 lix/legacy/dotgraph.cc                      |   31 ++-
 lix/legacy/graphml.cc                       |   18 +-
 lix/legacy/nix-build.cc                     |  370 ++++++++++++++++++----------
 lix/legacy/nix-channel.cc                   |  195 ++++++++-------
 lix/legacy/nix-collect-garbage.cc           |   42 ++--
 lix/legacy/nix-copy-closure.cc              |   35 +--
 lix/legacy/nix-env.cc                       | 1164 +++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------
 lix/legacy/nix-instantiate.cc               |  190 +++++++++------
 lix/legacy/nix-store.cc                     | 1199 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------
 lix/legacy/user-env.cc                      |   61 +++--
 lix/libcmd/built-path.cc                    |   27 +-
 lix/libcmd/cmd-profiles.cc                  |   56 +++--
 lix/libcmd/command.cc                       |  131 ++++++----
 lix/libcmd/common-eval-args.cc              |   66 ++---
 lix/libcmd/editor-for.cc                    |   10 +-
 lix/libcmd/installable-attr-path.cc         |   61 +++--
 lix/libcmd/installable-derived-path.cc      |    7 +-
 lix/libcmd/installable-flake.cc             |  119 +++++----
 lix/libcmd/installable-value.cc             |   39 +--
 lix/libcmd/installables.cc                  |  636 +++++++++++++++++++++++++----------------------
 lix/libcmd/markdown.cc                      |   23 +-
 lix/libcmd/repl-interacter.cc               |   30 ++-
 lix/libcmd/repl.cc                          |  555 +++++++++++++++++++++++------------------
 lix/libexpr/attr-path.cc                    |   44 ++--
 lix/libexpr/attr-set.cc                     |   20 +-
 lix/libexpr/eval-cache.cc                   |  459 ++++++++++++++++++----------------
 lix/libexpr/eval-error.cc                   |   24 +-
 lix/libexpr/eval-settings.cc                |   41 +++-
 lix/libexpr/eval.cc                         | 1579 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------------------------
 lix/libexpr/flake/config.cc                 |   76 ++++--
 lix/libexpr/flake/flake.cc                  |  712 ++++++++++++++++++++++++++++++++++-------------------
 lix/libexpr/flake/flakeref.cc               |  133 +++++-----
 lix/libexpr/flake/lockfile.cc               |  159 +++++++-----
 lix/libexpr/function-trace.cc               |    6 +-
 lix/libexpr/gc-alloc.cc                     |    3 +-
 lix/libexpr/get-drvs.cc                     |  306 ++++++++++++++---------
 lix/libexpr/json-to-value.cc                |   50 ++--
 lix/libexpr/nixexpr.cc                      |  327 ++++++++++++-------------
 lix/libexpr/parser/parser-impl1.inc.cc      |  856 ++++++++++++++++++++++++++++++++++++++++++----------------------
 lix/libexpr/parser/parser.cc                |   40 +--
 lix/libexpr/primops.cc                      | 2139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------------------------------
 lix/libexpr/primops/context.cc              |  249 +++++++++++--------
 lix/libexpr/primops/fetchClosure.cc         |  145 +++++++----
 lix/libexpr/primops/fetchMercurial.cc       |   92 ++++---
 lix/libexpr/primops/fetchTree.cc            |  263 +++++++++++++-------
 lix/libexpr/primops/fromTOML.cc             |  124 +++++-----
 lix/libexpr/print-ambiguous.cc              |   24 +-
 lix/libexpr/print.cc                        |  186 ++++++++------
 lix/libexpr/search-path.cc                  |   32 ++-
 lix/libexpr/value-to-json.cc                |  182 +++++++-------
 lix/libexpr/value-to-xml.cc                 |  253 +++++++++++--------
 lix/libexpr/value.cc                        |   26 +-
 lix/libexpr/value/context.cc                |   48 ++--
 lix/libfetchers/attrs.cc                    |   49 ++--
 lix/libfetchers/cache.cc                    |   53 ++--
 lix/libfetchers/fetch-settings.cc           |   79 +++---
 lix/libfetchers/fetch-to-store.cc           |   13 +-
 lix/libfetchers/fetchers.cc                 |  149 ++++++++----
 lix/libfetchers/git.cc                      |  567 +++++++++++++++++++++++++++++-------------
 lix/libfetchers/github.cc                   |  219 +++++++++++------
 lix/libfetchers/indirect.cc                 |   70 ++++--
 lix/libfetchers/mercurial.cc                |  199 +++++++++------
 lix/libfetchers/path.cc                     |   70 ++++--
 lix/libfetchers/registry.cc                 |   82 +++----
 lix/libfetchers/tarball.cc                  |  140 +++++++----
 lix/libmain/common-args.cc                  |   78 +++---
 lix/libmain/crash-handler.cc                |    6 +-
 lix/libmain/loggers.cc                      |   30 ++-
 lix/libmain/progress-bar.cc                 |  219 +++++++++++------
 lix/libmain/shared.cc                       |  251 ++++++++++++-------
 lix/libmain/stack.cc                        |   29 ++-
 lix/libstore/binary-cache-store.cc          |  162 ++++++------
 lix/libstore/build-result.cc                |    8 +-
 lix/libstore/build/child.cc                 |   12 +-
 lix/libstore/build/derivation-goal.cc       |  573 ++++++++++++++++++++++++++-----------------
 lix/libstore/build/entry-points.cc          |   58 +++--
 lix/libstore/build/goal.cc                  |   32 ++-
 lix/libstore/build/hook-instance.cc         |   17 +-
 lix/libstore/build/local-derivation-goal.cc | 1273 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------
 lix/libstore/build/personality.cc           |   47 ++--
 lix/libstore/build/substitution-goal.cc     |   73 +++---
 lix/libstore/build/worker.cc                |  102 +++++---
 lix/libstore/builtins/buildenv.cc           |   93 ++++---
 lix/libstore/builtins/fetchurl.cc           |   16 +-
 lix/libstore/builtins/unpack-channel.cc     |    7 +-
 lix/libstore/common-protocol.cc             |   44 ++--
 lix/libstore/content-address.cc             |  192 ++++++++-------
 lix/libstore/crypto.cc                      |   43 ++--
 lix/libstore/daemon.cc                      |  334 ++++++++++++++++---------
 lix/libstore/derivations.cc                 |  653 +++++++++++++++++++++++++++++--------------------
 lix/libstore/derived-path.cc                |  108 ++++----
 lix/libstore/dummy-store.cc                 |   48 ++--
 lix/libstore/export-import.cc               |   37 +--
 lix/libstore/filetransfer.cc                |  252 ++++++++++++-------
 lix/libstore/gc.cc                          |  304 ++++++++++++++---------
 lix/libstore/globals.cc                     |  231 +++++++++++-------
 lix/libstore/http-binary-cache-store.cc     |    5 +-
 lix/libstore/legacy-ssh-store.cc            |  175 ++++++++-----
 lix/libstore/local-binary-cache-store.cc    |   47 ++--
 lix/libstore/local-fs-store.cc              |   51 ++--
 lix/libstore/local-store.cc                 |  653 +++++++++++++++++++++++++++++--------------------
 lix/libstore/lock.cc                        |  140 +++++++----
 lix/libstore/log-store.cc                   |    3 +-
 lix/libstore/machines.cc                    |  116 +++++----
 lix/libstore/make-content-addressed.cc      |   30 +--
 lix/libstore/misc.cc                        |  137 +++++++----
 lix/libstore/names.cc                       |   80 +++---
 lix/libstore/nar-accessor.cc                |   62 +++--
 lix/libstore/nar-info-disk-cache.cc         |  313 ++++++++++++++----------
 lix/libstore/nar-info.cc                    |   87 ++++---
 lix/libstore/optimise-store.cc              |   92 ++++---
 lix/libstore/outputs-spec.cc                |  222 +++++++++--------
 lix/libstore/parsed-derivations.cc          |  141 +++++++----
 lix/libstore/path-info.cc                   |  161 ++++++------
 lix/libstore/path-references.cc             |   20 +-
 lix/libstore/path-tree.cc                   |   16 +-
 lix/libstore/path-with-outputs.cc           |   85 +++----
 lix/libstore/path.cc                        |   68 ++++--
 lix/libstore/pathlocks.cc                   |   43 ++--
 lix/libstore/platform.cc                    |   16 +-
 lix/libstore/platform/darwin.cc             |   18 +-
 lix/libstore/platform/fallback.cc           |    3 +-
 lix/libstore/platform/linux.cc              |  206 ++++++++++------
 lix/libstore/profiles.cc                    |  143 +++++------
 lix/libstore/realisation.cc                 |   68 +++---
 lix/libstore/remote-fs-accessor.cc          |   31 ++-
 lix/libstore/remote-store.cc                |  167 ++++++-------
 lix/libstore/s3-binary-cache-store.cc       |  261 ++++++++++++--------
 lix/libstore/serve-protocol.cc              |   26 +-
 lix/libstore/sqlite.cc                      |  112 ++++++---
 lix/libstore/ssh-store.cc                   |   33 ++-
 lix/libstore/ssh.cc                         |   92 ++++---
 lix/libstore/store-api.cc                   |  565 ++++++++++++++++++++++++------------------
 lix/libstore/temporary-dir.cc               |   36 +--
 lix/libstore/uds-remote-store.cc            |   15 +-
 lix/libstore/worker-protocol.cc             |   80 +++---
 lix/libutil/archive.cc                      |   74 +++---
 lix/libutil/args.cc                         |  403 ++++++++++++++++++------------
 lix/libutil/canon-path.cc                   |   67 +++--
 lix/libutil/cgroup.cc                       |   10 +-
 lix/libutil/compression.cc                  |  108 +++++---
 lix/libutil/compute-levels.cc               |   65 ++---
 lix/libutil/config.cc                       |  399 ++++++++++++++++++++----------
 lix/libutil/current-process.cc              |   68 ++++--
 lix/libutil/deprecated-features.cc          |   51 ++--
 lix/libutil/english.cc                      |    8 +-
 lix/libutil/environment-variables.cc        |   23 +-
 lix/libutil/error.cc                        |  201 ++++++++-------
 lix/libutil/experimental-features.cc        |   53 ++--
 lix/libutil/file-descriptor.cc              |  100 ++++----
 lix/libutil/file-system.cc                  |  337 +++++++++++++++----------
 lix/libutil/fmt.cc                          |    4 +-
 lix/libutil/git.cc                          |   12 +-
 lix/libutil/hash.cc                         |  202 +++++++++------
 lix/libutil/hilite.cc                       |    9 +-
 lix/libutil/json-utils.cc                   |   26 +-
 lix/libutil/logging.cc                      |  182 +++++++++-----
 lix/libutil/mount.cc                        |    8 +-
 lix/libutil/namespaces.cc                   |   79 +++---
 lix/libutil/position.cc                     |   90 ++++---
 lix/libutil/print-elided.cc                 |    9 +-
 lix/libutil/processes.cc                    |  250 ++++++++++---------
 lix/libutil/references.cc                   |   35 ++-
 lix/libutil/regex.cc                        |    2 +-
 lix/libutil/serialise.cc                    |   66 ++---
 lix/libutil/shlex.cc                        |    5 +-
 lix/libutil/signals.cc                      |   21 +-
 lix/libutil/source-path.cc                  |   28 ++-
 lix/libutil/strings.cc                      |  100 ++++----
 lix/libutil/suggestions.cc                  |   60 +++--
 lix/libutil/tarfile.cc                      |   48 ++--
 lix/libutil/terminal.cc                     |   91 +++++--
 lix/libutil/thread-pool.cc                  |   34 ++-
 lix/libutil/unix-domain-socket.cc           |   43 ++--
 lix/libutil/url-name.cc                     |   29 ++-
 lix/libutil/url.cc                          |   74 +++---
 lix/libutil/users.cc                        |   29 ++-
 lix/libutil/xml-writer.cc                   |   70 +++---
 lix/nix/add-to-store.cc                     |   19 +-
 lix/nix/app.cc                              |   91 +++----
 lix/nix/build.cc                            |  148 ++++++-----
 lix/nix/bundle.cc                           |   86 ++++---
 lix/nix/cat.cc                              |   26 +-
 lix/nix/config.cc                           |   19 +-
 lix/nix/copy.cc                             |   19 +-
 lix/nix/daemon.cc                           |  129 +++++-----
 lix/nix/derivation-add.cc                   |   12 +-
 lix/nix/derivation-show.cc                  |   25 +-
 lix/nix/derivation.cc                       |   11 +-
 lix/nix/develop.cc                          |  265 ++++++++++++--------
 lix/nix/diff-closures.cc                    |   82 ++++---
 lix/nix/doctor.cc                           |   43 +++-
 lix/nix/dump-path.cc                        |   14 +-
 lix/nix/edit.cc                             |   13 +-
 lix/nix/eval.cc                             |   58 +++--
 lix/nix/flake.cc                            | 1100 ++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------
 lix/nix/fmt.cc                              |   33 ++-
 lix/nix/hash.cc                             |  140 ++++++-----
 lix/nix/log.cc                              |   30 ++-
 lix/nix/ls.cc                               |   86 ++++---
 lix/nix/main.cc                             |  161 +++++++-----
 lix/nix/make-content-addressed.cc           |   15 +-
 lix/nix/nar.cc                              |   15 +-
 lix/nix/optimise-store.cc                   |    4 +-
 lix/nix/path-from-hash-part.cc              |    9 +-
 lix/nix/path-info.cc                        |   65 +++--
 lix/nix/ping-store.cc                       |   20 +-
 lix/nix/prefetch.cc                         |  233 +++++++++++-------
 lix/nix/profile.cc                          |  220 +++++++++--------
 lix/nix/realisation.cc                      |   18 +-
 lix/nix/registry.cc                         |   93 ++++---
 lix/nix/repl.cc                             |   17 +-
 lix/nix/run.cc                              |  141 +++++++----
 lix/nix/search.cc                           |  156 ++++++++----
 lix/nix/sigs.cc                             |   70 +++---
 lix/nix/store-copy-log.cc                   |   13 +-
 lix/nix/store-delete.cc                     |   36 +--
 lix/nix/store-gc.cc                         |   16 +-
 lix/nix/store-repair.cc                     |    7 +-
 lix/nix/store.cc                            |   11 +-
 lix/nix/upgrade-nix.cc                      |   90 ++++---
 lix/nix/verify.cc                           |   89 ++++---
 lix/nix/why-depends.cc                      |   23 +-
 225 files changed, 19948 insertions(+), 12955 deletions(-)
(Not in favor of this proposal but will do a more thorough answer later once time permits.) Here's the diffstat of a full formatting for reference starting at revision a4717e1315ab62e089e912c2b95b1461f8e49680. ``` lix/asan-options/asan-options.cc | 6 +- lix/legacy/build-remote.cc | 49 ++-- lix/legacy/dotgraph.cc | 31 ++- lix/legacy/graphml.cc | 18 +- lix/legacy/nix-build.cc | 370 ++++++++++++++++++---------- lix/legacy/nix-channel.cc | 195 ++++++++------- lix/legacy/nix-collect-garbage.cc | 42 ++-- lix/legacy/nix-copy-closure.cc | 35 +-- lix/legacy/nix-env.cc | 1164 +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------- lix/legacy/nix-instantiate.cc | 190 +++++++++------ lix/legacy/nix-store.cc | 1199 ++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------- lix/legacy/user-env.cc | 61 +++-- lix/libcmd/built-path.cc | 27 +- lix/libcmd/cmd-profiles.cc | 56 +++-- lix/libcmd/command.cc | 131 ++++++---- lix/libcmd/common-eval-args.cc | 66 ++--- lix/libcmd/editor-for.cc | 10 +- lix/libcmd/installable-attr-path.cc | 61 +++-- lix/libcmd/installable-derived-path.cc | 7 +- lix/libcmd/installable-flake.cc | 119 +++++---- lix/libcmd/installable-value.cc | 39 +-- lix/libcmd/installables.cc | 636 +++++++++++++++++++++++++---------------------- lix/libcmd/markdown.cc | 23 +- lix/libcmd/repl-interacter.cc | 30 ++- lix/libcmd/repl.cc | 555 +++++++++++++++++++++++------------------ lix/libexpr/attr-path.cc | 44 ++-- lix/libexpr/attr-set.cc | 20 +- lix/libexpr/eval-cache.cc | 459 ++++++++++++++++++---------------- lix/libexpr/eval-error.cc | 24 +- lix/libexpr/eval-settings.cc | 41 +++- lix/libexpr/eval.cc | 1579 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------- lix/libexpr/flake/config.cc | 76 ++++-- lix/libexpr/flake/flake.cc | 712 ++++++++++++++++++++++++++++++++++------------------- lix/libexpr/flake/flakeref.cc | 133 +++++----- lix/libexpr/flake/lockfile.cc | 159 +++++++----- lix/libexpr/function-trace.cc | 6 +- lix/libexpr/gc-alloc.cc | 3 +- lix/libexpr/get-drvs.cc | 306 ++++++++++++++--------- lix/libexpr/json-to-value.cc | 50 ++-- lix/libexpr/nixexpr.cc | 327 ++++++++++++------------- lix/libexpr/parser/parser-impl1.inc.cc | 856 ++++++++++++++++++++++++++++++++++++++++++---------------------- lix/libexpr/parser/parser.cc | 40 +-- lix/libexpr/primops.cc | 2139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------- lix/libexpr/primops/context.cc | 249 +++++++++++-------- lix/libexpr/primops/fetchClosure.cc | 145 +++++++---- lix/libexpr/primops/fetchMercurial.cc | 92 ++++--- lix/libexpr/primops/fetchTree.cc | 263 +++++++++++++------- lix/libexpr/primops/fromTOML.cc | 124 +++++----- lix/libexpr/print-ambiguous.cc | 24 +- lix/libexpr/print.cc | 186 ++++++++------ lix/libexpr/search-path.cc | 32 ++- lix/libexpr/value-to-json.cc | 182 +++++++------- lix/libexpr/value-to-xml.cc | 253 +++++++++++-------- lix/libexpr/value.cc | 26 +- lix/libexpr/value/context.cc | 48 ++-- lix/libfetchers/attrs.cc | 49 ++-- lix/libfetchers/cache.cc | 53 ++-- lix/libfetchers/fetch-settings.cc | 79 +++--- lix/libfetchers/fetch-to-store.cc | 13 +- lix/libfetchers/fetchers.cc | 149 ++++++++---- lix/libfetchers/git.cc | 567 +++++++++++++++++++++++++++++------------- lix/libfetchers/github.cc | 219 +++++++++++------ lix/libfetchers/indirect.cc | 70 ++++-- lix/libfetchers/mercurial.cc | 199 +++++++++------ lix/libfetchers/path.cc | 70 ++++-- lix/libfetchers/registry.cc | 82 +++---- lix/libfetchers/tarball.cc | 140 +++++++---- lix/libmain/common-args.cc | 78 +++--- lix/libmain/crash-handler.cc | 6 +- lix/libmain/loggers.cc | 30 ++- lix/libmain/progress-bar.cc | 219 +++++++++++------ lix/libmain/shared.cc | 251 ++++++++++++------- lix/libmain/stack.cc | 29 ++- lix/libstore/binary-cache-store.cc | 162 ++++++------ lix/libstore/build-result.cc | 8 +- lix/libstore/build/child.cc | 12 +- lix/libstore/build/derivation-goal.cc | 573 ++++++++++++++++++++++++++----------------- lix/libstore/build/entry-points.cc | 58 +++-- lix/libstore/build/goal.cc | 32 ++- lix/libstore/build/hook-instance.cc | 17 +- lix/libstore/build/local-derivation-goal.cc | 1273 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------ lix/libstore/build/personality.cc | 47 ++-- lix/libstore/build/substitution-goal.cc | 73 +++--- lix/libstore/build/worker.cc | 102 +++++--- lix/libstore/builtins/buildenv.cc | 93 ++++--- lix/libstore/builtins/fetchurl.cc | 16 +- lix/libstore/builtins/unpack-channel.cc | 7 +- lix/libstore/common-protocol.cc | 44 ++-- lix/libstore/content-address.cc | 192 ++++++++------- lix/libstore/crypto.cc | 43 ++-- lix/libstore/daemon.cc | 334 ++++++++++++++++--------- lix/libstore/derivations.cc | 653 +++++++++++++++++++++++++++++-------------------- lix/libstore/derived-path.cc | 108 ++++---- lix/libstore/dummy-store.cc | 48 ++-- lix/libstore/export-import.cc | 37 +-- lix/libstore/filetransfer.cc | 252 ++++++++++++------- lix/libstore/gc.cc | 304 ++++++++++++++--------- lix/libstore/globals.cc | 231 +++++++++++------- lix/libstore/http-binary-cache-store.cc | 5 +- lix/libstore/legacy-ssh-store.cc | 175 ++++++++----- lix/libstore/local-binary-cache-store.cc | 47 ++-- lix/libstore/local-fs-store.cc | 51 ++-- lix/libstore/local-store.cc | 653 +++++++++++++++++++++++++++++-------------------- lix/libstore/lock.cc | 140 +++++++---- lix/libstore/log-store.cc | 3 +- lix/libstore/machines.cc | 116 +++++---- lix/libstore/make-content-addressed.cc | 30 +-- lix/libstore/misc.cc | 137 +++++++---- lix/libstore/names.cc | 80 +++--- lix/libstore/nar-accessor.cc | 62 +++-- lix/libstore/nar-info-disk-cache.cc | 313 ++++++++++++++---------- lix/libstore/nar-info.cc | 87 ++++--- lix/libstore/optimise-store.cc | 92 ++++--- lix/libstore/outputs-spec.cc | 222 +++++++++-------- lix/libstore/parsed-derivations.cc | 141 +++++++---- lix/libstore/path-info.cc | 161 ++++++------ lix/libstore/path-references.cc | 20 +- lix/libstore/path-tree.cc | 16 +- lix/libstore/path-with-outputs.cc | 85 +++---- lix/libstore/path.cc | 68 ++++-- lix/libstore/pathlocks.cc | 43 ++-- lix/libstore/platform.cc | 16 +- lix/libstore/platform/darwin.cc | 18 +- lix/libstore/platform/fallback.cc | 3 +- lix/libstore/platform/linux.cc | 206 ++++++++++------ lix/libstore/profiles.cc | 143 +++++------ lix/libstore/realisation.cc | 68 +++--- lix/libstore/remote-fs-accessor.cc | 31 ++- lix/libstore/remote-store.cc | 167 ++++++------- lix/libstore/s3-binary-cache-store.cc | 261 ++++++++++++-------- lix/libstore/serve-protocol.cc | 26 +- lix/libstore/sqlite.cc | 112 ++++++--- lix/libstore/ssh-store.cc | 33 ++- lix/libstore/ssh.cc | 92 ++++--- lix/libstore/store-api.cc | 565 ++++++++++++++++++++++++------------------ lix/libstore/temporary-dir.cc | 36 +-- lix/libstore/uds-remote-store.cc | 15 +- lix/libstore/worker-protocol.cc | 80 +++--- lix/libutil/archive.cc | 74 +++--- lix/libutil/args.cc | 403 ++++++++++++++++++------------ lix/libutil/canon-path.cc | 67 +++-- lix/libutil/cgroup.cc | 10 +- lix/libutil/compression.cc | 108 +++++--- lix/libutil/compute-levels.cc | 65 ++--- lix/libutil/config.cc | 399 ++++++++++++++++++++---------- lix/libutil/current-process.cc | 68 ++++-- lix/libutil/deprecated-features.cc | 51 ++-- lix/libutil/english.cc | 8 +- lix/libutil/environment-variables.cc | 23 +- lix/libutil/error.cc | 201 ++++++++------- lix/libutil/experimental-features.cc | 53 ++-- lix/libutil/file-descriptor.cc | 100 ++++---- lix/libutil/file-system.cc | 337 +++++++++++++++---------- lix/libutil/fmt.cc | 4 +- lix/libutil/git.cc | 12 +- lix/libutil/hash.cc | 202 +++++++++------ lix/libutil/hilite.cc | 9 +- lix/libutil/json-utils.cc | 26 +- lix/libutil/logging.cc | 182 +++++++++----- lix/libutil/mount.cc | 8 +- lix/libutil/namespaces.cc | 79 +++--- lix/libutil/position.cc | 90 ++++--- lix/libutil/print-elided.cc | 9 +- lix/libutil/processes.cc | 250 ++++++++++--------- lix/libutil/references.cc | 35 ++- lix/libutil/regex.cc | 2 +- lix/libutil/serialise.cc | 66 ++--- lix/libutil/shlex.cc | 5 +- lix/libutil/signals.cc | 21 +- lix/libutil/source-path.cc | 28 ++- lix/libutil/strings.cc | 100 ++++---- lix/libutil/suggestions.cc | 60 +++-- lix/libutil/tarfile.cc | 48 ++-- lix/libutil/terminal.cc | 91 +++++-- lix/libutil/thread-pool.cc | 34 ++- lix/libutil/unix-domain-socket.cc | 43 ++-- lix/libutil/url-name.cc | 29 ++- lix/libutil/url.cc | 74 +++--- lix/libutil/users.cc | 29 ++- lix/libutil/xml-writer.cc | 70 +++--- lix/nix/add-to-store.cc | 19 +- lix/nix/app.cc | 91 +++---- lix/nix/build.cc | 148 ++++++----- lix/nix/bundle.cc | 86 ++++--- lix/nix/cat.cc | 26 +- lix/nix/config.cc | 19 +- lix/nix/copy.cc | 19 +- lix/nix/daemon.cc | 129 +++++----- lix/nix/derivation-add.cc | 12 +- lix/nix/derivation-show.cc | 25 +- lix/nix/derivation.cc | 11 +- lix/nix/develop.cc | 265 ++++++++++++-------- lix/nix/diff-closures.cc | 82 ++++--- lix/nix/doctor.cc | 43 +++- lix/nix/dump-path.cc | 14 +- lix/nix/edit.cc | 13 +- lix/nix/eval.cc | 58 +++-- lix/nix/flake.cc | 1100 ++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------- lix/nix/fmt.cc | 33 ++- lix/nix/hash.cc | 140 ++++++----- lix/nix/log.cc | 30 ++- lix/nix/ls.cc | 86 ++++--- lix/nix/main.cc | 161 +++++++----- lix/nix/make-content-addressed.cc | 15 +- lix/nix/nar.cc | 15 +- lix/nix/optimise-store.cc | 4 +- lix/nix/path-from-hash-part.cc | 9 +- lix/nix/path-info.cc | 65 +++-- lix/nix/ping-store.cc | 20 +- lix/nix/prefetch.cc | 233 +++++++++++------- lix/nix/profile.cc | 220 +++++++++-------- lix/nix/realisation.cc | 18 +- lix/nix/registry.cc | 93 ++++--- lix/nix/repl.cc | 17 +- lix/nix/run.cc | 141 +++++++---- lix/nix/search.cc | 156 ++++++++---- lix/nix/sigs.cc | 70 +++--- lix/nix/store-copy-log.cc | 13 +- lix/nix/store-delete.cc | 36 +-- lix/nix/store-gc.cc | 16 +- lix/nix/store-repair.cc | 7 +- lix/nix/store.cc | 11 +- lix/nix/upgrade-nix.cc | 90 ++++--- lix/nix/verify.cc | 89 ++++--- lix/nix/why-depends.cc | 23 +- 225 files changed, 19948 insertions(+), 12955 deletions(-) ```
Owner

the current autoformatter config for c++ is a best approximation of a reasonable style and produces extremely distateful results in a number of corner cases we have in the codebase[1]. applying it across the entire tree in bulk to make a few people's life easier because their tools of choice do not have full support for our development setup is a very, very skewed proposal. if we do anything here we should disable the formatting check in ci, and maybe the pre-commit hook for c++ formatting as well.

clarification [1]: clang-format simply does not support a number of things we'd need it to do to not produce nonsense when nobody is looking. that alone is reason enough to NACK a bulk format.

the current autoformatter config for c++ is a best approximation of a reasonable style and produces extremely distateful results in a number of corner cases we have in the codebase[1]. applying it across the entire tree in bulk to make a few people's life easier because *their* tools of choice do not have full support for our development setup is a very, *very* skewed proposal. if we do *anything* here we should disable the formatting check in ci, and maybe the pre-commit hook for c++ formatting as well. clarification [1]: clang-format simply *does not support* a number of things we'd need it to do to *not* produce nonsense when nobody is looking. that *alone* is reason enough to NACK a bulk format.
Owner

Adding on @pennae's comment:

Looking at the reformatting output for a while.

  • Nested ternaries seems displaced by a blanket reformat and we have a lot of them and their manual formatting contains visual information
  • Large ifs with string literals get broken down and cut in half, causing more visual noise
  • I'm reminded that clang-format does not seem to be // NOLINT aware meaning that manual fixups will be required on the top of that bulk reformat, their cost is unknown.
  • Construction via aggregate initialization is also broken down weirdly
  • Interaction with #ifdef is not great in certain cases and makes things unreadable, e.g. AutoCloseFD flags assembling.

It's plausible that more of the clang-format output cannot be taken at face value without manual verification.

In general, I would like to generalize the following:

The codebase is in an inconsistent format, with the usual costs to readability.

The codebase is an inconsistent state. With or without formatting, this changes nothing in my eyes.

Moving this particular point aside, the rest looks like DX tool integration, Lix is first and foremost a codebase meant for git, yes, it doesn't work super well with git-revise, but git-clang-format can operate to reformat automatically via git rebase -i --exec.

Picking a certain setup will probably increase toil, and I'm more than willing to assist on decreasing it, but I think bulk formatting is the thing that would add too much to my overloaded plate.

Therefore, I reiterate that I'm against this change.

Interested in the opinions of @jade on this.

Adding on @pennae's comment: Looking at the reformatting output for a while. - Nested ternaries seems displaced by a blanket reformat and we have a lot of them and their manual formatting contains visual information - Large ifs with string literals get broken down and cut in half, causing more visual noise - I'm reminded that clang-format does not seem to be `// NOLINT` aware meaning that manual fixups will be required on the top of that bulk reformat, their cost is unknown. - Construction via aggregate initialization is also broken down weirdly - Interaction with `#ifdef` is not great in certain cases and makes things unreadable, e.g. AutoCloseFD flags assembling. It's plausible that more of the clang-format output cannot be taken at face value without manual verification. In general, I would like to generalize the following: > The codebase is in an inconsistent format, with the usual costs to readability. The codebase is an inconsistent state. With or without formatting, this changes nothing in my eyes. Moving this particular point aside, the rest looks like DX tool integration, Lix is first and foremost a codebase meant for `git`, yes, it doesn't work super well with `git-revise`, but `git-clang-format` can operate to reformat automatically via `git rebase -i --exec`. Picking a certain setup will probably increase toil, and I'm more than willing to assist on decreasing it, but I think bulk formatting is the thing that would add too much to my overloaded plate. Therefore, I reiterate that I'm against this change. Interested in the opinions of @jade on this.
Owner

I would love to have a code formatter consistently applied, but in spite of my best efforts as the author of the clang format configuration, it still kind of sucks! I think a proposal to improve the state of things requires triaging the egregiously bad formatting instances and figuring out why they happened and if we can fix them.

If we can't fix them then we should add excludes to the relevant code blocks and move on with life. The suggestion that it's a NOLINT problem is incorrect: there is a disable comment, it's just not called NOLINT.

The partial format situation sucks quite a bit and I've been annoyed at it a lot. it's better than no formatter to some degree because it means we're not adding more diff to an eventual proper reformat run, but it is really frustrating to use with jj. Fundamentally it's a stepping stone to just running clang-format and I think we're being too conservative about the amount of bother it is to do that. But also I've been kind of unimpressed with the output quality of clang format. idk.

I think you'd get warmer reception if clang-format were anywhere near as good and well behaved as either nixfmt, fourmolu, or rustfmt. But clang-format makes several utterly baffling alignment choices that are seemingly impossible to turn off and it thus sucks. I wonder how much it would be annoying to fix those upstream.

I would love to have a code formatter consistently applied, but in spite of my best efforts as the author of the clang format configuration, it still kind of sucks! I think a proposal to improve the state of things requires triaging the egregiously bad formatting instances and figuring out why they happened and if we can fix them. If we can't fix them then we should add excludes to the relevant code blocks and move on with life. The suggestion that it's a NOLINT problem is incorrect: there *is* a disable comment, it's just not called NOLINT. The partial format situation sucks quite a bit and I've been annoyed at it a lot. it's better than no formatter to some degree because it means we're not adding *more* diff to an eventual proper reformat run, but it is really frustrating to use with jj. Fundamentally it's a stepping stone to just running clang-format and I think we're being too conservative about the amount of bother it is to do that. But also I've been kind of unimpressed with the output quality of clang format. idk. I think you'd get warmer reception if clang-format were anywhere near as good and well behaved as either nixfmt, fourmolu, *or* rustfmt. But clang-format makes several utterly baffling alignment choices that are seemingly impossible to turn off and it thus sucks. I wonder how much it would be annoying to fix those upstream.
Author
Member

(It would have been nice if “the clang-format style is bad and we are automatically setting up tooling that makes the code worse” had been mentioned a single time as an objection during the long Matrix discussion, as it would have saved me the trouble of writing up this issue and I could have opened a simpler one to propose disabling the formatter entirely.)

(It would have been nice if “the `clang-format` style is bad and we are automatically setting up tooling that makes the code worse” had been mentioned a single time as an objection during the long Matrix discussion, as it would have saved me the trouble of writing up this issue and I could have opened a simpler one to propose disabling the formatter entirely.)
Owner

If we can't fix them then we should add excludes to the relevant code blocks and move on with life. The suggestion that it's a NOLINT problem is incorrect: there is a disable comment, it's just not called NOLINT.

the nolint problem isn't that clang-format can't be disabled selectively, it's that it sometimes shuffles nolint comments and thus breaks them

> If we can't fix them then we should add excludes to the relevant code blocks and move on with life. The suggestion that it's a NOLINT problem is incorrect: there is a disable comment, it's just not called NOLINT. the nolint problem isn't that clang-format can't be disabled selectively, it's that it sometimes shuffles nolint comments and thus *breaks them*
Owner

@emilazy wrote in #948 (comment):

(It would have been nice if “the clang-format style is bad and we are automatically setting up tooling that makes the code worse” had been mentioned a single time as an objection during the long Matrix discussion, as it would have saved me the trouble of writing up this issue and I could have opened a simpler one to propose disabling the formatter entirely.)

This is a larger problem which is that not everyone holds this view and the people who are cranky about clang format or remembered well that original discussion and testing a year ago weren't looking at matrix at the time (or literally weren't in the channel at all) or so, so it's not just that "nobody told you" but "the ppl holding the opinions were different ppl than were on matrix".

I didn't realize the incremental formatting tooling was especially objectionable at all, so that part is news to me! I did know that part of the reason we hadn't fully applied it was that the style made code illegible sometimes.

@emilazy wrote in https://git.lix.systems/lix-project/lix/issues/948#issuecomment-13831: > (It would have been nice if “the `clang-format` style is bad and we are automatically setting up tooling that makes the code worse” had been mentioned a single time as an objection during the long Matrix discussion, as it would have saved me the trouble of writing up this issue and I could have opened a simpler one to propose disabling the formatter entirely.) This is a larger problem which is that not everyone holds this view and the people who are cranky about clang format or remembered well that original discussion and testing a year ago weren't looking at matrix at the time (or literally weren't in the channel at all) or so, so it's not just that "nobody told you" but "the ppl holding the opinions were different ppl than were on matrix". I didn't realize the incremental formatting tooling was especially objectionable at all, so that part is news to me! I did know that part of the reason we hadn't fully applied it was that the style made code illegible sometimes.
Sign in to join this conversation.
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix#948
No description provided.