Cleanup and some fixes

This commit is contained in:
Daniel Gröber 2015-03-28 02:33:42 +01:00
parent 2a02742f9e
commit 80d91776c5
12 changed files with 94 additions and 52 deletions

View File

@ -34,6 +34,7 @@ module Language.Haskell.GhcMod (
, check , check
, checkSyntax , checkSyntax
, debugInfo , debugInfo
, componentInfo
, expandTemplate , expandTemplate
, info , info
, lint , lint
@ -58,7 +59,6 @@ module Language.Haskell.GhcMod (
import Language.Haskell.GhcMod.Boot import Language.Haskell.GhcMod.Boot
import Language.Haskell.GhcMod.Browse import Language.Haskell.GhcMod.Browse
import Language.Haskell.GhcMod.CaseSplit import Language.Haskell.GhcMod.CaseSplit
import Language.Haskell.GhcMod.CabalHelper
import Language.Haskell.GhcMod.Check import Language.Haskell.GhcMod.Check
import Language.Haskell.GhcMod.Cradle import Language.Haskell.GhcMod.Cradle
import Language.Haskell.GhcMod.Debug import Language.Haskell.GhcMod.Debug
@ -73,4 +73,3 @@ import Language.Haskell.GhcMod.Modules
import Language.Haskell.GhcMod.Monad import Language.Haskell.GhcMod.Monad
import Language.Haskell.GhcMod.PkgDoc import Language.Haskell.GhcMod.PkgDoc
import Language.Haskell.GhcMod.Types import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Target

View File

@ -14,6 +14,7 @@
-- You should have received a copy of the GNU Affero General Public License -- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>. -- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE CPP #-}
module Language.Haskell.GhcMod.CabalHelper ( module Language.Haskell.GhcMod.CabalHelper (
getComponents getComponents
, getGhcPkgOptions , getGhcPkgOptions
@ -33,6 +34,8 @@ import Language.Haskell.GhcMod.World
import Language.Haskell.GhcMod.PathsAndFiles import Language.Haskell.GhcMod.PathsAndFiles
import System.FilePath import System.FilePath
import Paths_ghc_mod as GhcMod
-- | Only package related GHC options, sufficient for things that don't need to -- | Only package related GHC options, sufficient for things that don't need to
-- access home modules -- access home modules
getGhcPkgOptions :: (MonadIO m, GmEnv m) => m [(ChComponentName, [GHCOption])] getGhcPkgOptions :: (MonadIO m, GmEnv m) => m [(ChComponentName, [GHCOption])]
@ -87,6 +90,7 @@ cabalHelperCache = Cached {
, a == a' , a == a'
] ]
withCabal :: (MonadIO m, GmEnv m) => m a -> m a withCabal :: (MonadIO m, GmEnv m) => m a -> m a
withCabal action = do withCabal action = do
crdl <- cradle crdl <- cradle

View File

@ -1,9 +1,10 @@
module Language.Haskell.GhcMod.Debug (debugInfo, rootInfo) where module Language.Haskell.GhcMod.Debug (debugInfo, rootInfo, componentInfo) where
import Control.Arrow (first) import Control.Arrow (first)
import Control.Applicative ((<$>)) import Control.Applicative ((<$>))
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Char
import Text.PrettyPrint import Text.PrettyPrint
import Language.Haskell.GhcMod.Convert import Language.Haskell.GhcMod.Convert
import Language.Haskell.GhcMod.Monad import Language.Haskell.GhcMod.Monad
@ -35,8 +36,8 @@ debugInfo = do
cabalDebug :: IOish m => GhcModT m [String] cabalDebug :: IOish m => GhcModT m [String]
cabalDebug = do cabalDebug = do
Cradle {..} <- cradle crdl@Cradle {..} <- cradle
mcs <- resolveGmComponents Nothing =<< getComponents mcs <- resolveGmComponents Nothing =<< mapM (resolveEntrypoint crdl) =<< getComponents
let entrypoints = Map.map gmcEntrypoints mcs let entrypoints = Map.map gmcEntrypoints mcs
graphs = Map.map gmcHomeModuleGraph mcs graphs = Map.map gmcHomeModuleGraph mcs
opts = Map.map gmcGhcOpts mcs opts = Map.map gmcGhcOpts mcs
@ -54,6 +55,20 @@ cabalDebug = do
mapDoc gmComponentNameDoc (fsep . map text) srcOpts) mapDoc gmComponentNameDoc (fsep . map text) srcOpts)
] ]
componentInfo :: IOish m => [String] -> GhcModT m String
componentInfo ts = do
crdl <- cradle
opts <- targetGhcOptions crdl $ Set.fromList $ map guessModuleFile ts
return $ unlines $
[ "GHC Cabal options:\n" ++ render (nest 4 $ fsep $ map text opts)
]
guessModuleFile :: String -> Either FilePath ModuleName
guessModuleFile mn@(h:r)
| isUpper h && all isAlphaNum r = Right $ mkModuleName mn
guessModuleFile str = Left str
graphDoc :: GmModuleGraph -> Doc graphDoc :: GmModuleGraph -> Doc
graphDoc GmModuleGraph{..} = graphDoc GmModuleGraph{..} =
mapDoc mpDoc' smpDoc' gmgGraph mapDoc mpDoc' smpDoc' gmgGraph

