diff --git a/exe/Main.hs b/exe/Main.hs index 1c66926..a12450a 100644 --- a/exe/Main.hs +++ b/exe/Main.hs @@ -9,6 +9,7 @@ import Language.PureScript.Backend qualified as Backend import Language.PureScript.Backend.IR qualified as IR import Language.PureScript.Backend.Lua qualified as Lua import Language.PureScript.Backend.Lua.Printer qualified as Printer +import Language.PureScript.Backend.Output (withOutputFile) import Language.PureScript.CoreFn.Reader qualified as CoreFn import Language.PureScript.Names (runIdent, runModuleName) import Main.Utf8 qualified as Utf8 @@ -53,19 +54,19 @@ main = Utf8.withUtf8 do & Oops.runOops let outputFile = toFilePath luaOutput - withFile outputFile WriteMode \h → + withOutputFile luaOutput \h → renderIO h . layoutPretty defaultLayoutOptions $ Printer.printLuaChunk lua when (OutputIR `elem` extraOutputs) do - irOutputFile ← toFilePath <$> replaceExtension ".ir" luaOutput - withFile irOutputFile WriteMode (`pHPrint` ir) - putTextLn $ "Wrote IR to " <> toText irOutputFile + irOutputPath ← replaceExtension ".ir" luaOutput + withOutputFile irOutputPath (`pHPrint` ir) + putTextLn $ "Wrote IR to " <> toText (toFilePath irOutputPath) when (OutputLuaAst `elem` extraOutputs) do - luaAstOutputFile ← toFilePath <$> replaceExtension ".lua-ast" luaOutput - withFile luaAstOutputFile WriteMode (`pHPrint` lua) - putTextLn $ "Wrote Lua AST to " <> toText luaAstOutputFile + luaAstOutputPath ← replaceExtension ".lua-ast" luaOutput + withOutputFile luaAstOutputPath (`pHPrint` lua) + putTextLn $ "Wrote Lua AST to " <> toText (toFilePath luaAstOutputPath) putTextLn $ "Wrote linked modules to " <> toText outputFile diff --git a/lib/Language/PureScript/Backend/Output.hs b/lib/Language/PureScript/Backend/Output.hs new file mode 100644 index 0000000..63df543 --- /dev/null +++ b/lib/Language/PureScript/Backend/Output.hs @@ -0,0 +1,20 @@ +module Language.PureScript.Backend.Output + ( withOutputFile + ) where + +import Path (Abs, File, Path, parent, toFilePath) +import Path.IO (ensureDir) + +-------------------------------------------------------------------------------- +-- Output ---------------------------------------------------------------------- + +{- | Open a file for writing, first creating its parent directory (and any +missing ancestors). pslua's @--lua-output-file@ may point into a directory +that does not exist yet (a gitignored @dist/@, say); plain 'withFile' would +abort with @does not exist@, a sharp edge each fork's build script would +otherwise work around with @mkdir -p@. +-} +withOutputFile ∷ Path Abs File → (Handle → IO r) → IO r +withOutputFile path action = do + ensureDir (parent path) + withFile (toFilePath path) WriteMode action diff --git a/pslua.cabal b/pslua.cabal index d8dad70..66c11f7 100644 --- a/pslua.cabal +++ b/pslua.cabal @@ -140,6 +140,7 @@ library Language.PureScript.Backend.Lua.Printer Language.PureScript.Backend.Lua.Traversal Language.PureScript.Backend.Lua.Types + Language.PureScript.Backend.Output Language.PureScript.Backend.Types Language.PureScript.Comments Language.PureScript.CoreFn @@ -172,6 +173,7 @@ test-suite spec Language.PureScript.Backend.Lua.Linker.Foreign.Spec Language.PureScript.Backend.Lua.Optimizer.Spec Language.PureScript.Backend.Lua.Printer.Spec + Language.PureScript.Backend.Output.Spec Test.Hspec.Expectations.Pretty Test.Hspec.Extra Test.Hspec.Golden diff --git a/test/Language/PureScript/Backend/Output/Spec.hs b/test/Language/PureScript/Backend/Output/Spec.hs new file mode 100644 index 0000000..b2b9795 --- /dev/null +++ b/test/Language/PureScript/Backend/Output/Spec.hs @@ -0,0 +1,14 @@ +module Language.PureScript.Backend.Output.Spec (spec) where + +import Language.PureScript.Backend.Output (withOutputFile) +import Path (parseRelFile, ()) +import Path.IO (doesFileExist, withSystemTempDir) +import Test.Hspec (Spec, describe, it, shouldReturn) + +spec ∷ Spec +spec = describe "Language.PureScript.Backend.Output" do + it "withOutputFile creates the missing parent directory" do + withSystemTempDir "pslua-output" \tmp → do + file ← (tmp ) <$> parseRelFile "nested/dir/out.lua" + withOutputFile file (const pass) + doesFileExist file `shouldReturn` True diff --git a/test/Main.hs b/test/Main.hs index 6d27b1d..545ba10 100644 --- a/test/Main.hs +++ b/test/Main.hs @@ -11,6 +11,7 @@ import Language.PureScript.Backend.Lua.Golden.Spec qualified as Golden import Language.PureScript.Backend.Lua.Linker.Foreign.Spec qualified as LuaLinkerForeign import Language.PureScript.Backend.Lua.Optimizer.Spec qualified as LuaOptimizer import Language.PureScript.Backend.Lua.Printer.Spec qualified as Printer +import Language.PureScript.Backend.Output.Spec qualified as Output import Test.Hspec (hspec) main ∷ IO () @@ -26,3 +27,4 @@ main = hspec do LuaOptimizer.spec Printer.spec LuaLinkerForeign.spec + Output.spec