this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cmd/cue: check all file I/O errors in fmt

First, we weren't checking any errors while opening and parsing CUE
files for formatting via Decoder.Err. This is somewhat harmless, as
cue/load currently opens all of those files, so any error like "file
does not exist" or "file cannot be read" would likely already be caught.

However, we called Encoder.Close without checking its returned error,
and it turns out that when encoding into a filename on disk,
that ultimately returns the ioutil.WriteFile error.
This meant that we ignored any errors while opening, writing, and
closing the destination file, potentially doing less work silently.

This is what happened in #1791. Before the fix, I can reliably reproduce
the problem by lowering my hard limit on open files like so:

$ ulimit -n 256

With 500 badly formatted CUE files, we would run:

$ cue fmt *.cue

And the result was that, without an error, only 249 files were changed
on disk. After the fix, the error is very clear:

$ cue fmt *.cue
open [...]/250.cue: too many open files

Note that this CL only fixes the ignored errors, not the cause of the
"too many open files" error.

Add a test; with a read-only file containing badly formatted CUE,
`cue fmt` used to hide the fact that it failed to write to the file.
That makes for a fairly simple error test.
We can't test the ignored Decoder error as easily, because as explained
above, most reasonable errors will already be caught by cue/load today.

Updates #1791.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: Ic4beed9c6139194d71566722cf0f8749fa8150d6
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/552624
Unity-Result: CUEcueckoo <cueckoo@cuelang.org>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Paul Jolly <paul@myitcv.io>

+27 -1
+6 -1
cmd/cue/cmd/fmt.go
··· 79 79 80 80 files = append(files, f) 81 81 } 82 + if err := d.Err(); err != nil { 83 + exitOnErr(cmd, err, true) 84 + } 82 85 83 86 e, err := encoding.NewEncoder(file, &cfg) 84 87 exitOnErr(cmd, err, true) ··· 87 90 err := e.EncodeFile(f) 88 91 exitOnErr(cmd, err, false) 89 92 } 90 - e.Close() 93 + if err := e.Close(); err != nil { 94 + exitOnErr(cmd, err, true) 95 + } 91 96 } 92 97 } 93 98 return nil
+21
cmd/cue/cmd/testdata/script/fmt_issue1791.txtar
··· 1 + # Note that the permission errors below cover unix and windows. 2 + 3 + # We can't read nor write. 4 + chmod 000 in.cue 5 + ! exec cue fmt in.cue 6 + stderr 'permission denied|Access is denied' 7 + 8 + # We can read, but not write. We used to ignore some open/write errors. 9 + chmod 444 in.cue 10 + ! exec cue fmt in.cue 11 + stderr 'permission denied|Access is denied' 12 + 13 + # We can read and write. 14 + chmod 666 in.cue 15 + exec cue fmt in.cue 16 + cmp in.cue in.cue.golden 17 + 18 + -- in.cue -- 19 + foo: "bar" 20 + -- in.cue.golden -- 21 + foo: "bar"