Skip to content

Loading…

'cabal repl': when there's no .cabal file, just start ghci. #1607

Merged
merged 2 commits into from

2 participants

@23Skidoo
Haskell member

Fixes #1554.

@tibbe
Haskell member

:+1:

@23Skidoo 23Skidoo merged commit b310d70 into haskell:master

1 check passed

Details default The Travis CI build passed
@23Skidoo 23Skidoo deleted the 23Skidoo:repl-no-project branch
@23Skidoo
Haskell member

Wrong ticket reference: I meant #1544 instead of #1554.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 19, 2013
  1. @23Skidoo

    Rename 'findPackageDesc' to 'tryFindPackageDesc'.

    23Skidoo committed
    Make 'findPackageDesc' return an 'Either'.
  2. @23Skidoo
This page is out of date. Refresh to see the latest.
View
11 Cabal/Distribution/Simple/Build.hs
@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -}
module Distribution.Simple.Build (
build, repl,
+ startInterpreter,
initialBuildSteps,
writeAutogenFiles,
@@ -67,7 +68,8 @@ import Distribution.Package
( Package(..), PackageName(..), PackageIdentifier(..)
, Dependency(..), thisPackageVersion )
import Distribution.Simple.Compiler
- ( CompilerFlavor(..), compilerFlavor, PackageDB(..) )
+ ( Compiler, CompilerFlavor(..), compilerFlavor
+ , PackageDB(..), PackageDBStack )
import Distribution.PackageDescription
( PackageDescription(..), BuildInfo(..), Library(..), Executable(..)
, TestSuite(..), TestSuiteInterface(..), Benchmark(..)
@@ -202,6 +204,13 @@ repl pkg_descr lbi flags suffixes args = do
in replComponent verbosity pkg_descr lbi' suffixes comp clbi distPref
+-- | Start an interpreter without loading any package files.
+startInterpreter :: Verbosity -> ProgramDb -> Compiler -> PackageDBStack -> IO ()
+startInterpreter verbosity programDb comp packageDBs =
+ case compilerFlavor comp of
+ GHC -> GHC.startInterpreter verbosity programDb comp packageDBs
+ _ -> die "A REPL is not supported with this compiler."
+
buildComponent :: Verbosity
-> Flag (Maybe Int)
-> PackageDescription
View
12 Cabal/Distribution/Simple/GHC.hs
@@ -65,6 +65,7 @@ module Distribution.Simple.GHC (
configure, getInstalledPackages, getPackageDBContents,
buildLib, buildExe,
replLib, replExe,
+ startInterpreter,
installLib, installExe,
libAbiHash,
initPackageDB,
@@ -917,6 +918,17 @@ buildOrReplLib forRepl verbosity numJobsFlag pkg_descr lbi lib clbi = do
whenSharedLib False $
runGhcProg ghcSharedLinkArgs
+-- | Start a REPL without loading any source files.
+startInterpreter :: Verbosity -> ProgramConfiguration -> Compiler
+ -> PackageDBStack -> IO ()
+startInterpreter verbosity conf comp packageDBs = do
+ let replOpts = mempty {
+ ghcOptMode = toFlag GhcModeInteractive,
+ ghcOptPackageDBs = packageDBs
+ }
+ checkPackageDbStack packageDBs
+ (ghcProg, _) <- requireProgram verbosity ghcProgram conf
+ runGHC verbosity ghcProg comp replOpts
-- | Build an executable with GHC.
--
View
35 Cabal/Distribution/Simple/Utils.hs
@@ -121,6 +121,7 @@ module Distribution.Simple.Utils (
-- * .cabal and .buildinfo files
defaultPackageDesc,
findPackageDesc,
+ tryFindPackageDesc,
defaultHookedPackageDesc,
findHookedPackageDesc,
@@ -148,7 +149,7 @@ module Distribution.Simple.Utils (
) where
import Control.Monad
- ( when, unless, filterM )
+ ( join, when, unless, filterM )
import Control.Concurrent.MVar
( newEmptyMVar, putMVar, takeMVar )
import Data.List
@@ -1130,12 +1131,12 @@ currentDir = "."
-- |Package description file (/pkgname/@.cabal@)
defaultPackageDesc :: Verbosity -> IO FilePath
-defaultPackageDesc _verbosity = findPackageDesc currentDir
+defaultPackageDesc _verbosity = tryFindPackageDesc currentDir
-- |Find a package description file in the given directory. Looks for
-- @.cabal@ files.
-findPackageDesc :: FilePath -- ^Where to look
- -> IO FilePath -- ^<pkgname>.cabal
+findPackageDesc :: FilePath -- ^Where to look
+ -> IO (Either String FilePath) -- ^<pkgname>.cabal
findPackageDesc dir
= do files <- getDirectoryContents dir
-- to make sure we do not mistake a ~/.cabal/ dir for a <pkgname>.cabal
@@ -1146,19 +1147,23 @@ findPackageDesc dir
, let (name, ext) = splitExtension file
, not (null name) && ext == ".cabal" ]
case cabalFiles of
- [] -> noDesc
- [cabalFile] -> return cabalFile
- multiple -> multiDesc multiple
+ [] -> return (Left noDesc)
+ [cabalFile] -> return (Right cabalFile)
+ multiple -> return (Left $ multiDesc multiple)
where
- noDesc :: IO a
- noDesc = die $ "No cabal file found.\n"
- ++ "Please create a package description file <pkgname>.cabal"
-
- multiDesc :: [String] -> IO a
- multiDesc l = die $ "Multiple cabal files found.\n"
- ++ "Please use only one of: "
- ++ intercalate ", " l
+ noDesc :: String
+ noDesc = "No cabal file found.\n"
+ ++ "Please create a package description file <pkgname>.cabal"
+
+ multiDesc :: [String] -> String
+ multiDesc l = "Multiple cabal files found.\n"
+ ++ "Please use only one of: "
+ ++ intercalate ", " l
+
+-- |Like 'findPackageDesc', but calls 'die' in case of error.
+tryFindPackageDesc :: FilePath -> IO FilePath
+tryFindPackageDesc dir = join . fmap (either die return) $ findPackageDesc dir
-- |Optional auxiliary package information file (/pkgname/@.buildinfo@)
defaultHookedPackageDesc :: IO (Maybe FilePath)
View
6 cabal-install/Distribution/Client/IndexUtils.hs
@@ -55,7 +55,7 @@ import Distribution.Text
import Distribution.Verbosity
( Verbosity, normal, lessVerbose )
import Distribution.Simple.Utils
- ( die, warn, info, fromUTF8, findPackageDesc )
+ ( die, warn, info, fromUTF8, tryFindPackageDesc )
import Data.Char (isAlphaNum)
import Data.Maybe (mapMaybe, fromMaybe)
@@ -351,7 +351,7 @@ extractPkg entry blockNo = case Tar.entryContent entry of
| Tar.isBuildTreeRefTypeCode typeCode ->
Just $ do
let path = byteStringToFilePath content
- cabalFile <- findPackageDesc path
+ cabalFile <- tryFindPackageDesc path
descr <- PackageDesc.Parse.readPackageDescription normal cabalFile
return $ BuildTreeRef (refTypeFromTypeCode typeCode) (packageId descr)
descr path blockNo
@@ -452,7 +452,7 @@ packageIndexFromCache mkPkg hnd entrs mode = accum mempty [] entrs
-- package id for build tree references - the user might edit the .cabal
-- file after the reference was added to the index.
path <- liftM byteStringToFilePath . getEntryContent $ blockno
- pkg <- do cabalFile <- findPackageDesc path
+ pkg <- do cabalFile <- tryFindPackageDesc path
PackageDesc.Parse.readPackageDescription normal cabalFile
let srcpkg = mkPkg (BuildTreeRef refType (packageId pkg) pkg path blockno)
accum (srcpkg:srcpkgs) prefs entries
View
4 cabal-install/Distribution/Client/Sandbox.hs
@@ -79,7 +79,7 @@ import Distribution.Simple.Setup ( Flag(..), HaddockFlags(..)
import Distribution.Simple.SrcDist ( prepareTree )
import Distribution.Simple.Utils ( die, debug, notice, info, warn
, debugNoWrap, defaultPackageDesc
- , findPackageDesc
+ , tryFindPackageDesc
, intercalate, topHandlerWith
, createDirectoryIfMissingVerbose )
import Distribution.Package ( Package(..) )
@@ -592,7 +592,7 @@ withSandboxPackageInfo verbosity configFlags globalFlags
configFlags comp conf
-- Get the package descriptions for all add-source deps.
- depsCabalFiles <- mapM findPackageDesc buildTreeRefs
+ depsCabalFiles <- mapM tryFindPackageDesc buildTreeRefs
depsPkgDescs <- mapM (readPackageDescription verbosity) depsCabalFiles
let depsMap = M.fromList (zip buildTreeRefs depsPkgDescs)
isInstalled pkgid = not . null
View
4 cabal-install/Distribution/Client/Sandbox/Index.hs
@@ -31,7 +31,7 @@ import Distribution.Client.Utils ( byteStringToFilePath, filePathToByteString
, makeAbsoluteToCwd, tryCanonicalizePath
, canonicalizePathNoThrow )
-import Distribution.Simple.Utils ( die, debug, findPackageDesc )
+import Distribution.Simple.Utils ( die, debug, tryFindPackageDesc )
import Distribution.Verbosity ( Verbosity )
import qualified Data.ByteString.Lazy as BS
@@ -61,7 +61,7 @@ buildTreeRefFromPath refType dir = do
dirExists <- doesDirectoryExist dir
unless dirExists $
die $ "directory '" ++ dir ++ "' does not exist"
- _ <- findPackageDesc dir
+ _ <- tryFindPackageDesc dir
return . Just $ BuildTreeRef refType dir
-- | Given a tar archive entry, try to parse it as a local build tree reference.
View
4 cabal-install/Distribution/Client/Sandbox/Timestamp.hs
@@ -33,7 +33,7 @@ import Distribution.Simple.Setup (Flag (..),
defaultSDistFlags,
sdistCommand)
import Distribution.Simple.Utils (debug, die,
- findPackageDesc, warn)
+ tryFindPackageDesc, warn)
import Distribution.System (Platform)
import Distribution.Text (display)
import Distribution.Verbosity (Verbosity, lessVerbose,
@@ -215,7 +215,7 @@ withActionOnCompilerTimestamps f sandboxDir compId platform act = do
allPackageSourceFiles :: Verbosity -> FilePath -> IO [FilePath]
allPackageSourceFiles verbosity packageDir = inDir (Just packageDir) $ do
pkg <- fmap (flattenPackageDescription)
- . readPackageDescription verbosity =<< findPackageDesc packageDir
+ . readPackageDescription verbosity =<< tryFindPackageDesc packageDir
let file = "cabal-sdist-list-sources"
flags = defaultSDistFlags {
View
4 cabal-install/Distribution/Client/SetupWrapper.hs
@@ -69,7 +69,7 @@ import Distribution.Client.JobControl
import Distribution.Simple.Setup
( Flag(..) )
import Distribution.Simple.Utils
- ( die, debug, info, cabalVersion, findPackageDesc, comparing
+ ( die, debug, info, cabalVersion, tryFindPackageDesc, comparing
, createDirectoryIfMissingVerbose, installExecutableFile
, copyFileVerbose, rewriteFile, intercalate )
import Distribution.Client.Utils
@@ -159,7 +159,7 @@ setupWrapper verbosity options mpkg cmd flags extraArgs = do
checkBuildType buildType'
setupMethod verbosity options' (packageId pkg) buildType' mkArgs
where
- getPkg = findPackageDesc (fromMaybe "." (useWorkingDir options))
+ getPkg = tryFindPackageDesc (fromMaybe "." (useWorkingDir options))
>>= readPackageDescription verbosity
>>= return . packageDescription
View
6 cabal-install/Distribution/Client/Targets.hs
@@ -70,7 +70,7 @@ import Distribution.Text
( Text(..), display )
import Distribution.Verbosity (Verbosity)
import Distribution.Simple.Utils
- ( die, warn, intercalate, findPackageDesc, fromUTF8, lowercase )
+ ( die, warn, intercalate, tryFindPackageDesc, fromUTF8, lowercase )
import Data.List
( find, nub )
@@ -422,7 +422,7 @@ expandUserTarget worldFile userTarget = case userTarget of
UserTargetLocalCabalFile file -> do
let dir = takeDirectory file
- _ <- findPackageDesc dir -- just as a check
+ _ <- tryFindPackageDesc dir -- just as a check
return [ PackageTargetLocation (LocalUnpackedPackage dir) ]
UserTargetLocalTarball tarballFile ->
@@ -468,7 +468,7 @@ readPackageTarget verbosity target = case target of
PackageTargetLocation location -> case location of
LocalUnpackedPackage dir -> do
- pkg <- readPackageDescription verbosity =<< findPackageDesc dir
+ pkg <- readPackageDescription verbosity =<< tryFindPackageDesc dir
return $ PackageTargetLocation $
SourcePackage {
packageInfoId = packageId pkg,
View
73 cabal-install/Main.hs
@@ -101,6 +101,8 @@ import Distribution.Client.Utils (determineNumJobs
import Distribution.PackageDescription
( Executable(..) )
+import Distribution.Simple.Build
+ ( startInterpreter )
import Distribution.Simple.Command
( CommandParse(..), CommandUI(..), Command
, commandsRun, commandAddAction, hiddenCommand )
@@ -114,7 +116,7 @@ import qualified Distribution.Simple.LocalBuildInfo as LBI
import Distribution.Simple.Program (defaultProgramConfiguration)
import qualified Distribution.Simple.Setup as Cabal
import Distribution.Simple.Utils
- ( cabalVersion, die, notice, info, topHandler )
+ ( cabalVersion, die, notice, info, topHandler, findPackageDesc )
import Distribution.Text
( display )
import Distribution.Verbosity as Verbosity
@@ -128,7 +130,7 @@ import System.Exit (exitFailure)
import System.FilePath (splitExtension, takeExtension)
import System.IO (BufferMode(LineBuffering),
hSetBuffering, stdout)
-import System.Directory (doesFileExist)
+import System.Directory (doesFileExist, getCurrentDirectory)
import Data.List (intercalate)
import Data.Monoid (Monoid(..))
import Control.Monad (when, unless)
@@ -326,32 +328,47 @@ filterBuildFlags version config buildFlags
replAction :: ReplFlags -> [String] -> GlobalFlags -> IO ()
replAction replFlags extraArgs globalFlags = do
- let distPref = fromFlagOrDefault (useDistPref defaultSetupScriptOptions)
- (replDistPref replFlags)
- verbosity = fromFlagOrDefault normal (replVerbosity replFlags)
- noAddSource = case replReload replFlags of
- Flag True -> SkipAddSourceDepsCheck
- _ -> DontSkipAddSourceDepsCheck
-
- -- Calls 'configureAction' to do the real work, so nothing special has to be
- -- done to support sandboxes.
- (useSandbox, _config) <- reconfigure verbosity distPref
- mempty [] globalFlags noAddSource NoFlag
- (const Nothing)
-
- maybeWithSandboxDirOnSearchPath useSandbox $
- let progConf = defaultProgramConfiguration
- setupOptions = defaultSetupScriptOptions
- { useCabalVersion = orLaterVersion $ Version [1,18,0] []
- , useDistPref = distPref
- }
- replFlags' = replFlags
- { replVerbosity = toFlag verbosity
- , replDistPref = toFlag distPref
- }
- in setupWrapper verbosity setupOptions Nothing
- (Cabal.replCommand progConf) (const replFlags') extraArgs
-
+ cwd <- getCurrentDirectory
+ pkgDesc <- findPackageDesc cwd
+ either (const onNoPkgDesc) (const onPkgDesc) pkgDesc
+ where
+ verbosity = fromFlagOrDefault normal (replVerbosity replFlags)
+
+ -- There is a .cabal file in the current directory: start a REPL and load
+ -- the project's modules.
+ onPkgDesc = do
+ let distPref = fromFlagOrDefault (useDistPref defaultSetupScriptOptions)
+ (replDistPref replFlags)
+ noAddSource = case replReload replFlags of
+ Flag True -> SkipAddSourceDepsCheck
+ _ -> DontSkipAddSourceDepsCheck
+ progConf = defaultProgramConfiguration
+ setupOptions = defaultSetupScriptOptions
+ { useCabalVersion = orLaterVersion $ Version [1,18,0] []
+ , useDistPref = distPref
+ }
+ replFlags' = replFlags
+ { replVerbosity = toFlag verbosity
+ , replDistPref = toFlag distPref
+ }
+ -- Calls 'configureAction' to do the real work, so nothing special has to
+ -- be done to support sandboxes.
+ (useSandbox, _config) <- reconfigure verbosity distPref
+ mempty [] globalFlags noAddSource NoFlag
+ (const Nothing)
+
+ maybeWithSandboxDirOnSearchPath useSandbox $
+ setupWrapper verbosity setupOptions Nothing
+ (Cabal.replCommand progConf) (const replFlags') extraArgs
+
+ -- No .cabal file in the current directory: just start the REPL (possibly
+ -- using the sandbox package DB).
+ onNoPkgDesc = do
+ (_useSandbox, config) <- loadConfigOrSandboxConfig verbosity globalFlags
+ mempty
+ let configFlags = savedConfigureFlags config
+ (comp, _platform, programDb) <- configCompilerAux' configFlags
+ startInterpreter verbosity programDb comp (configPackageDB' configFlags)
-- | Re-configure the package in the current directory if needed. Deciding
-- when to reconfigure and with which options is convoluted:
Something went wrong with that request. Please try again.