1 {-# LANGUAGE RecordWildCards #-}
2 -- | cabal-install CLI command: configure
4 module Distribution
.Client
.CmdConfigure
(
10 import Distribution
.Client
.Compat
.Prelude
13 import System
.Directory
14 import System
.FilePath
16 import Distribution
.Simple
.Flag
17 import Distribution
.Client
.ProjectOrchestration
18 import Distribution
.Client
.ProjectConfig
19 ( writeProjectLocalExtraConfig
, readProjectLocalExtraConfig
)
20 import Distribution
.Client
.ProjectFlags
21 ( removeIgnoreProjectOption
)
23 import Distribution
.Client
.NixStyleOptions
24 ( NixStyleFlags
(..), nixStyleOptions
, defaultNixStyleFlags
)
25 import Distribution
.Client
.Setup
26 ( GlobalFlags
, ConfigFlags
(..), ConfigExFlags
(..) )
27 import Distribution
.Verbosity
30 import Distribution
.Simple
.Command
31 ( CommandUI
(..), usageAlternatives
)
32 import Distribution
.Simple
.Utils
33 ( wrapText
, notice
, die
' )
35 import Distribution
.Client
.DistDirLayout
37 import Distribution
.Client
.RebuildMonad
(runRebuild
)
38 import Distribution
.Client
.ProjectConfig
.Types
39 import Distribution
.Client
.HttpUtils
40 import Distribution
.Utils
.NubList
42 import Distribution
.Types
.CondTree
45 configureCommand
:: CommandUI
(NixStyleFlags
())
46 configureCommand
= CommandUI
{
47 commandName
= "v2-configure",
48 commandSynopsis
= "Add extra project configuration.",
49 commandUsage
= usageAlternatives
"v2-configure" [ "[FLAGS]" ],
50 commandDescription
= Just
$ \_
-> wrapText
$
51 "Adjust how the project is built by setting additional package flags "
52 ++ "and other flags.\n\n"
54 ++ "The configuration options are written to the 'cabal.project.local' "
55 ++ "file (or '$project_file.local', if '--project-file' is specified) "
56 ++ "which extends the configuration from the 'cabal.project' file "
57 ++ "(if any). This combination is used as the project configuration for "
58 ++ "all other commands (such as 'v2-build', 'v2-repl' etc) though it "
59 ++ "can be extended/overridden on a per-command basis.\n\n"
61 ++ "The v2-configure command also checks that the project configuration "
62 ++ "will work. In particular it checks that there is a consistent set of "
63 ++ "dependencies for the project as a whole.\n\n"
65 ++ "The 'cabal.project.local' file persists across 'v2-clean' but is "
66 ++ "overwritten on the next use of the 'v2-configure' command. The "
67 ++ "intention is that the 'cabal.project' file should be kept in source "
68 ++ "control but the 'cabal.project.local' should not.\n\n"
70 ++ "It is never necessary to use the 'v2-configure' command. It is "
71 ++ "merely a convenience in cases where you do not want to specify flags "
72 ++ "to 'v2-build' (and other commands) every time and yet do not want "
73 ++ "to alter the 'cabal.project' persistently.",
74 commandNotes
= Just
$ \pname
->
76 ++ " " ++ pname
++ " v2-configure --with-compiler ghc-7.10.3\n"
77 ++ " Adjust the project configuration to use the given compiler\n"
78 ++ " program and check the resulting configuration works.\n"
79 ++ " " ++ pname
++ " v2-configure\n"
80 ++ " Reset the local configuration to empty. To check that the\n"
81 ++ " project configuration works, use 'cabal build'.\n"
83 , commandDefaultFlags
= defaultNixStyleFlags
()
84 , commandOptions
= removeIgnoreProjectOption
85 . nixStyleOptions
(const [])
88 -- | To a first approximation, the @configure@ just runs the first phase of
89 -- the @build@ command where we bring the install plan up to date (thus
90 -- checking that it's possible).
92 -- The only difference is that @configure@ also allows the user to specify
93 -- some extra config flags which we save in the file @cabal.project.local@.
95 -- For more details on how this works, see the module
96 -- "Distribution.Client.ProjectOrchestration"
98 configureAction
:: NixStyleFlags
() -> [String] -> GlobalFlags
-> IO ()
99 configureAction flags
@NixStyleFlags
{..} extraArgs globalFlags
= do
100 (baseCtx
, projConfig
) <- configureAction
' flags extraArgs globalFlags
102 if shouldNotWriteFile baseCtx
103 then notice v
"Config file not written due to flag(s)."
104 else writeProjectLocalExtraConfig
(distDirLayout baseCtx
) projConfig
106 v
= fromFlagOrDefault normal
(configVerbosity configFlags
)
108 configureAction
' :: NixStyleFlags
() -> [String] -> GlobalFlags
-> IO (ProjectBaseContext
, ProjectConfig
)
109 configureAction
' flags
@NixStyleFlags
{..} _extraArgs globalFlags
= do
110 --TODO: deal with _extraArgs, since flags with wrong syntax end up there
112 baseCtx
<- establishProjectBaseContext v cliConfig OtherCommand
114 let localFile
= distProjectFile
(distDirLayout baseCtx
) "local"
115 -- If cabal.project.local already exists, and the flags allow, back up to cabal.project.local~
116 let backups
= fromFlagOrDefault
True $ configBackup configExFlags
117 appends
= fromFlagOrDefault
False $ configAppend configExFlags
118 backupFile
= localFile
<> "~"
120 if shouldNotWriteFile baseCtx
122 return (baseCtx
, cliConfig
)
124 exists
<- doesFileExist localFile
125 when (exists
&& backups
) $ do
127 quote
(takeFileName localFile
) <> " already exists, backing it up to "
128 <> quote
(takeFileName backupFile
) <> "."
129 copyFile localFile backupFile
131 -- If the flag @configAppend@ is set to true, append and do not overwrite
134 httpTransport
<- configureTransport v
135 (fromNubList
. projectConfigProgPathExtra
$ projectConfigShared cliConfig
)
136 (flagToMaybe
. projectConfigHttpTransport
$ projectConfigBuildOnly cliConfig
)
137 (CondNode conf imps bs
) <- runRebuild
(distProjectRootDirectory
. distDirLayout
$ baseCtx
) $
138 readProjectLocalExtraConfig v httpTransport
(distDirLayout baseCtx
)
139 when (not (null imps
&& null bs
)) $ die
' v
"local project file has conditional and/or import logic, unable to perform and automatic in-place update"
140 return (baseCtx
, conf
<> cliConfig
)
142 return (baseCtx
, cliConfig
)
144 v
= fromFlagOrDefault normal
(configVerbosity configFlags
)
145 cliConfig
= commandLineFlagsToProjectConfig globalFlags flags
146 mempty
-- ClientInstallFlags, not needed here
147 quote s
= "'" <> s
<> "'"
149 -- Config file should not be written when certain flags are present
150 shouldNotWriteFile
:: ProjectBaseContext
-> Bool
151 shouldNotWriteFile baseCtx
=
152 buildSettingDryRun
(buildSettings baseCtx
)
153 || buildSettingOnlyDownload
(buildSettings baseCtx
)