From fbfb5483a78ae2c5dbee1f0d3654a2a3735d4b99 Mon Sep 17 00:00:00 2001 From: Fabrizio Ferrai Date: Tue, 17 Sep 2024 03:03:37 +0400 Subject: [PATCH] Fix detection of some flags passed to purs (#1286) --- src/Spago/Cmd.purs | 40 ++++++++++++++++++------------- test-fixtures/json-errors-err.txt | 11 +++++++++ test/Spago/Build.purs | 10 +++++--- test/Spago/Unit/FindFlags.purs | 28 ++++++++++++---------- 4 files changed, 57 insertions(+), 32 deletions(-) create mode 100644 test-fixtures/json-errors-err.txt diff --git a/src/Spago/Cmd.purs b/src/Spago/Cmd.purs index 0479ad9c5..c7ce8a7be 100644 --- a/src/Spago/Cmd.purs +++ b/src/Spago/Cmd.purs @@ -130,7 +130,9 @@ getStderr = either _.stderr _.stderr -- | For example, trying to find the `output` arg -- | we would run -- | `findFlags { flags: [ "-o", "--output" ], args }` --- | where `args` is one of the 5 variants below: +-- | where `args` is one of the 6 variants below: +-- | - args are just one element: +-- | - `[ "--output"]` -- | - args are two separate array elements: -- | - `[ "-o", "dir"]` -- | - `[ "--output", "dir"]` @@ -139,27 +141,31 @@ getStderr = either _.stderr _.stderr -- | - `[ "--output dir"]` -- | - `[ "--output=dir"]` findFlag :: { flags :: Array String, args :: Array String } -> Maybe String -findFlag { flags, args } = if len == 0 then Nothing else go 0 +findFlag { flags, args } = if argsLen == 0 then Nothing else go 0 where - len = Array.length args - lastIdx = len - 1 - go idx = do - let arg = unsafePartial $ Array.unsafeIndex args idx - case Array.findMap (\flag -> stripFlag flag arg) flags of - Just (Tuple isOneCharFlag restOfArg) - | restOfArg == "" -> do - Array.index args $ idx + 1 - | otherwise -> - dropExtra isOneCharFlag restOfArg - Nothing - | idx < lastIdx -> - go $ idx + 1 - | otherwise -> - Nothing + argsLen = Array.length args + lastArgIdx = argsLen - 1 + go idx = do + let currentArg = unsafePartial $ Array.unsafeIndex args idx + case Array.findMap (\flag -> stripFlag flag currentArg) flags of + Just (Tuple isOneCharFlag restOfArg) -> case restOfArg of + -- If the flag is the entirety of the arg, we need to look at the next arg: + "" -> case Array.index args (idx + 1) of + -- If there's a next arg we return it + Just next -> Just next + -- If there's not then this was a boolean flag + Nothing -> Just "" + _ -> dropExtra isOneCharFlag restOfArg + Nothing -> case idx < lastArgIdx of + true -> go (idx + 1) + false -> Nothing + + stripFlag :: String -> String -> Maybe (Tuple Boolean String) stripFlag flag arg = Tuple (isSingleCharFlag flag) <$> String.stripPrefix (Pattern flag) arg + dropExtra :: Boolean -> String -> Maybe String dropExtra isOneCharFlag restOfArg = if isOneCharFlag then dropSpace restOfArg else dropSpace restOfArg <|> dropEquals restOfArg diff --git a/test-fixtures/json-errors-err.txt b/test-fixtures/json-errors-err.txt new file mode 100644 index 000000000..d7fb0085f --- /dev/null +++ b/test-fixtures/json-errors-err.txt @@ -0,0 +1,11 @@ +Reading Spago workspace configuration... + +✓ Selecting package to build: aaa + +Downloading dependencies... +No lockfile found, generating it... +Lockfile written to spago.lock. Please commit this file. +Building... + +✘ Can't pass `--json-errors` option directly to purs. +Use the --json-errors flag for Spago. diff --git a/test/Spago/Build.purs b/test/Spago/Build.purs index 8a5f2df4e..e377b0d6c 100644 --- a/test/Spago/Build.purs +++ b/test/Spago/Build.purs @@ -34,7 +34,11 @@ spec = Spec.around withTempDir do Spec.it "passes options to purs" \{ spago } -> do spago [ "init" ] >>= shouldBeSuccess - spago [ "build", "--purs-args", "--verbose-errors", "--purs-args", "--json-errors" ] >>= shouldBeSuccess + spago [ "build", "--purs-args", "--verbose-errors", "--purs-args", "--comments" ] >>= shouldBeSuccess + + Spec.it "can't pass the --json-errors flag to purs" \{ spago, fixture } -> do + spago [ "init", "--name", "aaa" ] >>= shouldBeSuccess + spago [ "build", "--purs-args", "--json-errors" ] >>= shouldBeFailureErr (fixture "json-errors-err.txt") Spec.it "can use a different output folder" \{ spago } -> do spago [ "init" ] >>= shouldBeSuccess @@ -224,8 +228,8 @@ spec = Spec.around withTempDir do , result , sanitize: String.trim - >>> String.replaceAll (String.Pattern $ "src\\") (String.Replacement "src/") - >>> String.replaceAll (String.Pattern $ "\r\n") (String.Replacement "\n") + >>> 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: "." } diff --git a/test/Spago/Unit/FindFlags.purs b/test/Spago/Unit/FindFlags.purs index af251c2e5..08f1c96c0 100644 --- a/test/Spago/Unit/FindFlags.purs +++ b/test/Spago/Unit/FindFlags.purs @@ -2,32 +2,36 @@ module Test.Spago.Unit.FindFlags where import Prelude -import Data.Maybe (fromMaybe) +import Data.Maybe (Maybe(..)) import Spago.Cmd as Cmd -import Test.Spec as Spec import Test.Spec (Spec) +import Test.Spec as Spec import Test.Spec.Assertions as Assertions spec :: Spec Unit spec = do Spec.describe "findFlags" $ do Spec.it "[\"-o\", \"something\"]" $ do - let a = fromMaybe "" $ Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "-o", "something" ] } - let b = "something" + let a = Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "-o", "something" ] } + let b = Just "something" a `Assertions.shouldEqual` b Spec.it "[\"--output\", \"something\"]" $ do - let a = fromMaybe "" $ Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "--output", "something" ] } - let b = "something" + let a = Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "--output", "something" ] } + let b = Just "something" a `Assertions.shouldEqual` b Spec.it "[\"-o something\"]" $ do - let a = fromMaybe "" $ Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "-o something" ] } - let b = "something" + let a = Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "-o something" ] } + let b = Just "something" a `Assertions.shouldEqual` b Spec.it "[\"--output something\"]" $ do - let a = fromMaybe "" $ Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "--output something" ] } - let b = "something" + let a = Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "--output something" ] } + let b = Just "something" a `Assertions.shouldEqual` b Spec.it "[\"--output=something\"]" $ do - let a = fromMaybe "" $ Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "--output=something" ] } - let b = "something" + let a = Cmd.findFlag { flags: [ "-o", "--output" ], args: [ "--output=something" ] } + let b = Just "something" + a `Assertions.shouldEqual` b + Spec.it "[ '--verbose-errors', '--json-errors' ]" do + let a = Cmd.findFlag { flags: [ "--json-errors" ], args: [ "--verbose-errors", "--json-errors" ] } + let b = Just "" a `Assertions.shouldEqual` b