Commit fe7b5975 authored by Tomas Vestelind's avatar Tomas Vestelind Committed by Mikhail Glushenkov
Browse files

Add new 'user-config' subcommand 'init'.

'cabal user-config init' creates a default config file if it doesn't already
exist.

If '--config-file' is set, then that file will be written.

If '-f' or '--force' is used, then the file will be overwritten if it already
exists.
parent 002d709e
......@@ -37,7 +37,8 @@ module Distribution.Client.Config (
withProgramsFields,
withProgramOptionsFields,
userConfigDiff,
userConfigUpdate
userConfigUpdate,
createDefaultConfigFile
) where
import Distribution.Client.Types
......@@ -526,11 +527,8 @@ loadConfig verbosity configFileFlag = addBaseConf $ do
Nothing -> do
notice verbosity $ "Config file path source is " ++ sourceMsg source ++ "."
notice verbosity $ "Config file " ++ configFile ++ " not found."
notice verbosity $ "Writing default configuration to " ++ configFile
commentConf <- commentSavedConfig
initialConf <- initialSavedConfig
writeConfigFile configFile commentConf initialConf
return initialConf
createDefaultConfigFile verbosity configFile
loadConfig verbosity configFileFlag
Just (ParseOk ws conf) -> do
unless (null ws) $ warn verbosity $
unlines (map (showPWarning configFile) ws)
......@@ -579,6 +577,13 @@ readConfigFile initial file = handleNotExists $
then return Nothing
else ioError ioe
createDefaultConfigFile :: Verbosity -> FilePath -> IO ()
createDefaultConfigFile verbosity filePath = do
commentConf <- commentSavedConfig
initialConf <- initialSavedConfig
notice verbosity $ "Writing default configuration to " ++ filePath
writeConfigFile filePath commentConf initialConf
writeConfigFile :: FilePath -> SavedConfig -> SavedConfig -> IO ()
writeConfigFile file comments vals = do
let tmpFile = file <.> "tmp"
......
......@@ -2112,15 +2112,18 @@ instance Monoid ExecFlags where
-- ------------------------------------------------------------
data UserConfigFlags = UserConfigFlags {
userConfigVerbosity :: Flag Verbosity
userConfigVerbosity :: Flag Verbosity,
userConfigForce :: Flag Bool
}
instance Monoid UserConfigFlags where
mempty = UserConfigFlags {
userConfigVerbosity = toFlag normal
userConfigVerbosity = toFlag normal,
userConfigForce = toFlag False
}
mappend a b = UserConfigFlags {
userConfigVerbosity = combine userConfigVerbosity
userConfigVerbosity = combine userConfigVerbosity,
userConfigForce = combine userConfigForce
}
where combine field = field a `mappend` field b
......@@ -2135,6 +2138,9 @@ userConfigCommand = CommandUI {
++ " (i.e. all bindings that are actually defined and not commented out)"
++ " and the default config of the new version.\n"
++ "\n"
++ "init: Creates a new config file at either ~/.cabal/config or as"
++ " specified by --config-file, if given. An existing file won't be "
++ " overwritten unless -f or --force is given.\n"
++ "diff: Shows a pseudo-diff of the user's ~/.cabal/config file and"
++ " the default configuration that would be created by cabal if the"
++ " config file did not exist.\n"
......@@ -2142,10 +2148,14 @@ userConfigCommand = CommandUI {
++ " created by default, and write the result back to ~/.cabal/config.",
commandNotes = Nothing,
commandUsage = usageAlternatives "user-config" ["diff", "update"],
commandUsage = usageAlternatives "user-config" ["init", "diff", "update"],
commandDefaultFlags = mempty,
commandOptions = \ _ -> [
optionVerbosity userConfigVerbosity (\v flags -> flags { userConfigVerbosity = v })
, option ['f'] ["force"]
"Overwrite the config file if it already exists."
userConfigForce (\v flags -> flags { userConfigForce = v })
trueArg
]
}
......
......@@ -60,7 +60,7 @@ import Distribution.Client.SetupWrapper
( setupWrapper, SetupScriptOptions(..), defaultSetupScriptOptions )
import Distribution.Client.Config
( SavedConfig(..), loadConfig, defaultConfigFile, userConfigDiff
, userConfigUpdate )
, userConfigUpdate, createDefaultConfigFile )
import Distribution.Client.Targets
( readUserTargets )
import qualified Distribution.Client.List as List
......@@ -1224,13 +1224,22 @@ execAction execFlags extraArgs globalFlags = do
userConfigAction :: UserConfigFlags -> [String] -> Action
userConfigAction ucflags extraArgs globalFlags = do
let verbosity = fromFlag (userConfigVerbosity ucflags)
force = fromFlag (userConfigForce ucflags)
case extraArgs of
("init":_) -> do
path <- configFile
fileExists <- doesFileExist path
if (not fileExists || (fileExists && force))
then createDefaultConfigFile verbosity path
else die $ path ++ " already exists."
("diff":_) -> mapM_ putStrLn =<< userConfigDiff globalFlags
("update":_) -> userConfigUpdate verbosity globalFlags
-- Error handling.
[] -> die $ "Please specify a subcommand (see 'help user-config')"
_ -> die $ "Unknown 'user-config' subcommand: " ++ unwords extraArgs
where configFile = do
defaultFile <- defaultConfigFile
return $ fromFlagOrDefault defaultFile (globalConfigFile globalFlags)
-- | See 'Distribution.Client.Install.withWin32SelfUpgrade' for details.
--
......
......@@ -37,6 +37,9 @@
* Support for secure repos using hackage-security (#2983).
* Added a log file message similar to one printed by 'make' when
building in another directory (#2642).
* Added new subcommand 'init' to 'cabal user-config'. This
subcommand creates a cabal configuration file in either the
default location or as specified by --config-file (#2553).
1.22.0.0 Johan Tibell <johan.tibell@gmail.com> January 2015
* New command: user-config (#2159).
......
# Helper to run Cabal
cabal() {
$CABAL $CABAL_ARGS "$@"
}
die() {
echo "die: $@"
exit 1
}
. ../common.sh
rm -f ./cabal-config
cabal --config-file=./cabal-config user-config init > /dev/null
cabal --config-file=./cabal-config user-config init
rm -f ./cabal-config
-- This is the configuration file for the 'cabal' command line tool.
-- The available configuration options are listed below.
-- Some of them have default values listed.
-- Lines (like this one) beginning with '--' are comments.
-- Be careful with spaces and indentation because they are
-- used to indicate layout for nested sections.
-- Cabal library version: 1.23.1.0
-- cabal-install version: 1.23.0.0
repository hackage.haskell.org
url: http://hackage.haskell.org/
-- default-user-config:
-- require-sandbox: False
-- ignore-sandbox: False
-- ignore-expiry: False
-- http-transport:
remote-repo-cache: /home/gman/.cabal/packages
-- local-repo:
-- logs-dir:
world-file: /home/gman/.cabal/world
-- verbose: 1
-- compiler: ghc
-- with-compiler:
-- with-hc-pkg:
-- program-prefix:
-- program-suffix:
-- library-vanilla: True
-- library-profiling:
-- shared:
-- executable-dynamic: False
-- profiling:
-- executable-profiling:
-- profiling-detail:
-- library-profiling-detail:
-- optimization: True
-- debug-info: False
-- library-for-ghci:
-- split-objs: False
-- executable-stripping: True
-- library-stripping: True
-- configure-option:
-- user-install: True
-- package-db:
-- flags:
-- extra-include-dirs:
-- extra-lib-dirs:
extra-prog-path: /home/gman/.cabal/bin
-- tests: False
-- coverage: False
-- library-coverage:
-- exact-configuration: False
-- benchmarks: False
-- relocatable: False
-- cabal-lib-version:
-- constraint:
-- preference:
-- solver: choose
-- allow-newer: False
-- documentation: False
-- doc-index-file: $datadir/doc/$arch-$os-$compiler/index.html
-- max-backjumps: 2000
-- reorder-goals: False
-- shadow-installed-packages: False
-- strong-flags: False
-- reinstall: False
-- avoid-reinstalls: False
-- force-reinstalls: False
-- upgrade-dependencies: False
-- root-cmd:
-- symlink-bindir:
build-summary: /home/gman/.cabal/logs/build.log
-- build-log:
remote-build-reporting: anonymous
-- report-planning-failure: False
-- one-shot: False
-- run-tests:
jobs: $ncpus
-- offline: False
-- username:
-- password:
-- password-command:
-- builddir:
haddock
-- keep-temp-files: False
-- hoogle: False
-- html: False
-- html-location:
-- for-hackage: False
-- executables: False
-- tests: False
-- benchmarks: False
-- all:
-- internal: False
-- css:
-- hyperlink-source: False
-- hscolour-css:
-- contents-location:
install-dirs user
-- prefix: /home/gman/.cabal
-- bindir: $prefix/bin
-- libdir: $prefix/lib
-- libsubdir: $abi/$libname
-- libexecdir: $prefix/libexec
-- datadir: $prefix/share
-- datasubdir: $abi/$pkgid
-- docdir: $datadir/doc/$abi/$pkgid
-- htmldir: $docdir/html
-- haddockdir: $htmldir
-- sysconfdir: $prefix/etc
install-dirs global
-- prefix: /usr/local
-- bindir: $prefix/bin
-- libdir: $prefix/lib
-- libsubdir: $abi/$libname
-- libexecdir: $prefix/libexec
-- datadir: $prefix/share
-- datasubdir: $abi/$pkgid
-- docdir: $datadir/doc/$abi/$pkgid
-- htmldir: $docdir/html
-- haddockdir: $htmldir
-- sysconfdir: $prefix/etc
program-locations
-- alex-location:
-- ar-location:
-- c2hs-location:
-- cpphs-location:
-- gcc-location:
-- ghc-location:
-- ghc-pkg-location:
-- ghcjs-location:
-- ghcjs-pkg-location:
-- greencard-location:
-- haddock-location:
-- happy-location:
-- haskell-suite-location:
-- haskell-suite-pkg-location:
-- hmake-location:
-- hpc-location:
-- hsc2hs-location:
-- hscolour-location:
-- jhc-location:
-- ld-location:
-- lhc-location:
-- lhc-pkg-location:
-- pkg-config-location:
-- strip-location:
-- tar-location:
-- uhc-location:
program-default-options
-- alex-options:
-- ar-options:
-- c2hs-options:
-- cpphs-options:
-- gcc-options:
-- ghc-options:
-- ghc-pkg-options:
-- ghcjs-options:
-- ghcjs-pkg-options:
-- greencard-options:
-- haddock-options:
-- happy-options:
-- haskell-suite-options:
-- haskell-suite-pkg-options:
-- hmake-options:
-- hpc-options:
-- hsc2hs-options:
-- hscolour-options:
-- jhc-options:
-- ld-options:
-- lhc-options:
-- lhc-pkg-options:
-- pkg-config-options:
-- strip-options:
-- tar-options:
-- uhc-options:
Writing default configuration to ./cabal-config
Writing default configuration to ./cabal-config
. ../common.sh
rm -f ./cabal-config
cabal --config-file=./cabal-config user-config init \
|| die "Couldn't create config file"
cabal --config-file=./cabal-config user-config -f init \
|| die "Couldn't create config file"
test -e ./cabal-config || die "Config file doesn't exist"
rm -f ./cabal-config
. ../common.sh
rm -f ./cabal-config
cabal --config-file=./cabal-config user-config init \
|| die "Couldn't create config file"
test -e ./cabal-config || die "Config file doesn't exist"
rm -f ./cabal-config
......@@ -9,7 +9,8 @@ import Data.List (sort, nub)
#if !MIN_VERSION_base(4,8,0)
import Data.Monoid
#endif
import System.Directory (getCurrentDirectory)
import System.Directory (doesFileExist,
getCurrentDirectory, getTemporaryDirectory)
import System.FilePath ((</>))
import Test.Tasty
......@@ -20,6 +21,7 @@ import Distribution.Utils.NubList (fromNubList)
import Distribution.Client.Setup (GlobalFlags (..), InstallFlags (..))
import Distribution.Client.Utils (removeExistingFile)
import Distribution.Simple.Setup (Flag (..), ConfigFlags (..), fromFlag)
import Distribution.Simple.Utils (withTempDirectory)
import Distribution.Verbosity (silent)
tests :: [TestTree]
......@@ -27,6 +29,7 @@ tests = [ testCase "nullDiffOnCreate" nullDiffOnCreateTest
, testCase "canDetectDifference" canDetectDifference
, testCase "canUpdateConfig" canUpdateConfig
, testCase "doubleUpdateConfig" doubleUpdateConfig
, testCase "newDefaultConfig" newDefaultConfig
]
nullDiffOnCreateTest :: Assertion
......@@ -77,6 +80,16 @@ doubleUpdateConfig = bracketTest $ \configFile -> do
listUnique (map show . fromNubList . installSummaryFile $ savedInstallFlags updated)
newDefaultConfig :: Assertion
newDefaultConfig = do
sysTmpDir <- getTemporaryDirectory
withTempDirectory silent sysTmpDir "cabal-test" $ \tmpDir -> do
let configFile = tmpDir </> "tmp.config"
createDefaultConfigFile silent configFile
exists <- doesFileExist configFile
assertBool ("Config file should be written to " ++ configFile) exists
globalFlags :: FilePath -> GlobalFlags
globalFlags configFile = mempty { globalConfigFile = Flag configFile }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment