From eff0f8f1d5a19f11e8f8302d70a527475b5e80b4 Mon Sep 17 00:00:00 2001 From: loicb Date: Tue, 1 Sep 2026 09:42:15 +0800 Subject: [PATCH] fix(io): spit truncates on write and honours :append (#32) file-mode returned FileMode/OpenOrCreate for every write, so an existing file was opened at position 0 without truncating, and :append was ignored. A plain write now opens with FileMode/Create and :append with FileMode/Append, matching JVM Clojure. --- CHANGES_FLYBOT.md | 10 +++++++++ Clojure/Clojure.Source/clojure/clr/io.clj | 7 +++--- .../clojure/test_clojure/clr/io.clj | 22 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/CHANGES_FLYBOT.md b/CHANGES_FLYBOT.md index facb6e322..502d0c275 100644 --- a/CHANGES_FLYBOT.md +++ b/CHANGES_FLYBOT.md @@ -9,6 +9,16 @@ still under Backports. upstream commit it came from. *(partial)* means only some hunks of that commit were taken. +# Changes to ClojureCLR in Version 1.11.0-flybot4 (unreleased) + +## Fixes + +* [#32](https://github.com/flybot-sg/clojure-clr/pull/32) `file-mode` opens a + plain write with `FileMode/Create` and `:append` with `FileMode/Append` + instead of `FileMode/OpenOrCreate` for every write, so `spit` and `writer` + truncate the file they overwrite and `:append` appends, like JVM Clojure, + instead of writing at position 0 and dropping the option + # Changes to ClojureCLR in Version 1.11.0-flybot3 ## Fixes diff --git a/Clojure/Clojure.Source/clojure/clr/io.clj b/Clojure/Clojure.Source/clojure/clr/io.clj index 54fc21f23..a8d0d493f 100644 --- a/Clojure/Clojure.Source/clojure/clr/io.clj +++ b/Clojure/Clojure.Source/clojure/clr/io.clj @@ -219,9 +219,10 @@ (defn- ^FileMode file-mode [mode opts] (or (:file-mode opts) - (if (= mode :read) - FileMode/Open - FileMode/OpenOrCreate))) + (cond + (= mode :read) FileMode/Open + (:append opts) FileMode/Append + :else FileMode/Create))) (defn- ^FileShare file-share [opts] (or (:file-share opts) FileShare/None)) diff --git a/Clojure/Clojure.Tests/clojure/test_clojure/clr/io.clj b/Clojure/Clojure.Tests/clojure/test_clojure/clr/io.clj index 1fa7087ff..ba722a322 100644 --- a/Clojure/Clojure.Tests/clojure/test_clojure/clr/io.clj +++ b/Clojure/Clojure.Tests/clojure/test_clojure/clr/io.clj @@ -62,6 +62,28 @@ (platform-newlines "WARNING: (slurp f enc) is deprecated, use (slurp f :encoding enc).\n") (with-out-str (is (= content (slurp f utf16)))))))))) + +(deftest test-spit-truncates + (with-temp-file [f] + (spit f "DATA-PRESENT") + (spit f "AB") + (is (= "AB" (slurp f)))) + (with-temp-file [f] + (spit f "DATA-PRESENT") + (spit f nil) + (is (= "" (slurp f))))) + +(deftest test-spit-append + (with-temp-file [f] + (spit f "AAA") + (spit f "BBB" :append true) + (is (= "AAABBB" (slurp f))))) + +(deftest test-spit-file-mode-overrides + (with-temp-file [f] + (spit f "AAA") + (spit f "BBB" :file-mode FileMode/Append) + (is (= "AAABBB" (slurp f))))) (deftest test-streams-defaults (let [f (temp-file "test-reader-writer")