Skip to content

Commit 497caee

Browse files
author
Lennart Spitzner
committed
Add "status" command
The "status" command prints a summary over several aspects of a cabal environment, such as the cabal and ghc versions, the package and its components, the package-databases, the sandbox etc.
1 parent a984914 commit 497caee

File tree

16 files changed

+659
-25
lines changed

16 files changed

+659
-25
lines changed

Cabal/Distribution/PackageDescription/Parse.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ import Control.Arrow (first)
6767
import System.Directory (doesFileExist)
6868
import qualified Data.ByteString.Lazy.Char8 as BS.Char8
6969

70-
import Text.PrettyPrint
70+
import Text.PrettyPrint hiding (render)
7171

7272

7373
-- -----------------------------------------------------------------------------

Cabal/Distribution/PackageDescription/PrettyPrint.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import Data.Monoid as Mon (Monoid(mempty))
2828
import Data.Maybe (isJust)
2929
import Text.PrettyPrint
3030
(hsep, parens, char, nest, empty, isEmpty, ($$), (<+>),
31-
colon, (<>), text, vcat, ($+$), Doc, render)
31+
colon, (<>), text, vcat, ($+$), Doc)
3232

3333
-- | Recompile with false for regression testing
3434
simplifiedPrinting :: Bool

Cabal/Distribution/ParseUtils.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import Distribution.Text
5151
import Distribution.Simple.Utils
5252
import Language.Haskell.Extension
5353

54-
import Text.PrettyPrint hiding (braces)
54+
import Text.PrettyPrint hiding (braces, render)
5555
import Data.Char (isSpace, toLower, isAlphaNum, isDigit)
5656
import Data.Maybe (fromMaybe)
5757
import Data.Tree as Tree (Tree(..), flatten)

