Skip to content

Commit 70600e9

Browse files
committed
Merge pull request #2633 from tibbe/act-as-setup
Allow using cabal program itself as the external setup method
2 parents 2cf65bf + 03b02fb commit 70600e9

File tree

3 files changed

+108
-8
lines changed

3 files changed

+108
-8
lines changed

cabal-install/Distribution/Client/Setup.hs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ module Distribution.Client.Setup
3535
, initCommand, IT.InitFlags(..)
3636
, sdistCommand, SDistFlags(..), SDistExFlags(..), ArchiveFormat(..)
3737
, win32SelfUpgradeCommand, Win32SelfUpgradeFlags(..)
38+
, actAsSetupCommand, ActAsSetupFlags(..)
3839
, sandboxCommand, defaultSandboxLocation, SandboxFlags(..)
3940
, execCommand, ExecFlags(..)
4041
, userConfigCommand, UserConfigFlags(..)
@@ -79,7 +80,7 @@ import Distribution.Version
7980
import Distribution.Package
8081
( PackageIdentifier, packageName, packageVersion, Dependency(..) )
8182
import Distribution.PackageDescription
82-
( RepoKind(..) )
83+
( BuildType(..), RepoKind(..) )
8384
import Distribution.Text
8485
( Text(..), display )
8586
import Distribution.ReadE
@@ -1813,6 +1814,47 @@ instance Monoid Win32SelfUpgradeFlags where
18131814
}
18141815
where combine field = field a `mappend` field b
18151816

1817+
-- ------------------------------------------------------------
1818+
-- * ActAsSetup flags
1819+
-- ------------------------------------------------------------
1820+
1821+
data ActAsSetupFlags = ActAsSetupFlags {
1822+
actAsSetupBuildType :: Flag BuildType
1823+
}
1824+
1825+
defaultActAsSetupFlags :: ActAsSetupFlags
1826+
defaultActAsSetupFlags = ActAsSetupFlags {
1827+
actAsSetupBuildType = toFlag Simple
1828+
}
1829+
1830+
actAsSetupCommand :: CommandUI ActAsSetupFlags
1831+
actAsSetupCommand = CommandUI {
1832+
commandName = "act-as-setup",
1833+
commandSynopsis = "Run as-if this was a Setup.hs",
1834+
commandDescription = Nothing,
1835+
commandNotes = Nothing,
1836+
commandUsage = \pname ->
1837+
"Usage: " ++ pname ++ " act-as-setup\n",
1838+
commandDefaultFlags = defaultActAsSetupFlags,
1839+
commandOptions = \_ ->
1840+
[option "" ["build-type"]
1841+
"Use the given build type."
1842+
actAsSetupBuildType (\v flags -> flags { actAsSetupBuildType = v })
1843+
(reqArg "BUILD-TYPE" (readP_to_E ("Cannot parse build type: "++)
1844+
(fmap toFlag parse))
1845+
(map display . flagToList))
1846+
]
1847+
}
1848+
1849+
instance Monoid ActAsSetupFlags where
1850+
mempty = ActAsSetupFlags {
1851+
actAsSetupBuildType = mempty
1852+
}
1853+
mappend a b = ActAsSetupFlags {
1854+
actAsSetupBuildType = combine actAsSetupBuildType
1855+
}
1856+
where combine field = field a `mappend` field b
1857+
18161858
-- ------------------------------------------------------------
18171859
-- * Sandbox-related flags
18181860
-- ------------------------------------------------------------

