diff --git a/Makefile b/Makefile index 414f674..d706d8e 100644 --- a/Makefile +++ b/Makefile @@ -9,18 +9,10 @@ run: deps build dev: build tags -build: dist/setup-config - @if ! $(CABAL) build; then $(CABAL) configure; $(CABAL) build; fi - @ln -sf dist/build/propellor-config/propellor-config propellor - deps: @if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install $(DEBDEPS) || (apt-get update && apt-get --no-upgrade --no-install-recommends -y install $(DEBDEPS)); fi || true @if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install libghc-async-dev || (cabal update; cabal install async); fi || true -dist/setup-config: propellor.cabal - @if [ "$(CABAL)" = ./Setup ]; then ghc --make Setup; fi - @$(CABAL) configure - install: propellor.1 install -d $(DESTDIR)/usr/bin $(DESTDIR)/usr/src/propellor install -s dist/build/propellor/propellor $(DESTDIR)/usr/bin/propellor @@ -56,3 +48,14 @@ hackage: @cabal upload dist/*.tar.gz .PHONY: tags + +# The rules below are only used when bootstrapping new propellor +# installations; propellor contains equivilant haksell code. + +build: dist/setup-config + @if ! $(CABAL) build; then $(CABAL) configure; $(CABAL) build; fi + @ln -sf dist/build/propellor-config/propellor-config propellor + +dist/setup-config: propellor.cabal + @if [ "$(CABAL)" = ./Setup ]; then ghc --make Setup; fi + @$(CABAL) configure diff --git a/debian/changelog b/debian/changelog index 47e683c..ca7452a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ propellor (2.2.0) UNRELEASED; urgency=medium improve process name visible in ps. * Add shebang to cron.daily etc files. * Some changes to tor configuration, minor API change. + * Propellor now builds itself without needing the Makefile. -- Joey Hess Mon, 16 Feb 2015 19:00:48 -0400 diff --git a/propellor.cabal b/propellor.cabal index 0615457..ff37003 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -128,6 +128,7 @@ Library Propellor.Types.Result Propellor.Types.CmdLine Other-Modules: + Propellor.Bootstrap Propellor.Git Propellor.Gpg Propellor.Spin diff --git a/src/Propellor/Bootstrap.hs b/src/Propellor/Bootstrap.hs new file mode 100644 index 0000000..7ad4bb1 --- /dev/null +++ b/src/Propellor/Bootstrap.hs @@ -0,0 +1,42 @@ +module Propellor.Bootstrap ( + buildPropellor +) where + +import Propellor +import Utility.SafeCommand + +import System.Posix.Files + +buildPropellor :: IO () +buildPropellor = unlessM (actionMessage "Propellor build" build) $ + errorMessage "Propellor build failed!" + +-- Build propellor using cabal, and symlink propellor to where cabal +-- leaves the built binary. +-- +-- For speed, only runs cabal configure when it's not been run before. +-- If the build fails cabal may need to have configure re-run. +build :: IO Bool +build = catchBoolIO $ do + make "dist/setup-config" ["propellor.cabal"] $ + cabal ["configure"] + unlessM (cabal ["build"]) $ do + void $ cabal ["configure"] + unlessM (cabal ["build"]) $ + error "cabal build failed" + nukeFile "propellor" + createSymbolicLink "dist/build/propellor-config/propellor-config" "propellor" + return True + +make :: FilePath -> [FilePath] -> IO Bool -> IO () +make dest srcs builder = do + dt <- getmtime dest + st <- mapM getmtime srcs + when (dt == Nothing || any (> dt) st) $ + unlessM builder $ + error $ "failed to make " ++ dest + where + getmtime = catchMaybeIO . getModificationTime + +cabal :: [String] -> IO Bool +cabal = boolSystem "cabal" . map Param diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs index 15dc09c..9d7d0d9 100644 --- a/src/Propellor/CmdLine.hs +++ b/src/Propellor/CmdLine.hs @@ -12,6 +12,7 @@ import qualified Network.BSD import Propellor import Propellor.Gpg import Propellor.Git +import Propellor.Bootstrap import Propellor.Spin import Propellor.Types.CmdLine import qualified Propellor.Property.Docker as Docker @@ -31,6 +32,7 @@ usage h = hPutStrLn h $ unlines , " propellor --edit field context" , " propellor --list-fields" , " propellor --merge" + , " propellor --build" ] usageError :: [String] -> IO a @@ -128,19 +130,16 @@ unknownhost h hosts = errorMessage $ unlines ] buildFirst :: CmdLine -> IO () -> IO () -buildFirst cmdline next = ifM (doesFileExist "Makefile") - ( do - oldtime <- getmtime - ifM (actionMessage "Propellor build" $ boolSystem "make" [Param "build"]) - ( do - newtime <- getmtime - if newtime == oldtime - then next - else void $ boolSystem "./propellor" [Param "--continue", Param (show cmdline)] - , errorMessage "Propellor build failed!" - ) - , next - ) +buildFirst cmdline next = do + oldtime <- getmtime + buildPropellor + newtime <- getmtime + if newtime == oldtime + then next + else void $ boolSystem "./propellor" + [ Param "--continue" + , Param (show cmdline) + ] where getmtime = catchMaybeIO $ getModificationTime "propellor" @@ -155,10 +154,12 @@ updateFirst cmdline next = ifM hasOrigin (updateFirst' cmdline next, next) updateFirst' :: CmdLine -> IO () -> IO () updateFirst' cmdline next = ifM fetchOrigin - ( ifM (actionMessage "Propellor build" $ boolSystem "make" [Param "build"]) - ( void $ boolSystem "./propellor" [Param "--continue", Param (show cmdline)] - , errorMessage "Propellor build failed!" - ) + ( do + buildPropellor + void $ boolSystem "./propellor" + [ Param "--continue" + , Param (show cmdline) + ] , next ) diff --git a/src/wrapper.hs b/src/wrapper.hs index 304e833..034eb2b 100644 --- a/src/wrapper.hs +++ b/src/wrapper.hs @@ -15,6 +15,7 @@ module Main where import Propellor.Message +import Propellor.Bootstrap import Utility.UserInfo import Utility.Monad import Utility.Process @@ -91,13 +92,10 @@ wrapper args propellordir propellorbin = do warnoutofdate propellordir True buildruncfg = do changeWorkingDirectory propellordir - ifM (boolSystem "make" [Param "build"]) - ( do - putStrLn "" - putStrLn "" - chain - , error "Propellor build failed." - ) + buildPropellor + putStrLn "" + putStrLn "" + chain chain = do (_, _, _, pid) <- createProcess (proc propellorbin args) exitWith =<< waitForProcess pid