edf2csv 0.5.90 → 0.5.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,60 @@
3
3
  Notable changes to edf2csv. Versions follow [semantic versioning](https://semver.org); while the
4
4
  major version is 0, a minor bump may contain breaking changes.
5
5
 
6
+ ## 0.5.92
7
+
8
+ ### Fixed: `--info` redirected into a full filesystem wrote nothing and exited 0
9
+
10
+ ```
11
+ $ edf2csv wide.edf --info > desc.txt
12
+ $ echo $?
13
+ 0
14
+ $ wc -c desc.txt
15
+ 0 desc.txt
16
+ ```
17
+
18
+ A conversion audits what actually reached stdout — that is what 0.5.82 and the disk-image tests
19
+ are about. `--info` wrote its description with `process.stdout.write` and looked at nothing, so
20
+ a run that produced no description at all reported success. `edf2csv rec.edf --info > desc.txt`
21
+ in a script is exactly how someone captures one.
22
+
23
+ A description is usually a few hundred bytes, which is why this went unnoticed; a 900-channel
24
+ recording's is 58 KB, and no destination is guaranteed to have that.
25
+
26
+ It uses the same audit now, so it exits 1 and names the cause. That audit declines anything
27
+ that is not a regular file, so a pipe and a terminal are untouched and `--info | head` still
28
+ exits 0.
29
+
30
+ The test took two attempts: filling the volume completely means the shell cannot create the
31
+ redirect target and the tool never runs, which is what the first one measured. It leaves twenty
32
+ kilobytes and writes 58 into it.
33
+
34
+ ## 0.5.91
35
+
36
+ ### Fixed: `--start` at the recording's exact length was accepted when the length was a product
37
+
38
+ `--start` at or past the end of a recording is an error, because the result would be an empty
39
+ file that looks like a successful conversion. The guard compares against
40
+ `recordCount * recordDuration` — and with a fractional record duration that product is not the
41
+ number it prints as. 6003 records of 0.1s is 600.3000000000001, so on a recording `--info`
42
+ calls "10m 0.3s":
43
+
44
+ ```
45
+ $ edf2csv tenmin.edf --start 600.3 --out out
46
+ warning: No samples fall inside the requested window (600.300s to 600.300s), so the signal
47
+ files hold their headers and no data.
48
+ $ echo $?
49
+ 0
50
+ ```
51
+
52
+ Exactly the empty conversion the error exists to prevent, and exactly what `--start 2` on a
53
+ two-second recording is refused for. Which of the two you get depends on whether your record
54
+ duration is a whole number.
55
+
56
+ Compared with a relative epsilon now — the same shape the long layout uses to decide two sample
57
+ times are one instant: well below any real sample interval, and well above the rounding that two
58
+ routes to one quantity produce. `--start 600.2` on the same file still converts its ten samples.
59
+
6
60
  ## 0.5.90
7
61
 
8
62
  ### Fixed: the duration warnings described rows a window had excluded
package/dist/cli.js CHANGED
@@ -18,7 +18,7 @@ import process from 'node:process';
18
18
  import { EdfError } from './edf/errors.js';
19
19
  import { EdfFile } from './edf/reader.js';
20
20
  import { buildPlan, withoutFileRateWarning } from './convert/plan.js';
21
- import { ConversionError, USAGE_ERROR_CODES, convert, defaultOutputDir, durationDiagnostics, stdoutRefusal, } from './convert/run.js';
21
+ import { ConversionError, USAGE_ERROR_CODES, auditStdout, convert, defaultOutputDir, durationDiagnostics, stdoutRefusal, } from './convert/run.js';
22
22
  import { ChannelSelectionError } from './convert/channels.js';
23
23
  // Shared with the library so a bad option is the same error whichever way it arrived.
24
24
  import { OptionError } from './convert/options.js';
@@ -709,7 +709,21 @@ async function showInfo(input, shared, asJson, jsonIndent, batch = false, toStdo
709
709
  });
710
710
  }
711
711
  }
712
- process.stdout.write(asJson ? `${infoJson(file, plan, jsonIndent)}\n` : `${formatInfo(file, plan)}\n`);
712
+ /*
713
+ Checked, like a conversion's stdout is.
714
+
715
+ This wrote and looked at nothing, so `--info > desc.txt` into a filesystem with no room
716
+ produced a zero-byte file and exited 0. The same audit the `--stdout` path uses: it
717
+ declines anything that is not a regular file, so a pipe or a terminal is unaffected, and
718
+ `--info | head` keeps exiting 0.
719
+ */
720
+ const audit = auditStdout();
721
+ const description = asJson
722
+ ? `${infoJson(file, plan, jsonIndent)}\n`
723
+ : `${formatInfo(file, plan)}\n`;
724
+ process.stdout.write(description);
725
+ audit?.count(Buffer.byteLength(description));
726
+ audit?.verify();
713
727
  // Under --json the warnings travel inside the document, exactly as they do for a
714
728
  // conversion, so stderr stays empty and the whole result is one parseable thing.
715
729
  const diagnostics = [...withoutFileRateWarning(file.diagnostics), ...plan.diagnostics];