| 🛟 Updated. 28d5985 k33g 20h ago | 1 | # projectfile |
| 2 | |
| 3 | Writes the TOML files a project keeps in the editor's own directory — `.turbo-go`, `.turbo-rust` — namely its settings, its snippets and its tools. |
| 4 | |
| 5 | ## Why it exists |
| 6 | |
| 7 | Three packages were writing one identically — the same temporary file, the same rename, the same mode. A fourth would have been the point at which nobody remembered which copy was the correct one, and the project's own standard is to extract at the second occurrence. |
| 8 | |
| 9 | The quality gate is what surfaced it: `qlty` reported the duplication as a smell across `settings`, `snippets` and `tools`, and the only honest way past it was to write the thing once. |
| 10 | |
| 11 | ## What it does not do |
| 12 | |
| 13 | **It is not what `buffer` does for a source file.** That one preserves the mode of the file it is replacing, because it is saving over something the user already had, and it takes care to remove the temporary on every failure path. This one is creating a file the editor is introducing, and a fixed `0644` is the right answer for it — these files are meant to be committed and read by a team. |
| 14 | |
| 15 | The two look alike and are not the same operation. Merging them would mean parameterising the mode and giving up the different error text, for no gain. |
| 16 | |
| 17 | ## How |
| 18 | |
| 19 | The write goes to a temporary file **in the same directory** as its destination, which is then renamed over it. A rename is only atomic within one filesystem, and an interrupted write must leave the previous file intact rather than half of the new one. |
| 20 | |
| 21 | `CreateTemp` makes a file readable by its owner only, so the mode is set before the rename — otherwise the permissions would silently tighten on a file a team shares. |
| 22 | |
| 23 | The destination's directory is created if it is not there, so a caller does not have to. |
| 24 | |
| 25 | ## Public API |
| 26 | |
| 27 | | Name | What it does | |
| 28 | | --- | --- | |
| 29 | | `Write(path string, data []byte) error` | Creates or replaces a project file atomically, making its directory if need be | |
| 30 | |
| 31 | ```go |
| 32 | if err := projectfile.Write(".turbo-go/tools.toml", []byte(template)); err != nil { |
| 33 | return err |
| 34 | } |
| 35 | ``` |
| 36 | |
| 37 | ## Tests |
| 38 | |
| 39 | ```sh |
| 40 | make test |
| 41 | go test ./projectfile/ |
| 42 | ``` |
| 43 | |
| 44 | One of them checks that no temporary file is left behind — a failed write littering somebody's project directory with `.projectfile-*.toml` is the kind of thing that has to be explained rather than noticed. |