Skip to content

Commit

Permalink
Fix detection of some flags passed to purs (#1286)
Browse files Browse the repository at this point in the history
  • Loading branch information
f-f committed Sep 16, 2024
1 parent b7c0483 commit fbfb548
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 32 deletions.
40 changes: 23 additions & 17 deletions src/Spago/Cmd.purs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]`
Expand All @@ -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
Expand Down
11 changes: 11 additions & 0 deletions test-fixtures/json-errors-err.txt
Original file line number Diff line number Diff line change
@@ -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.
10 changes: 7 additions & 3 deletions test/Spago/Build.purs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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: "." }
Expand Down
28 changes: 16 additions & 12 deletions test/Spago/Unit/FindFlags.purs
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit fbfb548

Please sign in to comment.