summaryrefslogtreecommitdiff
path: root/src/wrapper.hs
blob: 694067dfd09893fbc9ef81e41584d49efe0e2983 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
-- | Wrapper program for propellor distribution.
--
-- Distributions should install this program into PATH.
-- (Cabal builds it as dist/build/propellor/propellor).
--
-- This is not the propellor main program (that's config.hs)
--
-- This installs propellor's source into ~/.propellor,
-- uses it to build the real propellor program (if not already built),
-- and runs it.
-- 
-- The source is cloned from /usr/src/propellor when available,
-- or is cloned from git over the network.

module Main where

import Utility.UserInfo
import Utility.Monad
import Utility.Process
import Utility.SafeCommand
import Utility.Directory

import Control.Monad
import Control.Monad.IfElse
import System.Directory
import System.FilePath
import System.Environment (getArgs)
import System.Exit
import System.Posix.Directory

localrepo :: FilePath
localrepo = "/usr/src/propellor"

-- Using the github mirror of the main propellor repo because
-- it is accessible over https for better security.
netrepo :: String
netrepo = "https://github.com/joeyh/propellor.git"

main :: IO ()
main = do
	args <- getArgs
	home <- myHomeDir
	let propellordir = home </> ".propellor"
	let propellorbin = propellordir </> "propellor"
	wrapper args propellordir propellorbin

wrapper :: [String] -> FilePath -> FilePath -> IO ()
wrapper args propellordir propellorbin = do
	unlessM (doesDirectoryExist propellordir) $
		makeRepo
	buildruncfg
  where
	chain = do
		(_, _, _, pid) <- createProcess (proc propellorbin args) 
		exitWith =<< waitForProcess pid
	makeRepo = do
		putStrLn $ "Setting up your propellor repo in " ++ propellordir
		putStrLn ""
		ifM (doesDirectoryExist localrepo)
			( do
				void $ boolSystem "git" [Param "clone", File localrepo, File propellordir]
				setuprepo True localrepo
			, do
				void $ boolSystem "git" [Param "clone", Param netrepo, File propellordir] 
				setuprepo False netrepo
			)
	setuprepo fromlocalrepo repolocation = do
		changeWorkingDirectory propellordir
		whenM (doesDirectoryExist "privdata") $
			mapM_ nukeFile =<< dirContents "privdata"
		void $ boolSystem "git" [Param "remote", Param "rm", Param "origin"]
		void $ boolSystem "git" [Param "remote", Param "add", Param "upstream", Param repolocation]
		-- Connect synthetic git repo with upstream history so
		-- merging with upstream will work going forward.
		-- Note -s ours is used to avoid getting any divergent
		-- changes from upstream.
		when (not fromlocalrepo) $ do
			void $ boolSystem "git" [Param "fetch", Param "upstream"]
			version <- readProcess "dpkg-query" ["--showformat", "${Version}", "--show", "propellor"]
			void $ boolSystem "git" [Param "merge", Param "-s", Param "ours", Param version]
	buildruncfg = do
		changeWorkingDirectory propellordir
		ifM (boolSystem "make" [Param "build"])
			( do
				putStrLn ""
				putStrLn ""
				chain
			, error "Propellor build failed."
			)