From 4e4efd1627a63129116df226ec92be9857acd8bd Mon Sep 17 00:00:00 2001 From: Jason Whittle Date: Mon, 8 Oct 2018 16:38:02 -0400 Subject: [PATCH 1/3] In the route syntax, allow trailing backslashes to indicate line continuation. --- yesod-core/Yesod/Routes/Parse.hs | 9 ++++++++- yesod-core/test/RouteSpec.hs | 10 ++++++++-- .../test/fixtures/routes_with_line_continuations | 11 +++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 yesod-core/test/fixtures/routes_with_line_continuations diff --git a/yesod-core/Yesod/Routes/Parse.hs b/yesod-core/Yesod/Routes/Parse.hs index e372fc0f..5b325590 100644 --- a/yesod-core/Yesod/Routes/Parse.hs +++ b/yesod-core/Yesod/Routes/Parse.hs @@ -65,7 +65,7 @@ parseRoutesNoCheck = QuasiQuoter -- invalid input. resourcesFromString :: String -> [ResourceTree String] resourcesFromString = - fst . parse 0 . filter (not . all (== ' ')) . lines . filter (/= '\r') + fst . parse 0 . filter (not . all (== ' ')) . foldr lineContinuations [] . lines . filter (/= '\r') where parse _ [] = ([], []) parse indent (thisLine:otherLines) @@ -285,3 +285,10 @@ dropBracket str@('{':x) = case break (== '}') x of _ -> error $ "Unclosed bracket ('{'): " ++ str dropBracket x = x +-- If this line ends with a backslash, concatenate it together with the next line. +lineContinuations :: String -> [String] -> [String] +lineContinuations this [] = [this] +lineContinuations this below@(next:rest) = case unsnoc this of + Just (this', '\\') -> (this'++next):rest + _ -> this:below + where unsnoc s = if null s then Nothing else Just (init s, last s) diff --git a/yesod-core/test/RouteSpec.hs b/yesod-core/test/RouteSpec.hs index c5c7be66..db8ac92d 100644 --- a/yesod-core/test/RouteSpec.hs +++ b/yesod-core/test/RouteSpec.hs @@ -17,7 +17,7 @@ import Test.HUnit ((@?=)) import Data.Text (Text, pack, unpack, singleton) import Yesod.Routes.Class hiding (Route) import qualified Yesod.Routes.Class as YRC -import Yesod.Routes.Parse (parseRoutesNoCheck, parseTypeTree, TypeTree (..)) +import Yesod.Routes.Parse (parseRoutesFile, parseRoutesNoCheck, parseTypeTree, TypeTree (..)) import Yesod.Routes.Overlap (findOverlapNames) import Yesod.Routes.TH hiding (Dispatch) import Language.Haskell.TH.Syntax @@ -219,11 +219,17 @@ main = hspec $ do it "routes to subparam" $ disp "PUT" ["subparam", "6", "q"] @?= (pack "subparam 6 q", Just $ SubparamR 6 $ ParamRoute 'q') - describe "parsing" $ do + describe "route parsing" $ do it "subsites work" $ do parseRoute ([pack "subsite", pack "foo"], [(pack "bar", pack "baz")]) @?= Just (SubsiteR $ MySubRoute ([pack "foo"], [(pack "bar", pack "baz")])) + describe "routing table parsing" $ do + it "recognizes trailing backslashes as line continuation directives" $ do + let routes :: [ResourceTree String] + routes = $(parseRoutesFile "test/fixtures/routes_with_line_continuations") + length routes @?= 3 + describe "overlap checking" $ do it "catches overlapping statics" $ do let routes :: [ResourceTree String] diff --git a/yesod-core/test/fixtures/routes_with_line_continuations b/yesod-core/test/fixtures/routes_with_line_continuations new file mode 100644 index 00000000..9f035ff5 --- /dev/null +++ b/yesod-core/test/fixtures/routes_with_line_continuations @@ -0,0 +1,11 @@ +-- This fixture to test line continuations is in a separate file +-- because when I put it in an in-line quasi-quotation, the compiler +-- performed the line continuations processing itself. + +/foo1 \ + Foo1 +/foo2 Foo2 +/foo3 \ + Foo3 \ + GET POST \ + !foo From ca602d11bfc140800b5c4ef0c7c2305486fef8a8 Mon Sep 17 00:00:00 2001 From: Jason Whittle Date: Mon, 8 Oct 2018 16:53:14 -0400 Subject: [PATCH 2/3] Bump minor version. --- yesod-core/Yesod/Routes/Parse.hs | 4 +++- yesod-core/yesod-core.cabal | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/yesod-core/Yesod/Routes/Parse.hs b/yesod-core/Yesod/Routes/Parse.hs index 5b325590..dcc9e501 100644 --- a/yesod-core/Yesod/Routes/Parse.hs +++ b/yesod-core/Yesod/Routes/Parse.hs @@ -285,7 +285,9 @@ dropBracket str@('{':x) = case break (== '}') x of _ -> error $ "Unclosed bracket ('{'): " ++ str dropBracket x = x --- If this line ends with a backslash, concatenate it together with the next line. +-- | If this line ends with a backslash, concatenate it together with the next line. +-- +-- @since 1.6.8 lineContinuations :: String -> [String] -> [String] lineContinuations this [] = [this] lineContinuations this below@(next:rest) = case unsnoc this of diff --git a/yesod-core/yesod-core.cabal b/yesod-core/yesod-core.cabal index 83eb5f7a..95cbe114 100644 --- a/yesod-core/yesod-core.cabal +++ b/yesod-core/yesod-core.cabal @@ -1,5 +1,5 @@ name: yesod-core -version: 1.6.7 +version: 1.6.8 license: MIT license-file: LICENSE author: Michael Snoyman From ee260e24cbb90047607951c0b0c9bdd128013963 Mon Sep 17 00:00:00 2001 From: Jason Whittle Date: Mon, 8 Oct 2018 18:04:10 -0400 Subject: [PATCH 3/3] Update changelog with a link to PR #1558. --- yesod-core/ChangeLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/yesod-core/ChangeLog.md b/yesod-core/ChangeLog.md index 4788b2ec..67f9cf9c 100644 --- a/yesod-core/ChangeLog.md +++ b/yesod-core/ChangeLog.md @@ -1,5 +1,9 @@ # ChangeLog for yesod-core +## 1.6.8 +* In the route syntax, allow trailing backslashes to indicate line + continuation. [#1558](https://github.com/yesodweb/yesod/pull/1558) + ## 1.6.7 * If no matches are found, `selectRep` chooses first representation regardless