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 +20/−0
- Setup.hs +2/−0
- file-modules.cabal +44/−0
- src/Development/FileModules.hs +43/−0
- src/Main.hs +15/−0
+ 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