如何传递获取某个项目所依赖的库列表?
How to transitive get a list of libraries on which a certain project depends?
我主要对基于 stack 构建的项目感兴趣。
我设法通过编写一个分析命令输出的脚本解决了这个问题,例如 ghc-pkg field SOMEPKG hs-libraries
等
但是这种方法比较慢,主要是因为使用stack命令从项目中提取信息。
是否有另一种方法可以在不使用大量工具的情况下解决这个问题?
编辑
这是脚本草稿。
main = do
pkgSet <- newIORef . asHashSet $ mempty
libSet <- newIORef . asHashSet $ mempty
let proc ghcId pkgId = do
guard =<< (liftIO . map (pkgId `notMember`) . readIORef $ pkgSet)
liftIO . modifyIORef pkgSet $ insertSet pkgId
libDir1 <- lineToText <$> inproc "ghc-pkg"
["--simple-output", "field", pkgId, "dynamic-library-dirs"]
(pure "")
libDir2 <- lineToText <$> inproc "ghc-pkg"
["--simple-output", "field", pkgId, "library-dirs"] (pure "")
libDir <- select . filter (not . null) $ [libDir1, libDir2]
lib <- select =<< (map (words . lineToText) $ inproc "ghc-pkg"
["--simple-output", "field", pkgId, "hs-libraries"] (pure ""))
let libPath = asText . repack $ repack libDir
</> (shlibPrefix ++ repack lib ++ "-" ++ repack ghcId)
<.> shlibSuffix
guard =<< (liftIO . map (libPath `notMember`) . readIORef $ libSet)
guard =<< (liftIO . doesFileExist . repack $ libPath)
liftIO . modifyIORef libSet $ insertSet libPath
dep <- select =<< (map (words . lineToText) $ inproc "ghc-pkg"
["--simple-output", "field", pkgId, "depends"] (pure ""))
proc ghcId dep
sh $ do
ghcPkgPath <- lineToText <$> inshell "stack path --ghc-package-path" (pure "")
export "GHC_PACKAGE_PATH" ghcPkgPath
ghcVer <- lineToText <$> inshell "stack exec -- ghc --numeric-version" (pure "")
let ghcId = "ghc" ++ ghcVer
[pkg, ver] <- words . lineToText <$> inshell "stack list-dependencies" (pure "")
let pkgId = pkg ++ "-" ++ ver
proc ghcId pkgId
-- processing libSet
$ stack list-dependencies
MonadPrompt 1.0.0.5
MonadRandom 0.4
StateVar 1.1.0.1
...
对于 cabal 项目尝试 cabal freeze --help
我主要对基于 stack 构建的项目感兴趣。
我设法通过编写一个分析命令输出的脚本解决了这个问题,例如 ghc-pkg field SOMEPKG hs-libraries
等
但是这种方法比较慢,主要是因为使用stack命令从项目中提取信息。
是否有另一种方法可以在不使用大量工具的情况下解决这个问题?
编辑
这是脚本草稿。
main = do
pkgSet <- newIORef . asHashSet $ mempty
libSet <- newIORef . asHashSet $ mempty
let proc ghcId pkgId = do
guard =<< (liftIO . map (pkgId `notMember`) . readIORef $ pkgSet)
liftIO . modifyIORef pkgSet $ insertSet pkgId
libDir1 <- lineToText <$> inproc "ghc-pkg"
["--simple-output", "field", pkgId, "dynamic-library-dirs"]
(pure "")
libDir2 <- lineToText <$> inproc "ghc-pkg"
["--simple-output", "field", pkgId, "library-dirs"] (pure "")
libDir <- select . filter (not . null) $ [libDir1, libDir2]
lib <- select =<< (map (words . lineToText) $ inproc "ghc-pkg"
["--simple-output", "field", pkgId, "hs-libraries"] (pure ""))
let libPath = asText . repack $ repack libDir
</> (shlibPrefix ++ repack lib ++ "-" ++ repack ghcId)
<.> shlibSuffix
guard =<< (liftIO . map (libPath `notMember`) . readIORef $ libSet)
guard =<< (liftIO . doesFileExist . repack $ libPath)
liftIO . modifyIORef libSet $ insertSet libPath
dep <- select =<< (map (words . lineToText) $ inproc "ghc-pkg"
["--simple-output", "field", pkgId, "depends"] (pure ""))
proc ghcId dep
sh $ do
ghcPkgPath <- lineToText <$> inshell "stack path --ghc-package-path" (pure "")
export "GHC_PACKAGE_PATH" ghcPkgPath
ghcVer <- lineToText <$> inshell "stack exec -- ghc --numeric-version" (pure "")
let ghcId = "ghc" ++ ghcVer
[pkg, ver] <- words . lineToText <$> inshell "stack list-dependencies" (pure "")
let pkgId = pkg ++ "-" ++ ver
proc ghcId pkgId
-- processing libSet
$ stack list-dependencies
MonadPrompt 1.0.0.5
MonadRandom 0.4
StateVar 1.1.0.1
...
对于 cabal 项目尝试 cabal freeze --help