packages feed

implicit-hie 0.1.3.0 → 0.1.4.0

raw patch · 6 files changed

+352/−122 lines, 6 filesdep −Cabal-syntaxdep −bytestringPVP ok

version bump matches the API change (PVP)

Dependencies removed: Cabal-syntax, bytestring

API changes (from Hackage documentation)

+ Hie.Cabal.Parser: (<//>) :: Text -> Text -> Text
+ Hie.Cabal.Parser: comment :: Parser ()
+ Hie.Cabal.Parser: componentHeader :: Indent -> Text -> Parser Name
+ Hie.Cabal.Parser: emptyOrComLine :: Parser ()
+ Hie.Cabal.Parser: extractPath :: Indent -> [Path] -> Parser [Path]
+ Hie.Cabal.Parser: field :: Indent -> Text -> (Indent -> Parser a) -> Parser a
+ Hie.Cabal.Parser: hsSourceDir :: Indent -> Parser [Text]
+ Hie.Cabal.Parser: indent :: Indent -> Parser Int
+ Hie.Cabal.Parser: infixr 5 <//>
+ Hie.Cabal.Parser: parseBench :: Indent -> Parser [Component]
+ Hie.Cabal.Parser: parseComponent :: Indent -> Parser [Component]
+ Hie.Cabal.Parser: parseExe :: Indent -> Parser [Component]
+ Hie.Cabal.Parser: parseLib :: Indent -> Parser [Component]
+ Hie.Cabal.Parser: parseList :: Indent -> Parser [Text]
+ Hie.Cabal.Parser: parsePackage :: Parser Package
+ Hie.Cabal.Parser: parseQuoted :: Parser Text
+ Hie.Cabal.Parser: parseSec :: Indent -> Text -> (Name -> Path -> Component) -> Parser [Component]
+ Hie.Cabal.Parser: parseSecMain :: (Name -> Path -> Component) -> Text -> Indent -> Parser [Component]
+ Hie.Cabal.Parser: parseString :: Parser Name
+ Hie.Cabal.Parser: parseTestSuite :: Indent -> Parser [Component]
+ Hie.Cabal.Parser: pathMain :: Indent -> [Text] -> Text -> [Text] -> [Text] -> Parser [Text]
+ Hie.Cabal.Parser: skipBlock :: Indent -> Parser ()
+ Hie.Cabal.Parser: skipBlockLine :: Indent -> Parser ()
+ Hie.Cabal.Parser: skipFreeformField :: Parser ()
+ Hie.Cabal.Parser: skipToNextLine :: Parser ()
+ Hie.Cabal.Parser: tabOrSpace :: Parser Char
+ Hie.Cabal.Parser: type Indent = Int
+ Hie.Cabal.Parser: type Path = Text
+ Hie.Cabal.Parser: unqualName :: Parser Text

Files

implicit-hie.cabal view
@@ -7,7 +7,7 @@ -- hash: b2b829a658e33ea328c725dea732391089d03ffd2a216d413a75d88aefa7c181  name:               implicit-hie-version:            0.1.3.0+version:            0.1.4.0 description:   Auto generate a stack or cabal multi component hie.yaml file @@ -46,16 +46,15 @@   hs-source-dirs:   src   ghc-options:     -Wall -Wincomplete-record-updates -Wincomplete-uni-patterns+    -fno-warn-unused-imports -fno-warn-unused-binds     -fno-warn-name-shadowing -fwarn-redundant-constraints    build-depends:       attoparsec    >=0.13     , base          >=4.7  && <5-    , bytestring     , directory     >=1.3     , filepath      >=1.4     , filepattern   >=0.1-    , Cabal-syntax  >=3.8     , text          >=1.2     , transformers  >=0.5     , yaml          >=0.5@@ -89,7 +88,7 @@     , yaml    default-language: Haskell2010-+     if !flag(executable)     buildable: False 
src/Hie/Cabal/Parser.hs view
@@ -1,51 +1,17 @@+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards   #-} -module Hie.Cabal.Parser-( Package(..)-, Component(..)-, CompType(..)-, Name-, extractPkgs-, parsePackage'-) where--import           Control.Applicative-import           Control.Monad-import           Data.Attoparsec.Text-import           Data.Char-import           Data.Foldable                                 (asum)-import           Data.Maybe                                    (catMaybes,-                                                                maybeToList)-import           Data.Text                                     (Text)-import qualified Data.Text                                     as T-import           Data.Text.Encoding                            (encodeUtf8)-import           Distribution.ModuleName                       (ModuleName,-                                                                toFilePath)-import           Distribution.Package                          (pkgName,-                                                                unPackageName)-import           Distribution.PackageDescription               (Benchmark (benchmarkBuildInfo, benchmarkInterface, benchmarkName),-                                                                BenchmarkInterface (BenchmarkExeV10),-                                                                Executable (buildInfo, exeName, modulePath),-                                                                ForeignLib (foreignLibBuildInfo, foreignLibName),-                                                                Library (libBuildInfo, libName),-                                                                LibraryName (..),-                                                                TestSuiteInterface (TestSuiteExeV10),-                                                                benchmarkModules,-                                                                exeModules,-                                                                explicitLibModules,-                                                                foreignLibModules)-import           Distribution.PackageDescription.Configuration-import           Distribution.PackageDescription.Parsec-import           Distribution.Types.BuildInfo-import           Distribution.Types.PackageDescription-import           Distribution.Types.TestSuite-import           Distribution.Types.UnqualComponentName-import           Distribution.Utils.Path                       (getSymbolicPath)-import           GHC.IO                                        (unsafePerformIO)-import           System.Directory                              (doesFileExist)-import           System.FilePath                               ((<.>), (</>))+module Hie.Cabal.Parser where +import Control.Applicative+import Control.Monad+import Data.Attoparsec.Text+import Data.Char+import Data.Functor+import Data.Maybe+import Data.Text (Text)+import qualified Data.Text as T+import System.FilePath.Posix ((</>))  type Name = Text @@ -63,6 +29,83 @@   = Comp CompType Name Path   deriving (Show, Eq, Ord) +parsePackage' :: Text -> Either String Package+parsePackage' = parseOnly parsePackage++-- Skip over entire fields that are known to be free-form.  Ensures lines that+-- look like the beginning of sections/stanzas are not inadvertently intepreted+-- as such.+-- List gathered by searching "free text field" in:+-- https://cabal.readthedocs.io/en/3.4/buildinfo-fields-reference.html+-- May be subject to change across Cabal versions.+skipFreeformField :: Parser ()+skipFreeformField =+  choice $+    flip (field 0) skipBlock+      <$> [ "author",+            "bug-reports",+            "category",+            "copyright",+            "description",+            "homepage",+            "maintainer",+            "package-url",+            "stability",+            "synopsis"+          ]++parsePackage :: Parser Package+parsePackage =+  ( do+      n <- field 0 "name" $ const parseString+      (Package _ t) <- parsePackage+      pure $ Package n t+  )+    <|> (skipFreeformField >> parsePackage)+    <|> ( do+            h <- parseComponent 0+            (Package n t) <- parsePackage+            pure $ Package n (h <> t)+        )+    <|> (skipToNextLine >> parsePackage)+    <|> pure (Package "" [])++componentHeader :: Indent -> Text -> Parser Name+componentHeader i t = do+  _ <- indent i+  _ <- asciiCI t+  skipMany tabOrSpace+  n <- parseString <|> pure ""+  skipToNextLine+  pure n++parseComponent :: Indent -> Parser [Component]+parseComponent i =+  parseExe i+    <|> parseLib i+    <|> parseBench i+    <|> parseTestSuite i++parseLib :: Indent -> Parser [Component]+parseLib i =+  (parseSec i "library" $ Comp Lib)+    <|> (parseSec i "foreign-library" $ Comp Lib)++parseTestSuite :: Indent -> Parser [Component]+parseTestSuite i = parseSec i "test-suite" $ Comp Test++parseExe :: Indent -> Parser [Component]+parseExe = parseSecMain (Comp Exe) "executable"++parseBench :: Indent -> Parser [Component]+parseBench = parseSecMain (Comp Bench) "benchmark"++parseSecMain :: (Name -> Path -> Component) -> Text -> Indent -> Parser [Component]+parseSecMain c s i = do+  n <- componentHeader i s+  p <- pathMain (i + 1) ["./"] "" [] []+  pure $ map (c n) p+ parseQuoted :: Parser Text parseQuoted = do   q <- char '"' <|> char '\''@@ -99,28 +142,65 @@       skipMany com       pure x +pathMain :: Indent -> [Text] -> Text -> [Text] -> [Text] -> Parser [Text]+pathMain i p m o a =+  (hsSourceDir i >>= (\p' -> pathMain i p' m o a))+    <|> (field i "main-is" (const parseString) >>= (\m' -> pathMain i p m' o a))+    <|> (field i "other-modules" parseList >>= flip (pathMain i p m) a)+    <|> (field i "autogen-modules" parseList >>= pathMain i p m o)+    <|> (skipBlockLine i >> pathMain i p m o a)+    <|> pure+      ( map (<//> m) p+          <> [ p' <//> (o'' <> ".hs")+               | p' <- p,+                 o' <- filter (`notElem` a) o,+                 let o'' = T.replace "." "/" o'+             ]+      )++(<//>) :: Text -> Text -> Text+a <//> b = T.pack (T.unpack a </> T.unpack b)++infixr 5 <//>++parseSec :: Indent -> Text -> (Name -> Path -> Component) -> Parser [Component]+parseSec i compType compCon = do+  n <- componentHeader i compType+  p <- extractPath (i + 1) []+  let p' = if null p then ["./"] else p+  pure $ map (compCon n) p'+ skipToNextLine :: Parser () skipToNextLine = skipWhile (not . isEndOfLine) >> endOfLine +skipBlock :: Indent -> Parser ()+skipBlock i = skipMany $ skipBlockLine i+ comment :: Parser () comment = skipMany tabOrSpace >> "--" >> skipToNextLine +skipBlockLine :: Indent -> Parser ()+skipBlockLine i = (indent i >> skipToNextLine) <|> emptyOrComLine+ emptyOrComLine :: Parser () emptyOrComLine = (skipMany tabOrSpace >> endOfLine) <|> comment  tabOrSpace :: Parser Char tabOrSpace = char ' ' <|> char '\t' +hsSourceDir :: Indent -> Parser [Text]+hsSourceDir i = field i "hs-source-dirs" parseList+ -- field :: Indent -> Text -> Parser Text field ::   Indent ->-  [Text] ->+  Text ->   (Indent -> Parser a) ->   Parser a field i f p =   do     i' <- indent i-    _ <- asum $ map asciiCI f+    _ <- asciiCI f     skipMany tabOrSpace     _ <- char ':'     skipMany tabOrSpace@@ -128,6 +208,13 @@     skipToNextLine     pure p' +extractPath :: Indent -> [Path] -> Parser [Path]+extractPath i ps =+  (field i "hs-source-dirs" parseList >>= (\p -> extractPath i $ ps <> p))+    <|> (skipBlockLine i >> extractPath i ps)+    <|> (comment >> extractPath i ps)+    <|> pure ps+ -- | Skip at least n spaces indent :: Indent -> Parser Int indent i = do@@ -135,52 +222,4 @@   if c >= i then pure c else fail "insufficient indent"  extractPkgs :: Parser [T.Text]-extractPkgs = join . catMaybes <$> many' (Just <$> field 0 ["packages"] parseList <|> (skipToNextLine >> pure Nothing))--parsePackage' :: T.Text -> Either String Package-parsePackage' t = do-  let bytes = encodeUtf8 t-  case runParseResult (parseGenericPackageDescription bytes) of-    (_warnings, Left err) ->-        error $ "Cannot parse Cabal file: " <> show err-    (_warnings, Right res) -> do-      let pkg = flattenPackageDescription res-      Right $ extractPackage pkg--extractPackage :: PackageDescription -> Package-extractPackage PackageDescription{..} = Package n cc where-  n = T.pack . unPackageName $ pkgName package--  cc = concat $-    [mkComp Test (unqName $ testName t) (testBuildInfo t) (testExePath t) (testModules t) | t <- testSuites] ++-    [mkComp Bench (unqName $ benchmarkName b) (benchmarkBuildInfo b) (benchmarkExePath b) (benchmarkModules b) | b <- benchmarks] ++-    [mkComp Exe (unqName $ exeName e) (buildInfo e) [modulePath e] (exeModules e) | e <- executables] ++-    [mkComp Lib (libName' l) (libBuildInfo l) [] (explicitLibModules l) | l <- maybeToList library ++ subLibraries ] ++-    [mkComp Lib (unqName $ foreignLibName f) (foreignLibBuildInfo f) [] (foreignLibModules f) | f <- foreignLibs]--  mkComp :: CompType -> T.Text -> BuildInfo -> [FilePath] -> [ModuleName] -> [Component]-  mkComp typ name bi fps mods =-    [Comp typ name (T.pack fp)-    | fp0 <- fps <> concatMap toFilePath' mods-    , srcDir <- map getSymbolicPath $ hsSourceDirs bi-    , let fp = srcDir </> fp0-    , unsafePerformIO $ doesFileExist fp-    ]--  unqName = T.pack . unUnqualComponentName-  libName' x = case libName x of-    LMainLibName  -> ""-    LSubLibName u -> unqName u--benchmarkExePath :: Benchmark -> [FilePath]-benchmarkExePath b = case benchmarkInterface b of-  BenchmarkExeV10 _ f -> [f]-  _                   -> []--toFilePath' :: ModuleName -> [FilePath]-toFilePath' mod = [ toFilePath mod <.> ext | ext <- ["hs", "lhs"]]--testExePath :: TestSuite -> [FilePath]-testExePath t = case testInterface t of-    TestSuiteExeV10 _ fp -> [fp]-    _                    -> []+extractPkgs = join . catMaybes <$> many' (Just <$> field 0 "packages" parseList <|> (skipToNextLine >> pure Nothing))
test/Spec.hs view
@@ -14,31 +14,212 @@ spec :: Spec spec = do   describe "Should Succeed" $+    it "successfully parses executable section" $+      exeSection ~> parseExe 0+        `shouldParse` [Comp Exe "gen-hie" "app/Main.hs"]+  describe "Should Succeed" $+    it "successfully parses test section" $+      testSection ~> parseTestSuite 0+        `shouldParse` [Comp Test "implicit-hie-test" "test"]+  describe "Should Succeed" $+    it "successfully parses library section" $+      libSection ~> parseLib 0+        `shouldParse` [Comp Lib "" "src"]+  describe "Should Succeed" $+    it "successfully parses library section with 2 hs-source-dirs" $+      libSection2 ~> parseLib 0+        `shouldParse` [Comp Lib "" "src", Comp Lib "" "src2"]+  describe "Should Succeed" $+    it "successfully parses library section with 2 paths under hs-source-dirs" $+      libSection3 ~> parseLib 0+        `shouldParse` [Comp Lib "" "src", Comp Lib "" "src2"]+  describe "Should Succeed" $+    it "successfully parses bench section" $+      do+        bs <- T.readFile "test/benchSection"+        bs ~> parseBench 0+          `shouldParse` [Comp Bench "folds" "benchmarks/folds.hs"]+  describe "Should Succeed" $     it "successfully parses package" $       do         cf <- T.readFile "implicit-hie.cabal"-        parsePackage' cf+        cf ~> parsePackage           `shouldParse` Package             "implicit-hie"-            [ Comp Test "implicit-hie-test" "test/Spec.hs",+            [ Comp Lib "" "src",               Comp Exe "gen-hie" "app/Main.hs",-              Comp Lib "" "src/Hie/Cabal/Parser.hs",-              Comp Lib "" "src/Hie/Locate.hs",-              Comp Lib "" "src/Hie/Yaml.hs"+              Comp Test "implicit-hie-test" "test"             ]-   describe "Should Succeed" $+    it+      "skips to end of block section"+      $ let r = "test\n"+         in (libSection <> r) ~?> parseLib 0+              `leavesUnconsumed` r+  describe "Should Succeed" $     it "successfully generates stack hie.yaml" $       do         sf <- readFile "test/stackHie.yaml"         cf <- T.readFile "implicit-hie.cabal"-        (hieYaml "stack" . fmtPkgs "stack" . (: []) <$> parsePackage' cf)+        (hieYaml "stack" . fmtPkgs "stack" . (: []) <$> parseOnly parsePackage cf)           `shouldBe` Right sf-   describe "Should Succeed" $     it "successfully generates cabal hie.yaml for haskell-language-server" $       do         f <- T.readFile "test/haskell-language-server-cabal"         o <- readFile "test/hie.yaml.cbl"-        (hieYaml "cabal" . fmtPkgs "cabal" . (: []) <$> parsePackage' f)+        (hieYaml "cabal" . fmtPkgs "cabal" . (: []) <$> parseOnly parsePackage f)           `shouldBe` Right o+  describe "Should Succeed" $+    it "successfully parses comma list" $+      ("one, two" :: Text) ~> parseList 1 `shouldParse` ["one", "two"]+  describe "Should Succeed" $+    it "successfully parses newline list" $+      ("one\n two \n three3" :: Text) ~> parseList 1+        `shouldParse` ["one", "two", "three3"]+  describe "Should Succeed" $+    it "successfully parses newline comma list" $+      ("one\n two,  three3" :: Text) ~> parseList 1+        `shouldParse` ["one", "two", "three3"]+  describe "Should Succeed" $+    it "quoted list" $+      ("\"one\"\n two\n three3" :: Text) ~> parseList 1+        `shouldParse` ["one", "two", "three3"]+  describe "Should Succeed" $+    it "list with leading commas" $+      ("one\n , two\n , three3" :: Text) ~> parseList 1+        `shouldParse` ["one", "two", "three3"]+  describe "Should Succeed" $+    it "list with a comment" $+      ("foo\n  -- need to include this too\n  bar\n" :: Text) ~> parseList 1+        `shouldParse` ["foo", "bar"]+  describe "Should Succeed" $+    it "list2 with a comment" $+      ("foo  -- need to include this too\n  bar\n" :: Text) ~> parseList 1+        `shouldParse` ["foo", "bar"]+  describe "Should Succeed" $+    it "list3 with a comment" $+      ("foo  -- need to include this too\n  bar" :: Text) ~> parseList 1+        `shouldParse` ["foo", "bar"]+  describe "Should Succeed" $+    it "list4 with a comment" $+      ("foo\n bar\n  -- need to include this too" :: Text) ~> parseList 1+        `shouldParse` ["foo", "bar"]+  describe "Should Succeed" $+    it "list5 with a comment" $+      ("foo\n bar -- need to include this too" :: Text) ~> parseList 1+        `shouldParse` ["foo", "bar"]+  describe "Should Succeed" $+    it "succesfully parses exe component with other-modules containing dots" $+      exeSection2 ~> parseExe 0+        `shouldParse` [ Comp Exe "gen-hie" "app/Main.hs",+                        Comp Exe "gen-hie" "app/Hie/Executable/Helper.hs",+                        Comp Exe "gen-hie" "app/Hie/Executable/Utils.hs"+                      ]+  describe "Should Succeed" $+    it "succesfully parses single other-modules" $+      ("other-modules: test\ndefault-language:   Haskell2011" :: Text) ~?> field 0 "other-modules" parseList+        `leavesUnconsumed` "default-language:   Haskell2011"+  describe "Should Succeed" $+    it "succesfully parses empty other-modules1" $+      ("other-modules: test\ndefault-language:   Haskell2011" :: Text) ~?> field 0 "other-modules" parseList+        `leavesUnconsumed` "default-language:   Haskell2011"+  describe "Should Succeed" $+    it "succesfully parses empty other-modules2" $+      ("    other-modules: \n    build-depends:\n        base >=4.9 && <5" :: Text) ~> field 0 "other-modules" parseList+        `shouldParse` []++exeSection :: Text+exeSection =+  "executable gen-hie\n\+  \  other-modules:\n\+  \    Paths_implicit_hie\n\+  \  autogen-modules:\n\+  \    Paths_implicit_hie\n\+  \  hs-source-dirs:\n\+  \      app\n\+  \  ghc-options: -O2\n\+  \  main-is: Main.hs \n"++testSection :: Text+testSection =+  "test-suite implicit-hie-test\n\+  \  type: exitcode-stdio-1.0\n\+  \  other-modules:\n\+  \      Paths_implicit_hie\n\+  \  hs-source-dirs:\n\+  \      test\n\+  \  ghc-options: -fspecialize-aggressively -Wall -Wincomplete-record-updates -Wincomplete-uni-patterns -fno-warn-unused-imports -fno-warn-unused-binds -fno-warn-name-shadowing -fwarn-redundant-constraints -threaded -rtsopts -with-rtsopts=-N\n\+  \  main-is: Spec.hs\n\+  \  build-depends:\n\+  \      attoparsec\n\+  \    , base >=4.7 && <5\n\+  \    , hspec\n\+  \    , hspec-attoparsec\n\+  \    , implicit-hie\n\+  \    , text\n\+  \  default-language: Haskell2010\n"++libSection :: Text+libSection =+  "library\n\+  \  exposed-modules:\n\+  \  Lib\n\+  \  other-modules:\n\+  \    Paths_implicit_hie\n\+  \  hs-source-dirs:\n\+  \    src\n\+  \  ghc-options: -fspecialize-aggressively -Wall -Wincomplete-record-updates -Wincomplete-uni-patterns -fno-warn-unused-imports -fno-warn-unused-binds -fno-warn-name-shadowing -fwarn-redundant-constraints\n\+  \  build-depends:\n\+  \    attoparsec\n\+  \  , base >=4.7 && <5\n\+  \  , text\n\+  \  default-language: Haskell2010\n\+  \"++libSection2 :: Text+libSection2 =+  "library\n\+  \  exposed-modules:\n\+  \  Lib\n\+  \  other-modules:\n\+  \  Paths_implicit_hie\n\+  \  hs-source-dirs:\n\+  \    src\n\+  \  hs-source-dirs:\n\+  \   src2\n\+  \  ghc-options: -fspecialize-aggressively -Wall -Wincomplete-record-updates -Wincomplete-uni-patterns -fno-warn-unused-imports -fno-warn-unused-binds -fno-warn-name-shadowing -fwarn-redundant-constraints\n\+  \  build-depends:\n\+  \  attoparsec\n\+  \  , base >=4.7 && <5\n\+  \  , text\n\+  \  default-language: Haskell2010\n\+  \"++libSection3 :: Text+libSection3 =+  "library\n\+  \  exposed-modules:\n\+  \  Lib\n\+  \  other-modules:\n\+  \  Paths_implicit_hie\n\+  \  hs-source-dirs:\n\+  \   src,\n\+  \   src2\n\+  \  ghc-options: -fspecialize-aggressively -Wall -Wincomplete-record-updates -Wincomplete-uni-patterns -fno-warn-unused-imports -fno-warn-unused-binds -fno-warn-name-shadowing -fwarn-redundant-constraints\n\+  \  build-depends:\n\+  \  attoparsec\n\+  \  , base >=4.7 && <5\n\+  \  , text\n\+  \  default-language: Haskell2010\n\+  \"++exeSection2 :: Text+exeSection2 =+  "executable gen-hie\n\+  \  other-modules:\n\+  \    Hie.Executable.Helper\n\+  \    Hie.Executable.Utils\n\+  \  hs-source-dirs:\n\+  \      app\n\+  \  main-is: Main.hs \n"
test/benchSection view
@@ -1,6 +1,3 @@-name:               folds-test-version:            0.1- benchmark folds   default-language: Haskell2010   hs-source-dirs:   benchmarks
test/hie.yaml.cbl view
@@ -1,2 +1,22 @@ cradle:   cabal:+    - path: "src"+      component: "lib:haskell-language-server"++    - path: "exe/Main.hs"+      component: "haskell-language-server:exe:haskell-language-server"++    - path: "exe/Arguments.hs"+      component: "haskell-language-server:exe:haskell-language-server"++    - path: "exe/Wrapper.hs"+      component: "haskell-language-server:exe:haskell-language-server-wrapper"++    - path: "exe/Arguments.hs"+      component: "haskell-language-server:exe:haskell-language-server-wrapper"++    - path: "test/functional"+      component: "haskell-language-server:test:func-test"++    - path: "test/utils"+      component: "haskell-language-server:lib:hls-test-utils"
test/stackHie.yaml view
@@ -1,16 +1,10 @@ cradle:   stack:-    - path: "test/Spec.hs"-      component: "implicit-hie:test:implicit-hie-test"+    - path: "src"+      component: "implicit-hie:lib"      - path: "app/Main.hs"       component: "implicit-hie:exe:gen-hie" -    - path: "src/Hie/Cabal/Parser.hs"-      component: "implicit-hie:lib"--    - path: "src/Hie/Locate.hs"-      component: "implicit-hie:lib"--    - path: "src/Hie/Yaml.hs"-      component: "implicit-hie:lib"+    - path: "test"+      component: "implicit-hie:test:implicit-hie-test"