View File

@ -216,7 +216,7 @@ updateHomeModuleGraph' env smp0 = do
Left errs -> do Left errs -> do
-- TODO: Remember these and present them as proper errors if this is -- TODO: Remember these and present them as proper errors if this is
-- the file the user is looking at. -- the file the user is looking at.
gmLog GmWarning "preprocess'" $ vcat $ map strDoc errs gmLog GmWarning ("preprocess' " ++ show fn) $ vcat $ map strDoc errs
return Nothing return Nothing
imports :: ModulePath -> String -> DynFlags -> MaybeT m (Set ModulePath) imports :: ModulePath -> String -> DynFlags -> MaybeT m (Set ModulePath)

View File

@ -14,6 +14,8 @@
-- You should have received a copy of the GNU Affero General Public License -- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>. -- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Language.Haskell.GhcMod.Logging ( module Language.Haskell.GhcMod.Logging (
module Language.Haskell.GhcMod.Logging module Language.Haskell.GhcMod.Logging
, module Language.Haskell.GhcMod.Pretty , module Language.Haskell.GhcMod.Pretty
@ -22,7 +24,9 @@ module Language.Haskell.GhcMod.Logging (
, module Data.Monoid , module Data.Monoid
) where ) where
import Control.Applicative hiding (empty)
import Control.Monad import Control.Monad
import Control.Monad.Trans.Class
import Data.List import Data.List
import Data.Char import Data.Char
import Data.Monoid (mempty, mappend, mconcat, (<>)) import Data.Monoid (mempty, mappend, mconcat, (<>))
@ -57,9 +61,20 @@ gmLog level loc' doc = do
let loc | loc' == "" = empty let loc | loc' == "" = empty
| otherwise = text loc' | otherwise = text loc'
msg = gmRenderDoc $ (gmLogLevelDoc level <+> loc) <+>: doc msg = gmRenderDoc $ (gmLogLevelDoc level <+>: loc) <+>: doc
msg' = dropWhileEnd isSpace msg msg' = dropWhileEnd isSpace msg
when (Just level <= level') $ when (Just level <= level') $
liftIO $ hPutStrLn stderr msg' liftIO $ hPutStrLn stderr msg'
gmlJournal (GhcModLog Nothing [(level, render loc, msg)]) gmlJournal (GhcModLog Nothing [(level, render loc, msg)])
newtype LogDiscardT m a = LogDiscardT { runLogDiscard :: m a }
deriving (Functor, Applicative, Monad)
instance MonadTrans LogDiscardT where
lift = LogDiscardT
instance Monad m => GmLog (LogDiscardT m) where
gmlJournal = const $ return ()
gmlHistory = return mempty
gmlClear = return ()

View File

@ -27,14 +27,14 @@ module Language.Haskell.GhcMod.Monad.Types (
, LightGhc(..) , LightGhc(..)
, GmGhc , GmGhc
, IOish , IOish
-- ** Environment, state and logging -- * Environment, state and logging
, GhcModEnv(..) , GhcModEnv(..)
, GhcModState(..) , GhcModState(..)
, defaultGhcModState , defaultGhcModState
, GmGhcSession(..) , GmGhcSession(..)
, GmComponent(..) , GmComponent(..)
, CompilerMode(..) , CompilerMode(..)
-- ** Accessing 'GhcModEnv', 'GhcModState' and 'GhcModLog' -- * Accessing 'GhcModEnv', 'GhcModState' and 'GhcModLog'
, GmLogLevel(..) , GmLogLevel(..)
, GhcModLog(..) , GhcModLog(..)
, GhcModError(..) , GhcModError(..)
@ -46,7 +46,7 @@ module Language.Haskell.GhcMod.Monad.Types (
, withOptions , withOptions
, getCompilerMode , getCompilerMode
, setCompilerMode , setCompilerMode
-- ** Re-exporting convenient stuff -- * Re-exporting convenient stuff
, MonadIO , MonadIO
, liftIO , liftIO
) where ) where

View File

@ -72,18 +72,20 @@ Library
Default-Language: Haskell2010 Default-Language: Haskell2010
GHC-Options: -Wall -fno-warn-deprecations GHC-Options: -Wall -fno-warn-deprecations
Default-Extensions: ScopedTypeVariables, RecordWildCards, NamedFieldPuns, Default-Extensions: ScopedTypeVariables, RecordWildCards, NamedFieldPuns,
ConstraintKinds, FlexibleContexts ConstraintKinds, FlexibleContexts,
DataKinds, KindSignatures
Exposed-Modules: Language.Haskell.GhcMod Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal Language.Haskell.GhcMod.Internal
Other-Modules: Paths_ghc_mod Other-Modules: Paths_ghc_mod
Utils Utils
Language.Haskell.GhcMod.Boot Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.CabalHelper
Language.Haskell.GhcMod.Caching
Language.Haskell.GhcMod.CaseSplit Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.CabalHelper
Language.Haskell.GhcMod.Debug Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags Language.Haskell.GhcMod.DynFlags
@ -113,6 +115,7 @@ Library
Language.Haskell.GhcMod.World Language.Haskell.GhcMod.World
Build-Depends: base >= 4.0 && < 5 Build-Depends: base >= 4.0 && < 5
, bytestring , bytestring
, cereal >= 0.4
, containers , containers
, cabal-helper >= 0.3 , cabal-helper >= 0.3
, deepseq , deepseq
@ -200,7 +203,8 @@ Test-Suite doctest
Test-Suite spec Test-Suite spec
Default-Language: Haskell2010 Default-Language: Haskell2010
Default-Extensions: ScopedTypeVariables, RecordWildCards, NamedFieldPuns, Default-Extensions: ScopedTypeVariables, RecordWildCards, NamedFieldPuns,
ConstraintKinds, FlexibleContexts ConstraintKinds, FlexibleContexts,
DataKinds, KindSignatures
Main-Is: Main.hs Main-Is: Main.hs
Hs-Source-Dirs: test, . Hs-Source-Dirs: test, .
Ghc-Options: -Wall -fno-warn-deprecations Ghc-Options: -Wall -fno-warn-deprecations

View File

@ -196,6 +196,9 @@ ghcModUsage =
\ Print debugging information. Please include the output in any bug\n\ \ Print debugging information. Please include the output in any bug\n\
\ reports you submit.\n\ \ reports you submit.\n\
\\n\ \\n\
\ - debugComponent [MODULE_OR_FILE...]\n\
\ Debugging information related to cabal component resolution.\n\
\\n\
\ - boot\n\ \ - boot\n\
\ Internal command used by the emacs frontend.\n" \ Internal command used by the emacs frontend.\n"
-- "\n\ -- "\n\
@ -514,6 +517,7 @@ ghcCommands (cmd:args) = fn args
"check" -> checkSyntaxCmd "check" -> checkSyntaxCmd
"expand" -> expandTemplateCmd "expand" -> expandTemplateCmd
"debug" -> debugInfoCmd "debug" -> debugInfoCmd
"debugComponent" -> componentInfoCmd
"info" -> infoCmd "info" -> infoCmd
"type" -> typesCmd "type" -> typesCmd
"split" -> splitsCmd "split" -> splitsCmd
@ -565,7 +569,7 @@ catchArgs cmd action =
throw $ InvalidCommandLine (Left cmd) throw $ InvalidCommandLine (Left cmd)
modulesCmd, languagesCmd, flagsCmd, browseCmd, checkSyntaxCmd, expandTemplateCmd, modulesCmd, languagesCmd, flagsCmd, browseCmd, checkSyntaxCmd, expandTemplateCmd,
debugInfoCmd, infoCmd, typesCmd, splitsCmd, sigCmd, refineCmd, autoCmd, debugInfoCmd, componentInfoCmd, infoCmd, typesCmd, splitsCmd, sigCmd, refineCmd, autoCmd,
findSymbolCmd, lintCmd, rootInfoCmd, pkgDocCmd, dumpSymbolCmd, bootCmd findSymbolCmd, lintCmd, rootInfoCmd, pkgDocCmd, dumpSymbolCmd, bootCmd
:: IOish m => [String] -> GhcModT m String :: IOish m => [String] -> GhcModT m String
@ -575,6 +579,7 @@ languagesCmd = withParseCmd' "lang" [] $ \[] -> languages
flagsCmd = withParseCmd' "flag" [] $ \[] -> flags flagsCmd = withParseCmd' "flag" [] $ \[] -> flags
debugInfoCmd = withParseCmd' "debug" [] $ \[] -> debugInfo debugInfoCmd = withParseCmd' "debug" [] $ \[] -> debugInfo
rootInfoCmd = withParseCmd' "root" [] $ \[] -> rootInfo rootInfoCmd = withParseCmd' "root" [] $ \[] -> rootInfo
componentInfoCmd = withParseCmd' "debugComponent" [] $ \ts -> componentInfo ts
-- internal -- internal
bootCmd = withParseCmd' "boot" [] $ \[] -> boot bootCmd = withParseCmd' "boot" [] $ \[] -> boot

View File

@ -2,16 +2,16 @@ module CabalHelperSpec where
import Control.Arrow import Control.Arrow
import Control.Applicative import Control.Applicative
import Language.Haskell.GhcMod.CabalHelper -- import Language.Haskell.GhcMod.CabalHelper
import Language.Haskell.GhcMod.PathsAndFiles -- import Language.Haskell.GhcMod.PathsAndFiles
import Language.Haskell.GhcMod.Error import Language.Haskell.GhcMod.Error
import Test.Hspec import Test.Hspec
import System.Directory -- import System.Directory
import System.FilePath -- import System.FilePath
import System.Process (readProcess) -- import System.Process (readProcess)
import Dir -- import Dir
import TestUtils -- import TestUtils
import Data.List import Data.List
import Config (cProjectVersionInt) import Config (cProjectVersionInt)
@ -36,35 +36,35 @@ idirOpts :: [(c, [String])] -> [(c, [String])]
idirOpts = map (second $ map (drop 2) . filter ("-i"`isPrefixOf`)) idirOpts = map (second $ map (drop 2) . filter ("-i"`isPrefixOf`))
spec :: Spec spec :: Spec
spec = do spec = do return ()
describe "getGhcOptions" $ do -- describe "getGhcOptions" $ do
it "throws an exception if the cabal file is broken" $ do -- it "throws an exception if the cabal file is broken" $ do
let tdir = "test/data/broken-caba" -- let tdir = "test/data/broken-caba"
runD' tdir getGhcOptions `shouldThrow` anyIOException -- runD' tdir getGhcOptions `shouldThrow` anyIOException
it "handles sandboxes correctly" $ do -- it "handles sandboxes correctly" $ do
let tdir = "test/data/cabal-project" -- let tdir = "test/data/cabal-project"
cwd <- getCurrentDirectory -- cwd <- getCurrentDirectory
opts <- runD' tdir getGhcOptions -- opts <- runD' tdir getGhcOptions
if ghcVersion < 706 -- if ghcVersion < 706
then forM_ opts (\(_, o) -> o `shouldContain` ["-no-user-package-conf","-package-conf", cwd </> "test/data/cabal-project/.cabal-sandbox/"++ghcSandboxPkgDbDir]) -- then forM_ opts (\(_, o) -> o `shouldContain` ["-no-user-package-conf","-package-conf", cwd </> "test/data/cabal-project/.cabal-sandbox/"++ghcSandboxPkgDbDir])
else forM_ opts (\(_, o) -> o `shouldContain` ["-no-user-package-db","-package-db",cwd </> "test/data/cabal-project/.cabal-sandbox/"++ghcSandboxPkgDbDir]) -- else forM_ opts (\(_, o) -> o `shouldContain` ["-no-user-package-db","-package-db",cwd </> "test/data/cabal-project/.cabal-sandbox/"++ghcSandboxPkgDbDir])
it "extracts build dependencies" $ do -- it "extracts build dependencies" $ do
let tdir = "test/data/cabal-project" -- let tdir = "test/data/cabal-project"
opts <- runD' tdir getGhcOptions -- opts <- runD' tdir getGhcOptions
let ghcOpts = snd $ head opts -- let ghcOpts = snd $ head opts
pkgs = pkgOptions ghcOpts -- pkgs = pkgOptions ghcOpts
pkgs `shouldBe` ["Cabal","base","template-haskell"] -- pkgs `shouldBe` ["Cabal","base","template-haskell"]
it "uses non default flags" $ do -- it "uses non default flags" $ do
let tdir = "test/data/cabal-flags" -- let tdir = "test/data/cabal-flags"
_ <- withDirectory_ tdir $ -- _ <- withDirectory_ tdir $
readProcess "cabal" ["configure", "-ftest-flag"] "" -- readProcess "cabal" ["configure", "-ftest-flag"] ""
opts <- runD' tdir getGhcOptions -- opts <- runD' tdir getGhcOptions
let ghcOpts = snd $ head opts -- let ghcOpts = snd $ head opts
pkgs = pkgOptions ghcOpts -- pkgs = pkgOptions ghcOpts
pkgs `shouldBe` ["Cabal","base"] -- pkgs `shouldBe` ["Cabal","base"]

View File

@ -29,9 +29,8 @@ main = do
genGhcPkgCache `mapM_` pkgDirs genGhcPkgCache `mapM_` pkgDirs
let caches = [ "setup-config" let caches = [ "setup-config"
, "setup-config.ghc-mod.cabal-ghc-options"
, "setup-config.ghc-mod.cabal-helper.ghc-options"
, "setup-config.ghc-mod.cabal-helper" , "setup-config.ghc-mod.cabal-helper"
, "setup-config.ghc-mod.resolved-components"
, "ghc-mod.cache" , "ghc-mod.cache"
] ]
cachesFindExp :: String cachesFindExp :: String
@ -39,10 +38,9 @@ main = do
cleanCmd = "find test \\( "++ cachesFindExp ++" \\) -exec rm {} \\;" cleanCmd = "find test \\( "++ cachesFindExp ++" \\) -exec rm {} \\;"
print cleanCmd putStrLn $ "$ " ++ cleanCmd
void $ system cleanCmd void $ system cleanCmd
void $ system "cabal --version" void $ system "cabal --version"
putStrLn $ "ghc-mod was built with Cabal version " ++ VERSION_Cabal
void $ system "ghc --version" void $ system "ghc --version"
(putStrLn =<< runD debugInfo) (putStrLn =<< runD debugInfo)

View File

@ -13,3 +13,4 @@ test-suite test
build-depends: base == 4.* build-depends: base == 4.*
hs-source-dirs: test hs-source-dirs: test
main-is: Main.hs main-is: Main.hs
ghc-options: -Wall

View File

@ -21,4 +21,5 @@ library
other-extensions: PatternSynonyms other-extensions: PatternSynonyms
build-depends: base build-depends: base
-- hs-source-dirs: -- hs-source-dirs:
default-language: Haskell2010 default-language: Haskell2010
ghc-options: -Wall