packages feed

file-modules (empty) → 0.1.0.0

raw patch · 5 files changed

+124/−0 lines, 5 filesdep +MissingHdep +asyncdep +basesetup-changed

Dependencies added: MissingH, async, base, directory, filepath, haskell-src-exts, stm, stm-containers

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Pedro Tacla Yamada++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ file-modules.cabal view
@@ -0,0 +1,44 @@+name: file-modules+version: 0.1.0.0+cabal-version: >=1.10+build-type: Simple+license: MIT+license-file: LICENSE+copyright: Copyright (c) Pedro Tacla Yamada 2015+maintainer: tacla.yamada@gmail.com+homepage: https://github.com/yamadapc/stack-run-auto+synopsis: Takes a Haskell source-code file and outputs the modules it+          . imports. Follows links to local modules as well.+category: Development+author: Pedro Tacla Yamada++library+    exposed-modules:+        Development.FileModules+    build-depends:+        MissingH -any,+        directory -any,+        async -any,+        base >=4.5 && <5,+        filepath -any,+        haskell-src-exts >=1.17 && <2,+        stm -any,+        stm-containers -any+    default-language: Haskell2010+    hs-source-dirs: src++executable file-modules+    main-is: Main.hs+    build-depends:+        base >=4.5 && <5,+        MissingH -any,+        directory -any,+        async -any,+        base >=4.5 && <5,+        filepath -any,+        haskell-src-exts >=1.17 && <2,+        stm -any,+        stm-containers -any+    default-language: Haskell2010+    hs-source-dirs: src+
+ src/Development/FileModules.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE RecordWildCards #-}+module Development.FileModules where++import           Control.Concurrent.Async (mapConcurrently)+import           Control.Concurrent.STM+import           Control.Monad            (forM)+import           Data.String.Utils        (split)+import           Language.Haskell.Exts    (ImportDecl (..),+                                           ModuleHeadAndImports (..),+                                           ModuleName (..), NonGreedy (..),+                                           ParseResult (..), parse)+import qualified STMContainers.Set        as Set+import           System.Directory+import           System.FilePath++fileModulesRecur :: Set.Set String -> FilePath -> IO [String]+fileModulesRecur seen fname = do+    modules <- fileModules fname+    modules' <- flip mapConcurrently modules $ \m -> do+        let pth = takeDirectory fname </> joinPath (split "." m) ++ ".hs"+        isSeen <- atomically $ Set.lookup pth seen+        if isSeen+           then return [m]+           else do+               atomically $ Set.insert pth seen+               isLocalModule <- doesFileExist pth+               if isLocalModule+                   -- If we're hitting a local modules, ignore it on the+                   -- output (this may not be what we want)+                   then fileModulesRecur seen pth+                   else return [m]+    return (concat modules')++fileModules :: FilePath -> IO [String]+fileModules fname = do+    result <- parse <$> readFile fname+    case result of+        (ParseOk (NonGreedy{..})) -> do+            let (ModuleHeadAndImports _ _ mimports) = unNonGreedy+            forM mimports $ \imp ->+                let ModuleName iname = importModule imp+                in return iname+        (ParseFailed _ _) -> error $ "Failed to parse module in " ++ fname
+ src/Main.hs view
@@ -0,0 +1,15 @@+module Main where++import           Control.Concurrent.Async (mapConcurrently)+import           Control.Monad            (forM_)+import           Data.List.Utils          (uniq)+import           Development.FileModules+import qualified STMContainers.Set        as Set+import           System.Environment       (getArgs)++main :: IO ()+main = do+    args <- getArgs+    seen <- Set.newIO+    modules <- mapConcurrently (fileModulesRecur seen) args+    forM_ (uniq (concat modules)) putStrLn