cabal-install/Distribution/Client/SetupWrapper.hs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ import Control.Monad ( when, unless )
105105
import Data.List ( foldl1' )
106106
import Data.Maybe ( fromMaybe, isJust )
107107
import Data.Char ( isSpace )
108+
import Distribution.Client.Compat.ExecutablePath ( getExecutablePath )
108109

109110
#ifdef mingw32_HOST_OS
110111
import Distribution.Simple.Utils
@@ -222,12 +223,22 @@ setupWrapper verbosity options mpkg cmd flags extraArgs = do
222223
--
223224
determineSetupMethod :: SetupScriptOptions -> BuildType -> SetupMethod
224225
determineSetupMethod options buildType'
225-
| forceExternalSetupMethod options = externalSetupMethod
226+
-- This order is picked so that it's stable. The build type and
227+
-- required cabal version are external info, coming from .cabal
228+
-- files and the command line. Those do switch between the
229+
-- external and self & internal methods, but that info itself can
230+
-- be considered stable. The logging and force-external conditions
231+
-- are internally generated choices but now these only switch
232+
-- between the self and internal setup methods, which are
233+
-- consistent with each other.
234+
| buildType' == Custom = externalSetupMethod
235+
| not (cabalVersion `withinRange`
236+
useCabalVersion options) = externalSetupMethod
226237
| isJust (useLoggingHandle options)
227-
|| buildType' == Custom = externalSetupMethod
228-
| cabalVersion `withinRange`
229-
useCabalVersion options = internalSetupMethod
230-
| otherwise = externalSetupMethod
238+
-- Forcing is done to use an external process e.g. due to parallel
239+
-- build concerns.
240+
|| forceExternalSetupMethod options = selfExecSetupMethod
241+
| otherwise = internalSetupMethod
231242

232243
type SetupMethod = Verbosity
233244
-> SetupScriptOptions
@@ -255,6 +266,34 @@ buildTypeAction Make = Make.defaultMainArgs
255266
buildTypeAction Custom = error "buildTypeAction Custom"
256267
buildTypeAction (UnknownBuildType _) = error "buildTypeAction UnknownBuildType"
257268

269+
-- ------------------------------------------------------------
270+
-- * Self-Exec SetupMethod
271+
-- ------------------------------------------------------------
272+
273+
selfExecSetupMethod :: SetupMethod
274+
selfExecSetupMethod verbosity options _pkg bt mkargs = do
275+
let args = ["act-as-setup",
276+
"--build-type=" ++ display bt,
277+
"--"] ++ mkargs cabalVersion
278+
debug verbosity $ "Using self-exec internal setup method with build-type "
279+
++ show bt ++ " and args:\n " ++ show args
280+
path <- getExecutablePath
281+
info verbosity $ unwords (path : args)
282+
case useLoggingHandle options of
283+
Nothing -> return ()
284+
Just logHandle -> info verbosity $ "Redirecting build log to "
285+
++ show logHandle
286+
287+
searchpath <- programSearchPathAsPATHVar
288+
(getProgramSearchPath (useProgramConfig options))
289+
env <- getEffectiveEnvironment [("PATH", Just searchpath)]
290+
291+
process <- runProcess path args
292+
(useWorkingDir options) env Nothing
293+
(useLoggingHandle options) (useLoggingHandle options)
294+
exitCode <- waitForProcess process
295+
unless (exitCode == ExitSuccess) $ exitWith exitCode
296+
258297
-- ------------------------------------------------------------
259298
-- * External SetupMethod
260299
-- ------------------------------------------------------------

cabal-install/Main.hs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import Distribution.Client.Setup
3737
, InitFlags(initVerbosity), initCommand
3838
, SDistFlags(..), SDistExFlags(..), sdistCommand
3939
, Win32SelfUpgradeFlags(..), win32SelfUpgradeCommand
40+
, ActAsSetupFlags(..), actAsSetupCommand
4041
, SandboxFlags(..), sandboxCommand
4142
, ExecFlags(..), execCommand
4243
, UserConfigFlags(..), userConfigCommand
@@ -112,12 +113,14 @@ import Distribution.Client.Utils (determineNumJobs
112113
,existsAndIsMoreRecentThan)
113114

114115
import Distribution.PackageDescription
115-
( Executable(..), benchmarkName, benchmarkBuildInfo, testName
116-
, testBuildInfo, buildable )
116+
( BuildType(..), Executable(..), benchmarkName, benchmarkBuildInfo
117+
, testName, testBuildInfo, buildable )
117118
import Distribution.PackageDescription.Parse
118119
( readPackageDescription )
119120
import Distribution.PackageDescription.PrettyPrint
120121
( writeGenericPackageDescription )
122+
import qualified Distribution.Simple as Simple
123+
import qualified Distribution.Make as Make
121124
import Distribution.Simple.Build
122125
( startInterpreter )
123126
import Distribution.Simple.Command
@@ -262,6 +265,8 @@ mainWorker args = topHandler $
262265
upgradeCommand `commandAddAction` upgradeAction
263266
,hiddenCommand $
264267
win32SelfUpgradeCommand`commandAddAction` win32SelfUpgradeAction
268+
,hiddenCommand $
269+
actAsSetupCommand`commandAddAction` actAsSetupAction
265270
]
266271

267272
wrapperAction :: Monoid flags
@@ -1155,3 +1160,17 @@ win32SelfUpgradeAction selfUpgradeFlags (pid:path:_extraArgs) _globalFlags = do
11551160
let verbosity = fromFlag (win32SelfUpgradeVerbosity selfUpgradeFlags)
11561161
Win32SelfUpgrade.deleteOldExeFile verbosity (read pid) path
11571162
win32SelfUpgradeAction _ _ _ = return ()
1163+
1164+
-- | Used as an entry point when cabal-install needs to invoke itself
1165+
-- as a setup script. This can happen e.g. when doing parallel builds.
1166+
--
1167+
actAsSetupAction :: ActAsSetupFlags -> [String] -> GlobalFlags -> IO ()
1168+
actAsSetupAction actAsSetupFlags args _globalFlags =
1169+
let bt = fromFlag (actAsSetupBuildType actAsSetupFlags)
1170+
in case bt of
1171+
Simple -> Simple.defaultMainArgs args
1172+
Configure -> Simple.defaultMainWithHooksArgs
1173+
Simple.autoconfUserHooks args
1174+
Make -> Make.defaultMainArgs args
1175+
Custom -> error "actAsSetupAction Custom"
1176+
(UnknownBuildType _) -> error "actAsSetupAction UnknownBuildType"

0 commit comments

Comments
 (0)