Cabal/Distribution/Simple/Configure.hs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ module Distribution.Simple.Configure (configure,
4040
getInstalledPackages,
4141
getInstalledPackagesMonitorFiles,
4242
getPackageDBContents,
43+
checkPackageDBs,
4344
configCompiler, configCompilerAux,
4445
configCompilerEx, configCompilerAuxEx,
4546
ccLdOptionsBuildInfo,
@@ -1051,6 +1052,29 @@ getInstalledPackages verbosity comp packageDBs progconf = do
10511052
flv -> die $ "don't know how to find the installed packages for "
10521053
++ display flv
10531054

1055+
-- | Check the consistency of the given package databases.
1056+
checkPackageDBs :: Verbosity -> Compiler
1057+
-> PackageDBStack -- ^ The stack of package databases.
1058+
-> ProgramConfiguration
1059+
-> IO [(PackageDB, [String])]
1060+
checkPackageDBs verbosity comp packageDBs progconf = do
1061+
when (null packageDBs) $
1062+
die $ "No package databases have been specified. If you use "
1063+
++ "--package-db=clear, you must follow it with --package-db= "
1064+
++ "with 'global', 'user' or a specific file."
1065+
1066+
debug verbosity "checking package-db..."
1067+
case compilerFlavor comp of
1068+
GHC -> GHC.checkPackageDBs verbosity comp packageDBs progconf
1069+
-- GHCJS -> GHCJS.checkPackageDBs verbosity packageDBs progconf
1070+
-- JHC -> JHC.checkPackageDBs verbosity packageDBs progconf
1071+
-- LHC -> LHC.checkPackageDBs verbosity packageDBs progconf
1072+
-- UHC -> UHC.checkPackageDBs verbosity comp packageDBs progconf
1073+
-- HaskellSuite {} ->
1074+
-- HaskellSuite.checkPackageDBs verbosity packageDBs progconf
1075+
flv -> die $ "don't know how to check the packages database for "
1076+
++ display flv
1077+
10541078
-- | Like 'getInstalledPackages', but for a single package DB.
10551079
--
10561080
-- NB: Why isn't this always a fall through to 'getInstalledPackages'?

Cabal/Distribution/Simple/GHC.hs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ module Distribution.Simple.GHC (
3636
getGhcInfo,
3737
configure,
3838
getInstalledPackages,
39+
checkPackageDBs,
3940
getInstalledPackagesMonitorFiles,
4041
getPackageDBContents,
4142
buildLib, buildExe,
@@ -292,6 +293,17 @@ getInstalledPackages verbosity comp packagedbs conf = do
292293
_ -> index -- No (or multiple) ghc rts package is registered!!
293294
-- Feh, whatever, the ghc test suite does some crazy stuff.
294295

296+
-- | Check the consistency of the given package databases.
297+
checkPackageDBs :: Verbosity -> Compiler -> PackageDBStack -> ProgramConfiguration
298+
-> IO [(PackageDB, [String])]
299+
checkPackageDBs verbosity comp packagedbs conf = do
300+
checkPackageDbEnvVar
301+
checkPackageDbStack comp packagedbs
302+
sequence
303+
[ do strs <- HcPkg.check (hcPkgInfo conf) verbosity packagedb
304+
return (packagedb, strs)
305+
| packagedb <- packagedbs ]
306+
295307
-- | Given a list of @(PackageDB, InstalledPackageInfo)@ pairs, produce a
296308
-- @PackageIndex@. Helper function used by 'getPackageDBContents' and
297309
-- 'getInstalledPackages'.

Cabal/Distribution/Simple/Program/HcPkg.hs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module Distribution.Simple.Program.HcPkg (
2323
hide,
2424
dump,
2525
describe,
26+
check,
2627
list,
2728

2829
-- * Program invocations
@@ -264,6 +265,14 @@ splitPkgs = checkEmpty . map unlines . splitWith ("---" ==) . lines
264265
_:ws -> splitWith p ws
265266
where (ys,zs) = break p xs
266267

268+
-- | Call @hc-pkg@ to check the consistency of the specified package db.
269+
check :: HcPkgInfo -> Verbosity -> PackageDB -> IO [String]
270+
check hpi verbosity packagedb = do
271+
fmap lines $ getProgramInvocationOutput
272+
verbosity
273+
(checkInvocation hpi verbosity packagedb)
274+
`catchExit` \_ -> die $ programId (hcPkgProgram hpi) ++ " dump failed"
275+
267276
mungePackagePaths :: FilePath -> InstalledPackageInfo -> InstalledPackageInfo
268277
-- Perform path/URL variable substitution as per the Cabal ${pkgroot} spec
269278
-- (http://www.haskell.org/pipermail/libraries/2009-May/011772.html)
@@ -432,6 +441,17 @@ dumpInvocation hpi _verbosity packagedb =
432441
-- We use verbosity level 'silent' because it is important that we
433442
-- do not contaminate the output with info/debug messages.
434443

444+
checkInvocation :: HcPkgInfo -> Verbosity -> PackageDB -> ProgramInvocation
445+
checkInvocation hpi _verbosity packagedb =
446+
(programInvocation (hcPkgProgram hpi) args) {
447+
progInvokeOutputEncoding = IOEncodingUTF8
448+
}
449+
where
450+
args = ["check", packageDbOpts hpi packagedb]
451+
++ verbosityOpts hpi silent
452+
-- We use verbosity level 'silent' because it is important that we
453+
-- do not contaminate the output with info/debug messages.
454+
435455
listInvocation :: HcPkgInfo -> Verbosity -> PackageDB -> ProgramInvocation
436456
listInvocation hpi _verbosity packagedb =
437457
(programInvocation (hcPkgProgram hpi) args) {

Cabal/Distribution/Simple/Utils.hs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ module Distribution.Simple.Utils (
103103
-- * .cabal and .buildinfo files
104104
defaultPackageDesc,
105105
findPackageDesc,
106+
listPackageDescs,
106107
tryFindPackageDesc,
107108
defaultHookedPackageDesc,
108109
findHookedPackageDesc,
@@ -1224,30 +1225,37 @@ defaultPackageDesc _verbosity = tryFindPackageDesc currentDir
12241225
-- @.cabal@ files.
12251226
findPackageDesc :: FilePath -- ^Where to look
12261227
-> IO (Either String FilePath) -- ^<pkgname>.cabal
1227-
findPackageDesc dir
1228-
= do files <- getDirectoryContents dir
1229-
-- to make sure we do not mistake a ~/.cabal/ dir for a <pkgname>.cabal
1230-
-- file we filter to exclude dirs and null base file names:
1231-
cabalFiles <- filterM doesFileExist
1232-
[ dir </> file
1233-
| file <- files
1234-
, let (name, ext) = splitExtension file
1235-
, not (null name) && ext == ".cabal" ]
1236-
case cabalFiles of
1237-
[] -> return (Left noDesc)
1238-
[cabalFile] -> return (Right cabalFile)
1239-
multiple -> return (Left $ multiDesc multiple)
1240-
1228+
findPackageDesc dir = do
1229+
cabalFiles <- listPackageDescs dir
1230+
case cabalFiles of
1231+
[] -> return (Left noDesc)
1232+
[cabalFile] -> return (Right cabalFile)
1233+
multiple -> return (Left $ multiDesc multiple)
12411234
where
12421235
noDesc :: String
12431236
noDesc = "No cabal file found.\n"
12441237
++ "Please create a package description file <pkgname>.cabal"
1245-
12461238
multiDesc :: [String] -> String
12471239
multiDesc l = "Multiple cabal files found.\n"
12481240
++ "Please use only one of: "
12491241
++ intercalate ", " l
12501242

1243+
-- | List all package descriptions in the given directory.
1244+
--
1245+
-- In contrast to 'findPackageDesc', finding more than one
1246+
-- package description is possible and does not lead
1247+
-- to an error/'Left' value.
1248+
listPackageDescs :: FilePath -> IO [FilePath]
1249+
listPackageDescs dir = do
1250+
files <- getDirectoryContents dir
1251+
-- to make sure we do not mistake a ~/.cabal/ dir for a <pkgname>.cabal
1252+
-- file we filter to exclude dirs and null base file names:
1253+
filterM doesFileExist
1254+
[ dir </> file
1255+
| file <- files
1256+
, let (name, ext) = splitExtension file
1257+
, not (null name) && ext == ".cabal" ]
1258+
12511259
-- |Like 'findPackageDesc', but calls 'die' in case of error.
12521260
tryFindPackageDesc :: FilePath -> IO FilePath
12531261
tryFindPackageDesc dir = either die return =<< findPackageDesc dir

Cabal/Distribution/Text.hs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ module Distribution.Text (
1515
Text(..),
1616
display,
1717
simpleParse,
18+
render,
19+
brokenString
1820
) where
1921

2022
import qualified Distribution.Compat.ReadP as Parse
@@ -27,13 +29,27 @@ class Text a where
2729
disp :: a -> Disp.Doc
2830
parse :: Parse.ReadP r a
2931

32+
-- | Display a 'Text' value with the Cabal default style.
3033
display :: Text a => a -> String
31-
display = Disp.renderStyle style . disp
32-
where style = Disp.Style {
33-
Disp.mode = Disp.PageMode,
34-
Disp.lineLength = 79,
35-
Disp.ribbonsPerLine = 1.0
36-
}
34+
display = Disp.renderStyle defaultStyle . disp
35+
36+
-- | similar to Disp.render, but using the Cabal default style
37+
-- (which is different from Text.Prettyprint default).
38+
render :: Disp.Doc -> String
39+
render = Disp.renderStyle defaultStyle
40+
41+
-- | Takes a string, and turns it into a paragraph-like
42+
-- Doc, i.e. an fsep of the words in it. Main purpose is
43+
-- to produce indented paragraphs.
44+
brokenString :: String -> Disp.Doc
45+
brokenString s = Disp.fsep $ fmap Disp.text $ words s
46+
47+
defaultStyle :: Disp.Style
48+
defaultStyle = Disp.Style
49+
{ Disp.mode = Disp.PageMode
50+
, Disp.lineLength = 79 -- Disp default: 100
51+
, Disp.ribbonsPerLine = 1.0 -- Disp default: 1.5
52+
}
3753

3854
simpleParse :: Text a => String -> Maybe a
3955
simpleParse str = case [ p | (p, s) <- Parse.readP_to_S parse str

Cabal/changelog

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-*-change-log-*-
22

33
1.25.x.x (current development version)
4-
* No changes yet.
4+
* Add command 'status'
55

66
1.24.0.0 Ryan Thomas <[email protected]> February 2016
77
* Support GHC 8.

Cabal/doc/installing-packages.markdown

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,33 @@ $ cabal --ignore-sandbox install text
349349
# Installs 'text' in the user package database ('~/.cabal').
350350
~~~~~~~~~~~~~~~
351351

352+
## Displaying cabal environment information ##
353+
354+
A cabal environment (the directory containing a package) has a certain state.
355+
One example are the flags of the last (successful) configuration. The
356+
`cabal status` command will print a summary over several
357+
aspects of the environment, such as
358+
359+
* the cabal version;
360+
361+
* the (configured) versions of the compiler and other build-time dependencies;
362+
363+
* the package, its components and the install-plan;
364+
365+
* the (contents of) package-databases, the sandbox etc.
366+
367+
Just `cabal status` will display a default selection of information.
368+
Flags can be used to print specific items only; `cabal status --all` will
369+
print the full summary.
370+
371+
Example:
372+
373+
~~~~~~~~~~~~~~~
374+
$ cabal status --compiler
375+
Configured compiler:
376+
ghc-7.10.3
377+
~~~~~~~~~~~~~~~
378+
352379
## Creating a binary package ##
353380

354381
When creating binary packages (e.g. for Red Hat or Debian) one needs to

cabal-install/Distribution/Client/Freeze.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
-----------------------------------------------------------------------------
1515
module Distribution.Client.Freeze (
1616
freeze,
17+
planPackages
1718
) where
1819

1920
import Distribution.Client.Config ( SavedConfig(..) )

cabal-install/Distribution/Client/Sandbox.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module Distribution.Client.Sandbox (
2020
withSandboxBinDirOnSearchPath,
2121

2222
getSandboxConfigFilePath,
23+
tryLoadSandboxConfig,
2324
loadConfigOrSandboxConfig,
2425
findSavedDistPref,
2526
initPackageDBIfNeeded,

0 commit comments

Comments
 (0)