Prettier through `--stdin` does no formatting
Describe the bug
I run e.g. treefmt --stdin test.js < test.js, but no changes. Neither for json files. But file does change if I run treefmt test.js.
To Reproduce
Steps to reproduce the behavior:
I am using treefmt-nix, with this:
treefmt = {
programs = {
prettier.enable = true;
};
};
const x = () => {
console.log( "zxc " );
};
-
nix fmt -- --stdin test.js < test.js - Outputs the same content as went in, no changes.
- For reference,
nix fmt -- --stdin flake.nix < flake.nixdoes output changes (when needed) -
nix fmtresults in formatted js file
Expected behavior
It should format the JS through stdin via prettier.
System information
nixos-unstable 01f116e4df6a15f4ccdffb1bcd41096869fb385c treefmt v2.4.0
Additional context
I just did a quick test using treefmt directly using your sample js and the following config:
[formatter.prettier]
command = "prettier"
options = ["--write"]
includes = [
"*.js"
]
Here's what I'm seeing:
❯ nix run github:numtide/treefmt/v2.4.0 -- --stdin test.js < test.js
const x = () => {
console.log("zxc ");
};
traversed 1 files
emitted 1 files for processing
formatted 1 files (1 changed) in 173ms
Can you provide a standalone reproducer, or is your repo public?
https://github.com/losnappas/treefmt-repro
17:08:36{direnv}/tmp/treefmt-test $ nix fmt -- --stdin test.js < test.js
const x = () => {
console.log( "zxc " );
};traversed 1 files
emitted 1 files for processing
formatted 1 files (0 changed) in 94ms
17:08:40{direnv}/tmp/treefmt-test $ nix run github:numtide/treefmt/v2.4.0 -- --stdin test.js < test.js
warning: ignoring the client-specified setting 'trusted-public-keys', because it is a restricted setting and you are not a trusted user
const x = () => {
console.log( "zxc " );
};traversed 1 files
emitted 1 files for processing
formatted 1 files (0 changed) in 96ms
$ nix fmt
traversed 6 files
emitted 1 files for processing
formatted 1 files (1 changed) in 147ms
17:09:59{direnv}/tmp/treefmt-test $ cat test.js
const x = () => {
console.log("zxc ");
};
$ # and again after reverting file
$ nix run github:numtide/treefmt/v2.4.0 -- .
warning: ignoring the client-specified setting 'trusted-public-keys', because it is a restricted setting and you are not a trusted user
traversed 6 files
emitted 1 files for processing
formatted 1 files (1 changed) in 149ms
17:10:49{direnv}/tmp/treefmt-test $ cat test.js
const x = () => {
console.log("zxc ");
};
17:12:00{direnv}/tmp/treefmt-test $ prettier --stdin-filepath test.js < test.js
const x = () => {
console.log("zxc ");
};
@losnappas, thanks for the reproducer. I just checked it out and was able to replicate what you are seeing.
This gives me something to investigate.
I've done some quick testing, and here's what I've found so far.
I ejected the wrapped treefmt being used via flake-parts with nix build .# and:
perSystem = { config, self', inputs', pkgs, system, ... }: {
....
packages.default = config.treefmt.build.wrapper;
}
It looks like this:
#!/nix/store/ciarnmsx8lvsrmdbjddpmx0pqjrm8imb-bash-5.3p3/bin/bash
set -euo pipefail
unset PRJ_ROOT
exec /nix/store/xq1681mm2pyi0vidfxd4z0jfdm6psw3h-treefmt-2.4.0/bin/treefmt \
--config-file=/nix/store/13nidh2ij1am61s8n2nwbi864zf4sbz2-treefmt.toml \
--tree-root-file=flake.nix \
"$@"
If I run the command as is from the root of the repo it doesn't work:
/nix/store/xq1681mm2pyi0vidfxd4z0jfdm6psw3h-treefmt-2.4.0/bin/treefmt \
--config-file=/nix/store/13nidh2ij1am61s8n2nwbi864zf4sbz2-treefmt.toml \
--tree-root-file=flake.nix \
--stdin test.js < test.js
const x = () => {
console.log( "zxc " );
};
traversed 1 files
emitted 1 files for processing
formatted 1 files (0 changed) in 167ms
If I omit the --tree-root-file argument it works:
/nix/store/xq1681mm2pyi0vidfxd4z0jfdm6psw3h-treefmt-2.4.0/bin/treefmt \
--config-file=/nix/store/13nidh2ij1am61s8n2nwbi864zf4sbz2-treefmt.toml \
--stdin test.js < test.js
const x = () => {
console.log("zxc ");
};
traversed 1 files
emitted 1 files for processing
formatted 1 files (1 changed) in 201ms
I now know where to look for this bug. I'll try to find some time in the next few days to dig into it.
I found the issue.
https://github.com/numtide/treefmt/pull/624/commits/b68d3286440c818d2452a65d3c503a7245447269 introduced a change to how we create temp files for processing stdin. Previously, we had been making a temporary file local to the file being processed (the path passed in before < for matching purposes), a descendant of the root of the tree.
Now, we have a virtual path for matching, but we generate the temp file in /tmp.
Turns out, after some experimentation, prettier, for good reason, doesn't process files that are not descendants of the directory it's being invoked from. This behaviour likely differs on a per-formatter basis.
I need to consider how best to resolve this issue permanently. Feels like I keep flip-flopping with stdin processing. 🤔
@jfly @zimbatm I welcome your input.
Turns out, after some experimentation, prettier, for good reason, doesn't process files that are not descendants of the directory it's being invoked from.
This reminds me of the issue that originally brought me to treefmt. We decided to add this to the spec:
It MUST process the specified files. For example, it MUST NOT ignore files because they are not tracked by a VCS.
(With my pedantic hat on) I'd say that prettier is violating the formatter specification.
This behaviour likely differs on a per-formatter basis
I agree. I don't think there's any behavior that's perfect. Perhaps the old behavior (tempfiles alongside the original files) is more likely to play nicely with existing formatters. IMO, the only correct solution is for us to implement the stdin spec.