| 132 | } |
| 133 | |
| 134 | func (o *Writer) writeFile(category string, rows []row) (err error) { |
| 135 | // Format to buffer first — if formatter produces no output (e.g. |
| 136 | // cookie-editor skipping non-cookie data), don't create the file. |
| 137 | var buf bytes.Buffer |
| 138 | if err := o.formatter.format(&buf, rows); err != nil { |
| 139 | return fmt.Errorf("format %s: %w", category, err) |
| 140 | } |
| 141 | if buf.Len() == 0 { |
| 142 | return nil |
| 143 | } |
| 144 | |
| 145 | filename := fmt.Sprintf("%s.%s", category, o.formatter.ext()) |
| 146 | path := filepath.Join(o.dir, filename) |
| 147 | |
| 148 | f, err := os.OpenFile(filepath.Clean(path), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600) |
| 149 | if err != nil { |
| 150 | return fmt.Errorf("create %s: %w", filename, err) |
| 151 | } |
| 152 | defer func() { |
| 153 | if cerr := f.Close(); cerr != nil && err == nil { |
| 154 | err = fmt.Errorf("close %s: %w", filename, cerr) |
| 155 | } |
| 156 | }() |
| 157 | |
| 158 | if strings.HasSuffix(path, ".csv") { |
| 159 | if _, err := f.Write(utf8BOM); err != nil { |
| 160 | return fmt.Errorf("write BOM: %w", err) |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | if _, err := f.Write(buf.Bytes()); err != nil { |
| 165 | return fmt.Errorf("write %s: %w", filename, err) |
| 166 | } |
| 167 | return nil |
| 168 | } |