packages feed

haskell-import-graph (empty) → 1.0.0

raw patch · 7 files changed

+187/−0 lines, 7 filesdep +basedep +classy-preludedep +ghcsetup-changed

Dependencies added: base, classy-prelude, ghc, graphviz, haskell-import-graph, process, text, transformers

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 ncaq++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
+ exec/Main.hs view
@@ -0,0 +1,6 @@+module Main where+import           Prelude                    (IO)+import           System.ImportGraph.AppMain (appMain)++main :: IO ()+main = appMain
+ haskell-import-graph.cabal view
@@ -0,0 +1,51 @@+name:                haskell-import-graph+version:             1.0.0+synopsis:            create haskell import graph for graphviz+description:         {+create haskell import graph for graphviz+How to:+> cabal build+> haskell-import-graph+Or,+> haskell-import-graph dist/build/foo/foo-tmp/bar.hi+}+license:             MIT+license-file:        LICENSE+author:              ncaq+maintainer:          ncaq@ncaq.net+copyright:           Copyright (c) 2015 ncaq+category:            Development+build-type:          Simple+cabal-version:       >=1.10++source-repository head+  type:     git+  location: https://github.com/ncaq/haskell-import-graph.git++library+  hs-source-dirs:      lib+  exposed-modules:     System.ImportGraph.AppMain+                     , System.ImportGraph.GetIface+                     , System.ImportGraph.ModuleCluster++  ghc-options:         -Wall -fwarn-incomplete-uni-patterns -fwarn-monomorphism-restriction -fwarn-identities+  default-language:    Haskell2010+  default-extensions:  NamedFieldPuns+                       NoImplicitPrelude+                       OverloadedStrings+                       RecordWildCards++  build-depends:       base                   >= 4.8   && < 4.9+                     , classy-prelude         >= 0.12  && < 0.13+                     , ghc                    >= 7.10  && < 7.11+                     , graphviz               >= 2999  && < 3000+                     , process                >= 1.2   && < 1.3+                     , text                   >= 1.2   && < 1.3+                     , transformers           >= 0.4   && < 0.5++executable haskell-import-graph+  hs-source-dirs:      exec+  main-is:             Main.hs+  ghc-options:         -Wall -fwarn-incomplete-uni-patterns -fwarn-monomorphism-restriction -fwarn-identities+  default-language:    Haskell2010+  build-depends:       base, haskell-import-graph
+ lib/System/ImportGraph/AppMain.hs view
@@ -0,0 +1,45 @@+module System.ImportGraph.AppMain where+import           ClassyPrelude+import           Data.GraphViz+import           Data.GraphViz.Attributes.Complete+import           Data.GraphViz.Printing            (renderDot)+import qualified Data.GraphViz.Types.Generalised   as G+import           Data.GraphViz.Types.Monadic+import qualified Data.Text.Lazy                    as L+import qualified Data.Text.Lazy.IO                 as L+import           GHC+import           System.ImportGraph.GetIface+import           System.ImportGraph.ModuleCluster+import           System.Process++appMain :: IO ()+appMain = do+    args <- getArgs+    libDir <- getLibDirReadProcess+    runGhc libDir $+        case args of+            ["-h"] -> liftIO $ L.putStrLn help+            ["--help"] -> liftIO $ L.putStrLn help+            [] -> do+                ifaces <- findIfaces+                liftIO . L.putStrLn $ renderGraph ifaces+            [hiPath] -> do+                iface <- getIface $ unpack hiPath+                liftIO . L.putStrLn $ renderGraph [iface]+            _ -> liftIO $ L.putStrLn help++getLibDirReadProcess :: IO (Maybe FilePath)+getLibDirReadProcess = listToMaybe . lines <$> readProcess "ghc" ["--print-libdir"] ""++help :: L.Text+help = unlines [ "Usage: cabal build && haskell-import-graph"+               , "or:    cabal build && haskell-import-graph dist/build/foo/foo-tmp/bar.hi"+               ]++renderGraph :: [ModIface] -> L.Text+renderGraph = renderDot . toDot . importGraph (Str "haskell-import-graph")++importGraph :: GraphID -> [ModIface] -> G.DotGraph L.Text+importGraph graphName mods = digraph graphName $ do+    graphAttrs [Compound True, RankDir FromLeft]+    mapM moduleCluster mods
+ lib/System/ImportGraph/GetIface.hs view
@@ -0,0 +1,20 @@+module System.ImportGraph.GetIface where+import           BinIface+import           ClassyPrelude+import           GHC+import           System.Process+import           TcRnMonad++findIfaces :: Ghc [ModIface]+findIfaces = do+    his <- liftIO findHiFiles+    _ <- setSessionDynFlags =<< getSessionDynFlags+    mapM getIface his++findHiFiles :: IO [FilePath]+findHiFiles = lines <$> readProcess "find" ["-iname", "*.hi"] ""++getIface :: FilePath -> Ghc ModIface+getIface filename = do+    hsc_env <- getSession+    liftIO . initTcRnIf 's' hsc_env () () $ readBinIface IgnoreHiWay QuietBinIFaceReading filename
+ lib/System/ImportGraph/ModuleCluster.hs view
@@ -0,0 +1,43 @@+module System.ImportGraph.ModuleCluster where+import           Avail+import           ClassyPrelude+import           Data.GraphViz+import           Data.GraphViz.Attributes.Complete+import           Data.GraphViz.Types.Monadic+import qualified Data.Text.Lazy                    as L+import           HscTypes+import           Module+import           Name++moduleCluster :: ModIface -> Dot L.Text+moduleCluster iface@ModIface{..} = do+    cluster (Str (ifaceName iface)) $ do+        graphAttrs [textLabel (ifaceName iface)]+        node (ifaceDummyNodeName iface) [Style [SItem Invisible []]]+        mapM node' exports+    mapM_ (ifaceUsageEdges iface) mi_usages+  where exports = map (pack . getOccString . availName) mi_exports++ifaceName :: ModIface -> L.Text+ifaceName = moduleText . mi_module++moduleText :: Module -> L.Text+moduleText = pack . moduleNameString . moduleName++ifaceDummyNodeName :: ModIface -> L.Text+ifaceDummyNodeName iface = ifaceName iface <> "_dummy_node"++ifaceClusterName :: ModIface -> L.Text+ifaceClusterName iface = "cluster_" <> ifaceName iface++ifaceUsageEdges :: ModIface -> Usage -> Dot L.Text+ifaceUsageEdges iface UsagePackageModule{..} = do+    ifaceEdge iface (moduleText usg_mod)+    node (moduleText usg_mod) [Shape Component]+ifaceUsageEdges iface UsageHomeModule{..}    =+    mapM_ (ifaceEdge iface . pack . occNameString . fst) usg_entities+ifaceUsageEdges iface UsageFile{..}          =+    ifaceEdge iface (pack usg_file_path)++ifaceEdge :: ModIface -> L.Text -> Dot L.Text+ifaceEdge iface edgeTo = edge (ifaceDummyNodeName iface) edgeTo [LTail (ifaceClusterName iface)]