From f369b7982b1b13206d58187176cb395af1508dd6 Mon Sep 17 00:00:00 2001 From: Fyodor Soikin Date: Wed, 28 Aug 2024 17:18:32 -0400 Subject: [PATCH 1/7] In PSA output label warnings and errors as such --- src/Spago/Psa/Printer.purs | 34 ++++++++------- .../errors/expected-stderr.txt | 43 +++++++++++++++++++ .../errors/spago.yaml | 10 +++++ .../errors/src/Foo.purs | 4 ++ .../errors/src/Main.purs | 11 +++++ .../warnings/expected-stderr.txt | 43 +++++++++++++++++++ .../warnings/spago.yaml | 10 +++++ .../warnings/src/Main.purs | 11 +++++ test/Spago/Build.purs | 11 +++++ 9 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 test-fixtures/build/1148-warnings-diff-errors/errors/expected-stderr.txt create mode 100644 test-fixtures/build/1148-warnings-diff-errors/errors/spago.yaml create mode 100644 test-fixtures/build/1148-warnings-diff-errors/errors/src/Foo.purs create mode 100644 test-fixtures/build/1148-warnings-diff-errors/errors/src/Main.purs create mode 100644 test-fixtures/build/1148-warnings-diff-errors/warnings/expected-stderr.txt create mode 100644 test-fixtures/build/1148-warnings-diff-errors/warnings/spago.yaml create mode 100644 test-fixtures/build/1148-warnings-diff-errors/warnings/src/Main.purs diff --git a/src/Spago/Psa/Printer.purs b/src/Spago/Psa/Printer.purs index 968afc0dd..96ec78da0 100644 --- a/src/Spago/Psa/Printer.purs +++ b/src/Spago/Psa/Printer.purs @@ -5,9 +5,7 @@ -- Copyright © Nathan Faubion -- https://opensource.org/license/mit/ module Spago.Psa.Printer - ( renderWarning - , renderError - , renderStats + ( renderStats , renderVerboseStats , printDefaultOutputToErr , printJsonOutputToOut @@ -50,11 +48,11 @@ printJsonOutputToOut output = do printDefaultOutputToErr :: PsaArgs -> Output -> Effect Unit printDefaultOutputToErr options output = do forWithIndex_ output.warnings \i warning -> do - Console.error $ printDoc (renderWarning lenWarnings (i + 1) warning) + Console.error $ printDoc (renderCitation Warn lenWarnings (i + 1) warning) Console.error "" forWithIndex_ output.errors \i error -> do - Console.error $ printDoc (renderError lenErrors (i + 1) error) + Console.error $ printDoc (renderCitation Err lenErrors (i + 1) error) Console.error "" Console.error $ printDoc (renderStats' output.stats) @@ -70,17 +68,21 @@ printDefaultOutputToErr options output = do Core.CompactStats -> renderStats Core.VerboseStats -> renderVerboseStats -renderWarning :: Int -> Int -> PsaAnnotedError -> D.Doc Ansi.GraphicsParam -renderWarning = renderWrapper Ansi.BrightYellow +data Citation = Warn | Err -renderError :: Int -> Int -> PsaAnnotedError -> D.Doc Ansi.GraphicsParam -renderError = renderWrapper Ansi.BrightRed +citationColor :: Citation -> Ansi.Color +citationColor Warn = Ansi.BrightYellow +citationColor Err = Ansi.BrightRed -renderWrapper :: Ansi.Color -> Int -> Int -> PsaAnnotedError -> D.Doc Ansi.GraphicsParam -renderWrapper color total index { error, path, position, source, message } = +citationLabel :: Citation -> String +citationLabel Warn = "WARN" +citationLabel Err = "ERR" + +renderCitation :: Citation -> Int -> Int -> PsaAnnotedError -> D.Doc Ansi.GraphicsParam +renderCitation cit total index { error, path, position, source, message } = D.foldWithSeparator (D.break <> D.break) [ D.words $ - [ renderStatus color total index error.errorCode + [ renderStatus cit total index error.errorCode , renderPath path error.moduleName <> foldMap renderPosition position ] , D.indent $ D.lines @@ -92,9 +94,11 @@ renderWrapper color total index { error, path, position, source, message } = toLines :: String -> D.Doc Ansi.GraphicsParam toLines = D.lines <<< map D.text <<< Str.split (Str.Pattern "\n") -renderStatus :: Ansi.Color -> Int -> Int -> String -> D.Doc Ansi.GraphicsParam -renderStatus color total index code = - DA.foreground color $ D.text $ "[" <> show index <> "/" <> show total <> " " <> code <> "]" +renderStatus :: Citation -> Int -> Int -> String -> D.Doc Ansi.GraphicsParam +renderStatus cit total index code = + DA.foreground (citationColor cit) + $ D.text + $ "[" <> citationLabel cit <> " " <> show index <> "/" <> show total <> " " <> code <> "]" renderModuleName :: Maybe String -> D.Doc Ansi.GraphicsParam renderModuleName Nothing = DA.dim $ D.text "(unknown module)" diff --git a/test-fixtures/build/1148-warnings-diff-errors/errors/expected-stderr.txt b/test-fixtures/build/1148-warnings-diff-errors/errors/expected-stderr.txt new file mode 100644 index 000000000..01f0b4ecf --- /dev/null +++ b/test-fixtures/build/1148-warnings-diff-errors/errors/expected-stderr.txt @@ -0,0 +1,43 @@ +Reading Spago workspace configuration... + +✓ Selecting package to build: foo + +Downloading dependencies... +Building... +[1 of 2] Compiling Foo +[2 of 2] Compiling Main +[ERR 1/2 TypesDoNotUnify] src/Foo.purs:4:5 + + 4 x = "nope" + ^^^^^^ + + Could not match type + String + with type + Int + while checking that type String + is at least as general as type Int + while checking that expression "nope" + has type Int + in value declaration x + +[ERR 2/2 TypesDoNotUnify] src/Main.purs:10:7 + + 10 log 42 + ^^ + + Could not match type + Int + with type + String + while checking that type Int + is at least as general as type String + while checking that expression 42 + has type String + in value declaration main + + Src Lib All +Warnings 0 0 0 +Errors 2 0 2 + +✘ Failed to build. diff --git a/test-fixtures/build/1148-warnings-diff-errors/errors/spago.yaml b/test-fixtures/build/1148-warnings-diff-errors/errors/spago.yaml new file mode 100644 index 000000000..164648573 --- /dev/null +++ b/test-fixtures/build/1148-warnings-diff-errors/errors/spago.yaml @@ -0,0 +1,10 @@ +package: + name: foo + dependencies: + - console + - effect + - prelude + +workspace: + packageSet: + registry: 41.5.0 diff --git a/test-fixtures/build/1148-warnings-diff-errors/errors/src/Foo.purs b/test-fixtures/build/1148-warnings-diff-errors/errors/src/Foo.purs new file mode 100644 index 000000000..86224c155 --- /dev/null +++ b/test-fixtures/build/1148-warnings-diff-errors/errors/src/Foo.purs @@ -0,0 +1,4 @@ +module Foo where + +x :: Int +x = "nope" diff --git a/test-fixtures/build/1148-warnings-diff-errors/errors/src/Main.purs b/test-fixtures/build/1148-warnings-diff-errors/errors/src/Main.purs new file mode 100644 index 000000000..5fdeca2f0 --- /dev/null +++ b/test-fixtures/build/1148-warnings-diff-errors/errors/src/Main.purs @@ -0,0 +1,11 @@ +module Main where + +import Prelude + +import Effect +import Effect.Console (log) + +main :: Effect Unit +main = do + log 42 + pure unit diff --git a/test-fixtures/build/1148-warnings-diff-errors/warnings/expected-stderr.txt b/test-fixtures/build/1148-warnings-diff-errors/warnings/expected-stderr.txt new file mode 100644 index 000000000..a5185782d --- /dev/null +++ b/test-fixtures/build/1148-warnings-diff-errors/warnings/expected-stderr.txt @@ -0,0 +1,43 @@ +Reading Spago workspace configuration... + +✓ Selecting package to build: foo + +Downloading dependencies... +Building... +[1 of 1] Compiling Main +[WARN 1/4 ImplicitImport] src/Main.purs:3:1 + + 3 import Prelude + ^^^^^^^^^^^^^^ + + Module Prelude has unspecified imports, consider using the explicit form: + import Prelude (Unit, pure, unit) + +[WARN 2/4 ImplicitImport] src/Main.purs:5:1 + + 5 import Effect + ^^^^^^^^^^^^^ + + Module Effect has unspecified imports, consider using the explicit form: + import Effect (Effect) + +[WARN 3/4 UnusedImport] src/Main.purs:6:1 + + 6 import Effect.Console (log) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + The import of Effect.Console is redundant + +[WARN 4/4 UnusedName] src/Main.purs:10:7 + + 10 let unusedVar = 1 + ^^^^^^^^^^^^^ + + Name unusedVar was introduced but not used. + in value declaration main + + Src Lib All +Warnings 4 0 4 +Errors 0 0 0 + +✓ Build succeeded. diff --git a/test-fixtures/build/1148-warnings-diff-errors/warnings/spago.yaml b/test-fixtures/build/1148-warnings-diff-errors/warnings/spago.yaml new file mode 100644 index 000000000..164648573 --- /dev/null +++ b/test-fixtures/build/1148-warnings-diff-errors/warnings/spago.yaml @@ -0,0 +1,10 @@ +package: + name: foo + dependencies: + - console + - effect + - prelude + +workspace: + packageSet: + registry: 41.5.0 diff --git a/test-fixtures/build/1148-warnings-diff-errors/warnings/src/Main.purs b/test-fixtures/build/1148-warnings-diff-errors/warnings/src/Main.purs new file mode 100644 index 000000000..47a53c88d --- /dev/null +++ b/test-fixtures/build/1148-warnings-diff-errors/warnings/src/Main.purs @@ -0,0 +1,11 @@ +module Main where + +import Prelude + +import Effect +import Effect.Console (log) + +main :: Effect Unit +main = do + let unusedVar = 1 + pure unit diff --git a/test/Spago/Build.purs b/test/Spago/Build.purs index da5217d85..729a84932 100644 --- a/test/Spago/Build.purs +++ b/test/Spago/Build.purs @@ -211,6 +211,17 @@ spec = Spec.around withTempDir do spago [ "build" ] >>= shouldBeSuccessErr (fixture "build/migrate-config/migrated-output.txt") checkFixture "spago.yaml" (fixture "build/migrate-config/migrated-spago.yaml") + Spec.it "#1148: outputs errors and warnings after build" \{ spago, fixture } -> do + FS.copyTree { src: fixture "build/1148-warnings-diff-errors", dst: "." } + + liftEffect $ Process.chdir "errors" + spago [ "install" ] >>= shouldBeSuccess + spago [ "build" ] >>= shouldBeFailureErr (fixture "build/1148-warnings-diff-errors/errors/expected-stderr.txt") + + liftEffect $ Process.chdir "../warnings" + spago [ "install" ] >>= shouldBeSuccess + spago [ "build" ] >>= shouldBeSuccessErr (fixture "build/1148-warnings-diff-errors/warnings/expected-stderr.txt") + Pedantic.spec Monorepo.spec From d1d039cee61575ca42be394a45224b38dd1b19dd Mon Sep 17 00:00:00 2001 From: Fyodor Soikin Date: Wed, 28 Aug 2024 17:19:56 -0400 Subject: [PATCH 2/7] Changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6d6646de..508365973 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ Other improvements: cached locally. - `spago publish` now allows to publish a package with some test (but only test!) dependencies not present in the registry. +- errors and warnings are now explicitly labeled as "ERR" and "WARN" in Spago + build output. ## [0.21.0] - 2023-05-04 From 4f009697778ea4ba471cb45bf5c4a9cf16d943f1 Mon Sep 17 00:00:00 2001 From: Fyodor Soikin Date: Wed, 28 Aug 2024 17:22:49 -0400 Subject: [PATCH 3/7] And don't forget about Windows! --- test/Spago/Build.purs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/Spago/Build.purs b/test/Spago/Build.purs index 729a84932..65af81894 100644 --- a/test/Spago/Build.purs +++ b/test/Spago/Build.purs @@ -3,6 +3,7 @@ module Test.Spago.Build where import Test.Prelude import Data.Foldable (fold) +import Data.String as String import Node.FS.Aff as FSA import Node.Path as Path import Node.Platform as Platform @@ -212,15 +213,27 @@ spec = Spec.around withTempDir do checkFixture "spago.yaml" (fixture "build/migrate-config/migrated-spago.yaml") Spec.it "#1148: outputs errors and warnings after build" \{ spago, fixture } -> do + let + shouldBeSuccessErr' = checkOutputsWithPathSeparatorPatchErr isRight + shouldBeFailureErr' = checkOutputsWithPathSeparatorPatchErr isLeft + + checkOutputsWithPathSeparatorPatchErr result expectedFixture = + checkOutputs' + { stdoutFile: Nothing + , stderrFile: Just $ fixture expectedFixture + , result + , sanitize: String.trim >>> String.replaceAll (String.Pattern $ "src\\") (String.Replacement "src/") + } + FS.copyTree { src: fixture "build/1148-warnings-diff-errors", dst: "." } liftEffect $ Process.chdir "errors" spago [ "install" ] >>= shouldBeSuccess - spago [ "build" ] >>= shouldBeFailureErr (fixture "build/1148-warnings-diff-errors/errors/expected-stderr.txt") + spago [ "build" ] >>= shouldBeFailureErr' "build/1148-warnings-diff-errors/errors/expected-stderr.txt" liftEffect $ Process.chdir "../warnings" spago [ "install" ] >>= shouldBeSuccess - spago [ "build" ] >>= shouldBeSuccessErr (fixture "build/1148-warnings-diff-errors/warnings/expected-stderr.txt") + spago [ "build" ] >>= shouldBeSuccessErr' "build/1148-warnings-diff-errors/warnings/expected-stderr.txt" Pedantic.spec From c447d62c736f953a74b00ae3192dccb4732b5d08 Mon Sep 17 00:00:00 2001 From: Fyodor Soikin Date: Wed, 28 Aug 2024 17:29:43 -0400 Subject: [PATCH 4/7] And don't forget about Windows newlines either --- test/Spago/Build.purs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/Spago/Build.purs b/test/Spago/Build.purs index 65af81894..8a5f2df4e 100644 --- a/test/Spago/Build.purs +++ b/test/Spago/Build.purs @@ -222,7 +222,10 @@ spec = Spec.around withTempDir do { stdoutFile: Nothing , stderrFile: Just $ fixture expectedFixture , result - , sanitize: String.trim >>> String.replaceAll (String.Pattern $ "src\\") (String.Replacement "src/") + , sanitize: + String.trim + >>> String.replaceAll (String.Pattern $ "src\\") (String.Replacement "src/") + >>> String.replaceAll (String.Pattern $ "\r\n") (String.Replacement "\n") } FS.copyTree { src: fixture "build/1148-warnings-diff-errors", dst: "." } From a2becc51ab194ff4f6e10637d2b0794d40967f97 Mon Sep 17 00:00:00 2001 From: Fyodor Soikin Date: Wed, 28 Aug 2024 17:50:00 -0400 Subject: [PATCH 5/7] Fix another test, change to full words --- CHANGELOG.md | 4 ++-- src/Spago/Psa/Printer.purs | 4 ++-- .../1148-warnings-diff-errors/errors/expected-stderr.txt | 4 ++-- .../warnings/expected-stderr.txt | 8 ++++---- test/Spago/Test.purs | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 508365973..d34e21386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,8 +27,8 @@ Other improvements: cached locally. - `spago publish` now allows to publish a package with some test (but only test!) dependencies not present in the registry. -- errors and warnings are now explicitly labeled as "ERR" and "WARN" in Spago - build output. +- errors and warnings are now explicitly labeled as "ERROR" and "WARNING" in + Spago build output. ## [0.21.0] - 2023-05-04 diff --git a/src/Spago/Psa/Printer.purs b/src/Spago/Psa/Printer.purs index 96ec78da0..5536c94c8 100644 --- a/src/Spago/Psa/Printer.purs +++ b/src/Spago/Psa/Printer.purs @@ -75,8 +75,8 @@ citationColor Warn = Ansi.BrightYellow citationColor Err = Ansi.BrightRed citationLabel :: Citation -> String -citationLabel Warn = "WARN" -citationLabel Err = "ERR" +citationLabel Warn = "WARNING" +citationLabel Err = "ERROR" renderCitation :: Citation -> Int -> Int -> PsaAnnotedError -> D.Doc Ansi.GraphicsParam renderCitation cit total index { error, path, position, source, message } = diff --git a/test-fixtures/build/1148-warnings-diff-errors/errors/expected-stderr.txt b/test-fixtures/build/1148-warnings-diff-errors/errors/expected-stderr.txt index 01f0b4ecf..a3ffb4e6f 100644 --- a/test-fixtures/build/1148-warnings-diff-errors/errors/expected-stderr.txt +++ b/test-fixtures/build/1148-warnings-diff-errors/errors/expected-stderr.txt @@ -6,7 +6,7 @@ Downloading dependencies... Building... [1 of 2] Compiling Foo [2 of 2] Compiling Main -[ERR 1/2 TypesDoNotUnify] src/Foo.purs:4:5 +[ERROR 1/2 TypesDoNotUnify] src/Foo.purs:4:5 4 x = "nope" ^^^^^^ @@ -21,7 +21,7 @@ Building... has type Int in value declaration x -[ERR 2/2 TypesDoNotUnify] src/Main.purs:10:7 +[ERROR 2/2 TypesDoNotUnify] src/Main.purs:10:7 10 log 42 ^^ diff --git a/test-fixtures/build/1148-warnings-diff-errors/warnings/expected-stderr.txt b/test-fixtures/build/1148-warnings-diff-errors/warnings/expected-stderr.txt index a5185782d..87f4531b2 100644 --- a/test-fixtures/build/1148-warnings-diff-errors/warnings/expected-stderr.txt +++ b/test-fixtures/build/1148-warnings-diff-errors/warnings/expected-stderr.txt @@ -5,7 +5,7 @@ Reading Spago workspace configuration... Downloading dependencies... Building... [1 of 1] Compiling Main -[WARN 1/4 ImplicitImport] src/Main.purs:3:1 +[WARNING 1/4 ImplicitImport] src/Main.purs:3:1 3 import Prelude ^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ Building... Module Prelude has unspecified imports, consider using the explicit form: import Prelude (Unit, pure, unit) -[WARN 2/4 ImplicitImport] src/Main.purs:5:1 +[WARNING 2/4 ImplicitImport] src/Main.purs:5:1 5 import Effect ^^^^^^^^^^^^^ @@ -21,14 +21,14 @@ Building... Module Effect has unspecified imports, consider using the explicit form: import Effect (Effect) -[WARN 3/4 UnusedImport] src/Main.purs:6:1 +[WARNING 3/4 UnusedImport] src/Main.purs:6:1 6 import Effect.Console (log) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ The import of Effect.Console is redundant -[WARN 4/4 UnusedName] src/Main.purs:10:7 +[WARNING 4/4 UnusedName] src/Main.purs:10:7 10 let unusedVar = 1 ^^^^^^^^^^^^^ diff --git a/test/Spago/Test.purs b/test/Spago/Test.purs index 2bff0b29b..37f4ce3f3 100644 --- a/test/Spago/Test.purs +++ b/test/Spago/Test.purs @@ -60,7 +60,7 @@ spec = Spec.around withTempDir do FS.mkdirp "subpackage/test" FS.writeTextFile "subpackage/src/Main.purs" (Init.srcMainTemplate "Subpackage.Main") - -- We write a file into the current working directory. + -- We write a file into the current working directory. -- The subpackage test will read the given file without changing its directory -- and log its content as its output. let textFilePath = "foo.txt" @@ -130,8 +130,8 @@ spec = Spec.around withTempDir do let exp = case Process.platform of - Just Platform.Win32 -> "[1/1 UnusedName] test\\Test\\Main.purs:10:5" - _ -> "[1/1 UnusedName] test/Test/Main.purs:10:5" + Just Platform.Win32 -> "[WARNING 1/1 UnusedName] test\\Test\\Main.purs:10:5" + _ -> "[WARNING 1/1 UnusedName] test/Test/Main.purs:10:5" hasUnusedNameWarningError stdErr = do unless (String.contains (String.Pattern exp) stdErr) do From e35d4c7cc0a9fbc111a3823c58ba401cc6f42d21 Mon Sep 17 00:00:00 2001 From: Fyodor Soikin Date: Wed, 28 Aug 2024 23:31:05 -0400 Subject: [PATCH 6/7] Fix another test --- test/Spago/Build/Monorepo.purs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Spago/Build/Monorepo.purs b/test/Spago/Build/Monorepo.purs index 7300f0ecf..675b76b73 100644 --- a/test/Spago/Build/Monorepo.purs +++ b/test/Spago/Build/Monorepo.purs @@ -142,8 +142,8 @@ spec = Spec.describe "monorepo" do FS.copyTree { src: fixture "monorepo/strict-true-uncensored-warnings", dst: "." } let errs = - [ "[1/2 UnusedName] " <> escapePathInErrMsg [ "package-b", "src", "Main.purs:6:13" ] - , "[2/2 UnusedName] " <> escapePathInErrMsg [ "package-b", "test", "Main.purs:6:13" ] + [ "[WARNING 1/2 UnusedName] " <> escapePathInErrMsg [ "package-b", "src", "Main.purs:6:13" ] + , "[WARNING 2/2 UnusedName] " <> escapePathInErrMsg [ "package-b", "test", "Main.purs:6:13" ] ] hasUnusedWarningError = assertWarning errs true spago [ "build" ] >>= check { stdout: mempty, stderr: hasUnusedWarningError, result: isLeft } From 873e14fb64f282c2904e2184769caa5c67d560a4 Mon Sep 17 00:00:00 2001 From: Fyodor Soikin Date: Thu, 29 Aug 2024 10:52:54 -0400 Subject: [PATCH 7/7] Fix another test --- test/Prelude.purs | 8 +++++++- test/Spago/Build/Monorepo.purs | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/test/Prelude.purs b/test/Prelude.purs index eb73192d7..1ab419ae0 100644 --- a/test/Prelude.purs +++ b/test/Prelude.purs @@ -396,5 +396,11 @@ escapePathInErrMsg = case Process.platform of assertWarning :: forall m. MonadThrow Error m => Array String -> Boolean -> String -> m Unit assertWarning paths shouldHave stdErr = do when (not $ Array.all (\exp -> shouldHave == (String.contains (Pattern exp) stdErr)) paths) do - Assert.fail $ "STDERR contained one or more texts:\n" <> show paths <> "\n\nStderr was:\n" <> stdErr + Assert.fail + $ "STDERR " + <> (if shouldHave then "did not contain" else "contained") + <> " one or more texts:\n" + <> show paths + <> "\n\nStderr was:\n" + <> stdErr diff --git a/test/Spago/Build/Monorepo.purs b/test/Spago/Build/Monorepo.purs index 675b76b73..e1f9c2fab 100644 --- a/test/Spago/Build/Monorepo.purs +++ b/test/Spago/Build/Monorepo.purs @@ -142,8 +142,8 @@ spec = Spec.describe "monorepo" do FS.copyTree { src: fixture "monorepo/strict-true-uncensored-warnings", dst: "." } let errs = - [ "[WARNING 1/2 UnusedName] " <> escapePathInErrMsg [ "package-b", "src", "Main.purs:6:13" ] - , "[WARNING 2/2 UnusedName] " <> escapePathInErrMsg [ "package-b", "test", "Main.purs:6:13" ] + [ "[ERROR 1/2 UnusedName] " <> escapePathInErrMsg [ "package-b", "src", "Main.purs:6:13" ] + , "[ERROR 2/2 UnusedName] " <> escapePathInErrMsg [ "package-b", "test", "Main.purs:6:13" ] ] hasUnusedWarningError = assertWarning errs true spago [ "build" ] >>= check { stdout: mempty, stderr: hasUnusedWarningError, result: isLeft }